Use 32-bit hook functions where possible. Cleaned up a couple of
[wine/multimedia.git] / graphics / metafiledrv / graphics.c
blob067ef238b6efc3bbcaa3fd63e1bedec35d826719
1 /*
2 * Metafile driver graphics functions
4 * Copyright 1993, 1994 Alexandre Julliard
5 */
7 #include <stdlib.h>
8 #include <string.h>
10 #include "gdi.h"
11 #include "region.h"
12 #include "metafiledrv.h"
13 #include "heap.h"
14 #include "debugtools.h"
16 DEFAULT_DEBUG_CHANNEL(metafile);
18 /**********************************************************************
19 * MFDRV_MoveTo
21 BOOL
22 MFDRV_MoveTo(DC *dc, INT x, INT y)
24 return MFDRV_MetaParam2(dc,META_MOVETO,x,y);
27 /***********************************************************************
28 * MFDRV_LineTo
30 BOOL
31 MFDRV_LineTo( DC *dc, INT x, INT y )
33 return MFDRV_MetaParam2(dc, META_LINETO, x, y);
37 /***********************************************************************
38 * MFDRV_Arc
40 BOOL
41 MFDRV_Arc( DC *dc, INT left, INT top, INT right, INT bottom,
42 INT xstart, INT ystart, INT xend, INT yend )
44 return MFDRV_MetaParam8(dc, META_ARC, left, top, right, bottom,
45 xstart, ystart, xend, yend);
49 /***********************************************************************
50 * MFDRV_Pie
52 BOOL
53 MFDRV_Pie( DC *dc, INT left, INT top, INT right, INT bottom,
54 INT xstart, INT ystart, INT xend, INT yend )
56 return MFDRV_MetaParam8(dc, META_PIE, left, top, right, bottom,
57 xstart, ystart, xend, yend);
61 /***********************************************************************
62 * MFDRV_Chord
64 BOOL
65 MFDRV_Chord( DC *dc, INT left, INT top, INT right, INT bottom,
66 INT xstart, INT ystart, INT xend, INT yend )
68 return MFDRV_MetaParam8(dc, META_CHORD, left, top, right, bottom,
69 xstart, ystart, xend, yend);
72 /***********************************************************************
73 * MFDRV_Ellipse
75 BOOL
76 MFDRV_Ellipse( DC *dc, INT left, INT top, INT right, INT bottom )
78 return MFDRV_MetaParam4(dc, META_ELLIPSE, left, top, right, bottom);
81 /***********************************************************************
82 * MFDRV_Rectangle
84 BOOL
85 MFDRV_Rectangle(DC *dc, INT left, INT top, INT right, INT bottom)
87 return MFDRV_MetaParam4(dc, META_RECTANGLE, left, top, right, bottom);
90 /***********************************************************************
91 * MFDRV_RoundRect
93 BOOL
94 MFDRV_RoundRect( DC *dc, INT left, INT top, INT right,
95 INT bottom, INT ell_width, INT ell_height )
97 return MFDRV_MetaParam6(dc, META_ROUNDRECT, left, top, right, bottom,
98 ell_width, ell_height);
101 /***********************************************************************
102 * MFDRV_SetPixel
104 COLORREF
105 MFDRV_SetPixel( DC *dc, INT x, INT y, COLORREF color )
107 return MFDRV_MetaParam4(dc, META_SETPIXEL, x, y,HIWORD(color),
108 LOWORD(color));
112 /******************************************************************
113 * MFDRV_MetaPoly - implements Polygon and Polyline
115 static BOOL MFDRV_MetaPoly(DC *dc, short func, LPPOINT16 pt, short count)
117 BOOL ret;
118 DWORD len;
119 METARECORD *mr;
121 len = sizeof(METARECORD) + (count * 4);
122 if (!(mr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len )))
123 return FALSE;
125 mr->rdSize = len / 2;
126 mr->rdFunction = func;
127 *(mr->rdParm) = count;
128 memcpy(mr->rdParm + 1, pt, count * 4);
129 ret = MFDRV_WriteRecord( dc, mr, mr->rdSize * 2);
130 HeapFree( GetProcessHeap(), 0, mr);
131 return ret;
135 /**********************************************************************
136 * MFDRV_Polyline
138 BOOL
139 MFDRV_Polyline( DC *dc, const POINT* pt, INT count )
141 register int i;
142 LPPOINT16 pt16;
143 BOOL16 ret;
145 pt16 = (LPPOINT16)HeapAlloc( GetProcessHeap(), 0, sizeof(POINT16)*count );
146 if(!pt16) return FALSE;
147 for (i=count;i--;) CONV_POINT32TO16(&(pt[i]),&(pt16[i]));
148 ret = MFDRV_MetaPoly(dc, META_POLYLINE, pt16, count);
150 HeapFree( GetProcessHeap(), 0, pt16 );
151 return ret;
155 /**********************************************************************
156 * MFDRV_Polygon
158 BOOL
159 MFDRV_Polygon( DC *dc, const POINT* pt, INT count )
161 register int i;
162 LPPOINT16 pt16;
163 BOOL16 ret;
165 pt16 = (LPPOINT16) HeapAlloc( GetProcessHeap(), 0, sizeof(POINT16)*count );
166 if(!pt16) return FALSE;
167 for (i=count;i--;) CONV_POINT32TO16(&(pt[i]),&(pt16[i]));
168 ret = MFDRV_MetaPoly(dc, META_POLYGON, pt16, count);
170 HeapFree( GetProcessHeap(), 0, pt16 );
171 return ret;
175 /**********************************************************************
176 * MFDRV_PolyPolygon
178 BOOL
179 MFDRV_PolyPolygon( DC *dc, const POINT* pt, const INT* counts, UINT polygons)
181 int i,j;
182 LPPOINT16 pt16;
183 const POINT* curpt=pt;
184 BOOL ret;
186 for (i=0;i<polygons;i++) {
187 pt16=(LPPOINT16)HeapAlloc( GetProcessHeap(), 0,
188 sizeof(POINT16) * counts[i] );
189 if(!pt16) return FALSE;
190 for (j=counts[i];j--;) CONV_POINT32TO16(&(curpt[j]),&(pt16[j]));
191 ret = MFDRV_MetaPoly(dc, META_POLYGON, pt16, counts[i]);
192 HeapFree( GetProcessHeap(), 0, pt16 );
193 if (!ret)
194 return FALSE;
195 curpt+=counts[i];
197 return TRUE;
201 /**********************************************************************
202 * MFDRV_ExtFloodFill
204 BOOL
205 MFDRV_ExtFloodFill( DC *dc, INT x, INT y, COLORREF color, UINT fillType )
207 return MFDRV_MetaParam4(dc,META_FLOODFILL,x,y,HIWORD(color),
208 LOWORD(color));
212 /******************************************************************
213 * MFDRV_CreateRegion
215 * For explanation of the format of the record see MF_Play_MetaCreateRegion in
216 * objects/metafile.c
218 static INT16 MFDRV_CreateRegion(DC *dc, HRGN hrgn)
220 DWORD len;
221 METARECORD *mr;
222 RGNDATA *rgndata;
223 RECT *pCurRect, *pEndRect;
224 WORD Bands = 0, MaxBands = 0;
225 WORD *Param, *StartBand;
226 BOOL ret;
228 len = GetRegionData( hrgn, 0, NULL );
229 if( !(rgndata = HeapAlloc( GetProcessHeap(), 0, len )) ) {
230 WARN("Can't alloc rgndata buffer\n");
231 return -1;
233 GetRegionData( hrgn, len, rgndata );
235 /* Overestimate of length:
236 * Assume every rect is a separate band -> 6 WORDs per rect
238 len = sizeof(METARECORD) + 20 + (rgndata->rdh.nCount * 12);
239 if( !(mr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len )) ) {
240 WARN("Can't alloc METARECORD buffer\n");
241 HeapFree( GetProcessHeap(), 0, rgndata );
242 return -1;
245 Param = mr->rdParm + 11;
246 StartBand = NULL;
248 pEndRect = (RECT *)rgndata->Buffer + rgndata->rdh.nCount;
249 for(pCurRect = (RECT *)rgndata->Buffer; pCurRect < pEndRect; pCurRect++)
251 if( StartBand && pCurRect->top == *(StartBand + 1) )
253 *Param++ = pCurRect->left;
254 *Param++ = pCurRect->right;
256 else
258 if(StartBand)
260 *StartBand = Param - StartBand - 3;
261 *Param++ = *StartBand;
262 if(*StartBand > MaxBands)
263 MaxBands = *StartBand;
264 Bands++;
266 StartBand = Param++;
267 *Param++ = pCurRect->top;
268 *Param++ = pCurRect->bottom;
269 *Param++ = pCurRect->left;
270 *Param++ = pCurRect->right;
273 len = Param - (WORD *)mr;
275 mr->rdParm[0] = 0;
276 mr->rdParm[1] = 6;
277 mr->rdParm[2] = 0x1234;
278 mr->rdParm[3] = 0;
279 mr->rdParm[4] = len * 2;
280 mr->rdParm[5] = Bands;
281 mr->rdParm[6] = MaxBands;
282 mr->rdParm[7] = rgndata->rdh.rcBound.left;
283 mr->rdParm[8] = rgndata->rdh.rcBound.top;
284 mr->rdParm[9] = rgndata->rdh.rcBound.right;
285 mr->rdParm[10] = rgndata->rdh.rcBound.bottom;
286 mr->rdFunction = META_CREATEREGION;
287 mr->rdSize = len / 2;
288 ret = MFDRV_WriteRecord( dc, mr, mr->rdSize * 2 );
289 HeapFree( GetProcessHeap(), 0, mr );
290 HeapFree( GetProcessHeap(), 0, rgndata );
291 if(!ret)
293 WARN("MFDRV_WriteRecord failed\n");
294 return -1;
296 return MFDRV_AddHandleDC( dc );
300 /**********************************************************************
301 * MFDRV_PaintRgn
303 BOOL
304 MFDRV_PaintRgn( DC *dc, HRGN hrgn )
306 INT16 index;
307 index = MFDRV_CreateRegion( dc, hrgn );
308 if(index == -1)
309 return FALSE;
310 return MFDRV_MetaParam1( dc, META_PAINTREGION, index );
314 /**********************************************************************
315 * MFDRV_InvertRgn
317 BOOL
318 MFDRV_InvertRgn( DC *dc, HRGN hrgn )
320 INT16 index;
321 index = MFDRV_CreateRegion( dc, hrgn );
322 if(index == -1)
323 return FALSE;
324 return MFDRV_MetaParam1( dc, META_INVERTREGION, index );
328 /**********************************************************************
329 * MFDRV_FillRgn
331 BOOL
332 MFDRV_FillRgn( DC *dc, HRGN hrgn, HBRUSH hbrush )
334 INT16 iRgn, iBrush;
335 iRgn = MFDRV_CreateRegion( dc, hrgn );
336 if(iRgn == -1)
337 return FALSE;
338 iBrush = MFDRV_CreateBrushIndirect( dc, hbrush );
339 if(iBrush == -1)
340 return FALSE;
341 return MFDRV_MetaParam2( dc, META_FILLREGION, iRgn, iBrush );
344 /**********************************************************************
345 * MFDRV_FrameRgn
347 BOOL
348 MFDRV_FrameRgn( DC *dc, HRGN hrgn, HBRUSH hbrush, INT x, INT y )
350 INT16 iRgn, iBrush;
351 iRgn = MFDRV_CreateRegion( dc, hrgn );
352 if(iRgn == -1)
353 return FALSE;
354 iBrush = MFDRV_CreateBrushIndirect( dc, hbrush );
355 if(iBrush == -1)
356 return FALSE;
357 return MFDRV_MetaParam4( dc, META_FRAMEREGION, iRgn, iBrush, x, y );
361 /**********************************************************************
362 * MFDRV_SetBkColor
364 COLORREF
365 MFDRV_SetBkColor( DC *dc, COLORREF color )
367 return MFDRV_MetaParam2(dc, META_SETBKCOLOR, HIWORD(color), LOWORD(color));
371 /**********************************************************************
372 * MFDRV_SetTextColor
374 COLORREF
375 MFDRV_SetTextColor( DC *dc, COLORREF color )
377 return MFDRV_MetaParam2(dc, META_SETTEXTCOLOR, HIWORD(color),
378 LOWORD(color));
382 /**********************************************************************
383 * MFDRV_PolyBezier
384 * Since MetaFiles don't record Beziers and they don't even record
385 * approximations to them using lines, we need this stub function.
387 BOOL
388 MFDRV_PolyBezier( DC *dc, const POINT *pts, DWORD count )
390 return FALSE;
393 /**********************************************************************
394 * MFDRV_PolyBezierTo
395 * Since MetaFiles don't record Beziers and they don't even record
396 * approximations to them using lines, we need this stub function.
398 BOOL
399 MFDRV_PolyBezierTo( DC *dc, const POINT *pts, DWORD count )
401 return FALSE;