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_MoveToEx(DC
*dc
,INT x
,INT y
,LPPOINT pt
)
24 if (!MFDRV_MetaParam2(dc
,META_MOVETO
,x
,y
))
29 pt
->x
= dc
->w
.CursPosX
;
30 pt
->y
= dc
->w
.CursPosY
;
37 /***********************************************************************
41 MFDRV_LineTo( DC
*dc
, INT x
, INT y
)
43 return MFDRV_MetaParam2(dc
, META_LINETO
, x
, y
);
47 /***********************************************************************
51 MFDRV_Arc( DC
*dc
, INT left
, INT top
, INT right
, INT bottom
,
52 INT xstart
, INT ystart
, INT xend
, INT yend
)
54 return MFDRV_MetaParam8(dc
, META_ARC
, left
, top
, right
, bottom
,
55 xstart
, ystart
, xend
, yend
);
59 /***********************************************************************
63 MFDRV_Pie( DC
*dc
, INT left
, INT top
, INT right
, INT bottom
,
64 INT xstart
, INT ystart
, INT xend
, INT yend
)
66 return MFDRV_MetaParam8(dc
, META_PIE
, left
, top
, right
, bottom
,
67 xstart
, ystart
, xend
, yend
);
71 /***********************************************************************
75 MFDRV_Chord( DC
*dc
, INT left
, INT top
, INT right
, INT bottom
,
76 INT xstart
, INT ystart
, INT xend
, INT yend
)
78 return MFDRV_MetaParam8(dc
, META_CHORD
, left
, top
, right
, bottom
,
79 xstart
, ystart
, xend
, yend
);
82 /***********************************************************************
86 MFDRV_Ellipse( DC
*dc
, INT left
, INT top
, INT right
, INT bottom
)
88 return MFDRV_MetaParam4(dc
, META_ELLIPSE
, left
, top
, right
, bottom
);
91 /***********************************************************************
95 MFDRV_Rectangle(DC
*dc
, INT left
, INT top
, INT right
, INT bottom
)
97 return MFDRV_MetaParam4(dc
, META_RECTANGLE
, left
, top
, right
, bottom
);
100 /***********************************************************************
104 MFDRV_RoundRect( DC
*dc
, INT left
, INT top
, INT right
,
105 INT bottom
, INT ell_width
, INT ell_height
)
107 return MFDRV_MetaParam6(dc
, META_ROUNDRECT
, left
, top
, right
, bottom
,
108 ell_width
, ell_height
);
111 /***********************************************************************
115 MFDRV_SetPixel( DC
*dc
, INT x
, INT y
, COLORREF color
)
117 return MFDRV_MetaParam4(dc
, META_SETPIXEL
, x
, y
,HIWORD(color
),
122 /******************************************************************
123 * MFDRV_MetaPoly - implements Polygon and Polyline
125 static BOOL
MFDRV_MetaPoly(DC
*dc
, short func
, LPPOINT16 pt
, short count
)
131 len
= sizeof(METARECORD
) + (count
* 4);
132 if (!(mr
= HeapAlloc( SystemHeap
, HEAP_ZERO_MEMORY
, len
)))
135 mr
->rdSize
= len
/ 2;
136 mr
->rdFunction
= func
;
137 *(mr
->rdParm
) = count
;
138 memcpy(mr
->rdParm
+ 1, pt
, count
* 4);
139 ret
= MFDRV_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
140 HeapFree( SystemHeap
, 0, mr
);
145 /**********************************************************************
149 MFDRV_Polyline( DC
*dc
, const POINT
* pt
, INT count
)
155 pt16
= (LPPOINT16
)xmalloc(sizeof(POINT16
)*count
);
156 for (i
=count
;i
--;) CONV_POINT32TO16(&(pt
[i
]),&(pt16
[i
]));
157 ret
= MFDRV_MetaPoly(dc
, META_POLYLINE
, pt16
, count
);
164 /**********************************************************************
168 MFDRV_Polygon( DC
*dc
, const POINT
* pt
, INT count
)
174 pt16
= (LPPOINT16
)xmalloc(sizeof(POINT16
)*count
);
175 for (i
=count
;i
--;) CONV_POINT32TO16(&(pt
[i
]),&(pt16
[i
]));
176 ret
= MFDRV_MetaPoly(dc
, META_POLYGON
, pt16
, count
);
183 /**********************************************************************
187 MFDRV_PolyPolygon( DC
*dc
, const POINT
* pt
, const INT
* counts
, UINT polygons
)
191 const POINT
* curpt
=pt
;
194 for (i
=0;i
<polygons
;i
++) {
195 pt16
=(LPPOINT16
)xmalloc(sizeof(POINT16
)*counts
[i
]);
196 for (j
=counts
[i
];j
--;) CONV_POINT32TO16(&(curpt
[j
]),&(pt16
[j
]));
197 ret
= MFDRV_MetaPoly(dc
, META_POLYGON
, pt16
, counts
[i
]);
207 /**********************************************************************
211 MFDRV_ExtFloodFill( DC
*dc
, INT x
, INT y
, COLORREF color
, UINT fillType
)
213 return MFDRV_MetaParam4(dc
,META_FLOODFILL
,x
,y
,HIWORD(color
),
218 /******************************************************************
221 * For explanation of the format of the record see MF_Play_MetaCreateRegion in
224 static INT16
MFDRV_CreateRegion(DC
*dc
, HRGN hrgn
)
229 RECT
*pCurRect
, *pEndRect
;
230 WORD Bands
= 0, MaxBands
= 0;
231 WORD
*Param
, *StartBand
;
234 len
= GetRegionData( hrgn
, 0, NULL
);
235 if( !(rgndata
= HeapAlloc( SystemHeap
, 0, len
)) ) {
236 WARN("Can't alloc rgndata buffer\n");
239 GetRegionData( hrgn
, len
, rgndata
);
241 /* Overestimate of length:
242 * Assume every rect is a separate band -> 6 WORDs per rect
244 len
= sizeof(METARECORD
) + 20 + (rgndata
->rdh
.nCount
* 12);
245 if( !(mr
= HeapAlloc( SystemHeap
, HEAP_ZERO_MEMORY
, len
)) ) {
246 WARN("Can't alloc METARECORD buffer\n");
247 HeapFree( SystemHeap
, 0, rgndata
);
251 Param
= mr
->rdParm
+ 11;
254 pEndRect
= (RECT
*)rgndata
->Buffer
+ rgndata
->rdh
.nCount
;
255 for(pCurRect
= (RECT
*)rgndata
->Buffer
; pCurRect
< pEndRect
; pCurRect
++)
257 if( StartBand
&& pCurRect
->top
== *(StartBand
+ 1) )
259 *Param
++ = pCurRect
->left
;
260 *Param
++ = pCurRect
->right
;
266 *StartBand
= Param
- StartBand
- 3;
267 *Param
++ = *StartBand
;
268 if(*StartBand
> MaxBands
)
269 MaxBands
= *StartBand
;
273 *Param
++ = pCurRect
->top
;
274 *Param
++ = pCurRect
->bottom
;
275 *Param
++ = pCurRect
->left
;
276 *Param
++ = pCurRect
->right
;
279 len
= Param
- (WORD
*)mr
;
283 mr
->rdParm
[2] = 0x1234;
285 mr
->rdParm
[4] = len
* 2;
286 mr
->rdParm
[5] = Bands
;
287 mr
->rdParm
[6] = MaxBands
;
288 mr
->rdParm
[7] = rgndata
->rdh
.rcBound
.left
;
289 mr
->rdParm
[8] = rgndata
->rdh
.rcBound
.top
;
290 mr
->rdParm
[9] = rgndata
->rdh
.rcBound
.right
;
291 mr
->rdParm
[10] = rgndata
->rdh
.rcBound
.bottom
;
292 mr
->rdFunction
= META_CREATEREGION
;
293 mr
->rdSize
= len
/ 2;
294 ret
= MFDRV_WriteRecord( dc
, mr
, mr
->rdSize
* 2 );
295 HeapFree( SystemHeap
, 0, mr
);
296 HeapFree( SystemHeap
, 0, rgndata
);
299 WARN("MFDRV_WriteRecord failed\n");
302 return MFDRV_AddHandleDC( dc
);
306 /**********************************************************************
310 MFDRV_PaintRgn( DC
*dc
, HRGN hrgn
)
313 index
= MFDRV_CreateRegion( dc
, hrgn
);
316 return MFDRV_MetaParam1( dc
, META_PAINTREGION
, index
);
320 /**********************************************************************
324 MFDRV_InvertRgn( DC
*dc
, HRGN hrgn
)
327 index
= MFDRV_CreateRegion( dc
, hrgn
);
330 return MFDRV_MetaParam1( dc
, META_INVERTREGION
, index
);
334 /**********************************************************************
338 MFDRV_FillRgn( DC
*dc
, HRGN hrgn
, HBRUSH hbrush
)
341 iRgn
= MFDRV_CreateRegion( dc
, hrgn
);
344 iBrush
= MFDRV_CreateBrushIndirect( dc
, hbrush
);
347 return MFDRV_MetaParam2( dc
, META_FILLREGION
, iRgn
, iBrush
);
350 /**********************************************************************
354 MFDRV_FrameRgn( DC
*dc
, HRGN hrgn
, HBRUSH hbrush
, INT x
, INT y
)
357 iRgn
= MFDRV_CreateRegion( dc
, hrgn
);
360 iBrush
= MFDRV_CreateBrushIndirect( dc
, hbrush
);
363 return MFDRV_MetaParam4( dc
, META_FRAMEREGION
, iRgn
, iBrush
, x
, y
);
367 /**********************************************************************
371 MFDRV_SetBkColor( DC
*dc
, COLORREF color
)
373 return MFDRV_MetaParam2(dc
, META_SETBKCOLOR
, HIWORD(color
), LOWORD(color
));
377 /**********************************************************************
381 MFDRV_SetTextColor( DC
*dc
, COLORREF color
)
383 return MFDRV_MetaParam2(dc
, META_SETTEXTCOLOR
, HIWORD(color
),