2 * Metafile driver graphics functions
4 * Copyright 1993, 1994 Alexandre Julliard
12 #include "metafiledrv.h"
16 /**********************************************************************
20 MFDRV_MoveToEx(DC *dc,INT x,INT y,LPPOINT pt)
22 if (!MFDRV_MetaParam2(dc,META_MOVETO,x,y))
27 pt->x = dc->w.CursPosX;
28 pt->y = dc->w.CursPosY;
35 /***********************************************************************
39 MFDRV_LineTo( DC *dc, INT x, INT y )
41 return MFDRV_MetaParam2(dc, META_LINETO, x, y);
45 /***********************************************************************
49 MFDRV_Arc( DC *dc, INT left, INT top, INT right, INT bottom,
50 INT xstart, INT ystart, INT xend, INT yend )
52 return MFDRV_MetaParam8(dc, META_ARC, left, top, right, bottom,
53 xstart, ystart, xend, yend);
57 /***********************************************************************
61 MFDRV_Pie( DC *dc, INT left, INT top, INT right, INT bottom,
62 INT xstart, INT ystart, INT xend, INT yend )
64 return MFDRV_MetaParam8(dc, META_PIE, left, top, right, bottom,
65 xstart, ystart, xend, yend);
69 /***********************************************************************
73 MFDRV_Chord( DC *dc, INT left, INT top, INT right, INT bottom,
74 INT xstart, INT ystart, INT xend, INT yend )
76 return MFDRV_MetaParam8(dc, META_CHORD, left, top, right, bottom,
77 xstart, ystart, xend, yend);
80 /***********************************************************************
84 MFDRV_Ellipse( DC *dc, INT left, INT top, INT right, INT bottom )
86 return MFDRV_MetaParam4(dc, META_ELLIPSE, left, top, right, bottom);
89 /***********************************************************************
93 MFDRV_Rectangle(DC *dc, INT left, INT top, INT right, INT bottom)
95 return MFDRV_MetaParam4(dc, META_RECTANGLE, left, top, right, bottom);
98 /***********************************************************************
102 MFDRV_RoundRect( DC *dc, INT left, INT top, INT right,
103 INT bottom, INT ell_width, INT ell_height )
105 return MFDRV_MetaParam6(dc, META_ROUNDRECT, left, top, right, bottom,
106 ell_width, ell_height);
109 /***********************************************************************
113 MFDRV_SetPixel( DC *dc, INT x, INT y, COLORREF color )
115 return MFDRV_MetaParam4(dc, META_SETPIXEL, x, y,HIWORD(color),
120 /******************************************************************
121 * MFDRV_MetaPoly - implements Polygon and Polyline
123 static BOOL MFDRV_MetaPoly(DC *dc, short func, LPPOINT16 pt, short count)
129 len = sizeof(METARECORD) + (count * 4);
130 if (!(mr = HeapAlloc( SystemHeap, HEAP_ZERO_MEMORY, len )))
133 mr->rdSize = len / 2;
134 mr->rdFunction = func;
135 *(mr->rdParm) = count;
136 memcpy(mr->rdParm + 1, pt, count * 4);
137 ret = MFDRV_WriteRecord( dc, mr, mr->rdSize * 2);
138 HeapFree( SystemHeap, 0, mr);
143 /**********************************************************************
147 MFDRV_Polyline( DC *dc, const POINT* pt, INT count )
153 pt16 = (LPPOINT16)xmalloc(sizeof(POINT16)*count);
154 for (i=count;i--;) CONV_POINT32TO16(&(pt[i]),&(pt16[i]));
155 ret = MFDRV_MetaPoly(dc, META_POLYLINE, pt16, count);
162 /**********************************************************************
166 MFDRV_Polygon( DC *dc, const POINT* pt, INT count )
172 pt16 = (LPPOINT16)xmalloc(sizeof(POINT16)*count);
173 for (i=count;i--;) CONV_POINT32TO16(&(pt[i]),&(pt16[i]));
174 ret = MFDRV_MetaPoly(dc, META_POLYGON, pt16, count);
181 /**********************************************************************
185 MFDRV_PolyPolygon( DC *dc, const POINT* pt, const INT* counts, UINT polygons)
189 const POINT* curpt=pt;
192 for (i=0;i<polygons;i++) {
193 pt16=(LPPOINT16)xmalloc(sizeof(POINT16)*counts[i]);
194 for (j=counts[i];j--;) CONV_POINT32TO16(&(curpt[j]),&(pt16[j]));
195 ret = MFDRV_MetaPoly(dc, META_POLYGON, pt16, counts[i]);
205 /**********************************************************************
209 MFDRV_ExtFloodFill( DC *dc, INT x, INT y, COLORREF color, UINT fillType )
211 return MFDRV_MetaParam4(dc,META_FLOODFILL,x,y,HIWORD(color),
216 /******************************************************************
219 * For explanation of the format of the record see MF_Play_MetaCreateRegion in
222 static INT16 MFDRV_CreateRegion(DC *dc, HRGN hrgn)
227 RECT *pCurRect, *pEndRect;
228 WORD Bands = 0, MaxBands = 0;
229 WORD *Param, *StartBand;
232 len = GetRegionData( hrgn, 0, NULL );
233 if( !(rgndata = HeapAlloc( SystemHeap, 0, len )) ) {
234 WARN(metafile, "Can't alloc rgndata buffer\n");
237 GetRegionData( hrgn, len, rgndata );
239 /* Overestimate of length:
240 * Assume every rect is a separate band -> 6 WORDs per rect
242 len = sizeof(METARECORD) + 20 + (rgndata->rdh.nCount * 12);
243 if( !(mr = HeapAlloc( SystemHeap, HEAP_ZERO_MEMORY, len )) ) {
244 WARN(metafile, "Can't alloc METARECORD buffer\n");
245 HeapFree( SystemHeap, 0, rgndata );
249 Param = mr->rdParm + 11;
252 pEndRect = (RECT *)rgndata->Buffer + rgndata->rdh.nCount;
253 for(pCurRect = (RECT *)rgndata->Buffer; pCurRect < pEndRect; pCurRect++)
255 if( StartBand && pCurRect->top == *(StartBand + 1) )
257 *Param++ = pCurRect->left;
258 *Param++ = pCurRect->right;
264 *StartBand = Param - StartBand - 3;
265 *Param++ = *StartBand;
266 if(*StartBand > MaxBands)
267 MaxBands = *StartBand;
271 *Param++ = pCurRect->top;
272 *Param++ = pCurRect->bottom;
273 *Param++ = pCurRect->left;
274 *Param++ = pCurRect->right;
277 len = Param - (WORD *)mr;
281 mr->rdParm[2] = 0x1234;
283 mr->rdParm[4] = len * 2;
284 mr->rdParm[5] = Bands;
285 mr->rdParm[6] = MaxBands;
286 mr->rdParm[7] = rgndata->rdh.rcBound.left;
287 mr->rdParm[8] = rgndata->rdh.rcBound.top;
288 mr->rdParm[9] = rgndata->rdh.rcBound.right;
289 mr->rdParm[10] = rgndata->rdh.rcBound.bottom;
290 mr->rdFunction = META_CREATEREGION;
291 mr->rdSize = len / 2;
292 ret = MFDRV_WriteRecord( dc, mr, mr->rdSize * 2 );
293 HeapFree( SystemHeap, 0, mr );
294 HeapFree( SystemHeap, 0, rgndata );
297 WARN(metafile, "MFDRV_WriteRecord failed\n");
300 return MFDRV_AddHandleDC( dc );
304 /**********************************************************************
308 MFDRV_PaintRgn( DC *dc, HRGN hrgn )
311 index = MFDRV_CreateRegion( dc, hrgn );
314 return MFDRV_MetaParam1( dc, META_PAINTREGION, index );
318 /**********************************************************************
322 MFDRV_SetBkColor( DC *dc, COLORREF color )
324 return MFDRV_MetaParam2(dc, META_SETBKCOLOR, HIWORD(color), LOWORD(color));
328 /**********************************************************************
332 MFDRV_SetTextColor( DC *dc, COLORREF color )
334 return MFDRV_MetaParam2(dc, META_SETTEXTCOLOR, HIWORD(color),