2 * Metafile driver graphics functions
4 * Copyright 1993, 1994 Alexandre Julliard
13 #include "metafiledrv.h"
15 #include "debugtools.h"
17 DEFAULT_DEBUG_CHANNEL(metafile
)
19 /**********************************************************************
23 MFDRV_MoveToEx(DC
*dc
,INT x
,INT y
,LPPOINT pt
)
25 return MFDRV_MetaParam2(dc
,META_MOVETO
,x
,y
);
28 /***********************************************************************
32 MFDRV_LineTo( DC
*dc
, INT x
, INT y
)
34 return MFDRV_MetaParam2(dc
, META_LINETO
, x
, y
);
38 /***********************************************************************
42 MFDRV_Arc( DC
*dc
, INT left
, INT top
, INT right
, INT bottom
,
43 INT xstart
, INT ystart
, INT xend
, INT yend
)
45 return MFDRV_MetaParam8(dc
, META_ARC
, left
, top
, right
, bottom
,
46 xstart
, ystart
, xend
, yend
);
50 /***********************************************************************
54 MFDRV_Pie( 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_PIE
, left
, top
, right
, bottom
,
58 xstart
, ystart
, xend
, yend
);
62 /***********************************************************************
66 MFDRV_Chord( 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_CHORD
, left
, top
, right
, bottom
,
70 xstart
, ystart
, xend
, yend
);
73 /***********************************************************************
77 MFDRV_Ellipse( DC
*dc
, INT left
, INT top
, INT right
, INT bottom
)
79 return MFDRV_MetaParam4(dc
, META_ELLIPSE
, left
, top
, right
, bottom
);
82 /***********************************************************************
86 MFDRV_Rectangle(DC
*dc
, INT left
, INT top
, INT right
, INT bottom
)
88 return MFDRV_MetaParam4(dc
, META_RECTANGLE
, left
, top
, right
, bottom
);
91 /***********************************************************************
95 MFDRV_RoundRect( DC
*dc
, INT left
, INT top
, INT right
,
96 INT bottom
, INT ell_width
, INT ell_height
)
98 return MFDRV_MetaParam6(dc
, META_ROUNDRECT
, left
, top
, right
, bottom
,
99 ell_width
, ell_height
);
102 /***********************************************************************
106 MFDRV_SetPixel( DC
*dc
, INT x
, INT y
, COLORREF color
)
108 return MFDRV_MetaParam4(dc
, META_SETPIXEL
, x
, y
,HIWORD(color
),
113 /******************************************************************
114 * MFDRV_MetaPoly - implements Polygon and Polyline
116 static BOOL
MFDRV_MetaPoly(DC
*dc
, short func
, LPPOINT16 pt
, short count
)
122 len
= sizeof(METARECORD
) + (count
* 4);
123 if (!(mr
= HeapAlloc( SystemHeap
, HEAP_ZERO_MEMORY
, len
)))
126 mr
->rdSize
= len
/ 2;
127 mr
->rdFunction
= func
;
128 *(mr
->rdParm
) = count
;
129 memcpy(mr
->rdParm
+ 1, pt
, count
* 4);
130 ret
= MFDRV_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
131 HeapFree( SystemHeap
, 0, mr
);
136 /**********************************************************************
140 MFDRV_Polyline( DC
*dc
, const POINT
* pt
, INT count
)
146 pt16
= (LPPOINT16
)HeapAlloc( GetProcessHeap(), 0, sizeof(POINT16
)*count
);
147 if(!pt16
) return FALSE
;
148 for (i
=count
;i
--;) CONV_POINT32TO16(&(pt
[i
]),&(pt16
[i
]));
149 ret
= MFDRV_MetaPoly(dc
, META_POLYLINE
, pt16
, count
);
151 HeapFree( GetProcessHeap(), 0, pt16
);
156 /**********************************************************************
160 MFDRV_Polygon( DC
*dc
, const POINT
* pt
, INT count
)
166 pt16
= (LPPOINT16
) HeapAlloc( GetProcessHeap(), 0, sizeof(POINT16
)*count
);
167 if(!pt16
) return FALSE
;
168 for (i
=count
;i
--;) CONV_POINT32TO16(&(pt
[i
]),&(pt16
[i
]));
169 ret
= MFDRV_MetaPoly(dc
, META_POLYGON
, pt16
, count
);
171 HeapFree( GetProcessHeap(), 0, pt16
);
176 /**********************************************************************
180 MFDRV_PolyPolygon( DC
*dc
, const POINT
* pt
, const INT
* counts
, UINT polygons
)
184 const POINT
* curpt
=pt
;
187 for (i
=0;i
<polygons
;i
++) {
188 pt16
=(LPPOINT16
)HeapAlloc( GetProcessHeap(), 0,
189 sizeof(POINT16
) * counts
[i
] );
190 if(!pt16
) return FALSE
;
191 for (j
=counts
[i
];j
--;) CONV_POINT32TO16(&(curpt
[j
]),&(pt16
[j
]));
192 ret
= MFDRV_MetaPoly(dc
, META_POLYGON
, pt16
, counts
[i
]);
193 HeapFree( GetProcessHeap(), 0, pt16
);
202 /**********************************************************************
206 MFDRV_ExtFloodFill( DC
*dc
, INT x
, INT y
, COLORREF color
, UINT fillType
)
208 return MFDRV_MetaParam4(dc
,META_FLOODFILL
,x
,y
,HIWORD(color
),
213 /******************************************************************
216 * For explanation of the format of the record see MF_Play_MetaCreateRegion in
219 static INT16
MFDRV_CreateRegion(DC
*dc
, HRGN hrgn
)
224 RECT
*pCurRect
, *pEndRect
;
225 WORD Bands
= 0, MaxBands
= 0;
226 WORD
*Param
, *StartBand
;
229 len
= GetRegionData( hrgn
, 0, NULL
);
230 if( !(rgndata
= HeapAlloc( SystemHeap
, 0, len
)) ) {
231 WARN("Can't alloc rgndata buffer\n");
234 GetRegionData( hrgn
, len
, rgndata
);
236 /* Overestimate of length:
237 * Assume every rect is a separate band -> 6 WORDs per rect
239 len
= sizeof(METARECORD
) + 20 + (rgndata
->rdh
.nCount
* 12);
240 if( !(mr
= HeapAlloc( SystemHeap
, HEAP_ZERO_MEMORY
, len
)) ) {
241 WARN("Can't alloc METARECORD buffer\n");
242 HeapFree( SystemHeap
, 0, rgndata
);
246 Param
= mr
->rdParm
+ 11;
249 pEndRect
= (RECT
*)rgndata
->Buffer
+ rgndata
->rdh
.nCount
;
250 for(pCurRect
= (RECT
*)rgndata
->Buffer
; pCurRect
< pEndRect
; pCurRect
++)
252 if( StartBand
&& pCurRect
->top
== *(StartBand
+ 1) )
254 *Param
++ = pCurRect
->left
;
255 *Param
++ = pCurRect
->right
;
261 *StartBand
= Param
- StartBand
- 3;
262 *Param
++ = *StartBand
;
263 if(*StartBand
> MaxBands
)
264 MaxBands
= *StartBand
;
268 *Param
++ = pCurRect
->top
;
269 *Param
++ = pCurRect
->bottom
;
270 *Param
++ = pCurRect
->left
;
271 *Param
++ = pCurRect
->right
;
274 len
= Param
- (WORD
*)mr
;
278 mr
->rdParm
[2] = 0x1234;
280 mr
->rdParm
[4] = len
* 2;
281 mr
->rdParm
[5] = Bands
;
282 mr
->rdParm
[6] = MaxBands
;
283 mr
->rdParm
[7] = rgndata
->rdh
.rcBound
.left
;
284 mr
->rdParm
[8] = rgndata
->rdh
.rcBound
.top
;
285 mr
->rdParm
[9] = rgndata
->rdh
.rcBound
.right
;
286 mr
->rdParm
[10] = rgndata
->rdh
.rcBound
.bottom
;
287 mr
->rdFunction
= META_CREATEREGION
;
288 mr
->rdSize
= len
/ 2;
289 ret
= MFDRV_WriteRecord( dc
, mr
, mr
->rdSize
* 2 );
290 HeapFree( SystemHeap
, 0, mr
);
291 HeapFree( SystemHeap
, 0, rgndata
);
294 WARN("MFDRV_WriteRecord failed\n");
297 return MFDRV_AddHandleDC( dc
);
301 /**********************************************************************
305 MFDRV_PaintRgn( DC
*dc
, HRGN hrgn
)
308 index
= MFDRV_CreateRegion( dc
, hrgn
);
311 return MFDRV_MetaParam1( dc
, META_PAINTREGION
, index
);
315 /**********************************************************************
319 MFDRV_InvertRgn( DC
*dc
, HRGN hrgn
)
322 index
= MFDRV_CreateRegion( dc
, hrgn
);
325 return MFDRV_MetaParam1( dc
, META_INVERTREGION
, index
);
329 /**********************************************************************
333 MFDRV_FillRgn( DC
*dc
, HRGN hrgn
, HBRUSH hbrush
)
336 iRgn
= MFDRV_CreateRegion( dc
, hrgn
);
339 iBrush
= MFDRV_CreateBrushIndirect( dc
, hbrush
);
342 return MFDRV_MetaParam2( dc
, META_FILLREGION
, iRgn
, iBrush
);
345 /**********************************************************************
349 MFDRV_FrameRgn( DC
*dc
, HRGN hrgn
, HBRUSH hbrush
, INT x
, INT y
)
352 iRgn
= MFDRV_CreateRegion( dc
, hrgn
);
355 iBrush
= MFDRV_CreateBrushIndirect( dc
, hbrush
);
358 return MFDRV_MetaParam4( dc
, META_FRAMEREGION
, iRgn
, iBrush
, x
, y
);
362 /**********************************************************************
366 MFDRV_SetBkColor( DC
*dc
, COLORREF color
)
368 return MFDRV_MetaParam2(dc
, META_SETBKCOLOR
, HIWORD(color
), LOWORD(color
));
372 /**********************************************************************
376 MFDRV_SetTextColor( DC
*dc
, COLORREF color
)
378 return MFDRV_MetaParam2(dc
, META_SETTEXTCOLOR
, HIWORD(color
),
383 /**********************************************************************
385 * Since MetaFiles don't record Beziers and they don't even record
386 * approximations to them using lines, we need this stub function.
389 MFDRV_PolyBezier( DC
*dc
, const POINT
*pts
, DWORD count
)
394 /**********************************************************************
396 * Since MetaFiles don't record Beziers and they don't even record
397 * approximations to them using lines, we need this stub function.
400 MFDRV_PolyBezierTo( DC
*dc
, const POINT
*pts
, DWORD count
)