Added memory allocation test.
[wine/testsucceed.git] / graphics / metafiledrv / graphics.c
blobe1f5f1828dc243c4268fc7726d36f923442d1c2c
1 /*
2 * Metafile driver graphics functions
4 * Copyright 1993, 1994 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <stdlib.h>
22 #include <string.h>
24 #include "gdi.h"
25 #include "region.h"
26 #include "metafiledrv.h"
27 #include "wine/debug.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(metafile);
31 /**********************************************************************
32 * MFDRV_MoveTo
34 BOOL
35 MFDRV_MoveTo(DC *dc, INT x, INT y)
37 return MFDRV_MetaParam2(dc,META_MOVETO,x,y);
40 /***********************************************************************
41 * MFDRV_LineTo
43 BOOL
44 MFDRV_LineTo( DC *dc, INT x, INT y )
46 return MFDRV_MetaParam2(dc, META_LINETO, x, y);
50 /***********************************************************************
51 * MFDRV_Arc
53 BOOL
54 MFDRV_Arc( DC *dc, INT left, INT top, INT right, INT bottom,
55 INT xstart, INT ystart, INT xend, INT yend )
57 return MFDRV_MetaParam8(dc, META_ARC, left, top, right, bottom,
58 xstart, ystart, xend, yend);
62 /***********************************************************************
63 * MFDRV_Pie
65 BOOL
66 MFDRV_Pie( DC *dc, INT left, INT top, INT right, INT bottom,
67 INT xstart, INT ystart, INT xend, INT yend )
69 return MFDRV_MetaParam8(dc, META_PIE, left, top, right, bottom,
70 xstart, ystart, xend, yend);
74 /***********************************************************************
75 * MFDRV_Chord
77 BOOL
78 MFDRV_Chord( DC *dc, INT left, INT top, INT right, INT bottom,
79 INT xstart, INT ystart, INT xend, INT yend )
81 return MFDRV_MetaParam8(dc, META_CHORD, left, top, right, bottom,
82 xstart, ystart, xend, yend);
85 /***********************************************************************
86 * MFDRV_Ellipse
88 BOOL
89 MFDRV_Ellipse( DC *dc, INT left, INT top, INT right, INT bottom )
91 return MFDRV_MetaParam4(dc, META_ELLIPSE, left, top, right, bottom);
94 /***********************************************************************
95 * MFDRV_Rectangle
97 BOOL
98 MFDRV_Rectangle(DC *dc, INT left, INT top, INT right, INT bottom)
100 return MFDRV_MetaParam4(dc, META_RECTANGLE, left, top, right, bottom);
103 /***********************************************************************
104 * MFDRV_RoundRect
106 BOOL
107 MFDRV_RoundRect( DC *dc, INT left, INT top, INT right,
108 INT bottom, INT ell_width, INT ell_height )
110 return MFDRV_MetaParam6(dc, META_ROUNDRECT, left, top, right, bottom,
111 ell_width, ell_height);
114 /***********************************************************************
115 * MFDRV_SetPixel
117 COLORREF
118 MFDRV_SetPixel( DC *dc, INT x, INT y, COLORREF color )
120 return MFDRV_MetaParam4(dc, META_SETPIXEL, x, y,HIWORD(color),
121 LOWORD(color));
125 /******************************************************************
126 * MFDRV_MetaPoly - implements Polygon and Polyline
128 static BOOL MFDRV_MetaPoly(DC *dc, short func, LPPOINT16 pt, short count)
130 BOOL ret;
131 DWORD len;
132 METARECORD *mr;
134 len = sizeof(METARECORD) + (count * 4);
135 if (!(mr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len )))
136 return FALSE;
138 mr->rdSize = len / 2;
139 mr->rdFunction = func;
140 *(mr->rdParm) = count;
141 memcpy(mr->rdParm + 1, pt, count * 4);
142 ret = MFDRV_WriteRecord( dc, mr, mr->rdSize * 2);
143 HeapFree( GetProcessHeap(), 0, mr);
144 return ret;
148 /**********************************************************************
149 * MFDRV_Polyline
151 BOOL
152 MFDRV_Polyline( DC *dc, const POINT* pt, INT count )
154 register int i;
155 LPPOINT16 pt16;
156 BOOL16 ret;
158 pt16 = (LPPOINT16)HeapAlloc( GetProcessHeap(), 0, sizeof(POINT16)*count );
159 if(!pt16) return FALSE;
160 for (i=count;i--;) CONV_POINT32TO16(&(pt[i]),&(pt16[i]));
161 ret = MFDRV_MetaPoly(dc, META_POLYLINE, pt16, count);
163 HeapFree( GetProcessHeap(), 0, pt16 );
164 return ret;
168 /**********************************************************************
169 * MFDRV_Polygon
171 BOOL
172 MFDRV_Polygon( DC *dc, const POINT* pt, INT count )
174 register int i;
175 LPPOINT16 pt16;
176 BOOL16 ret;
178 pt16 = (LPPOINT16) HeapAlloc( GetProcessHeap(), 0, sizeof(POINT16)*count );
179 if(!pt16) return FALSE;
180 for (i=count;i--;) CONV_POINT32TO16(&(pt[i]),&(pt16[i]));
181 ret = MFDRV_MetaPoly(dc, META_POLYGON, pt16, count);
183 HeapFree( GetProcessHeap(), 0, pt16 );
184 return ret;
188 /**********************************************************************
189 * MFDRV_PolyPolygon
191 BOOL
192 MFDRV_PolyPolygon( DC *dc, const POINT* pt, const INT* counts, UINT polygons)
194 int i,j;
195 LPPOINT16 pt16;
196 const POINT* curpt=pt;
197 BOOL ret;
199 for (i=0;i<polygons;i++) {
200 pt16=(LPPOINT16)HeapAlloc( GetProcessHeap(), 0,
201 sizeof(POINT16) * counts[i] );
202 if(!pt16) return FALSE;
203 for (j=counts[i];j--;) CONV_POINT32TO16(&(curpt[j]),&(pt16[j]));
204 ret = MFDRV_MetaPoly(dc, META_POLYGON, pt16, counts[i]);
205 HeapFree( GetProcessHeap(), 0, pt16 );
206 if (!ret)
207 return FALSE;
208 curpt+=counts[i];
210 return TRUE;
214 /**********************************************************************
215 * MFDRV_ExtFloodFill
217 BOOL
218 MFDRV_ExtFloodFill( DC *dc, INT x, INT y, COLORREF color, UINT fillType )
220 return MFDRV_MetaParam4(dc,META_FLOODFILL,x,y,HIWORD(color),
221 LOWORD(color));
225 /******************************************************************
226 * MFDRV_CreateRegion
228 * For explanation of the format of the record see MF_Play_MetaCreateRegion in
229 * objects/metafile.c
231 static INT16 MFDRV_CreateRegion(DC *dc, HRGN hrgn)
233 DWORD len;
234 METARECORD *mr;
235 RGNDATA *rgndata;
236 RECT *pCurRect, *pEndRect;
237 WORD Bands = 0, MaxBands = 0;
238 WORD *Param, *StartBand;
239 BOOL ret;
241 len = GetRegionData( hrgn, 0, NULL );
242 if( !(rgndata = HeapAlloc( GetProcessHeap(), 0, len )) ) {
243 WARN("Can't alloc rgndata buffer\n");
244 return -1;
246 GetRegionData( hrgn, len, rgndata );
248 /* Overestimate of length:
249 * Assume every rect is a separate band -> 6 WORDs per rect
251 len = sizeof(METARECORD) + 20 + (rgndata->rdh.nCount * 12);
252 if( !(mr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len )) ) {
253 WARN("Can't alloc METARECORD buffer\n");
254 HeapFree( GetProcessHeap(), 0, rgndata );
255 return -1;
258 Param = mr->rdParm + 11;
259 StartBand = NULL;
261 pEndRect = (RECT *)rgndata->Buffer + rgndata->rdh.nCount;
262 for(pCurRect = (RECT *)rgndata->Buffer; pCurRect < pEndRect; pCurRect++)
264 if( StartBand && pCurRect->top == *(StartBand + 1) )
266 *Param++ = pCurRect->left;
267 *Param++ = pCurRect->right;
269 else
271 if(StartBand)
273 *StartBand = Param - StartBand - 3;
274 *Param++ = *StartBand;
275 if(*StartBand > MaxBands)
276 MaxBands = *StartBand;
277 Bands++;
279 StartBand = Param++;
280 *Param++ = pCurRect->top;
281 *Param++ = pCurRect->bottom;
282 *Param++ = pCurRect->left;
283 *Param++ = pCurRect->right;
286 len = Param - (WORD *)mr;
288 mr->rdParm[0] = 0;
289 mr->rdParm[1] = 6;
290 mr->rdParm[2] = 0x1234;
291 mr->rdParm[3] = 0;
292 mr->rdParm[4] = len * 2;
293 mr->rdParm[5] = Bands;
294 mr->rdParm[6] = MaxBands;
295 mr->rdParm[7] = rgndata->rdh.rcBound.left;
296 mr->rdParm[8] = rgndata->rdh.rcBound.top;
297 mr->rdParm[9] = rgndata->rdh.rcBound.right;
298 mr->rdParm[10] = rgndata->rdh.rcBound.bottom;
299 mr->rdFunction = META_CREATEREGION;
300 mr->rdSize = len / 2;
301 ret = MFDRV_WriteRecord( dc, mr, mr->rdSize * 2 );
302 HeapFree( GetProcessHeap(), 0, mr );
303 HeapFree( GetProcessHeap(), 0, rgndata );
304 if(!ret)
306 WARN("MFDRV_WriteRecord failed\n");
307 return -1;
309 return MFDRV_AddHandleDC( dc );
313 /**********************************************************************
314 * MFDRV_PaintRgn
316 BOOL
317 MFDRV_PaintRgn( DC *dc, HRGN hrgn )
319 INT16 index;
320 index = MFDRV_CreateRegion( dc, hrgn );
321 if(index == -1)
322 return FALSE;
323 return MFDRV_MetaParam1( dc, META_PAINTREGION, index );
327 /**********************************************************************
328 * MFDRV_InvertRgn
330 BOOL
331 MFDRV_InvertRgn( DC *dc, HRGN hrgn )
333 INT16 index;
334 index = MFDRV_CreateRegion( dc, hrgn );
335 if(index == -1)
336 return FALSE;
337 return MFDRV_MetaParam1( dc, META_INVERTREGION, index );
341 /**********************************************************************
342 * MFDRV_FillRgn
344 BOOL
345 MFDRV_FillRgn( DC *dc, HRGN hrgn, HBRUSH hbrush )
347 INT16 iRgn, iBrush;
348 iRgn = MFDRV_CreateRegion( dc, hrgn );
349 if(iRgn == -1)
350 return FALSE;
351 iBrush = MFDRV_CreateBrushIndirect( dc, hbrush );
352 if(iBrush == -1)
353 return FALSE;
354 return MFDRV_MetaParam2( dc, META_FILLREGION, iRgn, iBrush );
357 /**********************************************************************
358 * MFDRV_FrameRgn
360 BOOL
361 MFDRV_FrameRgn( DC *dc, HRGN hrgn, HBRUSH hbrush, INT x, INT y )
363 INT16 iRgn, iBrush;
364 iRgn = MFDRV_CreateRegion( dc, hrgn );
365 if(iRgn == -1)
366 return FALSE;
367 iBrush = MFDRV_CreateBrushIndirect( dc, hbrush );
368 if(iBrush == -1)
369 return FALSE;
370 return MFDRV_MetaParam4( dc, META_FRAMEREGION, iRgn, iBrush, x, y );
374 /**********************************************************************
375 * MFDRV_SetBkColor
377 COLORREF
378 MFDRV_SetBkColor( DC *dc, COLORREF color )
380 return MFDRV_MetaParam2(dc, META_SETBKCOLOR, HIWORD(color), LOWORD(color));
384 /**********************************************************************
385 * MFDRV_SetTextColor
387 COLORREF
388 MFDRV_SetTextColor( DC *dc, COLORREF color )
390 return MFDRV_MetaParam2(dc, META_SETTEXTCOLOR, HIWORD(color),
391 LOWORD(color));
395 /**********************************************************************
396 * MFDRV_PolyBezier
397 * Since MetaFiles don't record Beziers and they don't even record
398 * approximations to them using lines, we need this stub function.
400 BOOL
401 MFDRV_PolyBezier( DC *dc, const POINT *pts, DWORD count )
403 return FALSE;
406 /**********************************************************************
407 * MFDRV_PolyBezierTo
408 * Since MetaFiles don't record Beziers and they don't even record
409 * approximations to them using lines, we need this stub function.
411 BOOL
412 MFDRV_PolyBezierTo( DC *dc, const POINT *pts, DWORD count )
414 return FALSE;