change default iSmCaptionWidth to 12
[wine/kumbayo.git] / dlls / gdi32 / mfdrv / graphics.c
blob316ee7852ceb30ef15e4d83d6524dba843535519
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 "mfdrv/metafiledrv.h"
25 #include "wine/debug.h"
27 WINE_DEFAULT_DEBUG_CHANNEL(metafile);
29 /**********************************************************************
30 * MFDRV_MoveTo
32 BOOL
33 MFDRV_MoveTo(PHYSDEV dev, INT x, INT y)
35 return MFDRV_MetaParam2(dev,META_MOVETO,x,y);
38 /***********************************************************************
39 * MFDRV_LineTo
41 BOOL
42 MFDRV_LineTo( PHYSDEV dev, INT x, INT y )
44 return MFDRV_MetaParam2(dev, META_LINETO, x, y);
48 /***********************************************************************
49 * MFDRV_Arc
51 BOOL
52 MFDRV_Arc( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
53 INT xstart, INT ystart, INT xend, INT yend )
55 return MFDRV_MetaParam8(dev, META_ARC, left, top, right, bottom,
56 xstart, ystart, xend, yend);
60 /***********************************************************************
61 * MFDRV_Pie
63 BOOL
64 MFDRV_Pie( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
65 INT xstart, INT ystart, INT xend, INT yend )
67 return MFDRV_MetaParam8(dev, META_PIE, left, top, right, bottom,
68 xstart, ystart, xend, yend);
72 /***********************************************************************
73 * MFDRV_Chord
75 BOOL
76 MFDRV_Chord( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
77 INT xstart, INT ystart, INT xend, INT yend )
79 return MFDRV_MetaParam8(dev, META_CHORD, left, top, right, bottom,
80 xstart, ystart, xend, yend);
83 /***********************************************************************
84 * MFDRV_Ellipse
86 BOOL
87 MFDRV_Ellipse( PHYSDEV dev, INT left, INT top, INT right, INT bottom )
89 return MFDRV_MetaParam4(dev, META_ELLIPSE, left, top, right, bottom);
92 /***********************************************************************
93 * MFDRV_Rectangle
95 BOOL
96 MFDRV_Rectangle(PHYSDEV dev, INT left, INT top, INT right, INT bottom)
98 return MFDRV_MetaParam4(dev, META_RECTANGLE, left, top, right, bottom);
101 /***********************************************************************
102 * MFDRV_RoundRect
104 BOOL
105 MFDRV_RoundRect( PHYSDEV dev, INT left, INT top, INT right,
106 INT bottom, INT ell_width, INT ell_height )
108 return MFDRV_MetaParam6(dev, META_ROUNDRECT, left, top, right, bottom,
109 ell_width, ell_height);
112 /***********************************************************************
113 * MFDRV_SetPixel
115 COLORREF
116 MFDRV_SetPixel( PHYSDEV dev, INT x, INT y, COLORREF color )
118 return MFDRV_MetaParam4(dev, META_SETPIXEL, x, y,HIWORD(color),
119 LOWORD(color));
123 /******************************************************************
124 * MFDRV_MetaPoly - implements Polygon and Polyline
126 static BOOL MFDRV_MetaPoly(PHYSDEV dev, short func, LPPOINT16 pt, short count)
128 BOOL ret;
129 DWORD len;
130 METARECORD *mr;
132 len = sizeof(METARECORD) + (count * 4);
133 if (!(mr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len )))
134 return FALSE;
136 mr->rdSize = len / 2;
137 mr->rdFunction = func;
138 *(mr->rdParm) = count;
139 memcpy(mr->rdParm + 1, pt, count * 4);
140 ret = MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
141 HeapFree( GetProcessHeap(), 0, mr);
142 return ret;
146 /**********************************************************************
147 * MFDRV_Polyline
149 BOOL
150 MFDRV_Polyline( PHYSDEV dev, const POINT* pt, INT count )
152 register int i;
153 LPPOINT16 pt16;
154 BOOL16 ret;
156 pt16 = HeapAlloc( GetProcessHeap(), 0, sizeof(POINT16)*count );
157 if(!pt16) return FALSE;
158 for (i=count;i--;)
160 pt16[i].x = pt[i].x;
161 pt16[i].y = pt[i].y;
163 ret = MFDRV_MetaPoly(dev, META_POLYLINE, pt16, count);
165 HeapFree( GetProcessHeap(), 0, pt16 );
166 return ret;
170 /**********************************************************************
171 * MFDRV_Polygon
173 BOOL
174 MFDRV_Polygon( PHYSDEV dev, const POINT* pt, INT count )
176 register int i;
177 LPPOINT16 pt16;
178 BOOL16 ret;
180 pt16 = HeapAlloc( GetProcessHeap(), 0, sizeof(POINT16)*count );
181 if(!pt16) return FALSE;
182 for (i=count;i--;)
184 pt16[i].x = pt[i].x;
185 pt16[i].y = pt[i].y;
187 ret = MFDRV_MetaPoly(dev, META_POLYGON, pt16, count);
189 HeapFree( GetProcessHeap(), 0, pt16 );
190 return ret;
194 /**********************************************************************
195 * MFDRV_PolyPolygon
197 BOOL
198 MFDRV_PolyPolygon( PHYSDEV dev, const POINT* pt, const INT* counts, UINT polygons)
200 BOOL ret;
201 DWORD len;
202 METARECORD *mr;
203 unsigned int i,j;
204 LPPOINT16 pt16;
205 INT16 totalpoint16 = 0;
206 INT16 * pointcounts;
208 for (i=0;i<polygons;i++) {
209 totalpoint16 += counts[i];
212 /* allocate space for all points */
213 pt16=HeapAlloc( GetProcessHeap(), 0, sizeof(POINT16) * totalpoint16 );
214 pointcounts = HeapAlloc( GetProcessHeap(), 0, sizeof(INT16) * totalpoint16 );
216 /* copy point counts */
217 for (i=0;i<polygons;i++) {
218 pointcounts[i] = counts[i];
221 /* convert all points */
222 for (j = totalpoint16; j--;){
223 pt16[j].x = pt[j].x;
224 pt16[j].y = pt[j].y;
227 len = sizeof(METARECORD) + sizeof(WORD) + polygons*sizeof(INT16) + totalpoint16*sizeof(POINT16);
229 if (!(mr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len ))) {
230 HeapFree( GetProcessHeap(), 0, pt16 );
231 HeapFree( GetProcessHeap(), 0, pointcounts );
232 return FALSE;
235 mr->rdSize = len /2;
236 mr->rdFunction = META_POLYPOLYGON;
237 *(mr->rdParm) = polygons;
238 memcpy(mr->rdParm + 1, pointcounts, polygons*sizeof(INT16));
239 memcpy(mr->rdParm + 1+polygons, pt16 , totalpoint16*sizeof(POINT16));
240 ret = MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
242 HeapFree( GetProcessHeap(), 0, pt16 );
243 HeapFree( GetProcessHeap(), 0, pointcounts );
244 HeapFree( GetProcessHeap(), 0, mr);
245 return ret;
249 /**********************************************************************
250 * MFDRV_ExtFloodFill
252 BOOL
253 MFDRV_ExtFloodFill( PHYSDEV dev, INT x, INT y, COLORREF color, UINT fillType )
255 return MFDRV_MetaParam4(dev,META_FLOODFILL,x,y,HIWORD(color),
256 LOWORD(color));
260 /******************************************************************
261 * MFDRV_CreateRegion
263 * For explanation of the format of the record see MF_Play_MetaCreateRegion in
264 * objects/metafile.c
266 static INT16 MFDRV_CreateRegion(PHYSDEV dev, HRGN hrgn)
268 DWORD len;
269 METARECORD *mr;
270 RGNDATA *rgndata;
271 RECT *pCurRect, *pEndRect;
272 WORD Bands = 0, MaxBands = 0;
273 WORD *Param, *StartBand;
274 BOOL ret;
276 if (!(len = GetRegionData( hrgn, 0, NULL ))) return -1;
277 if( !(rgndata = HeapAlloc( GetProcessHeap(), 0, len )) ) {
278 WARN("Can't alloc rgndata buffer\n");
279 return -1;
281 GetRegionData( hrgn, len, rgndata );
283 /* Overestimate of length:
284 * Assume every rect is a separate band -> 6 WORDs per rect
286 len = sizeof(METARECORD) + 20 + (rgndata->rdh.nCount * 12);
287 if( !(mr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len )) ) {
288 WARN("Can't alloc METARECORD buffer\n");
289 HeapFree( GetProcessHeap(), 0, rgndata );
290 return -1;
293 Param = mr->rdParm + 11;
294 StartBand = NULL;
296 pEndRect = (RECT *)rgndata->Buffer + rgndata->rdh.nCount;
297 for(pCurRect = (RECT *)rgndata->Buffer; pCurRect < pEndRect; pCurRect++)
299 if( StartBand && pCurRect->top == *(StartBand + 1) )
301 *Param++ = pCurRect->left;
302 *Param++ = pCurRect->right;
304 else
306 if(StartBand)
308 *StartBand = Param - StartBand - 3;
309 *Param++ = *StartBand;
310 if(*StartBand > MaxBands)
311 MaxBands = *StartBand;
312 Bands++;
314 StartBand = Param++;
315 *Param++ = pCurRect->top;
316 *Param++ = pCurRect->bottom;
317 *Param++ = pCurRect->left;
318 *Param++ = pCurRect->right;
321 len = Param - (WORD *)mr;
323 mr->rdParm[0] = 0;
324 mr->rdParm[1] = 6;
325 mr->rdParm[2] = 0x1234;
326 mr->rdParm[3] = 0;
327 mr->rdParm[4] = len * 2;
328 mr->rdParm[5] = Bands;
329 mr->rdParm[6] = MaxBands;
330 mr->rdParm[7] = rgndata->rdh.rcBound.left;
331 mr->rdParm[8] = rgndata->rdh.rcBound.top;
332 mr->rdParm[9] = rgndata->rdh.rcBound.right;
333 mr->rdParm[10] = rgndata->rdh.rcBound.bottom;
334 mr->rdFunction = META_CREATEREGION;
335 mr->rdSize = len / 2;
336 ret = MFDRV_WriteRecord( dev, mr, mr->rdSize * 2 );
337 HeapFree( GetProcessHeap(), 0, mr );
338 HeapFree( GetProcessHeap(), 0, rgndata );
339 if(!ret)
341 WARN("MFDRV_WriteRecord failed\n");
342 return -1;
344 return MFDRV_AddHandle( dev, hrgn );
348 /**********************************************************************
349 * MFDRV_PaintRgn
351 BOOL
352 MFDRV_PaintRgn( PHYSDEV dev, HRGN hrgn )
354 INT16 index;
355 index = MFDRV_CreateRegion( dev, hrgn );
356 if(index == -1)
357 return FALSE;
358 return MFDRV_MetaParam1( dev, META_PAINTREGION, index );
362 /**********************************************************************
363 * MFDRV_InvertRgn
365 BOOL
366 MFDRV_InvertRgn( PHYSDEV dev, HRGN hrgn )
368 INT16 index;
369 index = MFDRV_CreateRegion( dev, hrgn );
370 if(index == -1)
371 return FALSE;
372 return MFDRV_MetaParam1( dev, META_INVERTREGION, index );
376 /**********************************************************************
377 * MFDRV_FillRgn
379 BOOL
380 MFDRV_FillRgn( PHYSDEV dev, HRGN hrgn, HBRUSH hbrush )
382 INT16 iRgn, iBrush;
383 iRgn = MFDRV_CreateRegion( dev, hrgn );
384 if(iRgn == -1)
385 return FALSE;
386 iBrush = MFDRV_CreateBrushIndirect( dev, hbrush );
387 if(!iBrush)
388 return FALSE;
389 return MFDRV_MetaParam2( dev, META_FILLREGION, iRgn, iBrush );
392 /**********************************************************************
393 * MFDRV_FrameRgn
395 BOOL
396 MFDRV_FrameRgn( PHYSDEV dev, HRGN hrgn, HBRUSH hbrush, INT x, INT y )
398 INT16 iRgn, iBrush;
399 iRgn = MFDRV_CreateRegion( dev, hrgn );
400 if(iRgn == -1)
401 return FALSE;
402 iBrush = MFDRV_CreateBrushIndirect( dev, hbrush );
403 if(!iBrush)
404 return FALSE;
405 return MFDRV_MetaParam4( dev, META_FRAMEREGION, iRgn, iBrush, x, y );
409 /**********************************************************************
410 * MFDRV_ExtSelectClipRgn
412 INT MFDRV_ExtSelectClipRgn( PHYSDEV dev, HRGN hrgn, INT mode )
414 INT16 iRgn;
415 INT ret;
417 if (mode != RGN_COPY) return ERROR;
418 if (!hrgn) return NULLREGION;
419 iRgn = MFDRV_CreateRegion( dev, hrgn );
420 if(iRgn == -1) return ERROR;
421 ret = MFDRV_MetaParam1( dev, META_SELECTCLIPREGION, iRgn ) ? NULLREGION : ERROR;
422 MFDRV_MetaParam1( dev, META_DELETEOBJECT, iRgn );
423 MFDRV_RemoveHandle( dev, 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;