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
24 #include "mfdrv/metafiledrv.h"
25 #include "wine/debug.h"
27 WINE_DEFAULT_DEBUG_CHANNEL(metafile
);
29 /**********************************************************************
33 MFDRV_MoveTo(PHYSDEV dev
, INT x
, INT y
)
35 return MFDRV_MetaParam2(dev
,META_MOVETO
,x
,y
);
38 /***********************************************************************
42 MFDRV_LineTo( PHYSDEV dev
, INT x
, INT y
)
44 return MFDRV_MetaParam2(dev
, META_LINETO
, x
, y
);
48 /***********************************************************************
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 /***********************************************************************
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 /***********************************************************************
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 /***********************************************************************
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 /***********************************************************************
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 /***********************************************************************
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 /***********************************************************************
116 MFDRV_SetPixel( PHYSDEV dev
, INT x
, INT y
, COLORREF color
)
118 return MFDRV_MetaParam4(dev
, META_SETPIXEL
, x
, y
,HIWORD(color
),
123 /******************************************************************
124 * MFDRV_MetaPoly - implements Polygon and Polyline
126 static BOOL
MFDRV_MetaPoly(PHYSDEV dev
, short func
, LPPOINT16 pt
, short count
)
132 len
= sizeof(METARECORD
) + (count
* 4);
133 if (!(mr
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, len
)))
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
);
146 /**********************************************************************
150 MFDRV_Polyline( PHYSDEV dev
, const POINT
* pt
, INT count
)
156 pt16
= HeapAlloc( GetProcessHeap(), 0, sizeof(POINT16
)*count
);
157 if(!pt16
) return FALSE
;
163 ret
= MFDRV_MetaPoly(dev
, META_POLYLINE
, pt16
, count
);
165 HeapFree( GetProcessHeap(), 0, pt16
);
170 /**********************************************************************
174 MFDRV_Polygon( PHYSDEV dev
, const POINT
* pt
, INT count
)
180 pt16
= HeapAlloc( GetProcessHeap(), 0, sizeof(POINT16
)*count
);
181 if(!pt16
) return FALSE
;
187 ret
= MFDRV_MetaPoly(dev
, META_POLYGON
, pt16
, count
);
189 HeapFree( GetProcessHeap(), 0, pt16
);
194 /**********************************************************************
198 MFDRV_PolyPolygon( PHYSDEV dev
, const POINT
* pt
, const INT
* counts
, UINT polygons
)
205 INT16 totalpoint16
= 0;
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
--;){
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
);
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
);
249 /**********************************************************************
253 MFDRV_ExtFloodFill( PHYSDEV dev
, INT x
, INT y
, COLORREF color
, UINT fillType
)
255 return MFDRV_MetaParam4(dev
,META_FLOODFILL
,x
,y
,HIWORD(color
),
260 /******************************************************************
263 * For explanation of the format of the record see MF_Play_MetaCreateRegion in
266 static INT16
MFDRV_CreateRegion(PHYSDEV dev
, HRGN hrgn
)
271 RECT
*pCurRect
, *pEndRect
;
272 WORD Bands
= 0, MaxBands
= 0;
273 WORD
*Param
, *StartBand
;
276 if (!(len
= GetRegionData( hrgn
, 0, NULL
))) return -1;
277 if( !(rgndata
= HeapAlloc( GetProcessHeap(), 0, len
)) ) {
278 WARN("Can't alloc rgndata buffer\n");
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
);
293 Param
= mr
->rdParm
+ 11;
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
;
308 *StartBand
= Param
- StartBand
- 3;
309 *Param
++ = *StartBand
;
310 if(*StartBand
> MaxBands
)
311 MaxBands
= *StartBand
;
315 *Param
++ = pCurRect
->top
;
316 *Param
++ = pCurRect
->bottom
;
317 *Param
++ = pCurRect
->left
;
318 *Param
++ = pCurRect
->right
;
321 len
= Param
- (WORD
*)mr
;
325 mr
->rdParm
[2] = 0x1234;
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
);
341 WARN("MFDRV_WriteRecord failed\n");
344 return MFDRV_AddHandle( dev
, hrgn
);
348 /**********************************************************************
352 MFDRV_PaintRgn( PHYSDEV dev
, HRGN hrgn
)
355 index
= MFDRV_CreateRegion( dev
, hrgn
);
358 return MFDRV_MetaParam1( dev
, META_PAINTREGION
, index
);
362 /**********************************************************************
366 MFDRV_InvertRgn( PHYSDEV dev
, HRGN hrgn
)
369 index
= MFDRV_CreateRegion( dev
, hrgn
);
372 return MFDRV_MetaParam1( dev
, META_INVERTREGION
, index
);
376 /**********************************************************************
380 MFDRV_FillRgn( PHYSDEV dev
, HRGN hrgn
, HBRUSH hbrush
)
383 iRgn
= MFDRV_CreateRegion( dev
, hrgn
);
386 iBrush
= MFDRV_CreateBrushIndirect( dev
, hbrush
);
389 return MFDRV_MetaParam2( dev
, META_FILLREGION
, iRgn
, iBrush
);
392 /**********************************************************************
396 MFDRV_FrameRgn( PHYSDEV dev
, HRGN hrgn
, HBRUSH hbrush
, INT x
, INT y
)
399 iRgn
= MFDRV_CreateRegion( dev
, hrgn
);
402 iBrush
= MFDRV_CreateBrushIndirect( dev
, hbrush
);
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
)
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
);
428 /**********************************************************************
432 MFDRV_SetBkColor( PHYSDEV dev
, COLORREF color
)
434 return MFDRV_MetaParam2(dev
, META_SETBKCOLOR
, HIWORD(color
),
435 LOWORD(color
)) ? color
: CLR_INVALID
;
439 /**********************************************************************
443 MFDRV_SetTextColor( PHYSDEV dev
, COLORREF color
)
445 return MFDRV_MetaParam2(dev
, META_SETTEXTCOLOR
, HIWORD(color
),
446 LOWORD(color
)) ? color
: CLR_INVALID
;
450 /**********************************************************************
452 * Since MetaFiles don't record Beziers and they don't even record
453 * approximations to them using lines, we need this stub function.
456 MFDRV_PolyBezier( PHYSDEV dev
, const POINT
*pts
, DWORD count
)
461 /**********************************************************************
463 * Since MetaFiles don't record Beziers and they don't even record
464 * approximations to them using lines, we need this stub function.
467 MFDRV_PolyBezierTo( PHYSDEV dev
, const POINT
*pts
, DWORD count
)