2 * Metafile driver graphics functions
4 * Copyright 1993, 1994 Alexandre Julliard
12 #include "metafiledrv.h"
13 #include "debugtools.h"
15 DEFAULT_DEBUG_CHANNEL(metafile);
17 /**********************************************************************
21 MFDRV_MoveTo(DC *dc, INT x, INT y)
23 return MFDRV_MetaParam2(dc,META_MOVETO,x,y);
26 /***********************************************************************
30 MFDRV_LineTo( DC *dc, INT x, INT y )
32 return MFDRV_MetaParam2(dc, META_LINETO, x, y);
36 /***********************************************************************
40 MFDRV_Arc( DC *dc, INT left, INT top, INT right, INT bottom,
41 INT xstart, INT ystart, INT xend, INT yend )
43 return MFDRV_MetaParam8(dc, META_ARC, left, top, right, bottom,
44 xstart, ystart, xend, yend);
48 /***********************************************************************
52 MFDRV_Pie( DC *dc, INT left, INT top, INT right, INT bottom,
53 INT xstart, INT ystart, INT xend, INT yend )
55 return MFDRV_MetaParam8(dc, META_PIE, left, top, right, bottom,
56 xstart, ystart, xend, yend);
60 /***********************************************************************
64 MFDRV_Chord( DC *dc, INT left, INT top, INT right, INT bottom,
65 INT xstart, INT ystart, INT xend, INT yend )
67 return MFDRV_MetaParam8(dc, META_CHORD, left, top, right, bottom,
68 xstart, ystart, xend, yend);
71 /***********************************************************************
75 MFDRV_Ellipse( DC *dc, INT left, INT top, INT right, INT bottom )
77 return MFDRV_MetaParam4(dc, META_ELLIPSE, left, top, right, bottom);
80 /***********************************************************************
84 MFDRV_Rectangle(DC *dc, INT left, INT top, INT right, INT bottom)
86 return MFDRV_MetaParam4(dc, META_RECTANGLE, left, top, right, bottom);
89 /***********************************************************************
93 MFDRV_RoundRect( DC *dc, INT left, INT top, INT right,
94 INT bottom, INT ell_width, INT ell_height )
96 return MFDRV_MetaParam6(dc, META_ROUNDRECT, left, top, right, bottom,
97 ell_width, ell_height);
100 /***********************************************************************
104 MFDRV_SetPixel( DC *dc, INT x, INT y, COLORREF color )
106 return MFDRV_MetaParam4(dc, META_SETPIXEL, x, y,HIWORD(color),
111 /******************************************************************
112 * MFDRV_MetaPoly - implements Polygon and Polyline
114 static BOOL MFDRV_MetaPoly(DC *dc, short func, LPPOINT16 pt, short count)
120 len = sizeof(METARECORD) + (count * 4);
121 if (!(mr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len )))
124 mr->rdSize = len / 2;
125 mr->rdFunction = func;
126 *(mr->rdParm) = count;
127 memcpy(mr->rdParm + 1, pt, count * 4);
128 ret = MFDRV_WriteRecord( dc, mr, mr->rdSize * 2);
129 HeapFree( GetProcessHeap(), 0, mr);
134 /**********************************************************************
138 MFDRV_Polyline( DC *dc, const POINT* pt, INT count )
144 pt16 = (LPPOINT16)HeapAlloc( GetProcessHeap(), 0, sizeof(POINT16)*count );
145 if(!pt16) return FALSE;
146 for (i=count;i--;) CONV_POINT32TO16(&(pt[i]),&(pt16[i]));
147 ret = MFDRV_MetaPoly(dc, META_POLYLINE, pt16, count);
149 HeapFree( GetProcessHeap(), 0, pt16 );
154 /**********************************************************************
158 MFDRV_Polygon( DC *dc, const POINT* pt, INT count )
164 pt16 = (LPPOINT16) HeapAlloc( GetProcessHeap(), 0, sizeof(POINT16)*count );
165 if(!pt16) return FALSE;
166 for (i=count;i--;) CONV_POINT32TO16(&(pt[i]),&(pt16[i]));
167 ret = MFDRV_MetaPoly(dc, META_POLYGON, pt16, count);
169 HeapFree( GetProcessHeap(), 0, pt16 );
174 /**********************************************************************
178 MFDRV_PolyPolygon( DC *dc, const POINT* pt, const INT* counts, UINT polygons)
182 const POINT* curpt=pt;
185 for (i=0;i<polygons;i++) {
186 pt16=(LPPOINT16)HeapAlloc( GetProcessHeap(), 0,
187 sizeof(POINT16) * counts[i] );
188 if(!pt16) return FALSE;
189 for (j=counts[i];j--;) CONV_POINT32TO16(&(curpt[j]),&(pt16[j]));
190 ret = MFDRV_MetaPoly(dc, META_POLYGON, pt16, counts[i]);
191 HeapFree( GetProcessHeap(), 0, pt16 );
200 /**********************************************************************
204 MFDRV_ExtFloodFill( DC *dc, INT x, INT y, COLORREF color, UINT fillType )
206 return MFDRV_MetaParam4(dc,META_FLOODFILL,x,y,HIWORD(color),
211 /******************************************************************
214 * For explanation of the format of the record see MF_Play_MetaCreateRegion in
217 static INT16 MFDRV_CreateRegion(DC *dc, HRGN hrgn)
222 RECT *pCurRect, *pEndRect;
223 WORD Bands = 0, MaxBands = 0;
224 WORD *Param, *StartBand;
227 len = GetRegionData( hrgn, 0, NULL );
228 if( !(rgndata = HeapAlloc( GetProcessHeap(), 0, len )) ) {
229 WARN("Can't alloc rgndata buffer\n");
232 GetRegionData( hrgn, len, rgndata );
234 /* Overestimate of length:
235 * Assume every rect is a separate band -> 6 WORDs per rect
237 len = sizeof(METARECORD) + 20 + (rgndata->rdh.nCount * 12);
238 if( !(mr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len )) ) {
239 WARN("Can't alloc METARECORD buffer\n");
240 HeapFree( GetProcessHeap(), 0, rgndata );
244 Param = mr->rdParm + 11;
247 pEndRect = (RECT *)rgndata->Buffer + rgndata->rdh.nCount;
248 for(pCurRect = (RECT *)rgndata->Buffer; pCurRect < pEndRect; pCurRect++)
250 if( StartBand && pCurRect->top == *(StartBand + 1) )
252 *Param++ = pCurRect->left;
253 *Param++ = pCurRect->right;
259 *StartBand = Param - StartBand - 3;
260 *Param++ = *StartBand;
261 if(*StartBand > MaxBands)
262 MaxBands = *StartBand;
266 *Param++ = pCurRect->top;
267 *Param++ = pCurRect->bottom;
268 *Param++ = pCurRect->left;
269 *Param++ = pCurRect->right;
272 len = Param - (WORD *)mr;
276 mr->rdParm[2] = 0x1234;
278 mr->rdParm[4] = len * 2;
279 mr->rdParm[5] = Bands;
280 mr->rdParm[6] = MaxBands;
281 mr->rdParm[7] = rgndata->rdh.rcBound.left;
282 mr->rdParm[8] = rgndata->rdh.rcBound.top;
283 mr->rdParm[9] = rgndata->rdh.rcBound.right;
284 mr->rdParm[10] = rgndata->rdh.rcBound.bottom;
285 mr->rdFunction = META_CREATEREGION;
286 mr->rdSize = len / 2;
287 ret = MFDRV_WriteRecord( dc, mr, mr->rdSize * 2 );
288 HeapFree( GetProcessHeap(), 0, mr );
289 HeapFree( GetProcessHeap(), 0, rgndata );
292 WARN("MFDRV_WriteRecord failed\n");
295 return MFDRV_AddHandleDC( dc );
299 /**********************************************************************
303 MFDRV_PaintRgn( DC *dc, HRGN hrgn )
306 index = MFDRV_CreateRegion( dc, hrgn );
309 return MFDRV_MetaParam1( dc, META_PAINTREGION, index );
313 /**********************************************************************
317 MFDRV_InvertRgn( DC *dc, HRGN hrgn )
320 index = MFDRV_CreateRegion( dc, hrgn );
323 return MFDRV_MetaParam1( dc, META_INVERTREGION, index );
327 /**********************************************************************
331 MFDRV_FillRgn( DC *dc, HRGN hrgn, HBRUSH hbrush )
334 iRgn = MFDRV_CreateRegion( dc, hrgn );
337 iBrush = MFDRV_CreateBrushIndirect( dc, hbrush );
340 return MFDRV_MetaParam2( dc, META_FILLREGION, iRgn, iBrush );
343 /**********************************************************************
347 MFDRV_FrameRgn( DC *dc, HRGN hrgn, HBRUSH hbrush, INT x, INT y )
350 iRgn = MFDRV_CreateRegion( dc, hrgn );
353 iBrush = MFDRV_CreateBrushIndirect( dc, hbrush );
356 return MFDRV_MetaParam4( dc, META_FRAMEREGION, iRgn, iBrush, x, y );
360 /**********************************************************************
364 MFDRV_SetBkColor( DC *dc, COLORREF color )
366 return MFDRV_MetaParam2(dc, META_SETBKCOLOR, HIWORD(color), LOWORD(color));
370 /**********************************************************************
374 MFDRV_SetTextColor( DC *dc, COLORREF color )
376 return MFDRV_MetaParam2(dc, META_SETTEXTCOLOR, HIWORD(color),
381 /**********************************************************************
383 * Since MetaFiles don't record Beziers and they don't even record
384 * approximations to them using lines, we need this stub function.
387 MFDRV_PolyBezier( DC *dc, const POINT *pts, DWORD count )
392 /**********************************************************************
394 * Since MetaFiles don't record Beziers and they don't even record
395 * approximations to them using lines, we need this stub function.
398 MFDRV_PolyBezierTo( DC *dc, const POINT *pts, DWORD count )