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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include "metafiledrv.h"
27 #include "wine/debug.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(metafile
);
31 /**********************************************************************
35 MFDRV_MoveTo(DC
*dc
, INT x
, INT y
)
37 return MFDRV_MetaParam2(dc
,META_MOVETO
,x
,y
);
40 /***********************************************************************
44 MFDRV_LineTo( DC
*dc
, INT x
, INT y
)
46 return MFDRV_MetaParam2(dc
, META_LINETO
, x
, y
);
50 /***********************************************************************
54 MFDRV_Arc( DC
*dc
, INT left
, INT top
, INT right
, INT bottom
,
55 INT xstart
, INT ystart
, INT xend
, INT yend
)
57 return MFDRV_MetaParam8(dc
, META_ARC
, left
, top
, right
, bottom
,
58 xstart
, ystart
, xend
, yend
);
62 /***********************************************************************
66 MFDRV_Pie( DC
*dc
, INT left
, INT top
, INT right
, INT bottom
,
67 INT xstart
, INT ystart
, INT xend
, INT yend
)
69 return MFDRV_MetaParam8(dc
, META_PIE
, left
, top
, right
, bottom
,
70 xstart
, ystart
, xend
, yend
);
74 /***********************************************************************
78 MFDRV_Chord( DC
*dc
, INT left
, INT top
, INT right
, INT bottom
,
79 INT xstart
, INT ystart
, INT xend
, INT yend
)
81 return MFDRV_MetaParam8(dc
, META_CHORD
, left
, top
, right
, bottom
,
82 xstart
, ystart
, xend
, yend
);
85 /***********************************************************************
89 MFDRV_Ellipse( DC
*dc
, INT left
, INT top
, INT right
, INT bottom
)
91 return MFDRV_MetaParam4(dc
, META_ELLIPSE
, left
, top
, right
, bottom
);
94 /***********************************************************************
98 MFDRV_Rectangle(DC
*dc
, INT left
, INT top
, INT right
, INT bottom
)
100 return MFDRV_MetaParam4(dc
, META_RECTANGLE
, left
, top
, right
, bottom
);
103 /***********************************************************************
107 MFDRV_RoundRect( DC
*dc
, INT left
, INT top
, INT right
,
108 INT bottom
, INT ell_width
, INT ell_height
)
110 return MFDRV_MetaParam6(dc
, META_ROUNDRECT
, left
, top
, right
, bottom
,
111 ell_width
, ell_height
);
114 /***********************************************************************
118 MFDRV_SetPixel( DC
*dc
, INT x
, INT y
, COLORREF color
)
120 return MFDRV_MetaParam4(dc
, META_SETPIXEL
, x
, y
,HIWORD(color
),
125 /******************************************************************
126 * MFDRV_MetaPoly - implements Polygon and Polyline
128 static BOOL
MFDRV_MetaPoly(DC
*dc
, short func
, LPPOINT16 pt
, short count
)
134 len
= sizeof(METARECORD
) + (count
* 4);
135 if (!(mr
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, len
)))
138 mr
->rdSize
= len
/ 2;
139 mr
->rdFunction
= func
;
140 *(mr
->rdParm
) = count
;
141 memcpy(mr
->rdParm
+ 1, pt
, count
* 4);
142 ret
= MFDRV_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
143 HeapFree( GetProcessHeap(), 0, mr
);
148 /**********************************************************************
152 MFDRV_Polyline( DC
*dc
, const POINT
* pt
, INT count
)
158 pt16
= (LPPOINT16
)HeapAlloc( GetProcessHeap(), 0, sizeof(POINT16
)*count
);
159 if(!pt16
) return FALSE
;
160 for (i
=count
;i
--;) CONV_POINT32TO16(&(pt
[i
]),&(pt16
[i
]));
161 ret
= MFDRV_MetaPoly(dc
, META_POLYLINE
, pt16
, count
);
163 HeapFree( GetProcessHeap(), 0, pt16
);
168 /**********************************************************************
172 MFDRV_Polygon( DC
*dc
, const POINT
* pt
, INT count
)
178 pt16
= (LPPOINT16
) HeapAlloc( GetProcessHeap(), 0, sizeof(POINT16
)*count
);
179 if(!pt16
) return FALSE
;
180 for (i
=count
;i
--;) CONV_POINT32TO16(&(pt
[i
]),&(pt16
[i
]));
181 ret
= MFDRV_MetaPoly(dc
, META_POLYGON
, pt16
, count
);
183 HeapFree( GetProcessHeap(), 0, pt16
);
188 /**********************************************************************
192 MFDRV_PolyPolygon( DC
*dc
, const POINT
* pt
, const INT
* counts
, UINT polygons
)
196 const POINT
* curpt
=pt
;
199 for (i
=0;i
<polygons
;i
++) {
200 pt16
=(LPPOINT16
)HeapAlloc( GetProcessHeap(), 0,
201 sizeof(POINT16
) * counts
[i
] );
202 if(!pt16
) return FALSE
;
203 for (j
=counts
[i
];j
--;) CONV_POINT32TO16(&(curpt
[j
]),&(pt16
[j
]));
204 ret
= MFDRV_MetaPoly(dc
, META_POLYGON
, pt16
, counts
[i
]);
205 HeapFree( GetProcessHeap(), 0, pt16
);
214 /**********************************************************************
218 MFDRV_ExtFloodFill( DC
*dc
, INT x
, INT y
, COLORREF color
, UINT fillType
)
220 return MFDRV_MetaParam4(dc
,META_FLOODFILL
,x
,y
,HIWORD(color
),
225 /******************************************************************
228 * For explanation of the format of the record see MF_Play_MetaCreateRegion in
231 static INT16
MFDRV_CreateRegion(DC
*dc
, HRGN hrgn
)
236 RECT
*pCurRect
, *pEndRect
;
237 WORD Bands
= 0, MaxBands
= 0;
238 WORD
*Param
, *StartBand
;
241 len
= GetRegionData( hrgn
, 0, NULL
);
242 if( !(rgndata
= HeapAlloc( GetProcessHeap(), 0, len
)) ) {
243 WARN("Can't alloc rgndata buffer\n");
246 GetRegionData( hrgn
, len
, rgndata
);
248 /* Overestimate of length:
249 * Assume every rect is a separate band -> 6 WORDs per rect
251 len
= sizeof(METARECORD
) + 20 + (rgndata
->rdh
.nCount
* 12);
252 if( !(mr
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, len
)) ) {
253 WARN("Can't alloc METARECORD buffer\n");
254 HeapFree( GetProcessHeap(), 0, rgndata
);
258 Param
= mr
->rdParm
+ 11;
261 pEndRect
= (RECT
*)rgndata
->Buffer
+ rgndata
->rdh
.nCount
;
262 for(pCurRect
= (RECT
*)rgndata
->Buffer
; pCurRect
< pEndRect
; pCurRect
++)
264 if( StartBand
&& pCurRect
->top
== *(StartBand
+ 1) )
266 *Param
++ = pCurRect
->left
;
267 *Param
++ = pCurRect
->right
;
273 *StartBand
= Param
- StartBand
- 3;
274 *Param
++ = *StartBand
;
275 if(*StartBand
> MaxBands
)
276 MaxBands
= *StartBand
;
280 *Param
++ = pCurRect
->top
;
281 *Param
++ = pCurRect
->bottom
;
282 *Param
++ = pCurRect
->left
;
283 *Param
++ = pCurRect
->right
;
286 len
= Param
- (WORD
*)mr
;
290 mr
->rdParm
[2] = 0x1234;
292 mr
->rdParm
[4] = len
* 2;
293 mr
->rdParm
[5] = Bands
;
294 mr
->rdParm
[6] = MaxBands
;
295 mr
->rdParm
[7] = rgndata
->rdh
.rcBound
.left
;
296 mr
->rdParm
[8] = rgndata
->rdh
.rcBound
.top
;
297 mr
->rdParm
[9] = rgndata
->rdh
.rcBound
.right
;
298 mr
->rdParm
[10] = rgndata
->rdh
.rcBound
.bottom
;
299 mr
->rdFunction
= META_CREATEREGION
;
300 mr
->rdSize
= len
/ 2;
301 ret
= MFDRV_WriteRecord( dc
, mr
, mr
->rdSize
* 2 );
302 HeapFree( GetProcessHeap(), 0, mr
);
303 HeapFree( GetProcessHeap(), 0, rgndata
);
306 WARN("MFDRV_WriteRecord failed\n");
309 return MFDRV_AddHandleDC( dc
);
313 /**********************************************************************
317 MFDRV_PaintRgn( DC
*dc
, HRGN hrgn
)
320 index
= MFDRV_CreateRegion( dc
, hrgn
);
323 return MFDRV_MetaParam1( dc
, META_PAINTREGION
, index
);
327 /**********************************************************************
331 MFDRV_InvertRgn( DC
*dc
, HRGN hrgn
)
334 index
= MFDRV_CreateRegion( dc
, hrgn
);
337 return MFDRV_MetaParam1( dc
, META_INVERTREGION
, index
);
341 /**********************************************************************
345 MFDRV_FillRgn( DC
*dc
, HRGN hrgn
, HBRUSH hbrush
)
348 iRgn
= MFDRV_CreateRegion( dc
, hrgn
);
351 iBrush
= MFDRV_CreateBrushIndirect( dc
, hbrush
);
354 return MFDRV_MetaParam2( dc
, META_FILLREGION
, iRgn
, iBrush
);
357 /**********************************************************************
361 MFDRV_FrameRgn( DC
*dc
, HRGN hrgn
, HBRUSH hbrush
, INT x
, INT y
)
364 iRgn
= MFDRV_CreateRegion( dc
, hrgn
);
367 iBrush
= MFDRV_CreateBrushIndirect( dc
, hbrush
);
370 return MFDRV_MetaParam4( dc
, META_FRAMEREGION
, iRgn
, iBrush
, x
, y
);
374 /**********************************************************************
378 MFDRV_SetBkColor( DC
*dc
, COLORREF color
)
380 return MFDRV_MetaParam2(dc
, META_SETBKCOLOR
, HIWORD(color
), LOWORD(color
));
384 /**********************************************************************
388 MFDRV_SetTextColor( DC
*dc
, COLORREF color
)
390 return MFDRV_MetaParam2(dc
, META_SETTEXTCOLOR
, HIWORD(color
),
395 /**********************************************************************
397 * Since MetaFiles don't record Beziers and they don't even record
398 * approximations to them using lines, we need this stub function.
401 MFDRV_PolyBezier( DC
*dc
, const POINT
*pts
, DWORD count
)
406 /**********************************************************************
408 * Since MetaFiles don't record Beziers and they don't even record
409 * approximations to them using lines, we need this stub function.
412 MFDRV_PolyBezierTo( DC
*dc
, const POINT
*pts
, DWORD count
)