Update the address of the Free Software Foundation.
[wine/testsucceed.git] / dlls / gdi / mfdrv / graphics.c
blob94c8514608259b4b73098125752b09ccd7c6a3a6
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <stdlib.h>
22 #include <string.h>
24 #include "gdi.h"
25 #include "mfdrv/metafiledrv.h"
26 #include "wine/debug.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(metafile);
30 /**********************************************************************
31 * MFDRV_MoveTo
33 BOOL
34 MFDRV_MoveTo(PHYSDEV dev, INT x, INT y)
36 return MFDRV_MetaParam2(dev,META_MOVETO,x,y);
39 /***********************************************************************
40 * MFDRV_LineTo
42 BOOL
43 MFDRV_LineTo( PHYSDEV dev, INT x, INT y )
45 return MFDRV_MetaParam2(dev, META_LINETO, x, y);
49 /***********************************************************************
50 * MFDRV_Arc
52 BOOL
53 MFDRV_Arc( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
54 INT xstart, INT ystart, INT xend, INT yend )
56 return MFDRV_MetaParam8(dev, META_ARC, left, top, right, bottom,
57 xstart, ystart, xend, yend);
61 /***********************************************************************
62 * MFDRV_Pie
64 BOOL
65 MFDRV_Pie( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
66 INT xstart, INT ystart, INT xend, INT yend )
68 return MFDRV_MetaParam8(dev, META_PIE, left, top, right, bottom,
69 xstart, ystart, xend, yend);
73 /***********************************************************************
74 * MFDRV_Chord
76 BOOL
77 MFDRV_Chord( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
78 INT xstart, INT ystart, INT xend, INT yend )
80 return MFDRV_MetaParam8(dev, META_CHORD, left, top, right, bottom,
81 xstart, ystart, xend, yend);
84 /***********************************************************************
85 * MFDRV_Ellipse
87 BOOL
88 MFDRV_Ellipse( PHYSDEV dev, INT left, INT top, INT right, INT bottom )
90 return MFDRV_MetaParam4(dev, META_ELLIPSE, left, top, right, bottom);
93 /***********************************************************************
94 * MFDRV_Rectangle
96 BOOL
97 MFDRV_Rectangle(PHYSDEV dev, INT left, INT top, INT right, INT bottom)
99 return MFDRV_MetaParam4(dev, META_RECTANGLE, left, top, right, bottom);
102 /***********************************************************************
103 * MFDRV_RoundRect
105 BOOL
106 MFDRV_RoundRect( PHYSDEV dev, INT left, INT top, INT right,
107 INT bottom, INT ell_width, INT ell_height )
109 return MFDRV_MetaParam6(dev, META_ROUNDRECT, left, top, right, bottom,
110 ell_width, ell_height);
113 /***********************************************************************
114 * MFDRV_SetPixel
116 COLORREF
117 MFDRV_SetPixel( PHYSDEV dev, INT x, INT y, COLORREF color )
119 return MFDRV_MetaParam4(dev, META_SETPIXEL, x, y,HIWORD(color),
120 LOWORD(color));
124 /******************************************************************
125 * MFDRV_MetaPoly - implements Polygon and Polyline
127 static BOOL MFDRV_MetaPoly(PHYSDEV dev, short func, LPPOINT16 pt, short count)
129 BOOL ret;
130 DWORD len;
131 METARECORD *mr;
133 len = sizeof(METARECORD) + (count * 4);
134 if (!(mr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len )))
135 return FALSE;
137 mr->rdSize = len / 2;
138 mr->rdFunction = func;
139 *(mr->rdParm) = count;
140 memcpy(mr->rdParm + 1, pt, count * 4);
141 ret = MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
142 HeapFree( GetProcessHeap(), 0, mr);
143 return ret;
147 /**********************************************************************
148 * MFDRV_Polyline
150 BOOL
151 MFDRV_Polyline( PHYSDEV dev, const POINT* pt, INT count )
153 register int i;
154 LPPOINT16 pt16;
155 BOOL16 ret;
157 pt16 = HeapAlloc( GetProcessHeap(), 0, sizeof(POINT16)*count );
158 if(!pt16) return FALSE;
159 for (i=count;i--;)
161 pt16[i].x = pt[i].x;
162 pt16[i].y = pt[i].y;
164 ret = MFDRV_MetaPoly(dev, META_POLYLINE, pt16, count);
166 HeapFree( GetProcessHeap(), 0, pt16 );
167 return ret;
171 /**********************************************************************
172 * MFDRV_Polygon
174 BOOL
175 MFDRV_Polygon( PHYSDEV dev, const POINT* pt, INT count )
177 register int i;
178 LPPOINT16 pt16;
179 BOOL16 ret;
181 pt16 = HeapAlloc( GetProcessHeap(), 0, sizeof(POINT16)*count );
182 if(!pt16) return FALSE;
183 for (i=count;i--;)
185 pt16[i].x = pt[i].x;
186 pt16[i].y = pt[i].y;
188 ret = MFDRV_MetaPoly(dev, META_POLYGON, pt16, count);
190 HeapFree( GetProcessHeap(), 0, pt16 );
191 return ret;
195 /**********************************************************************
196 * MFDRV_PolyPolygon
198 BOOL
199 MFDRV_PolyPolygon( PHYSDEV dev, const POINT* pt, const INT* counts, UINT polygons)
201 BOOL ret;
202 DWORD len;
203 METARECORD *mr;
204 unsigned int i,j;
205 LPPOINT16 pt16;
206 INT16 totalpoint16 = 0;
207 INT16 * pointcounts;
209 for (i=0;i<polygons;i++) {
210 totalpoint16 += counts[i];
213 /* allocate space for all points */
214 pt16=HeapAlloc( GetProcessHeap(), 0, sizeof(POINT16) * totalpoint16 );
215 pointcounts = HeapAlloc( GetProcessHeap(), 0, sizeof(INT16) * totalpoint16 );
217 /* copy point counts */
218 for (i=0;i<polygons;i++) {
219 pointcounts[i] = counts[i];
222 /* convert all points */
223 for (j = totalpoint16; j--;){
224 pt16[j].x = pt[j].x;
225 pt16[j].y = pt[j].y;
228 len = sizeof(METARECORD) + sizeof(WORD) + polygons*sizeof(INT16) + totalpoint16*sizeof(POINT16);
230 if (!(mr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len ))) {
231 HeapFree( GetProcessHeap(), 0, pt16 );
232 HeapFree( GetProcessHeap(), 0, pointcounts );
233 return FALSE;
236 mr->rdSize = len /2;
237 mr->rdFunction = META_POLYPOLYGON;
238 *(mr->rdParm) = polygons;
239 memcpy(mr->rdParm + 1, pointcounts, polygons*sizeof(INT16));
240 memcpy(mr->rdParm + 1+polygons, pt16 , totalpoint16*sizeof(POINT16));
241 ret = MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
243 HeapFree( GetProcessHeap(), 0, pt16 );
244 HeapFree( GetProcessHeap(), 0, pointcounts );
245 HeapFree( GetProcessHeap(), 0, mr);
246 return ret;
250 /**********************************************************************
251 * MFDRV_ExtFloodFill
253 BOOL
254 MFDRV_ExtFloodFill( PHYSDEV dev, INT x, INT y, COLORREF color, UINT fillType )
256 return MFDRV_MetaParam4(dev,META_FLOODFILL,x,y,HIWORD(color),
257 LOWORD(color));
261 /******************************************************************
262 * MFDRV_CreateRegion
264 * For explanation of the format of the record see MF_Play_MetaCreateRegion in
265 * objects/metafile.c
267 static INT16 MFDRV_CreateRegion(PHYSDEV dev, HRGN hrgn)
269 DWORD len;
270 METARECORD *mr;
271 RGNDATA *rgndata;
272 RECT *pCurRect, *pEndRect;
273 WORD Bands = 0, MaxBands = 0;
274 WORD *Param, *StartBand;
275 BOOL ret;
277 if (!(len = GetRegionData( hrgn, 0, NULL ))) return -1;
278 if( !(rgndata = HeapAlloc( GetProcessHeap(), 0, len )) ) {
279 WARN("Can't alloc rgndata buffer\n");
280 return -1;
282 GetRegionData( hrgn, len, rgndata );
284 /* Overestimate of length:
285 * Assume every rect is a separate band -> 6 WORDs per rect
287 len = sizeof(METARECORD) + 20 + (rgndata->rdh.nCount * 12);
288 if( !(mr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len )) ) {
289 WARN("Can't alloc METARECORD buffer\n");
290 HeapFree( GetProcessHeap(), 0, rgndata );
291 return -1;
294 Param = mr->rdParm + 11;
295 StartBand = NULL;
297 pEndRect = (RECT *)rgndata->Buffer + rgndata->rdh.nCount;
298 for(pCurRect = (RECT *)rgndata->Buffer; pCurRect < pEndRect; pCurRect++)
300 if( StartBand && pCurRect->top == *(StartBand + 1) )
302 *Param++ = pCurRect->left;
303 *Param++ = pCurRect->right;
305 else
307 if(StartBand)
309 *StartBand = Param - StartBand - 3;
310 *Param++ = *StartBand;
311 if(*StartBand > MaxBands)
312 MaxBands = *StartBand;
313 Bands++;
315 StartBand = Param++;
316 *Param++ = pCurRect->top;
317 *Param++ = pCurRect->bottom;
318 *Param++ = pCurRect->left;
319 *Param++ = pCurRect->right;
322 len = Param - (WORD *)mr;
324 mr->rdParm[0] = 0;
325 mr->rdParm[1] = 6;
326 mr->rdParm[2] = 0x1234;
327 mr->rdParm[3] = 0;
328 mr->rdParm[4] = len * 2;
329 mr->rdParm[5] = Bands;
330 mr->rdParm[6] = MaxBands;
331 mr->rdParm[7] = rgndata->rdh.rcBound.left;
332 mr->rdParm[8] = rgndata->rdh.rcBound.top;
333 mr->rdParm[9] = rgndata->rdh.rcBound.right;
334 mr->rdParm[10] = rgndata->rdh.rcBound.bottom;
335 mr->rdFunction = META_CREATEREGION;
336 mr->rdSize = len / 2;
337 ret = MFDRV_WriteRecord( dev, mr, mr->rdSize * 2 );
338 HeapFree( GetProcessHeap(), 0, mr );
339 HeapFree( GetProcessHeap(), 0, rgndata );
340 if(!ret)
342 WARN("MFDRV_WriteRecord failed\n");
343 return -1;
345 return MFDRV_AddHandle( dev, hrgn );
349 /**********************************************************************
350 * MFDRV_PaintRgn
352 BOOL
353 MFDRV_PaintRgn( PHYSDEV dev, HRGN hrgn )
355 INT16 index;
356 index = MFDRV_CreateRegion( dev, hrgn );
357 if(index == -1)
358 return FALSE;
359 return MFDRV_MetaParam1( dev, META_PAINTREGION, index );
363 /**********************************************************************
364 * MFDRV_InvertRgn
366 BOOL
367 MFDRV_InvertRgn( PHYSDEV dev, HRGN hrgn )
369 INT16 index;
370 index = MFDRV_CreateRegion( dev, hrgn );
371 if(index == -1)
372 return FALSE;
373 return MFDRV_MetaParam1( dev, META_INVERTREGION, index );
377 /**********************************************************************
378 * MFDRV_FillRgn
380 BOOL
381 MFDRV_FillRgn( PHYSDEV dev, HRGN hrgn, HBRUSH hbrush )
383 INT16 iRgn, iBrush;
384 iRgn = MFDRV_CreateRegion( dev, hrgn );
385 if(iRgn == -1)
386 return FALSE;
387 iBrush = MFDRV_CreateBrushIndirect( dev, hbrush );
388 if(!iBrush)
389 return FALSE;
390 return MFDRV_MetaParam2( dev, META_FILLREGION, iRgn, iBrush );
393 /**********************************************************************
394 * MFDRV_FrameRgn
396 BOOL
397 MFDRV_FrameRgn( PHYSDEV dev, HRGN hrgn, HBRUSH hbrush, INT x, INT y )
399 INT16 iRgn, iBrush;
400 iRgn = MFDRV_CreateRegion( dev, hrgn );
401 if(iRgn == -1)
402 return FALSE;
403 iBrush = MFDRV_CreateBrushIndirect( dev, hbrush );
404 if(!iBrush)
405 return FALSE;
406 return MFDRV_MetaParam4( dev, META_FRAMEREGION, iRgn, iBrush, x, y );
410 /**********************************************************************
411 * MFDRV_ExtSelectClipRgn
413 INT MFDRV_ExtSelectClipRgn( PHYSDEV dev, HRGN hrgn, INT mode )
415 INT16 iRgn;
416 INT ret;
418 if (mode != RGN_COPY) return ERROR;
419 if (!hrgn) return NULLREGION;
420 iRgn = MFDRV_CreateRegion( dev, hrgn );
421 if(iRgn == -1) return ERROR;
422 ret = MFDRV_MetaParam1( dev, META_SELECTCLIPREGION, iRgn ) ? NULLREGION : ERROR;
423 MFDRV_MetaParam1( dev, META_DELETEOBJECT, iRgn );
424 return ret;
428 /**********************************************************************
429 * MFDRV_SetBkColor
431 COLORREF
432 MFDRV_SetBkColor( PHYSDEV dev, COLORREF color )
434 return MFDRV_MetaParam2(dev, META_SETBKCOLOR, HIWORD(color),
435 LOWORD(color)) ? color : CLR_INVALID;
439 /**********************************************************************
440 * MFDRV_SetTextColor
442 COLORREF
443 MFDRV_SetTextColor( PHYSDEV dev, COLORREF color )
445 return MFDRV_MetaParam2(dev, META_SETTEXTCOLOR, HIWORD(color),
446 LOWORD(color)) ? color : CLR_INVALID;
450 /**********************************************************************
451 * MFDRV_PolyBezier
452 * Since MetaFiles don't record Beziers and they don't even record
453 * approximations to them using lines, we need this stub function.
455 BOOL
456 MFDRV_PolyBezier( PHYSDEV dev, const POINT *pts, DWORD count )
458 return FALSE;
461 /**********************************************************************
462 * MFDRV_PolyBezierTo
463 * Since MetaFiles don't record Beziers and they don't even record
464 * approximations to them using lines, we need this stub function.
466 BOOL
467 MFDRV_PolyBezierTo( PHYSDEV dev, const POINT *pts, DWORD count )
469 return FALSE;