2 * Metafile driver graphics functions
4 * Copyright 1993, 1994 Alexandre Julliard
12 #include "metafiledrv.h"
14 #include "debugtools.h"
16 DEFAULT_DEBUG_CHANNEL(metafile
);
18 /**********************************************************************
22 MFDRV_MoveTo(DC
*dc
, INT x
, INT y
)
24 return MFDRV_MetaParam2(dc
,META_MOVETO
,x
,y
);
27 /***********************************************************************
31 MFDRV_LineTo( DC
*dc
, INT x
, INT y
)
33 return MFDRV_MetaParam2(dc
, META_LINETO
, x
, y
);
37 /***********************************************************************
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 /***********************************************************************
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 /***********************************************************************
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 /***********************************************************************
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 /***********************************************************************
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 /***********************************************************************
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 /***********************************************************************
105 MFDRV_SetPixel( DC
*dc
, INT x
, INT y
, COLORREF color
)
107 return MFDRV_MetaParam4(dc
, META_SETPIXEL
, x
, y
,HIWORD(color
),
112 /******************************************************************
113 * MFDRV_MetaPoly - implements Polygon and Polyline
115 static BOOL
MFDRV_MetaPoly(DC
*dc
, short func
, LPPOINT16 pt
, short count
)
121 len
= sizeof(METARECORD
) + (count
* 4);
122 if (!(mr
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, len
)))
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
);
135 /**********************************************************************
139 MFDRV_Polyline( DC
*dc
, const POINT
* pt
, INT count
)
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
);
155 /**********************************************************************
159 MFDRV_Polygon( DC
*dc
, const POINT
* pt
, INT count
)
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
);
175 /**********************************************************************
179 MFDRV_PolyPolygon( DC
*dc
, const POINT
* pt
, const INT
* counts
, UINT polygons
)
183 const POINT
* curpt
=pt
;
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
);
201 /**********************************************************************
205 MFDRV_ExtFloodFill( DC
*dc
, INT x
, INT y
, COLORREF color
, UINT fillType
)
207 return MFDRV_MetaParam4(dc
,META_FLOODFILL
,x
,y
,HIWORD(color
),
212 /******************************************************************
215 * For explanation of the format of the record see MF_Play_MetaCreateRegion in
218 static INT16
MFDRV_CreateRegion(DC
*dc
, HRGN hrgn
)
223 RECT
*pCurRect
, *pEndRect
;
224 WORD Bands
= 0, MaxBands
= 0;
225 WORD
*Param
, *StartBand
;
228 len
= GetRegionData( hrgn
, 0, NULL
);
229 if( !(rgndata
= HeapAlloc( GetProcessHeap(), 0, len
)) ) {
230 WARN("Can't alloc rgndata buffer\n");
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
);
245 Param
= mr
->rdParm
+ 11;
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
;
260 *StartBand
= Param
- StartBand
- 3;
261 *Param
++ = *StartBand
;
262 if(*StartBand
> MaxBands
)
263 MaxBands
= *StartBand
;
267 *Param
++ = pCurRect
->top
;
268 *Param
++ = pCurRect
->bottom
;
269 *Param
++ = pCurRect
->left
;
270 *Param
++ = pCurRect
->right
;
273 len
= Param
- (WORD
*)mr
;
277 mr
->rdParm
[2] = 0x1234;
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
);
293 WARN("MFDRV_WriteRecord failed\n");
296 return MFDRV_AddHandleDC( dc
);
300 /**********************************************************************
304 MFDRV_PaintRgn( DC
*dc
, HRGN hrgn
)
307 index
= MFDRV_CreateRegion( dc
, hrgn
);
310 return MFDRV_MetaParam1( dc
, META_PAINTREGION
, index
);
314 /**********************************************************************
318 MFDRV_InvertRgn( DC
*dc
, HRGN hrgn
)
321 index
= MFDRV_CreateRegion( dc
, hrgn
);
324 return MFDRV_MetaParam1( dc
, META_INVERTREGION
, index
);
328 /**********************************************************************
332 MFDRV_FillRgn( DC
*dc
, HRGN hrgn
, HBRUSH hbrush
)
335 iRgn
= MFDRV_CreateRegion( dc
, hrgn
);
338 iBrush
= MFDRV_CreateBrushIndirect( dc
, hbrush
);
341 return MFDRV_MetaParam2( dc
, META_FILLREGION
, iRgn
, iBrush
);
344 /**********************************************************************
348 MFDRV_FrameRgn( DC
*dc
, HRGN hrgn
, HBRUSH hbrush
, INT x
, INT y
)
351 iRgn
= MFDRV_CreateRegion( dc
, hrgn
);
354 iBrush
= MFDRV_CreateBrushIndirect( dc
, hbrush
);
357 return MFDRV_MetaParam4( dc
, META_FRAMEREGION
, iRgn
, iBrush
, x
, y
);
361 /**********************************************************************
365 MFDRV_SetBkColor( DC
*dc
, COLORREF color
)
367 return MFDRV_MetaParam2(dc
, META_SETBKCOLOR
, HIWORD(color
), LOWORD(color
));
371 /**********************************************************************
375 MFDRV_SetTextColor( DC
*dc
, COLORREF color
)
377 return MFDRV_MetaParam2(dc
, META_SETTEXTCOLOR
, HIWORD(color
),
382 /**********************************************************************
384 * Since MetaFiles don't record Beziers and they don't even record
385 * approximations to them using lines, we need this stub function.
388 MFDRV_PolyBezier( DC
*dc
, const POINT
*pts
, DWORD count
)
393 /**********************************************************************
395 * Since MetaFiles don't record Beziers and they don't even record
396 * approximations to them using lines, we need this stub function.
399 MFDRV_PolyBezierTo( DC
*dc
, const POINT
*pts
, DWORD count
)