1 /*
2 * Enhanced MetaFile driver dc value functions
3 *
4 * Copyright 1999 Huw D M Davies
5 * Copyright 2016 Alexandre Julliard
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22 #include <assert.h>
23 #include "enhmfdrv/enhmetafiledrv.h"
24
25 /* get the emf physdev from the path physdev */
get_emfdev(PHYSDEV path)26 static inline PHYSDEV get_emfdev( PHYSDEV path )
27 {
28 return &CONTAINING_RECORD( path, EMFDRV_PDEVICE, pathdev )->dev;
29 }
30
31 static const struct gdi_dc_funcs emfpath_driver;
32
EMFDRV_SaveDC(PHYSDEV dev)33 INT EMFDRV_SaveDC( PHYSDEV dev )
34 {
35 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSaveDC );
36 INT ret = next->funcs->pSaveDC( next );
37
38 if (ret)
39 {
40 EMRSAVEDC emr;
41 emr.emr.iType = EMR_SAVEDC;
42 emr.emr.nSize = sizeof(emr);
43 EMFDRV_WriteRecord( dev, &emr.emr );
44 }
45 return ret;
46 }
47
EMFDRV_RestoreDC(PHYSDEV dev,INT level)48 BOOL EMFDRV_RestoreDC( PHYSDEV dev, INT level )
49 {
50 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pRestoreDC );
51 EMFDRV_PDEVICE* physDev = get_emf_physdev( dev );
52 DC *dc = get_physdev_dc( dev );
53 EMRRESTOREDC emr;
54 BOOL ret;
55
56 emr.emr.iType = EMR_RESTOREDC;
57 emr.emr.nSize = sizeof(emr);
58
59 if (level < 0)
60 emr.iRelative = level;
61 else
62 emr.iRelative = level - dc->saveLevel - 1;
63
64 physDev->restoring++;
65 ret = next->funcs->pRestoreDC( next, level );
66 physDev->restoring--;
67
68 if (ret) EMFDRV_WriteRecord( dev, &emr.emr );
69 return ret;
70 }
71
EMFDRV_SetTextAlign(PHYSDEV dev,UINT align)72 UINT EMFDRV_SetTextAlign( PHYSDEV dev, UINT align )
73 {
74 EMRSETTEXTALIGN emr;
75 emr.emr.iType = EMR_SETTEXTALIGN;
76 emr.emr.nSize = sizeof(emr);
77 emr.iMode = align;
78 return EMFDRV_WriteRecord( dev, &emr.emr ) ? align : GDI_ERROR;
79 }
80
EMFDRV_SetTextJustification(PHYSDEV dev,INT nBreakExtra,INT nBreakCount)81 BOOL EMFDRV_SetTextJustification(PHYSDEV dev, INT nBreakExtra, INT nBreakCount)
82 {
83 EMRSETTEXTJUSTIFICATION emr;
84 emr.emr.iType = EMR_SETTEXTJUSTIFICATION;
85 emr.emr.nSize = sizeof(emr);
86 emr.nBreakExtra = nBreakExtra;
87 emr.nBreakCount = nBreakCount;
88 return EMFDRV_WriteRecord(dev, &emr.emr);
89 }
90
EMFDRV_SetBkMode(PHYSDEV dev,INT mode)91 INT EMFDRV_SetBkMode( PHYSDEV dev, INT mode )
92 {
93 EMRSETBKMODE emr;
94 emr.emr.iType = EMR_SETBKMODE;
95 emr.emr.nSize = sizeof(emr);
96 emr.iMode = mode;
97 return EMFDRV_WriteRecord( dev, &emr.emr ) ? mode : 0;
98 }
99
EMFDRV_SetBkColor(PHYSDEV dev,COLORREF color)100 COLORREF EMFDRV_SetBkColor( PHYSDEV dev, COLORREF color )
101 {
102 EMRSETBKCOLOR emr;
103 EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
104
105 if (physDev->restoring) return color; /* don't output records during RestoreDC */
106
107 emr.emr.iType = EMR_SETBKCOLOR;
108 emr.emr.nSize = sizeof(emr);
109 emr.crColor = color;
110 return EMFDRV_WriteRecord( dev, &emr.emr ) ? color : CLR_INVALID;
111 }
112
113
EMFDRV_SetTextColor(PHYSDEV dev,COLORREF color)114 COLORREF EMFDRV_SetTextColor( PHYSDEV dev, COLORREF color )
115 {
116 EMRSETTEXTCOLOR emr;
117 EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
118
119 if (physDev->restoring) return color; /* don't output records during RestoreDC */
120
121 emr.emr.iType = EMR_SETTEXTCOLOR;
122 emr.emr.nSize = sizeof(emr);
123 emr.crColor = color;
124 return EMFDRV_WriteRecord( dev, &emr.emr ) ? color : CLR_INVALID;
125 }
126
EMFDRV_SetROP2(PHYSDEV dev,INT rop)127 INT EMFDRV_SetROP2( PHYSDEV dev, INT rop )
128 {
129 EMRSETROP2 emr;
130 emr.emr.iType = EMR_SETROP2;
131 emr.emr.nSize = sizeof(emr);
132 emr.iMode = rop;
133 return EMFDRV_WriteRecord( dev, &emr.emr ) ? rop : 0;
134 }
135
EMFDRV_SetPolyFillMode(PHYSDEV dev,INT mode)136 INT EMFDRV_SetPolyFillMode( PHYSDEV dev, INT mode )
137 {
138 EMRSETPOLYFILLMODE emr;
139 emr.emr.iType = EMR_SETPOLYFILLMODE;
140 emr.emr.nSize = sizeof(emr);
141 emr.iMode = mode;
142 return EMFDRV_WriteRecord( dev, &emr.emr ) ? mode : 0;
143 }
144
EMFDRV_SetStretchBltMode(PHYSDEV dev,INT mode)145 INT EMFDRV_SetStretchBltMode( PHYSDEV dev, INT mode )
146 {
147 EMRSETSTRETCHBLTMODE emr;
148 emr.emr.iType = EMR_SETSTRETCHBLTMODE;
149 emr.emr.nSize = sizeof(emr);
150 emr.iMode = mode;
151 return EMFDRV_WriteRecord( dev, &emr.emr ) ? mode : 0;
152 }
153
EMFDRV_SetArcDirection(PHYSDEV dev,INT arcDirection)154 INT EMFDRV_SetArcDirection(PHYSDEV dev, INT arcDirection)
155 {
156 EMRSETARCDIRECTION emr;
157
158 emr.emr.iType = EMR_SETARCDIRECTION;
159 emr.emr.nSize = sizeof(emr);
160 emr.iArcDirection = arcDirection;
161 return EMFDRV_WriteRecord(dev, &emr.emr) ? arcDirection : 0;
162 }
163
EMFDRV_ExcludeClipRect(PHYSDEV dev,INT left,INT top,INT right,INT bottom)164 INT EMFDRV_ExcludeClipRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom )
165 {
166 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pExcludeClipRect );
167 EMREXCLUDECLIPRECT emr;
168
169 emr.emr.iType = EMR_EXCLUDECLIPRECT;
170 emr.emr.nSize = sizeof(emr);
171 emr.rclClip.left = left;
172 emr.rclClip.top = top;
173 emr.rclClip.right = right;
174 emr.rclClip.bottom = bottom;
175 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return ERROR;
176 return next->funcs->pExcludeClipRect( next, left, top, right, bottom );
177 }
178
EMFDRV_IntersectClipRect(PHYSDEV dev,INT left,INT top,INT right,INT bottom)179 INT EMFDRV_IntersectClipRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom)
180 {
181 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pIntersectClipRect );
182 EMRINTERSECTCLIPRECT emr;
183
184 emr.emr.iType = EMR_INTERSECTCLIPRECT;
185 emr.emr.nSize = sizeof(emr);
186 emr.rclClip.left = left;
187 emr.rclClip.top = top;
188 emr.rclClip.right = right;
189 emr.rclClip.bottom = bottom;
190 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return ERROR;
191 return next->funcs->pIntersectClipRect( next, left, top, right, bottom );
192 }
193
EMFDRV_OffsetClipRgn(PHYSDEV dev,INT x,INT y)194 INT EMFDRV_OffsetClipRgn( PHYSDEV dev, INT x, INT y )
195 {
196 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pOffsetClipRgn );
197 EMROFFSETCLIPRGN emr;
198
199 emr.emr.iType = EMR_OFFSETCLIPRGN;
200 emr.emr.nSize = sizeof(emr);
201 emr.ptlOffset.x = x;
202 emr.ptlOffset.y = y;
203 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return ERROR;
204 return next->funcs->pOffsetClipRgn( next, x, y );
205 }
206
EMFDRV_ExtSelectClipRgn(PHYSDEV dev,HRGN hrgn,INT mode)207 INT EMFDRV_ExtSelectClipRgn( PHYSDEV dev, HRGN hrgn, INT mode )
208 {
209 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pExtSelectClipRgn );
210 EMREXTSELECTCLIPRGN *emr;
211 DWORD size, rgnsize;
212 BOOL ret;
213
214 if (!hrgn)
215 {
216 if (mode != RGN_COPY) return ERROR;
217 rgnsize = 0;
218 }
219 else rgnsize = GetRegionData( hrgn, 0, NULL );
220
221 size = rgnsize + offsetof(EMREXTSELECTCLIPRGN,RgnData);
222 emr = HeapAlloc( GetProcessHeap(), 0, size );
223 if (rgnsize) GetRegionData( hrgn, rgnsize, (RGNDATA *)&emr->RgnData );
224
225 emr->emr.iType = EMR_EXTSELECTCLIPRGN;
226 emr->emr.nSize = size;
227 emr->cbRgnData = rgnsize;
228 emr->iMode = mode;
229
230 ret = EMFDRV_WriteRecord( dev, &emr->emr );
231 HeapFree( GetProcessHeap(), 0, emr );
232 return ret ? next->funcs->pExtSelectClipRgn( next, hrgn, mode ) : ERROR;
233 }
234
EMFDRV_SetMapMode(PHYSDEV dev,INT mode)235 INT EMFDRV_SetMapMode( PHYSDEV dev, INT mode )
236 {
237 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetMapMode );
238 EMRSETMAPMODE emr;
239 emr.emr.iType = EMR_SETMAPMODE;
240 emr.emr.nSize = sizeof(emr);
241 emr.iMode = mode;
242
243 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return 0;
244 return next->funcs->pSetMapMode( next, mode );
245 }
246
EMFDRV_SetViewportExtEx(PHYSDEV dev,INT cx,INT cy,SIZE * size)247 BOOL EMFDRV_SetViewportExtEx( PHYSDEV dev, INT cx, INT cy, SIZE *size )
248 {
249 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetViewportExtEx );
250 EMRSETVIEWPORTEXTEX emr;
251
252 emr.emr.iType = EMR_SETVIEWPORTEXTEX;
253 emr.emr.nSize = sizeof(emr);
254 emr.szlExtent.cx = cx;
255 emr.szlExtent.cy = cy;
256
257 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
258 return next->funcs->pSetViewportExtEx( next, cx, cy, size );
259 }
260
EMFDRV_SetWindowExtEx(PHYSDEV dev,INT cx,INT cy,SIZE * size)261 BOOL EMFDRV_SetWindowExtEx( PHYSDEV dev, INT cx, INT cy, SIZE *size )
262 {
263 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetWindowExtEx );
264 EMRSETWINDOWEXTEX emr;
265
266 emr.emr.iType = EMR_SETWINDOWEXTEX;
267 emr.emr.nSize = sizeof(emr);
268 emr.szlExtent.cx = cx;
269 emr.szlExtent.cy = cy;
270
271 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
272 return next->funcs->pSetWindowExtEx( next, cx, cy, size );
273 }
274
EMFDRV_SetViewportOrgEx(PHYSDEV dev,INT x,INT y,POINT * pt)275 BOOL EMFDRV_SetViewportOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
276 {
277 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetViewportOrgEx );
278 EMRSETVIEWPORTORGEX emr;
279
280 emr.emr.iType = EMR_SETVIEWPORTORGEX;
281 emr.emr.nSize = sizeof(emr);
282 emr.ptlOrigin.x = x;
283 emr.ptlOrigin.y = y;
284
285 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
286 return next->funcs->pSetViewportOrgEx( next, x, y, pt );
287 }
288
EMFDRV_SetWindowOrgEx(PHYSDEV dev,INT x,INT y,POINT * pt)289 BOOL EMFDRV_SetWindowOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
290 {
291 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetWindowOrgEx );
292 EMRSETWINDOWORGEX emr;
293
294 emr.emr.iType = EMR_SETWINDOWORGEX;
295 emr.emr.nSize = sizeof(emr);
296 emr.ptlOrigin.x = x;
297 emr.ptlOrigin.y = y;
298
299 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
300 return next->funcs->pSetWindowOrgEx( next, x, y, pt );
301 }
302
EMFDRV_ScaleViewportExtEx(PHYSDEV dev,INT xNum,INT xDenom,INT yNum,INT yDenom,SIZE * size)303 BOOL EMFDRV_ScaleViewportExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNum, INT yDenom, SIZE *size )
304 {
305 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pScaleViewportExtEx );
306 EMRSCALEVIEWPORTEXTEX emr;
307
308 emr.emr.iType = EMR_SCALEVIEWPORTEXTEX;
309 emr.emr.nSize = sizeof(emr);
310 emr.xNum = xNum;
311 emr.xDenom = xDenom;
312 emr.yNum = yNum;
313 emr.yDenom = yDenom;
314
315 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
316 return next->funcs->pScaleViewportExtEx( next, xNum, xDenom, yNum, yDenom, size );
317 }
318
EMFDRV_ScaleWindowExtEx(PHYSDEV dev,INT xNum,INT xDenom,INT yNum,INT yDenom,SIZE * size)319 BOOL EMFDRV_ScaleWindowExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNum, INT yDenom, SIZE *size )
320 {
321 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pScaleWindowExtEx );
322 EMRSCALEWINDOWEXTEX emr;
323
324 emr.emr.iType = EMR_SCALEWINDOWEXTEX;
325 emr.emr.nSize = sizeof(emr);
326 emr.xNum = xNum;
327 emr.xDenom = xDenom;
328 emr.yNum = yNum;
329 emr.yDenom = yDenom;
330
331 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
332 return next->funcs->pScaleWindowExtEx( next, xNum, xDenom, yNum, yDenom, size );
333 }
334
EMFDRV_SetLayout(PHYSDEV dev,DWORD layout)335 DWORD EMFDRV_SetLayout( PHYSDEV dev, DWORD layout )
336 {
337 EMRSETLAYOUT emr;
338
339 emr.emr.iType = EMR_SETLAYOUT;
340 emr.emr.nSize = sizeof(emr);
341 emr.iMode = layout;
342 return EMFDRV_WriteRecord( dev, &emr.emr ) ? layout : GDI_ERROR;
343 }
344
EMFDRV_SetWorldTransform(PHYSDEV dev,const XFORM * xform)345 BOOL EMFDRV_SetWorldTransform( PHYSDEV dev, const XFORM *xform)
346 {
347 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetWorldTransform );
348 EMRSETWORLDTRANSFORM emr;
349
350 emr.emr.iType = EMR_SETWORLDTRANSFORM;
351 emr.emr.nSize = sizeof(emr);
352 emr.xform = *xform;
353
354 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
355 return next->funcs->pSetWorldTransform( next, xform );
356 }
357
EMFDRV_ModifyWorldTransform(PHYSDEV dev,const XFORM * xform,DWORD mode)358 BOOL EMFDRV_ModifyWorldTransform( PHYSDEV dev, const XFORM *xform, DWORD mode)
359 {
360 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pModifyWorldTransform );
361 EMRMODIFYWORLDTRANSFORM emr;
362
363 emr.emr.iType = EMR_MODIFYWORLDTRANSFORM;
364 emr.emr.nSize = sizeof(emr);
365 emr.xform = *xform;
366 emr.iMode = mode;
367
368 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
369 return next->funcs->pModifyWorldTransform( next, xform, mode );
370 }
371
EMFDRV_OffsetViewportOrgEx(PHYSDEV dev,INT x,INT y,POINT * pt)372 BOOL EMFDRV_OffsetViewportOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
373 {
374 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pOffsetViewportOrgEx );
375 EMRSETVIEWPORTORGEX emr;
376 POINT prev;
377
378 GetViewportOrgEx( dev->hdc, &prev );
379
380 emr.emr.iType = EMR_SETVIEWPORTORGEX;
381 emr.emr.nSize = sizeof(emr);
382 emr.ptlOrigin.x = prev.x + x;
383 emr.ptlOrigin.y = prev.y + y;
384
385 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
386 return next->funcs->pOffsetViewportOrgEx( next, x, y, pt );
387 }
388
EMFDRV_OffsetWindowOrgEx(PHYSDEV dev,INT x,INT y,POINT * pt)389 BOOL EMFDRV_OffsetWindowOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
390 {
391 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pOffsetWindowOrgEx );
392 EMRSETWINDOWORGEX emr;
393 POINT prev;
394
395 GetWindowOrgEx( dev->hdc, &prev );
396
397 emr.emr.iType = EMR_SETWINDOWORGEX;
398 emr.emr.nSize = sizeof(emr);
399 emr.ptlOrigin.x = prev.x + x;
400 emr.ptlOrigin.y = prev.y + y;
401
402 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
403 return next->funcs->pOffsetWindowOrgEx( next, x, y, pt );
404 }
405
EMFDRV_SetMapperFlags(PHYSDEV dev,DWORD flags)406 DWORD EMFDRV_SetMapperFlags( PHYSDEV dev, DWORD flags )
407 {
408 EMRSETMAPPERFLAGS emr;
409
410 emr.emr.iType = EMR_SETMAPPERFLAGS;
411 emr.emr.nSize = sizeof(emr);
412 emr.dwFlags = flags;
413
414 return EMFDRV_WriteRecord( dev, &emr.emr ) ? flags : GDI_ERROR;
415 }
416
EMFDRV_AbortPath(PHYSDEV dev)417 BOOL EMFDRV_AbortPath( PHYSDEV dev )
418 {
419 EMRABORTPATH emr;
420
421 emr.emr.iType = EMR_ABORTPATH;
422 emr.emr.nSize = sizeof(emr);
423
424 return EMFDRV_WriteRecord( dev, &emr.emr );
425 }
426
EMFDRV_BeginPath(PHYSDEV dev)427 BOOL EMFDRV_BeginPath( PHYSDEV dev )
428 {
429 EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
430 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pBeginPath );
431 EMRBEGINPATH emr;
432 DC *dc = get_physdev_dc( dev );
433
434 emr.emr.iType = EMR_BEGINPATH;
435 emr.emr.nSize = sizeof(emr);
436
437 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
438 if (physDev->path) return TRUE; /* already open */
439
440 if (!next->funcs->pBeginPath( next )) return FALSE;
441 push_dc_driver( &dc->physDev, &physDev->pathdev, &emfpath_driver );
442 physDev->path = TRUE;
443 return TRUE;
444 }
445
EMFDRV_CloseFigure(PHYSDEV dev)446 BOOL EMFDRV_CloseFigure( PHYSDEV dev )
447 {
448 EMRCLOSEFIGURE emr;
449
450 emr.emr.iType = EMR_CLOSEFIGURE;
451 emr.emr.nSize = sizeof(emr);
452
453 EMFDRV_WriteRecord( dev, &emr.emr );
454 return FALSE; /* always fails without a path */
455 }
456
EMFDRV_EndPath(PHYSDEV dev)457 BOOL EMFDRV_EndPath( PHYSDEV dev )
458 {
459 EMRENDPATH emr;
460
461 emr.emr.iType = EMR_ENDPATH;
462 emr.emr.nSize = sizeof(emr);
463
464 EMFDRV_WriteRecord( dev, &emr.emr );
465 return FALSE; /* always fails without a path */
466 }
467
EMFDRV_FlattenPath(PHYSDEV dev)468 BOOL EMFDRV_FlattenPath( PHYSDEV dev )
469 {
470 EMRFLATTENPATH emr;
471
472 emr.emr.iType = EMR_FLATTENPATH;
473 emr.emr.nSize = sizeof(emr);
474
475 return EMFDRV_WriteRecord( dev, &emr.emr );
476 }
477
EMFDRV_SelectClipPath(PHYSDEV dev,INT iMode)478 BOOL EMFDRV_SelectClipPath( PHYSDEV dev, INT iMode )
479 {
480 // PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSelectClipPath ); This HACK breaks test_emf_clipping
481 EMRSELECTCLIPPATH emr;
482 // BOOL ret = FALSE;
483 // HRGN hrgn;
484
485 emr.emr.iType = EMR_SELECTCLIPPATH;
486 emr.emr.nSize = sizeof(emr);
487 emr.iMode = iMode;
488
489 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
490 /* hrgn = PathToRegion( dev->hdc );
491 if (hrgn)
492 {
493 ret = next->funcs->pExtSelectClipRgn( next, hrgn, iMode );
494 DeleteObject( hrgn );
495 } ERR("EMFDRV_SelectClipPath ret %d\n",ret);
496 return ret;*/
497 return TRUE;
498 }
499
EMFDRV_WidenPath(PHYSDEV dev)500 BOOL EMFDRV_WidenPath( PHYSDEV dev )
501 {
502 EMRWIDENPATH emr;
503
504 emr.emr.iType = EMR_WIDENPATH;
505 emr.emr.nSize = sizeof(emr);
506
507 return EMFDRV_WriteRecord( dev, &emr.emr );
508 }
509
EMFDRV_GetDeviceCaps(PHYSDEV dev,INT cap)510 INT EMFDRV_GetDeviceCaps(PHYSDEV dev, INT cap)
511 {
512 EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
513
514 return GetDeviceCaps( physDev->ref_dc, cap );
515 }
516
517
518 /***********************************************************************
519 * emfpathdrv_AbortPath
520 */
emfpathdrv_AbortPath(PHYSDEV dev)521 static BOOL emfpathdrv_AbortPath( PHYSDEV dev )
522 {
523 PHYSDEV emfdev = get_emfdev( dev );
524 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pAbortPath );
525 DC *dc = get_physdev_dc( dev );
526
527 emfpath_driver.pDeleteDC( pop_dc_driver( dc, &emfpath_driver ));
528 emfdev->funcs->pAbortPath( emfdev );
529 return next->funcs->pAbortPath( next );
530 }
531
532 /***********************************************************************
533 * emfpathdrv_AngleArc
534 */
emfpathdrv_AngleArc(PHYSDEV dev,INT x,INT y,DWORD radius,FLOAT start,FLOAT sweep)535 static BOOL emfpathdrv_AngleArc( PHYSDEV dev, INT x, INT y, DWORD radius, FLOAT start, FLOAT sweep )
536 {
537 PHYSDEV emfdev = get_emfdev( dev );
538 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pAngleArc );
539
540 return (emfdev->funcs->pAngleArc( emfdev, x, y, radius, start, sweep ) &&
541 next->funcs->pAngleArc( next, x, y, radius, start, sweep ));
542 }
543
544 /***********************************************************************
545 * emfpathdrv_Arc
546 */
emfpathdrv_Arc(PHYSDEV dev,INT left,INT top,INT right,INT bottom,INT xstart,INT ystart,INT xend,INT yend)547 static BOOL emfpathdrv_Arc( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
548 INT xstart, INT ystart, INT xend, INT yend )
549 {
550 PHYSDEV emfdev = get_emfdev( dev );
551 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pArc );
552
553 return (emfdev->funcs->pArc( emfdev, left, top, right, bottom, xstart, ystart, xend, yend ) &&
554 next->funcs->pArc( next, left, top, right, bottom, xstart, ystart, xend, yend ));
555 }
556
557 /***********************************************************************
558 * emfpathdrv_ArcTo
559 */
emfpathdrv_ArcTo(PHYSDEV dev,INT left,INT top,INT right,INT bottom,INT xstart,INT ystart,INT xend,INT yend)560 static BOOL emfpathdrv_ArcTo( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
561 INT xstart, INT ystart, INT xend, INT yend )
562 {
563 PHYSDEV emfdev = get_emfdev( dev );
564 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pArcTo );
565
566 return (emfdev->funcs->pArcTo( emfdev, left, top, right, bottom, xstart, ystart, xend, yend ) &&
567 next->funcs->pArcTo( next, left, top, right, bottom, xstart, ystart, xend, yend ));
568 }
569
570 /***********************************************************************
571 * emfpathdrv_BeginPath
572 */
emfpathdrv_BeginPath(PHYSDEV dev)573 static BOOL emfpathdrv_BeginPath( PHYSDEV dev )
574 {
575 PHYSDEV emfdev = get_emfdev( dev );
576 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pBeginPath );
577
578 return (emfdev->funcs->pBeginPath( emfdev ) && next->funcs->pBeginPath( next ));
579 }
580
581 /***********************************************************************
582 * emfpathdrv_Chord
583 */
emfpathdrv_Chord(PHYSDEV dev,INT left,INT top,INT right,INT bottom,INT xstart,INT ystart,INT xend,INT yend)584 static BOOL emfpathdrv_Chord( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
585 INT xstart, INT ystart, INT xend, INT yend )
586 {
587 PHYSDEV emfdev = get_emfdev( dev );
588 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pChord );
589
590 return (emfdev->funcs->pChord( emfdev, left, top, right, bottom, xstart, ystart, xend, yend ) &&
591 next->funcs->pChord( next, left, top, right, bottom, xstart, ystart, xend, yend ));
592 }
593
594 /***********************************************************************
595 * emfpathdrv_CloseFigure
596 */
emfpathdrv_CloseFigure(PHYSDEV dev)597 static BOOL emfpathdrv_CloseFigure( PHYSDEV dev )
598 {
599 PHYSDEV emfdev = get_emfdev( dev );
600 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pCloseFigure );
601
602 emfdev->funcs->pCloseFigure( emfdev );
603 return next->funcs->pCloseFigure( next );
604 }
605
606 /***********************************************************************
607 * emfpathdrv_CreateDC
608 */
emfpathdrv_CreateDC(PHYSDEV * dev,LPCWSTR driver,LPCWSTR device,LPCWSTR output,const DEVMODEW * devmode)609 static BOOL emfpathdrv_CreateDC( PHYSDEV *dev, LPCWSTR driver, LPCWSTR device,
610 LPCWSTR output, const DEVMODEW *devmode )
611 {
612 assert( 0 ); /* should never be called */
613 return TRUE;
614 }
615
616 /*************************************************************
617 * emfpathdrv_DeleteDC
618 */
emfpathdrv_DeleteDC(PHYSDEV dev)619 static BOOL emfpathdrv_DeleteDC( PHYSDEV dev )
620 {
621 EMFDRV_PDEVICE *physdev = (EMFDRV_PDEVICE *)get_emfdev( dev );
622
623 physdev->path = FALSE;
624 return TRUE;
625 }
626
627 /***********************************************************************
628 * emfpathdrv_Ellipse
629 */
emfpathdrv_Ellipse(PHYSDEV dev,INT x1,INT y1,INT x2,INT y2)630 static BOOL emfpathdrv_Ellipse( PHYSDEV dev, INT x1, INT y1, INT x2, INT y2 )
631 {
632 PHYSDEV emfdev = get_emfdev( dev );
633 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pEllipse );
634
635 return (emfdev->funcs->pEllipse( emfdev, x1, y1, x2, y2 ) &&
636 next->funcs->pEllipse( next, x1, y1, x2, y2 ));
637 }
638
639 /***********************************************************************
640 * emfpathdrv_EndPath
641 */
emfpathdrv_EndPath(PHYSDEV dev)642 static BOOL emfpathdrv_EndPath( PHYSDEV dev )
643 {
644 PHYSDEV emfdev = get_emfdev( dev );
645 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pEndPath );
646 DC *dc = get_physdev_dc( dev );
647
648 emfpath_driver.pDeleteDC( pop_dc_driver( dc, &emfpath_driver ));
649 emfdev->funcs->pEndPath( emfdev );
650 return next->funcs->pEndPath( next );
651 }
652
653 /***********************************************************************
654 * emfpathdrv_ExtTextOut
655 */
emfpathdrv_ExtTextOut(PHYSDEV dev,INT x,INT y,UINT flags,const RECT * rect,LPCWSTR str,UINT count,const INT * dx)656 static BOOL emfpathdrv_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags, const RECT *rect,
657 LPCWSTR str, UINT count, const INT *dx )
658 {
659 PHYSDEV emfdev = get_emfdev( dev );
660 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pExtTextOut );
661
662 return (emfdev->funcs->pExtTextOut( emfdev, x, y, flags, rect, str, count, dx ) &&
663 next->funcs->pExtTextOut( next, x, y, flags, rect, str, count, dx ));
664 }
665
666 /***********************************************************************
667 * emfpathdrv_LineTo
668 */
emfpathdrv_LineTo(PHYSDEV dev,INT x,INT y)669 static BOOL emfpathdrv_LineTo( PHYSDEV dev, INT x, INT y )
670 {
671 PHYSDEV emfdev = get_emfdev( dev );
672 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pLineTo );
673
674 return (emfdev->funcs->pLineTo( emfdev, x, y ) && next->funcs->pLineTo( next, x, y ));
675 }
676
677 /***********************************************************************
678 * emfpathdrv_MoveTo
679 */
emfpathdrv_MoveTo(PHYSDEV dev,INT x,INT y)680 static BOOL emfpathdrv_MoveTo( PHYSDEV dev, INT x, INT y )
681 {
682 PHYSDEV emfdev = get_emfdev( dev );
683 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pMoveTo );
684
685 return (emfdev->funcs->pMoveTo( emfdev, x, y ) && next->funcs->pMoveTo( next, x, y ));
686 }
687
688 /***********************************************************************
689 * emfpathdrv_Pie
690 */
emfpathdrv_Pie(PHYSDEV dev,INT left,INT top,INT right,INT bottom,INT xstart,INT ystart,INT xend,INT yend)691 static BOOL emfpathdrv_Pie( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
692 INT xstart, INT ystart, INT xend, INT yend )
693 {
694 PHYSDEV emfdev = get_emfdev( dev );
695 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPie );
696
697 return (emfdev->funcs->pPie( emfdev, left, top, right, bottom, xstart, ystart, xend, yend ) &&
698 next->funcs->pPie( next, left, top, right, bottom, xstart, ystart, xend, yend ));
699 }
700
701 /***********************************************************************
702 * emfpathdrv_PolyBezier
703 */
emfpathdrv_PolyBezier(PHYSDEV dev,const POINT * pts,DWORD count)704 static BOOL emfpathdrv_PolyBezier( PHYSDEV dev, const POINT *pts, DWORD count )
705 {
706 PHYSDEV emfdev = get_emfdev( dev );
707 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolyBezier );
708
709 return (emfdev->funcs->pPolyBezier( emfdev, pts, count ) &&
710 next->funcs->pPolyBezier( next, pts, count ));
711 }
712
713 /***********************************************************************
714 * emfpathdrv_PolyBezierTo
715 */
emfpathdrv_PolyBezierTo(PHYSDEV dev,const POINT * pts,DWORD count)716 static BOOL emfpathdrv_PolyBezierTo( PHYSDEV dev, const POINT *pts, DWORD count )
717 {
718 PHYSDEV emfdev = get_emfdev( dev );
719 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolyBezierTo );
720
721 return (emfdev->funcs->pPolyBezierTo( emfdev, pts, count ) &&
722 next->funcs->pPolyBezierTo( next, pts, count ));
723 }
724
725 /***********************************************************************
726 * emfpathdrv_PolyDraw
727 */
emfpathdrv_PolyDraw(PHYSDEV dev,const POINT * pts,const BYTE * types,DWORD count)728 static BOOL emfpathdrv_PolyDraw( PHYSDEV dev, const POINT *pts, const BYTE *types, DWORD count )
729 {
730 PHYSDEV emfdev = get_emfdev( dev );
731 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolyDraw );
732
733 return (emfdev->funcs->pPolyDraw( emfdev, pts, types, count ) &&
734 next->funcs->pPolyDraw( next, pts, types, count ));
735 }
736
737 /***********************************************************************
738 * emfpathdrv_PolyPolygon
739 */
emfpathdrv_PolyPolygon(PHYSDEV dev,const POINT * pts,const INT * counts,UINT polygons)740 static BOOL emfpathdrv_PolyPolygon( PHYSDEV dev, const POINT *pts, const INT *counts, UINT polygons )
741 {
742 PHYSDEV emfdev = get_emfdev( dev );
743 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolyPolygon );
744
745 return (emfdev->funcs->pPolyPolygon( emfdev, pts, counts, polygons ) &&
746 next->funcs->pPolyPolygon( next, pts, counts, polygons ));
747 }
748
749 /***********************************************************************
750 * emfpathdrv_PolyPolyline
751 */
emfpathdrv_PolyPolyline(PHYSDEV dev,const POINT * pts,const DWORD * counts,DWORD polylines)752 static BOOL emfpathdrv_PolyPolyline( PHYSDEV dev, const POINT *pts, const DWORD *counts, DWORD polylines )
753 {
754 PHYSDEV emfdev = get_emfdev( dev );
755 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolyPolyline );
756
757 return (emfdev->funcs->pPolyPolyline( emfdev, pts, counts, polylines ) &&
758 next->funcs->pPolyPolyline( next, pts, counts, polylines ));
759 }
760
761 /***********************************************************************
762 * emfpathdrv_Polygon
763 */
emfpathdrv_Polygon(PHYSDEV dev,const POINT * pts,INT count)764 static BOOL emfpathdrv_Polygon( PHYSDEV dev, const POINT *pts, INT count )
765 {
766 PHYSDEV emfdev = get_emfdev( dev );
767 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolygon );
768
769 return (emfdev->funcs->pPolygon( emfdev, pts, count ) &&
770 next->funcs->pPolygon( next, pts, count ));
771 }
772
773 /***********************************************************************
774 * emfpathdrv_Polyline
775 */
emfpathdrv_Polyline(PHYSDEV dev,const POINT * pts,INT count)776 static BOOL emfpathdrv_Polyline( PHYSDEV dev, const POINT *pts, INT count )
777 {
778 PHYSDEV emfdev = get_emfdev( dev );
779 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolyline );
780
781 return (emfdev->funcs->pPolyline( emfdev, pts, count ) &&
782 next->funcs->pPolyline( next, pts, count ));
783 }
784
785 /***********************************************************************
786 * emfpathdrv_PolylineTo
787 */
emfpathdrv_PolylineTo(PHYSDEV dev,const POINT * pts,INT count)788 static BOOL emfpathdrv_PolylineTo( PHYSDEV dev, const POINT *pts, INT count )
789 {
790 PHYSDEV emfdev = get_emfdev( dev );
791 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolylineTo );
792
793 return (emfdev->funcs->pPolylineTo( emfdev, pts, count ) &&
794 next->funcs->pPolylineTo( next, pts, count ));
795 }
796
797 /***********************************************************************
798 * emfpathdrv_Rectangle
799 */
emfpathdrv_Rectangle(PHYSDEV dev,INT x1,INT y1,INT x2,INT y2)800 static BOOL emfpathdrv_Rectangle( PHYSDEV dev, INT x1, INT y1, INT x2, INT y2 )
801 {
802 PHYSDEV emfdev = get_emfdev( dev );
803 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pRectangle );
804
805 return (emfdev->funcs->pRectangle( emfdev, x1, y1, x2, y2 ) &&
806 next->funcs->pRectangle( next, x1, y1, x2, y2 ));
807 }
808
809 /***********************************************************************
810 * emfpathdrv_RoundRect
811 */
emfpathdrv_RoundRect(PHYSDEV dev,INT x1,INT y1,INT x2,INT y2,INT ell_width,INT ell_height)812 static BOOL emfpathdrv_RoundRect( PHYSDEV dev, INT x1, INT y1, INT x2, INT y2,
813 INT ell_width, INT ell_height )
814 {
815 PHYSDEV emfdev = get_emfdev( dev );
816 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pRoundRect );
817
818 return (emfdev->funcs->pRoundRect( emfdev, x1, y1, x2, y2, ell_width, ell_height ) &&
819 next->funcs->pRoundRect( next, x1, y1, x2, y2, ell_width, ell_height ));
820 }
821
822 static const struct gdi_dc_funcs emfpath_driver =
823 {
824 NULL, /* pAbortDoc */
825 emfpathdrv_AbortPath, /* pAbortPath */
826 NULL, /* pAlphaBlend */
827 emfpathdrv_AngleArc, /* pAngleArc */
828 emfpathdrv_Arc, /* pArc */
829 emfpathdrv_ArcTo, /* pArcTo */
830 emfpathdrv_BeginPath, /* pBeginPath */
831 NULL, /* pBlendImage */
832 emfpathdrv_Chord, /* pChord */
833 emfpathdrv_CloseFigure, /* pCloseFigure */
834 NULL, /* pCreateCompatibleDC */
835 emfpathdrv_CreateDC, /* pCreateDC */
836 emfpathdrv_DeleteDC, /* pDeleteDC */
837 NULL, /* pDeleteObject */
838 NULL, /* pDeviceCapabilities */
839 emfpathdrv_Ellipse, /* pEllipse */
840 NULL, /* pEndDoc */
841 NULL, /* pEndPage */
842 emfpathdrv_EndPath, /* pEndPath */
843 NULL, /* pEnumFonts */
844 NULL, /* pEnumICMProfiles */
845 NULL, /* pExcludeClipRect */
846 NULL, /* pExtDeviceMode */
847 NULL, /* pExtEscape */
848 NULL, /* pExtFloodFill */
849 NULL, /* pExtSelectClipRgn */
850 emfpathdrv_ExtTextOut, /* pExtTextOut */
851 NULL, /* pFillPath */
852 NULL, /* pFillRgn */
853 NULL, /* pFlattenPath */
854 NULL, /* pFontIsLinked */
855 NULL, /* pFrameRgn */
856 NULL, /* pGdiComment */
857 NULL, /* pGetBoundsRect */
858 NULL, /* pGetCharABCWidths */
859 NULL, /* pGetCharABCWidthsI */
860 NULL, /* pGetCharWidth */
861 NULL, /* pGetCharWidthInfo */
862 #ifdef __REACTOS__
863 EMFDRV_GetDeviceCaps, //// Work around HACK.
864 #else
865 NULL, /* pGetDeviceCaps */
866 #endif
867 NULL, /* pGetDeviceGammaRamp */
868 NULL, /* pGetFontData */
869 NULL, /* pGetFontRealizationInfo */
870 NULL, /* pGetFontUnicodeRanges */
871 NULL, /* pGetGlyphIndices */
872 NULL, /* pGetGlyphOutline */
873 NULL, /* pGetICMProfile */
874 NULL, /* pGetImage */
875 NULL, /* pGetKerningPairs */
876 NULL, /* pGetNearestColor */
877 NULL, /* pGetOutlineTextMetrics */
878 NULL, /* pGetPixel */
879 NULL, /* pGetSystemPaletteEntries */
880 NULL, /* pGetTextCharsetInfo */
881 NULL, /* pGetTextExtentExPoint */
882 NULL, /* pGetTextExtentExPointI */
883 NULL, /* pGetTextFace */
884 NULL, /* pGetTextMetrics */
885 NULL, /* pGradientFill */
886 NULL, /* pIntersectClipRect */
887 NULL, /* pInvertRgn */
888 emfpathdrv_LineTo, /* pLineTo */
889 NULL, /* pModifyWorldTransform */
890 emfpathdrv_MoveTo, /* pMoveTo */
891 NULL, /* pOffsetClipRgn */
892 NULL, /* pOffsetViewportOrg */
893 NULL, /* pOffsetWindowOrg */
894 NULL, /* pPaintRgn */
895 NULL, /* pPatBlt */
896 emfpathdrv_Pie, /* pPie */
897 emfpathdrv_PolyBezier, /* pPolyBezier */
898 emfpathdrv_PolyBezierTo, /* pPolyBezierTo */
899 emfpathdrv_PolyDraw, /* pPolyDraw */
900 emfpathdrv_PolyPolygon, /* pPolyPolygon */
901 emfpathdrv_PolyPolyline, /* pPolyPolyline */
902 emfpathdrv_Polygon, /* pPolygon */
903 emfpathdrv_Polyline, /* pPolyline */
904 emfpathdrv_PolylineTo, /* pPolylineTo */
905 NULL, /* pPutImage */
906 NULL, /* pRealizeDefaultPalette */
907 NULL, /* pRealizePalette */
908 emfpathdrv_Rectangle, /* pRectangle */
909 NULL, /* pResetDC */
910 NULL, /* pRestoreDC */
911 emfpathdrv_RoundRect, /* pRoundRect */
912 NULL, /* pSaveDC */
913 NULL, /* pScaleViewportExt */
914 NULL, /* pScaleWindowExt */
915 NULL, /* pSelectBitmap */
916 NULL, /* pSelectBrush */
917 NULL, /* pSelectClipPath */
918 NULL, /* pSelectFont */
919 NULL, /* pSelectPalette */
920 NULL, /* pSelectPen */
921 NULL, /* pSetArcDirection */
922 NULL, /* pSetBkColor */
923 NULL, /* pSetBkMode */
924 NULL, /* pSetDCBrushColor */
925 NULL, /* pSetDCPenColor */
926 NULL, /* pSetDIBColorTable */
927 NULL, /* pSetDIBitsToDevice */
928 NULL, /* pSetDeviceClipping */
929 NULL, /* pSetDeviceGammaRamp */
930 NULL, /* pSetLayout */
931 NULL, /* pSetMapMode */
932 NULL, /* pSetMapperFlags */
933 NULL, /* pSetPixel */
934 NULL, /* pSetPolyFillMode */
935 NULL, /* pSetROP2 */
936 NULL, /* pSetRelAbs */
937 NULL, /* pSetStretchBltMode */
938 NULL, /* pSetTextAlign */
939 NULL, /* pSetTextCharacterExtra */
940 NULL, /* pSetTextColor */
941 NULL, /* pSetTextJustification */
942 NULL, /* pSetViewportExt */
943 NULL, /* pSetViewportOrg */
944 NULL, /* pSetWindowExt */
945 NULL, /* pSetWindowOrg */
946 NULL, /* pSetWorldTransform */
947 NULL, /* pStartDoc */
948 NULL, /* pStartPage */
949 NULL, /* pStretchBlt */
950 NULL, /* pStretchDIBits */
951 NULL, /* pStrokeAndFillPath */
952 NULL, /* pStrokePath */
953 NULL, /* pUnrealizePalette */
954 NULL, /* pWidenPath */
955 NULL, /* wine_get_wgl_driver */
956 GDI_PRIORITY_PATH_DRV + 1 /* priority */
957 };
958