2 * Enhanced MetaFile driver dc value functions
4 * Copyright 1999 Huw D M Davies
5 * Copyright 2016 Alexandre Julliard
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.
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.
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
23 #include "enhmfdrv/enhmetafiledrv.h"
25 /* get the emf physdev from the path physdev */
26 static inline PHYSDEV
get_emfdev( PHYSDEV path
)
28 return &CONTAINING_RECORD( path
, EMFDRV_PDEVICE
, pathdev
)->dev
;
31 static const struct gdi_dc_funcs emfpath_driver
;
33 INT CDECL
EMFDRV_SaveDC( PHYSDEV dev
)
35 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pSaveDC
);
36 INT ret
= next
->funcs
->pSaveDC( next
);
41 emr
.emr
.iType
= EMR_SAVEDC
;
42 emr
.emr
.nSize
= sizeof(emr
);
43 EMFDRV_WriteRecord( dev
, &emr
.emr
);
48 BOOL CDECL
EMFDRV_RestoreDC( PHYSDEV dev
, INT level
)
50 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pRestoreDC
);
51 EMFDRV_PDEVICE
* physDev
= get_emf_physdev( dev
);
52 DC
*dc
= get_physdev_dc( dev
);
56 emr
.emr
.iType
= EMR_RESTOREDC
;
57 emr
.emr
.nSize
= sizeof(emr
);
60 emr
.iRelative
= level
;
62 emr
.iRelative
= level
- dc
->saveLevel
- 1;
65 ret
= next
->funcs
->pRestoreDC( next
, level
);
68 if (ret
) EMFDRV_WriteRecord( dev
, &emr
.emr
);
72 UINT CDECL
EMFDRV_SetTextAlign( PHYSDEV dev
, UINT align
)
75 emr
.emr
.iType
= EMR_SETTEXTALIGN
;
76 emr
.emr
.nSize
= sizeof(emr
);
78 return EMFDRV_WriteRecord( dev
, &emr
.emr
) ? align
: GDI_ERROR
;
81 BOOL CDECL
EMFDRV_SetTextJustification(PHYSDEV dev
, INT nBreakExtra
, INT nBreakCount
)
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
);
91 INT CDECL
EMFDRV_SetBkMode( PHYSDEV dev
, INT mode
)
94 emr
.emr
.iType
= EMR_SETBKMODE
;
95 emr
.emr
.nSize
= sizeof(emr
);
97 return EMFDRV_WriteRecord( dev
, &emr
.emr
) ? mode
: 0;
100 COLORREF CDECL
EMFDRV_SetBkColor( PHYSDEV dev
, COLORREF color
)
103 EMFDRV_PDEVICE
*physDev
= get_emf_physdev( dev
);
105 if (physDev
->restoring
) return color
; /* don't output records during RestoreDC */
107 emr
.emr
.iType
= EMR_SETBKCOLOR
;
108 emr
.emr
.nSize
= sizeof(emr
);
110 return EMFDRV_WriteRecord( dev
, &emr
.emr
) ? color
: CLR_INVALID
;
114 COLORREF CDECL
EMFDRV_SetTextColor( PHYSDEV dev
, COLORREF color
)
117 EMFDRV_PDEVICE
*physDev
= get_emf_physdev( dev
);
119 if (physDev
->restoring
) return color
; /* don't output records during RestoreDC */
121 emr
.emr
.iType
= EMR_SETTEXTCOLOR
;
122 emr
.emr
.nSize
= sizeof(emr
);
124 return EMFDRV_WriteRecord( dev
, &emr
.emr
) ? color
: CLR_INVALID
;
127 INT CDECL
EMFDRV_SetROP2( PHYSDEV dev
, INT rop
)
130 emr
.emr
.iType
= EMR_SETROP2
;
131 emr
.emr
.nSize
= sizeof(emr
);
133 return EMFDRV_WriteRecord( dev
, &emr
.emr
) ? rop
: 0;
136 INT CDECL
EMFDRV_SetPolyFillMode( PHYSDEV dev
, INT mode
)
138 EMRSETPOLYFILLMODE emr
;
139 emr
.emr
.iType
= EMR_SETPOLYFILLMODE
;
140 emr
.emr
.nSize
= sizeof(emr
);
142 return EMFDRV_WriteRecord( dev
, &emr
.emr
) ? mode
: 0;
145 INT CDECL
EMFDRV_SetStretchBltMode( PHYSDEV dev
, INT mode
)
147 EMRSETSTRETCHBLTMODE emr
;
148 emr
.emr
.iType
= EMR_SETSTRETCHBLTMODE
;
149 emr
.emr
.nSize
= sizeof(emr
);
151 return EMFDRV_WriteRecord( dev
, &emr
.emr
) ? mode
: 0;
154 INT CDECL
EMFDRV_SetArcDirection(PHYSDEV dev
, INT arcDirection
)
156 EMRSETARCDIRECTION emr
;
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;
164 INT CDECL
EMFDRV_ExcludeClipRect( PHYSDEV dev
, INT left
, INT top
, INT right
, INT bottom
)
166 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pExcludeClipRect
);
167 EMREXCLUDECLIPRECT emr
;
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
);
179 INT CDECL
EMFDRV_IntersectClipRect( PHYSDEV dev
, INT left
, INT top
, INT right
, INT bottom
)
181 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pIntersectClipRect
);
182 EMRINTERSECTCLIPRECT emr
;
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
);
194 INT CDECL
EMFDRV_OffsetClipRgn( PHYSDEV dev
, INT x
, INT y
)
196 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pOffsetClipRgn
);
197 EMROFFSETCLIPRGN emr
;
199 emr
.emr
.iType
= EMR_OFFSETCLIPRGN
;
200 emr
.emr
.nSize
= sizeof(emr
);
203 if (!EMFDRV_WriteRecord( dev
, &emr
.emr
)) return ERROR
;
204 return next
->funcs
->pOffsetClipRgn( next
, x
, y
);
207 INT CDECL
EMFDRV_ExtSelectClipRgn( PHYSDEV dev
, HRGN hrgn
, INT mode
)
209 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pExtSelectClipRgn
);
210 EMREXTSELECTCLIPRGN
*emr
;
216 if (mode
!= RGN_COPY
) return ERROR
;
219 else rgnsize
= GetRegionData( hrgn
, 0, NULL
);
221 size
= rgnsize
+ offsetof(EMREXTSELECTCLIPRGN
,RgnData
);
222 emr
= HeapAlloc( GetProcessHeap(), 0, size
);
223 if (rgnsize
) GetRegionData( hrgn
, rgnsize
, (RGNDATA
*)&emr
->RgnData
);
225 emr
->emr
.iType
= EMR_EXTSELECTCLIPRGN
;
226 emr
->emr
.nSize
= size
;
227 emr
->cbRgnData
= rgnsize
;
230 ret
= EMFDRV_WriteRecord( dev
, &emr
->emr
);
231 HeapFree( GetProcessHeap(), 0, emr
);
232 return ret
? next
->funcs
->pExtSelectClipRgn( next
, hrgn
, mode
) : ERROR
;
235 INT CDECL
EMFDRV_SetMapMode( PHYSDEV dev
, INT mode
)
237 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pSetMapMode
);
239 emr
.emr
.iType
= EMR_SETMAPMODE
;
240 emr
.emr
.nSize
= sizeof(emr
);
243 if (!EMFDRV_WriteRecord( dev
, &emr
.emr
)) return 0;
244 return next
->funcs
->pSetMapMode( next
, mode
);
247 BOOL CDECL
EMFDRV_SetViewportExtEx( PHYSDEV dev
, INT cx
, INT cy
, SIZE
*size
)
249 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pSetViewportExtEx
);
250 EMRSETVIEWPORTEXTEX emr
;
252 emr
.emr
.iType
= EMR_SETVIEWPORTEXTEX
;
253 emr
.emr
.nSize
= sizeof(emr
);
254 emr
.szlExtent
.cx
= cx
;
255 emr
.szlExtent
.cy
= cy
;
257 if (!EMFDRV_WriteRecord( dev
, &emr
.emr
)) return FALSE
;
258 return next
->funcs
->pSetViewportExtEx( next
, cx
, cy
, size
);
261 BOOL CDECL
EMFDRV_SetWindowExtEx( PHYSDEV dev
, INT cx
, INT cy
, SIZE
*size
)
263 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pSetWindowExtEx
);
264 EMRSETWINDOWEXTEX emr
;
266 emr
.emr
.iType
= EMR_SETWINDOWEXTEX
;
267 emr
.emr
.nSize
= sizeof(emr
);
268 emr
.szlExtent
.cx
= cx
;
269 emr
.szlExtent
.cy
= cy
;
271 if (!EMFDRV_WriteRecord( dev
, &emr
.emr
)) return FALSE
;
272 return next
->funcs
->pSetWindowExtEx( next
, cx
, cy
, size
);
275 BOOL CDECL
EMFDRV_SetViewportOrgEx( PHYSDEV dev
, INT x
, INT y
, POINT
*pt
)
277 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pSetViewportOrgEx
);
278 EMRSETVIEWPORTORGEX emr
;
280 emr
.emr
.iType
= EMR_SETVIEWPORTORGEX
;
281 emr
.emr
.nSize
= sizeof(emr
);
285 if (!EMFDRV_WriteRecord( dev
, &emr
.emr
)) return FALSE
;
286 return next
->funcs
->pSetViewportOrgEx( next
, x
, y
, pt
);
289 BOOL CDECL
EMFDRV_SetWindowOrgEx( PHYSDEV dev
, INT x
, INT y
, POINT
*pt
)
291 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pSetWindowOrgEx
);
292 EMRSETWINDOWORGEX emr
;
294 emr
.emr
.iType
= EMR_SETWINDOWORGEX
;
295 emr
.emr
.nSize
= sizeof(emr
);
299 if (!EMFDRV_WriteRecord( dev
, &emr
.emr
)) return FALSE
;
300 return next
->funcs
->pSetWindowOrgEx( next
, x
, y
, pt
);
303 BOOL CDECL
EMFDRV_ScaleViewportExtEx( PHYSDEV dev
, INT xNum
, INT xDenom
, INT yNum
, INT yDenom
, SIZE
*size
)
305 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pScaleViewportExtEx
);
306 EMRSCALEVIEWPORTEXTEX emr
;
308 emr
.emr
.iType
= EMR_SCALEVIEWPORTEXTEX
;
309 emr
.emr
.nSize
= sizeof(emr
);
315 if (!EMFDRV_WriteRecord( dev
, &emr
.emr
)) return FALSE
;
316 return next
->funcs
->pScaleViewportExtEx( next
, xNum
, xDenom
, yNum
, yDenom
, size
);
319 BOOL CDECL
EMFDRV_ScaleWindowExtEx( PHYSDEV dev
, INT xNum
, INT xDenom
, INT yNum
, INT yDenom
, SIZE
*size
)
321 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pScaleWindowExtEx
);
322 EMRSCALEWINDOWEXTEX emr
;
324 emr
.emr
.iType
= EMR_SCALEWINDOWEXTEX
;
325 emr
.emr
.nSize
= sizeof(emr
);
331 if (!EMFDRV_WriteRecord( dev
, &emr
.emr
)) return FALSE
;
332 return next
->funcs
->pScaleWindowExtEx( next
, xNum
, xDenom
, yNum
, yDenom
, size
);
335 DWORD CDECL
EMFDRV_SetLayout( PHYSDEV dev
, DWORD layout
)
339 emr
.emr
.iType
= EMR_SETLAYOUT
;
340 emr
.emr
.nSize
= sizeof(emr
);
342 return EMFDRV_WriteRecord( dev
, &emr
.emr
) ? layout
: GDI_ERROR
;
345 BOOL CDECL
EMFDRV_SetWorldTransform( PHYSDEV dev
, const XFORM
*xform
)
347 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pSetWorldTransform
);
348 EMRSETWORLDTRANSFORM emr
;
350 emr
.emr
.iType
= EMR_SETWORLDTRANSFORM
;
351 emr
.emr
.nSize
= sizeof(emr
);
354 if (!EMFDRV_WriteRecord( dev
, &emr
.emr
)) return FALSE
;
355 return next
->funcs
->pSetWorldTransform( next
, xform
);
358 BOOL CDECL
EMFDRV_ModifyWorldTransform( PHYSDEV dev
, const XFORM
*xform
, DWORD mode
)
360 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pModifyWorldTransform
);
361 EMRMODIFYWORLDTRANSFORM emr
;
363 emr
.emr
.iType
= EMR_MODIFYWORLDTRANSFORM
;
364 emr
.emr
.nSize
= sizeof(emr
);
365 if (mode
== MWT_IDENTITY
)
367 emr
.xform
.eM11
= 1.0f
;
368 emr
.xform
.eM12
= 0.0f
;
369 emr
.xform
.eM21
= 0.0f
;
370 emr
.xform
.eM22
= 1.0f
;
371 emr
.xform
.eDx
= 0.0f
;
372 emr
.xform
.eDy
= 0.0f
;
380 if (!EMFDRV_WriteRecord( dev
, &emr
.emr
)) return FALSE
;
381 return next
->funcs
->pModifyWorldTransform( next
, xform
, mode
);
384 BOOL CDECL
EMFDRV_OffsetViewportOrgEx( PHYSDEV dev
, INT x
, INT y
, POINT
*pt
)
386 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pOffsetViewportOrgEx
);
387 EMRSETVIEWPORTORGEX emr
;
390 GetViewportOrgEx( dev
->hdc
, &prev
);
392 emr
.emr
.iType
= EMR_SETVIEWPORTORGEX
;
393 emr
.emr
.nSize
= sizeof(emr
);
394 emr
.ptlOrigin
.x
= prev
.x
+ x
;
395 emr
.ptlOrigin
.y
= prev
.y
+ y
;
397 if (!EMFDRV_WriteRecord( dev
, &emr
.emr
)) return FALSE
;
398 return next
->funcs
->pOffsetViewportOrgEx( next
, x
, y
, pt
);
401 BOOL CDECL
EMFDRV_OffsetWindowOrgEx( PHYSDEV dev
, INT x
, INT y
, POINT
*pt
)
403 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pOffsetWindowOrgEx
);
404 EMRSETWINDOWORGEX emr
;
407 GetWindowOrgEx( dev
->hdc
, &prev
);
409 emr
.emr
.iType
= EMR_SETWINDOWORGEX
;
410 emr
.emr
.nSize
= sizeof(emr
);
411 emr
.ptlOrigin
.x
= prev
.x
+ x
;
412 emr
.ptlOrigin
.y
= prev
.y
+ y
;
414 if (!EMFDRV_WriteRecord( dev
, &emr
.emr
)) return FALSE
;
415 return next
->funcs
->pOffsetWindowOrgEx( next
, x
, y
, pt
);
418 DWORD CDECL
EMFDRV_SetMapperFlags( PHYSDEV dev
, DWORD flags
)
420 EMRSETMAPPERFLAGS emr
;
422 emr
.emr
.iType
= EMR_SETMAPPERFLAGS
;
423 emr
.emr
.nSize
= sizeof(emr
);
426 return EMFDRV_WriteRecord( dev
, &emr
.emr
) ? flags
: GDI_ERROR
;
429 BOOL CDECL
EMFDRV_AbortPath( PHYSDEV dev
)
433 emr
.emr
.iType
= EMR_ABORTPATH
;
434 emr
.emr
.nSize
= sizeof(emr
);
436 return EMFDRV_WriteRecord( dev
, &emr
.emr
);
439 BOOL CDECL
EMFDRV_BeginPath( PHYSDEV dev
)
441 EMFDRV_PDEVICE
*physDev
= get_emf_physdev( dev
);
442 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pBeginPath
);
444 DC
*dc
= get_physdev_dc( dev
);
446 emr
.emr
.iType
= EMR_BEGINPATH
;
447 emr
.emr
.nSize
= sizeof(emr
);
449 if (!EMFDRV_WriteRecord( dev
, &emr
.emr
)) return FALSE
;
450 if (physDev
->path
) return TRUE
; /* already open */
452 if (!next
->funcs
->pBeginPath( next
)) return FALSE
;
453 push_dc_driver( &dc
->physDev
, &physDev
->pathdev
, &emfpath_driver
);
454 physDev
->path
= TRUE
;
458 BOOL CDECL
EMFDRV_CloseFigure( PHYSDEV dev
)
462 emr
.emr
.iType
= EMR_CLOSEFIGURE
;
463 emr
.emr
.nSize
= sizeof(emr
);
465 EMFDRV_WriteRecord( dev
, &emr
.emr
);
466 return FALSE
; /* always fails without a path */
469 BOOL CDECL
EMFDRV_EndPath( PHYSDEV dev
)
473 emr
.emr
.iType
= EMR_ENDPATH
;
474 emr
.emr
.nSize
= sizeof(emr
);
476 EMFDRV_WriteRecord( dev
, &emr
.emr
);
477 return FALSE
; /* always fails without a path */
480 BOOL CDECL
EMFDRV_FlattenPath( PHYSDEV dev
)
484 emr
.emr
.iType
= EMR_FLATTENPATH
;
485 emr
.emr
.nSize
= sizeof(emr
);
487 return EMFDRV_WriteRecord( dev
, &emr
.emr
);
490 BOOL CDECL
EMFDRV_SelectClipPath( PHYSDEV dev
, INT iMode
)
492 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pSelectClipPath
);
493 EMRSELECTCLIPPATH emr
;
497 emr
.emr
.iType
= EMR_SELECTCLIPPATH
;
498 emr
.emr
.nSize
= sizeof(emr
);
501 if (!EMFDRV_WriteRecord( dev
, &emr
.emr
)) return FALSE
;
502 hrgn
= PathToRegion( dev
->hdc
);
505 ret
= next
->funcs
->pExtSelectClipRgn( next
, hrgn
, iMode
);
506 DeleteObject( hrgn
);
511 BOOL CDECL
EMFDRV_WidenPath( PHYSDEV dev
)
515 emr
.emr
.iType
= EMR_WIDENPATH
;
516 emr
.emr
.nSize
= sizeof(emr
);
518 return EMFDRV_WriteRecord( dev
, &emr
.emr
);
521 INT CDECL
EMFDRV_GetDeviceCaps(PHYSDEV dev
, INT cap
)
523 EMFDRV_PDEVICE
*physDev
= get_emf_physdev( dev
);
525 if (cap
>= 0 && cap
< ARRAY_SIZE( physDev
->dev_caps
))
526 return physDev
->dev_caps
[cap
];
531 /***********************************************************************
532 * emfpathdrv_AbortPath
534 static BOOL CDECL
emfpathdrv_AbortPath( PHYSDEV dev
)
536 PHYSDEV emfdev
= get_emfdev( dev
);
537 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pAbortPath
);
538 DC
*dc
= get_physdev_dc( dev
);
540 emfpath_driver
.pDeleteDC( pop_dc_driver( dc
, &emfpath_driver
));
541 emfdev
->funcs
->pAbortPath( emfdev
);
542 return next
->funcs
->pAbortPath( next
);
545 /***********************************************************************
546 * emfpathdrv_AngleArc
548 static BOOL CDECL
emfpathdrv_AngleArc( PHYSDEV dev
, INT x
, INT y
, DWORD radius
, FLOAT start
, FLOAT sweep
)
550 PHYSDEV emfdev
= get_emfdev( dev
);
551 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pAngleArc
);
553 return (emfdev
->funcs
->pAngleArc( emfdev
, x
, y
, radius
, start
, sweep
) &&
554 next
->funcs
->pAngleArc( next
, x
, y
, radius
, start
, sweep
));
557 /***********************************************************************
560 static BOOL CDECL
emfpathdrv_Arc( PHYSDEV dev
, INT left
, INT top
, INT right
, INT bottom
,
561 INT xstart
, INT ystart
, INT xend
, INT yend
)
563 PHYSDEV emfdev
= get_emfdev( dev
);
564 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pArc
);
566 return (emfdev
->funcs
->pArc( emfdev
, left
, top
, right
, bottom
, xstart
, ystart
, xend
, yend
) &&
567 next
->funcs
->pArc( next
, left
, top
, right
, bottom
, xstart
, ystart
, xend
, yend
));
570 /***********************************************************************
573 static BOOL CDECL
emfpathdrv_ArcTo( PHYSDEV dev
, INT left
, INT top
, INT right
, INT bottom
,
574 INT xstart
, INT ystart
, INT xend
, INT yend
)
576 PHYSDEV emfdev
= get_emfdev( dev
);
577 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pArcTo
);
579 return (emfdev
->funcs
->pArcTo( emfdev
, left
, top
, right
, bottom
, xstart
, ystart
, xend
, yend
) &&
580 next
->funcs
->pArcTo( next
, left
, top
, right
, bottom
, xstart
, ystart
, xend
, yend
));
583 /***********************************************************************
584 * emfpathdrv_BeginPath
586 static BOOL CDECL
emfpathdrv_BeginPath( PHYSDEV dev
)
588 PHYSDEV emfdev
= get_emfdev( dev
);
589 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pBeginPath
);
591 return (emfdev
->funcs
->pBeginPath( emfdev
) && next
->funcs
->pBeginPath( next
));
594 /***********************************************************************
597 static BOOL CDECL
emfpathdrv_Chord( PHYSDEV dev
, INT left
, INT top
, INT right
, INT bottom
,
598 INT xstart
, INT ystart
, INT xend
, INT yend
)
600 PHYSDEV emfdev
= get_emfdev( dev
);
601 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pChord
);
603 return (emfdev
->funcs
->pChord( emfdev
, left
, top
, right
, bottom
, xstart
, ystart
, xend
, yend
) &&
604 next
->funcs
->pChord( next
, left
, top
, right
, bottom
, xstart
, ystart
, xend
, yend
));
607 /***********************************************************************
608 * emfpathdrv_CloseFigure
610 static BOOL CDECL
emfpathdrv_CloseFigure( PHYSDEV dev
)
612 PHYSDEV emfdev
= get_emfdev( dev
);
613 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pCloseFigure
);
615 emfdev
->funcs
->pCloseFigure( emfdev
);
616 return next
->funcs
->pCloseFigure( next
);
619 /***********************************************************************
620 * emfpathdrv_CreateDC
622 static BOOL CDECL
emfpathdrv_CreateDC( PHYSDEV
*dev
, LPCWSTR driver
, LPCWSTR device
,
623 LPCWSTR output
, const DEVMODEW
*devmode
)
625 assert( 0 ); /* should never be called */
629 /*************************************************************
630 * emfpathdrv_DeleteDC
632 static BOOL CDECL
emfpathdrv_DeleteDC( PHYSDEV dev
)
634 EMFDRV_PDEVICE
*physdev
= (EMFDRV_PDEVICE
*)get_emfdev( dev
);
636 physdev
->path
= FALSE
;
640 /***********************************************************************
643 static BOOL CDECL
emfpathdrv_Ellipse( PHYSDEV dev
, INT x1
, INT y1
, INT x2
, INT y2
)
645 PHYSDEV emfdev
= get_emfdev( dev
);
646 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pEllipse
);
648 return (emfdev
->funcs
->pEllipse( emfdev
, x1
, y1
, x2
, y2
) &&
649 next
->funcs
->pEllipse( next
, x1
, y1
, x2
, y2
));
652 /***********************************************************************
655 static BOOL CDECL
emfpathdrv_EndPath( PHYSDEV dev
)
657 PHYSDEV emfdev
= get_emfdev( dev
);
658 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pEndPath
);
659 DC
*dc
= get_physdev_dc( dev
);
661 emfpath_driver
.pDeleteDC( pop_dc_driver( dc
, &emfpath_driver
));
662 emfdev
->funcs
->pEndPath( emfdev
);
663 return next
->funcs
->pEndPath( next
);
666 /***********************************************************************
667 * emfpathdrv_ExtTextOut
669 static BOOL CDECL
emfpathdrv_ExtTextOut( PHYSDEV dev
, INT x
, INT y
, UINT flags
, const RECT
*rect
,
670 LPCWSTR str
, UINT count
, const INT
*dx
)
672 PHYSDEV emfdev
= get_emfdev( dev
);
673 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pExtTextOut
);
675 return (emfdev
->funcs
->pExtTextOut( emfdev
, x
, y
, flags
, rect
, str
, count
, dx
) &&
676 next
->funcs
->pExtTextOut( next
, x
, y
, flags
, rect
, str
, count
, dx
));
679 /***********************************************************************
682 static BOOL CDECL
emfpathdrv_LineTo( PHYSDEV dev
, INT x
, INT y
)
684 PHYSDEV emfdev
= get_emfdev( dev
);
685 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pLineTo
);
687 return (emfdev
->funcs
->pLineTo( emfdev
, x
, y
) && next
->funcs
->pLineTo( next
, x
, y
));
690 /***********************************************************************
693 static BOOL CDECL
emfpathdrv_MoveTo( PHYSDEV dev
, INT x
, INT y
)
695 PHYSDEV emfdev
= get_emfdev( dev
);
696 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pMoveTo
);
698 return (emfdev
->funcs
->pMoveTo( emfdev
, x
, y
) && next
->funcs
->pMoveTo( next
, x
, y
));
701 /***********************************************************************
704 static BOOL CDECL
emfpathdrv_Pie( PHYSDEV dev
, INT left
, INT top
, INT right
, INT bottom
,
705 INT xstart
, INT ystart
, INT xend
, INT yend
)
707 PHYSDEV emfdev
= get_emfdev( dev
);
708 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pPie
);
710 return (emfdev
->funcs
->pPie( emfdev
, left
, top
, right
, bottom
, xstart
, ystart
, xend
, yend
) &&
711 next
->funcs
->pPie( next
, left
, top
, right
, bottom
, xstart
, ystart
, xend
, yend
));
714 /***********************************************************************
715 * emfpathdrv_PolyBezier
717 static BOOL CDECL
emfpathdrv_PolyBezier( PHYSDEV dev
, const POINT
*pts
, DWORD count
)
719 PHYSDEV emfdev
= get_emfdev( dev
);
720 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pPolyBezier
);
722 return (emfdev
->funcs
->pPolyBezier( emfdev
, pts
, count
) &&
723 next
->funcs
->pPolyBezier( next
, pts
, count
));
726 /***********************************************************************
727 * emfpathdrv_PolyBezierTo
729 static BOOL CDECL
emfpathdrv_PolyBezierTo( PHYSDEV dev
, const POINT
*pts
, DWORD count
)
731 PHYSDEV emfdev
= get_emfdev( dev
);
732 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pPolyBezierTo
);
734 return (emfdev
->funcs
->pPolyBezierTo( emfdev
, pts
, count
) &&
735 next
->funcs
->pPolyBezierTo( next
, pts
, count
));
738 /***********************************************************************
739 * emfpathdrv_PolyDraw
741 static BOOL CDECL
emfpathdrv_PolyDraw( PHYSDEV dev
, const POINT
*pts
, const BYTE
*types
, DWORD count
)
743 PHYSDEV emfdev
= get_emfdev( dev
);
744 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pPolyDraw
);
746 return (emfdev
->funcs
->pPolyDraw( emfdev
, pts
, types
, count
) &&
747 next
->funcs
->pPolyDraw( next
, pts
, types
, count
));
750 /***********************************************************************
751 * emfpathdrv_PolyPolygon
753 static BOOL CDECL
emfpathdrv_PolyPolygon( PHYSDEV dev
, const POINT
*pts
, const INT
*counts
, UINT polygons
)
755 PHYSDEV emfdev
= get_emfdev( dev
);
756 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pPolyPolygon
);
758 return (emfdev
->funcs
->pPolyPolygon( emfdev
, pts
, counts
, polygons
) &&
759 next
->funcs
->pPolyPolygon( next
, pts
, counts
, polygons
));
762 /***********************************************************************
763 * emfpathdrv_PolyPolyline
765 static BOOL CDECL
emfpathdrv_PolyPolyline( PHYSDEV dev
, const POINT
*pts
, const DWORD
*counts
, DWORD polylines
)
767 PHYSDEV emfdev
= get_emfdev( dev
);
768 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pPolyPolyline
);
770 return (emfdev
->funcs
->pPolyPolyline( emfdev
, pts
, counts
, polylines
) &&
771 next
->funcs
->pPolyPolyline( next
, pts
, counts
, polylines
));
774 /***********************************************************************
777 static BOOL CDECL
emfpathdrv_Polygon( PHYSDEV dev
, const POINT
*pts
, INT count
)
779 PHYSDEV emfdev
= get_emfdev( dev
);
780 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pPolygon
);
782 return (emfdev
->funcs
->pPolygon( emfdev
, pts
, count
) &&
783 next
->funcs
->pPolygon( next
, pts
, count
));
786 /***********************************************************************
787 * emfpathdrv_Polyline
789 static BOOL CDECL
emfpathdrv_Polyline( PHYSDEV dev
, const POINT
*pts
, INT count
)
791 PHYSDEV emfdev
= get_emfdev( dev
);
792 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pPolyline
);
794 return (emfdev
->funcs
->pPolyline( emfdev
, pts
, count
) &&
795 next
->funcs
->pPolyline( next
, pts
, count
));
798 /***********************************************************************
799 * emfpathdrv_PolylineTo
801 static BOOL CDECL
emfpathdrv_PolylineTo( PHYSDEV dev
, const POINT
*pts
, INT count
)
803 PHYSDEV emfdev
= get_emfdev( dev
);
804 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pPolylineTo
);
806 return (emfdev
->funcs
->pPolylineTo( emfdev
, pts
, count
) &&
807 next
->funcs
->pPolylineTo( next
, pts
, count
));
810 /***********************************************************************
811 * emfpathdrv_Rectangle
813 static BOOL CDECL
emfpathdrv_Rectangle( PHYSDEV dev
, INT x1
, INT y1
, INT x2
, INT y2
)
815 PHYSDEV emfdev
= get_emfdev( dev
);
816 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pRectangle
);
818 return (emfdev
->funcs
->pRectangle( emfdev
, x1
, y1
, x2
, y2
) &&
819 next
->funcs
->pRectangle( next
, x1
, y1
, x2
, y2
));
822 /***********************************************************************
823 * emfpathdrv_RoundRect
825 static BOOL CDECL
emfpathdrv_RoundRect( PHYSDEV dev
, INT x1
, INT y1
, INT x2
, INT y2
,
826 INT ell_width
, INT ell_height
)
828 PHYSDEV emfdev
= get_emfdev( dev
);
829 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pRoundRect
);
831 return (emfdev
->funcs
->pRoundRect( emfdev
, x1
, y1
, x2
, y2
, ell_width
, ell_height
) &&
832 next
->funcs
->pRoundRect( next
, x1
, y1
, x2
, y2
, ell_width
, ell_height
));
836 static const struct gdi_dc_funcs emfpath_driver
=
838 NULL
, /* pAbortDoc */
839 emfpathdrv_AbortPath
, /* pAbortPath */
840 NULL
, /* pAlphaBlend */
841 emfpathdrv_AngleArc
, /* pAngleArc */
842 emfpathdrv_Arc
, /* pArc */
843 emfpathdrv_ArcTo
, /* pArcTo */
844 emfpathdrv_BeginPath
, /* pBeginPath */
845 NULL
, /* pBlendImage */
846 emfpathdrv_Chord
, /* pChord */
847 emfpathdrv_CloseFigure
, /* pCloseFigure */
848 NULL
, /* pCreateCompatibleDC */
849 emfpathdrv_CreateDC
, /* pCreateDC */
850 emfpathdrv_DeleteDC
, /* pDeleteDC */
851 NULL
, /* pDeleteObject */
852 NULL
, /* pDeviceCapabilities */
853 emfpathdrv_Ellipse
, /* pEllipse */
856 emfpathdrv_EndPath
, /* pEndPath */
857 NULL
, /* pEnumFonts */
858 NULL
, /* pEnumICMProfiles */
859 NULL
, /* pExcludeClipRect */
860 NULL
, /* pExtDeviceMode */
861 NULL
, /* pExtEscape */
862 NULL
, /* pExtFloodFill */
863 NULL
, /* pExtSelectClipRgn */
864 emfpathdrv_ExtTextOut
, /* pExtTextOut */
865 NULL
, /* pFillPath */
867 NULL
, /* pFlattenPath */
868 NULL
, /* pFontIsLinked */
869 NULL
, /* pFrameRgn */
870 NULL
, /* pGdiComment */
871 NULL
, /* pGetBoundsRect */
872 NULL
, /* pGetCharABCWidths */
873 NULL
, /* pGetCharABCWidthsI */
874 NULL
, /* pGetCharWidth */
875 NULL
, /* pGetCharWidthInfo */
876 NULL
, /* pGetDeviceCaps */
877 NULL
, /* pGetDeviceGammaRamp */
878 NULL
, /* pGetFontData */
879 NULL
, /* pGetFontRealizationInfo */
880 NULL
, /* pGetFontUnicodeRanges */
881 NULL
, /* pGetGlyphIndices */
882 NULL
, /* pGetGlyphOutline */
883 NULL
, /* pGetICMProfile */
884 NULL
, /* pGetImage */
885 NULL
, /* pGetKerningPairs */
886 NULL
, /* pGetNearestColor */
887 NULL
, /* pGetOutlineTextMetrics */
888 NULL
, /* pGetPixel */
889 NULL
, /* pGetSystemPaletteEntries */
890 NULL
, /* pGetTextCharsetInfo */
891 NULL
, /* pGetTextExtentExPoint */
892 NULL
, /* pGetTextExtentExPointI */
893 NULL
, /* pGetTextFace */
894 NULL
, /* pGetTextMetrics */
895 NULL
, /* pGradientFill */
896 NULL
, /* pIntersectClipRect */
897 NULL
, /* pInvertRgn */
898 emfpathdrv_LineTo
, /* pLineTo */
899 NULL
, /* pModifyWorldTransform */
900 emfpathdrv_MoveTo
, /* pMoveTo */
901 NULL
, /* pOffsetClipRgn */
902 NULL
, /* pOffsetViewportOrg */
903 NULL
, /* pOffsetWindowOrg */
904 NULL
, /* pPaintRgn */
906 emfpathdrv_Pie
, /* pPie */
907 emfpathdrv_PolyBezier
, /* pPolyBezier */
908 emfpathdrv_PolyBezierTo
, /* pPolyBezierTo */
909 emfpathdrv_PolyDraw
, /* pPolyDraw */
910 emfpathdrv_PolyPolygon
, /* pPolyPolygon */
911 emfpathdrv_PolyPolyline
, /* pPolyPolyline */
912 emfpathdrv_Polygon
, /* pPolygon */
913 emfpathdrv_Polyline
, /* pPolyline */
914 emfpathdrv_PolylineTo
, /* pPolylineTo */
915 NULL
, /* pPutImage */
916 NULL
, /* pRealizeDefaultPalette */
917 NULL
, /* pRealizePalette */
918 emfpathdrv_Rectangle
, /* pRectangle */
920 NULL
, /* pRestoreDC */
921 emfpathdrv_RoundRect
, /* pRoundRect */
923 NULL
, /* pScaleViewportExt */
924 NULL
, /* pScaleWindowExt */
925 NULL
, /* pSelectBitmap */
926 NULL
, /* pSelectBrush */
927 NULL
, /* pSelectClipPath */
928 NULL
, /* pSelectFont */
929 NULL
, /* pSelectPalette */
930 NULL
, /* pSelectPen */
931 NULL
, /* pSetArcDirection */
932 NULL
, /* pSetBkColor */
933 NULL
, /* pSetBkMode */
934 NULL
, /* pSetBoundsRect */
935 NULL
, /* pSetDCBrushColor */
936 NULL
, /* pSetDCPenColor */
937 NULL
, /* pSetDIBitsToDevice */
938 NULL
, /* pSetDeviceClipping */
939 NULL
, /* pSetDeviceGammaRamp */
940 NULL
, /* pSetLayout */
941 NULL
, /* pSetMapMode */
942 NULL
, /* pSetMapperFlags */
943 NULL
, /* pSetPixel */
944 NULL
, /* pSetPolyFillMode */
946 NULL
, /* pSetRelAbs */
947 NULL
, /* pSetStretchBltMode */
948 NULL
, /* pSetTextAlign */
949 NULL
, /* pSetTextCharacterExtra */
950 NULL
, /* pSetTextColor */
951 NULL
, /* pSetTextJustification */
952 NULL
, /* pSetViewportExt */
953 NULL
, /* pSetViewportOrg */
954 NULL
, /* pSetWindowExt */
955 NULL
, /* pSetWindowOrg */
956 NULL
, /* pSetWorldTransform */
957 NULL
, /* pStartDoc */
958 NULL
, /* pStartPage */
959 NULL
, /* pStretchBlt */
960 NULL
, /* pStretchDIBits */
961 NULL
, /* pStrokeAndFillPath */
962 NULL
, /* pStrokePath */
963 NULL
, /* pUnrealizePalette */
964 NULL
, /* pWidenPath */
965 NULL
, /* pD3DKMTCheckVidPnExclusiveOwnership */
966 NULL
, /* pD3DKMTSetVidPnSourceOwner */
967 NULL
, /* wine_get_wgl_driver */
968 NULL
, /* wine_get_vulkan_driver */
969 GDI_PRIORITY_PATH_DRV
+ 1 /* priority */