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
25 #include "mfdrv/metafiledrv.h"
26 #include "wine/debug.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(metafile
);
30 /**********************************************************************
34 MFDRV_MoveTo(PHYSDEV dev
, INT x
, INT y
)
36 return MFDRV_MetaParam2(dev
,META_MOVETO
,x
,y
);
39 /***********************************************************************
43 MFDRV_LineTo( PHYSDEV dev
, INT x
, INT y
)
45 return MFDRV_MetaParam2(dev
, META_LINETO
, x
, y
);
49 /***********************************************************************
53 MFDRV_Arc( PHYSDEV dev
, INT left
, INT top
, INT right
, INT bottom
,
54 INT xstart
, INT ystart
, INT xend
, INT yend
)
56 return MFDRV_MetaParam8(dev
, META_ARC
, left
, top
, right
, bottom
,
57 xstart
, ystart
, xend
, yend
);
61 /***********************************************************************
65 MFDRV_Pie( PHYSDEV dev
, INT left
, INT top
, INT right
, INT bottom
,
66 INT xstart
, INT ystart
, INT xend
, INT yend
)
68 return MFDRV_MetaParam8(dev
, META_PIE
, left
, top
, right
, bottom
,
69 xstart
, ystart
, xend
, yend
);
73 /***********************************************************************
77 MFDRV_Chord( PHYSDEV dev
, INT left
, INT top
, INT right
, INT bottom
,
78 INT xstart
, INT ystart
, INT xend
, INT yend
)
80 return MFDRV_MetaParam8(dev
, META_CHORD
, left
, top
, right
, bottom
,
81 xstart
, ystart
, xend
, yend
);
84 /***********************************************************************
88 MFDRV_Ellipse( PHYSDEV dev
, INT left
, INT top
, INT right
, INT bottom
)
90 return MFDRV_MetaParam4(dev
, META_ELLIPSE
, left
, top
, right
, bottom
);
93 /***********************************************************************
97 MFDRV_Rectangle(PHYSDEV dev
, INT left
, INT top
, INT right
, INT bottom
)
99 return MFDRV_MetaParam4(dev
, META_RECTANGLE
, left
, top
, right
, bottom
);
102 /***********************************************************************
106 MFDRV_RoundRect( PHYSDEV dev
, INT left
, INT top
, INT right
,
107 INT bottom
, INT ell_width
, INT ell_height
)
109 return MFDRV_MetaParam6(dev
, META_ROUNDRECT
, left
, top
, right
, bottom
,
110 ell_width
, ell_height
);
113 /***********************************************************************
117 MFDRV_SetPixel( PHYSDEV dev
, INT x
, INT y
, COLORREF color
)
119 return MFDRV_MetaParam4(dev
, META_SETPIXEL
, x
, y
,HIWORD(color
),
124 /******************************************************************
125 * MFDRV_MetaPoly - implements Polygon and Polyline
127 static BOOL
MFDRV_MetaPoly(PHYSDEV dev
, short func
, LPPOINT16 pt
, short count
)
133 len
= sizeof(METARECORD
) + (count
* 4);
134 if (!(mr
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, len
)))
137 mr
->rdSize
= len
/ 2;
138 mr
->rdFunction
= func
;
139 *(mr
->rdParm
) = count
;
140 memcpy(mr
->rdParm
+ 1, pt
, count
* 4);
141 ret
= MFDRV_WriteRecord( dev
, mr
, mr
->rdSize
* 2);
142 HeapFree( GetProcessHeap(), 0, mr
);
147 /**********************************************************************
151 MFDRV_Polyline( PHYSDEV dev
, const POINT
* pt
, INT count
)
157 pt16
= (LPPOINT16
)HeapAlloc( GetProcessHeap(), 0, sizeof(POINT16
)*count
);
158 if(!pt16
) return FALSE
;
159 for (i
=count
;i
--;) CONV_POINT32TO16(&(pt
[i
]),&(pt16
[i
]));
160 ret
= MFDRV_MetaPoly(dev
, META_POLYLINE
, pt16
, count
);
162 HeapFree( GetProcessHeap(), 0, pt16
);
167 /**********************************************************************
171 MFDRV_Polygon( PHYSDEV dev
, const POINT
* pt
, INT count
)
177 pt16
= (LPPOINT16
) HeapAlloc( GetProcessHeap(), 0, sizeof(POINT16
)*count
);
178 if(!pt16
) return FALSE
;
179 for (i
=count
;i
--;) CONV_POINT32TO16(&(pt
[i
]),&(pt16
[i
]));
180 ret
= MFDRV_MetaPoly(dev
, META_POLYGON
, pt16
, count
);
182 HeapFree( GetProcessHeap(), 0, pt16
);
187 /**********************************************************************
191 MFDRV_PolyPolygon( PHYSDEV dev
, const POINT
* pt
, const INT
* counts
, UINT polygons
)
195 const POINT
* curpt
=pt
;
198 for (i
=0;i
<polygons
;i
++) {
199 pt16
=(LPPOINT16
)HeapAlloc( GetProcessHeap(), 0,
200 sizeof(POINT16
) * counts
[i
] );
201 if(!pt16
) return FALSE
;
202 for (j
=counts
[i
];j
--;) CONV_POINT32TO16(&(curpt
[j
]),&(pt16
[j
]));
203 ret
= MFDRV_MetaPoly(dev
, META_POLYGON
, pt16
, counts
[i
]);
204 HeapFree( GetProcessHeap(), 0, pt16
);
213 /**********************************************************************
217 MFDRV_ExtFloodFill( PHYSDEV dev
, INT x
, INT y
, COLORREF color
, UINT fillType
)
219 return MFDRV_MetaParam4(dev
,META_FLOODFILL
,x
,y
,HIWORD(color
),
224 /******************************************************************
227 * For explanation of the format of the record see MF_Play_MetaCreateRegion in
230 static INT16
MFDRV_CreateRegion(PHYSDEV dev
, HRGN hrgn
)
235 RECT
*pCurRect
, *pEndRect
;
236 WORD Bands
= 0, MaxBands
= 0;
237 WORD
*Param
, *StartBand
;
240 if (!(len
= GetRegionData( hrgn
, 0, NULL
))) return -1;
241 if( !(rgndata
= HeapAlloc( GetProcessHeap(), 0, len
)) ) {
242 WARN("Can't alloc rgndata buffer\n");
245 GetRegionData( hrgn
, len
, rgndata
);
247 /* Overestimate of length:
248 * Assume every rect is a separate band -> 6 WORDs per rect
250 len
= sizeof(METARECORD
) + 20 + (rgndata
->rdh
.nCount
* 12);
251 if( !(mr
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, len
)) ) {
252 WARN("Can't alloc METARECORD buffer\n");
253 HeapFree( GetProcessHeap(), 0, rgndata
);
257 Param
= mr
->rdParm
+ 11;
260 pEndRect
= (RECT
*)rgndata
->Buffer
+ rgndata
->rdh
.nCount
;
261 for(pCurRect
= (RECT
*)rgndata
->Buffer
; pCurRect
< pEndRect
; pCurRect
++)
263 if( StartBand
&& pCurRect
->top
== *(StartBand
+ 1) )
265 *Param
++ = pCurRect
->left
;
266 *Param
++ = pCurRect
->right
;
272 *StartBand
= Param
- StartBand
- 3;
273 *Param
++ = *StartBand
;
274 if(*StartBand
> MaxBands
)
275 MaxBands
= *StartBand
;
279 *Param
++ = pCurRect
->top
;
280 *Param
++ = pCurRect
->bottom
;
281 *Param
++ = pCurRect
->left
;
282 *Param
++ = pCurRect
->right
;
285 len
= Param
- (WORD
*)mr
;
289 mr
->rdParm
[2] = 0x1234;
291 mr
->rdParm
[4] = len
* 2;
292 mr
->rdParm
[5] = Bands
;
293 mr
->rdParm
[6] = MaxBands
;
294 mr
->rdParm
[7] = rgndata
->rdh
.rcBound
.left
;
295 mr
->rdParm
[8] = rgndata
->rdh
.rcBound
.top
;
296 mr
->rdParm
[9] = rgndata
->rdh
.rcBound
.right
;
297 mr
->rdParm
[10] = rgndata
->rdh
.rcBound
.bottom
;
298 mr
->rdFunction
= META_CREATEREGION
;
299 mr
->rdSize
= len
/ 2;
300 ret
= MFDRV_WriteRecord( dev
, mr
, mr
->rdSize
* 2 );
301 HeapFree( GetProcessHeap(), 0, mr
);
302 HeapFree( GetProcessHeap(), 0, rgndata
);
305 WARN("MFDRV_WriteRecord failed\n");
308 return MFDRV_AddHandleDC( dev
);
312 /**********************************************************************
316 MFDRV_PaintRgn( PHYSDEV dev
, HRGN hrgn
)
319 index
= MFDRV_CreateRegion( dev
, hrgn
);
322 return MFDRV_MetaParam1( dev
, META_PAINTREGION
, index
);
326 /**********************************************************************
330 MFDRV_InvertRgn( PHYSDEV dev
, HRGN hrgn
)
333 index
= MFDRV_CreateRegion( dev
, hrgn
);
336 return MFDRV_MetaParam1( dev
, META_INVERTREGION
, index
);
340 /**********************************************************************
344 MFDRV_FillRgn( PHYSDEV dev
, HRGN hrgn
, HBRUSH hbrush
)
347 iRgn
= MFDRV_CreateRegion( dev
, hrgn
);
350 iBrush
= MFDRV_CreateBrushIndirect( dev
, hbrush
);
353 return MFDRV_MetaParam2( dev
, META_FILLREGION
, iRgn
, iBrush
);
356 /**********************************************************************
360 MFDRV_FrameRgn( PHYSDEV dev
, HRGN hrgn
, HBRUSH hbrush
, INT x
, INT y
)
363 iRgn
= MFDRV_CreateRegion( dev
, hrgn
);
366 iBrush
= MFDRV_CreateBrushIndirect( dev
, hbrush
);
369 return MFDRV_MetaParam4( dev
, META_FRAMEREGION
, iRgn
, iBrush
, x
, y
);
373 /**********************************************************************
374 * MFDRV_ExtSelectClipRgn
376 INT
MFDRV_ExtSelectClipRgn( PHYSDEV dev
, HRGN hrgn
, INT mode
)
381 if (mode
!= RGN_COPY
) return ERROR
;
382 if (!hrgn
) return NULLREGION
;
383 iRgn
= MFDRV_CreateRegion( dev
, hrgn
);
384 if(iRgn
== -1) return ERROR
;
385 ret
= MFDRV_MetaParam1( dev
, META_SELECTCLIPREGION
, iRgn
) ? NULLREGION
: ERROR
;
386 MFDRV_MetaParam1( dev
, META_DELETEOBJECT
, iRgn
);
391 /**********************************************************************
395 MFDRV_SetBkColor( PHYSDEV dev
, COLORREF color
)
397 return MFDRV_MetaParam2(dev
, META_SETBKCOLOR
, HIWORD(color
),
398 LOWORD(color
)) ? color
: CLR_INVALID
;
402 /**********************************************************************
406 MFDRV_SetTextColor( PHYSDEV dev
, COLORREF color
)
408 return MFDRV_MetaParam2(dev
, META_SETTEXTCOLOR
, HIWORD(color
),
409 LOWORD(color
)) ? color
: CLR_INVALID
;
413 /**********************************************************************
415 * Since MetaFiles don't record Beziers and they don't even record
416 * approximations to them using lines, we need this stub function.
419 MFDRV_PolyBezier( PHYSDEV dev
, const POINT
*pts
, DWORD count
)
424 /**********************************************************************
426 * Since MetaFiles don't record Beziers and they don't even record
427 * approximations to them using lines, we need this stub function.
430 MFDRV_PolyBezierTo( PHYSDEV dev
, const POINT
*pts
, DWORD count
)