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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
);
368 if (!EMFDRV_WriteRecord( dev
, &emr
.emr
)) return FALSE
;
369 return next
->funcs
->pModifyWorldTransform( next
, xform
, mode
);
372 BOOL
EMFDRV_OffsetViewportOrgEx( PHYSDEV dev
, INT x
, INT y
, POINT
*pt
)
374 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pOffsetViewportOrgEx
);
375 EMRSETVIEWPORTORGEX emr
;
378 GetViewportOrgEx( dev
->hdc
, &prev
);
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
;
385 if (!EMFDRV_WriteRecord( dev
, &emr
.emr
)) return FALSE
;
386 return next
->funcs
->pOffsetViewportOrgEx( next
, x
, y
, pt
);
389 BOOL
EMFDRV_OffsetWindowOrgEx( PHYSDEV dev
, INT x
, INT y
, POINT
*pt
)
391 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pOffsetWindowOrgEx
);
392 EMRSETWINDOWORGEX emr
;
395 GetWindowOrgEx( dev
->hdc
, &prev
);
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
;
402 if (!EMFDRV_WriteRecord( dev
, &emr
.emr
)) return FALSE
;
403 return next
->funcs
->pOffsetWindowOrgEx( next
, x
, y
, pt
);
406 DWORD
EMFDRV_SetMapperFlags( PHYSDEV dev
, DWORD flags
)
408 EMRSETMAPPERFLAGS emr
;
410 emr
.emr
.iType
= EMR_SETMAPPERFLAGS
;
411 emr
.emr
.nSize
= sizeof(emr
);
414 return EMFDRV_WriteRecord( dev
, &emr
.emr
) ? flags
: GDI_ERROR
;
417 BOOL
EMFDRV_AbortPath( PHYSDEV dev
)
421 emr
.emr
.iType
= EMR_ABORTPATH
;
422 emr
.emr
.nSize
= sizeof(emr
);
424 return EMFDRV_WriteRecord( dev
, &emr
.emr
);
427 BOOL
EMFDRV_BeginPath( PHYSDEV dev
)
429 EMFDRV_PDEVICE
*physDev
= get_emf_physdev( dev
);
430 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pBeginPath
);
432 DC
*dc
= get_physdev_dc( dev
);
434 emr
.emr
.iType
= EMR_BEGINPATH
;
435 emr
.emr
.nSize
= sizeof(emr
);
437 if (!EMFDRV_WriteRecord( dev
, &emr
.emr
)) return FALSE
;
438 if (physDev
->path
) return TRUE
; /* already open */
440 if (!next
->funcs
->pBeginPath( next
)) return FALSE
;
441 push_dc_driver( &dc
->physDev
, &physDev
->pathdev
, &emfpath_driver
);
442 physDev
->path
= TRUE
;
446 BOOL
EMFDRV_CloseFigure( PHYSDEV dev
)
450 emr
.emr
.iType
= EMR_CLOSEFIGURE
;
451 emr
.emr
.nSize
= sizeof(emr
);
453 EMFDRV_WriteRecord( dev
, &emr
.emr
);
454 return FALSE
; /* always fails without a path */
457 BOOL
EMFDRV_EndPath( PHYSDEV dev
)
461 emr
.emr
.iType
= EMR_ENDPATH
;
462 emr
.emr
.nSize
= sizeof(emr
);
464 EMFDRV_WriteRecord( dev
, &emr
.emr
);
465 return FALSE
; /* always fails without a path */
468 BOOL
EMFDRV_FlattenPath( PHYSDEV dev
)
472 emr
.emr
.iType
= EMR_FLATTENPATH
;
473 emr
.emr
.nSize
= sizeof(emr
);
475 return EMFDRV_WriteRecord( dev
, &emr
.emr
);
478 BOOL
EMFDRV_SelectClipPath( PHYSDEV dev
, INT iMode
)
480 // PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSelectClipPath ); This HACK breaks test_emf_clipping
481 EMRSELECTCLIPPATH emr
;
485 emr
.emr
.iType
= EMR_SELECTCLIPPATH
;
486 emr
.emr
.nSize
= sizeof(emr
);
489 if (!EMFDRV_WriteRecord( dev
, &emr
.emr
)) return FALSE
;
490 /* hrgn = PathToRegion( dev->hdc );
493 ret = next->funcs->pExtSelectClipRgn( next, hrgn, iMode );
494 DeleteObject( hrgn );
495 } ERR("EMFDRV_SelectClipPath ret %d\n",ret);
500 BOOL
EMFDRV_WidenPath( PHYSDEV dev
)
504 emr
.emr
.iType
= EMR_WIDENPATH
;
505 emr
.emr
.nSize
= sizeof(emr
);
507 return EMFDRV_WriteRecord( dev
, &emr
.emr
);
510 INT
EMFDRV_GetDeviceCaps(PHYSDEV dev
, INT cap
)
512 EMFDRV_PDEVICE
*physDev
= get_emf_physdev( dev
);
514 return GetDeviceCaps( physDev
->ref_dc
, cap
);
518 /***********************************************************************
519 * emfpathdrv_AbortPath
521 static BOOL
emfpathdrv_AbortPath( PHYSDEV dev
)
523 PHYSDEV emfdev
= get_emfdev( dev
);
524 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pAbortPath
);
525 DC
*dc
= get_physdev_dc( dev
);
527 emfpath_driver
.pDeleteDC( pop_dc_driver( dc
, &emfpath_driver
));
528 emfdev
->funcs
->pAbortPath( emfdev
);
529 return next
->funcs
->pAbortPath( next
);
532 /***********************************************************************
533 * emfpathdrv_AngleArc
535 static BOOL
emfpathdrv_AngleArc( PHYSDEV dev
, INT x
, INT y
, DWORD radius
, FLOAT start
, FLOAT sweep
)
537 PHYSDEV emfdev
= get_emfdev( dev
);
538 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pAngleArc
);
540 return (emfdev
->funcs
->pAngleArc( emfdev
, x
, y
, radius
, start
, sweep
) &&
541 next
->funcs
->pAngleArc( next
, x
, y
, radius
, start
, sweep
));
544 /***********************************************************************
547 static BOOL
emfpathdrv_Arc( PHYSDEV dev
, INT left
, INT top
, INT right
, INT bottom
,
548 INT xstart
, INT ystart
, INT xend
, INT yend
)
550 PHYSDEV emfdev
= get_emfdev( dev
);
551 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pArc
);
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
));
557 /***********************************************************************
560 static BOOL
emfpathdrv_ArcTo( 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
, pArcTo
);
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
));
570 /***********************************************************************
571 * emfpathdrv_BeginPath
573 static BOOL
emfpathdrv_BeginPath( PHYSDEV dev
)
575 PHYSDEV emfdev
= get_emfdev( dev
);
576 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pBeginPath
);
578 return (emfdev
->funcs
->pBeginPath( emfdev
) && next
->funcs
->pBeginPath( next
));
581 /***********************************************************************
584 static BOOL
emfpathdrv_Chord( PHYSDEV dev
, INT left
, INT top
, INT right
, INT bottom
,
585 INT xstart
, INT ystart
, INT xend
, INT yend
)
587 PHYSDEV emfdev
= get_emfdev( dev
);
588 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pChord
);
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
));
594 /***********************************************************************
595 * emfpathdrv_CloseFigure
597 static BOOL
emfpathdrv_CloseFigure( PHYSDEV dev
)
599 PHYSDEV emfdev
= get_emfdev( dev
);
600 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pCloseFigure
);
602 emfdev
->funcs
->pCloseFigure( emfdev
);
603 return next
->funcs
->pCloseFigure( next
);
606 /***********************************************************************
607 * emfpathdrv_CreateDC
609 static BOOL
emfpathdrv_CreateDC( PHYSDEV
*dev
, LPCWSTR driver
, LPCWSTR device
,
610 LPCWSTR output
, const DEVMODEW
*devmode
)
612 assert( 0 ); /* should never be called */
616 /*************************************************************
617 * emfpathdrv_DeleteDC
619 static BOOL
emfpathdrv_DeleteDC( PHYSDEV dev
)
621 EMFDRV_PDEVICE
*physdev
= (EMFDRV_PDEVICE
*)get_emfdev( dev
);
623 physdev
->path
= FALSE
;
627 /***********************************************************************
630 static BOOL
emfpathdrv_Ellipse( PHYSDEV dev
, INT x1
, INT y1
, INT x2
, INT y2
)
632 PHYSDEV emfdev
= get_emfdev( dev
);
633 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pEllipse
);
635 return (emfdev
->funcs
->pEllipse( emfdev
, x1
, y1
, x2
, y2
) &&
636 next
->funcs
->pEllipse( next
, x1
, y1
, x2
, y2
));
639 /***********************************************************************
642 static BOOL
emfpathdrv_EndPath( PHYSDEV dev
)
644 PHYSDEV emfdev
= get_emfdev( dev
);
645 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pEndPath
);
646 DC
*dc
= get_physdev_dc( dev
);
648 emfpath_driver
.pDeleteDC( pop_dc_driver( dc
, &emfpath_driver
));
649 emfdev
->funcs
->pEndPath( emfdev
);
650 return next
->funcs
->pEndPath( next
);
653 /***********************************************************************
654 * emfpathdrv_ExtTextOut
656 static BOOL
emfpathdrv_ExtTextOut( PHYSDEV dev
, INT x
, INT y
, UINT flags
, const RECT
*rect
,
657 LPCWSTR str
, UINT count
, const INT
*dx
)
659 PHYSDEV emfdev
= get_emfdev( dev
);
660 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pExtTextOut
);
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
));
666 /***********************************************************************
669 static BOOL
emfpathdrv_LineTo( PHYSDEV dev
, INT x
, INT y
)
671 PHYSDEV emfdev
= get_emfdev( dev
);
672 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pLineTo
);
674 return (emfdev
->funcs
->pLineTo( emfdev
, x
, y
) && next
->funcs
->pLineTo( next
, x
, y
));
677 /***********************************************************************
680 static BOOL
emfpathdrv_MoveTo( PHYSDEV dev
, INT x
, INT y
)
682 PHYSDEV emfdev
= get_emfdev( dev
);
683 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pMoveTo
);
685 return (emfdev
->funcs
->pMoveTo( emfdev
, x
, y
) && next
->funcs
->pMoveTo( next
, x
, y
));
688 /***********************************************************************
691 static BOOL
emfpathdrv_Pie( PHYSDEV dev
, INT left
, INT top
, INT right
, INT bottom
,
692 INT xstart
, INT ystart
, INT xend
, INT yend
)
694 PHYSDEV emfdev
= get_emfdev( dev
);
695 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pPie
);
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
));
701 /***********************************************************************
702 * emfpathdrv_PolyBezier
704 static BOOL
emfpathdrv_PolyBezier( PHYSDEV dev
, const POINT
*pts
, DWORD count
)
706 PHYSDEV emfdev
= get_emfdev( dev
);
707 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pPolyBezier
);
709 return (emfdev
->funcs
->pPolyBezier( emfdev
, pts
, count
) &&
710 next
->funcs
->pPolyBezier( next
, pts
, count
));
713 /***********************************************************************
714 * emfpathdrv_PolyBezierTo
716 static BOOL
emfpathdrv_PolyBezierTo( PHYSDEV dev
, const POINT
*pts
, DWORD count
)
718 PHYSDEV emfdev
= get_emfdev( dev
);
719 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pPolyBezierTo
);
721 return (emfdev
->funcs
->pPolyBezierTo( emfdev
, pts
, count
) &&
722 next
->funcs
->pPolyBezierTo( next
, pts
, count
));
725 /***********************************************************************
726 * emfpathdrv_PolyDraw
728 static BOOL
emfpathdrv_PolyDraw( PHYSDEV dev
, const POINT
*pts
, const BYTE
*types
, DWORD count
)
730 PHYSDEV emfdev
= get_emfdev( dev
);
731 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pPolyDraw
);
733 return (emfdev
->funcs
->pPolyDraw( emfdev
, pts
, types
, count
) &&
734 next
->funcs
->pPolyDraw( next
, pts
, types
, count
));
737 /***********************************************************************
738 * emfpathdrv_PolyPolygon
740 static BOOL
emfpathdrv_PolyPolygon( PHYSDEV dev
, const POINT
*pts
, const INT
*counts
, UINT polygons
)
742 PHYSDEV emfdev
= get_emfdev( dev
);
743 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pPolyPolygon
);
745 return (emfdev
->funcs
->pPolyPolygon( emfdev
, pts
, counts
, polygons
) &&
746 next
->funcs
->pPolyPolygon( next
, pts
, counts
, polygons
));
749 /***********************************************************************
750 * emfpathdrv_PolyPolyline
752 static BOOL
emfpathdrv_PolyPolyline( PHYSDEV dev
, const POINT
*pts
, const DWORD
*counts
, DWORD polylines
)
754 PHYSDEV emfdev
= get_emfdev( dev
);
755 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pPolyPolyline
);
757 return (emfdev
->funcs
->pPolyPolyline( emfdev
, pts
, counts
, polylines
) &&
758 next
->funcs
->pPolyPolyline( next
, pts
, counts
, polylines
));
761 /***********************************************************************
764 static BOOL
emfpathdrv_Polygon( PHYSDEV dev
, const POINT
*pts
, INT count
)
766 PHYSDEV emfdev
= get_emfdev( dev
);
767 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pPolygon
);
769 return (emfdev
->funcs
->pPolygon( emfdev
, pts
, count
) &&
770 next
->funcs
->pPolygon( next
, pts
, count
));
773 /***********************************************************************
774 * emfpathdrv_Polyline
776 static BOOL
emfpathdrv_Polyline( PHYSDEV dev
, const POINT
*pts
, INT count
)
778 PHYSDEV emfdev
= get_emfdev( dev
);
779 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pPolyline
);
781 return (emfdev
->funcs
->pPolyline( emfdev
, pts
, count
) &&
782 next
->funcs
->pPolyline( next
, pts
, count
));
785 /***********************************************************************
786 * emfpathdrv_PolylineTo
788 static BOOL
emfpathdrv_PolylineTo( PHYSDEV dev
, const POINT
*pts
, INT count
)
790 PHYSDEV emfdev
= get_emfdev( dev
);
791 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pPolylineTo
);
793 return (emfdev
->funcs
->pPolylineTo( emfdev
, pts
, count
) &&
794 next
->funcs
->pPolylineTo( next
, pts
, count
));
797 /***********************************************************************
798 * emfpathdrv_Rectangle
800 static BOOL
emfpathdrv_Rectangle( PHYSDEV dev
, INT x1
, INT y1
, INT x2
, INT y2
)
802 PHYSDEV emfdev
= get_emfdev( dev
);
803 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pRectangle
);
805 return (emfdev
->funcs
->pRectangle( emfdev
, x1
, y1
, x2
, y2
) &&
806 next
->funcs
->pRectangle( next
, x1
, y1
, x2
, y2
));
809 /***********************************************************************
810 * emfpathdrv_RoundRect
812 static BOOL
emfpathdrv_RoundRect( PHYSDEV dev
, INT x1
, INT y1
, INT x2
, INT y2
,
813 INT ell_width
, INT ell_height
)
815 PHYSDEV emfdev
= get_emfdev( dev
);
816 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pRoundRect
);
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
));
822 static const struct gdi_dc_funcs emfpath_driver
=
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 */
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 */
853 NULL
, /* pFlattenPath */
854 NULL
, /* pFontIsLinked */
855 NULL
, /* pFrameRgn */
856 NULL
, /* pGdiComment */
857 NULL
, /* pGetBoundsRect */
858 NULL
, /* pGetCharABCWidths */
859 NULL
, /* pGetCharABCWidthsI */
860 NULL
, /* pGetCharWidth */
862 EMFDRV_GetDeviceCaps
, //// Work around HACK.
864 NULL
, /* pGetDeviceCaps */
866 NULL
, /* pGetDeviceGammaRamp */
867 NULL
, /* pGetFontData */
868 NULL
, /* pGetFontRealizationInfo */
869 NULL
, /* pGetFontUnicodeRanges */
870 NULL
, /* pGetGlyphIndices */
871 NULL
, /* pGetGlyphOutline */
872 NULL
, /* pGetICMProfile */
873 NULL
, /* pGetImage */
874 NULL
, /* pGetKerningPairs */
875 NULL
, /* pGetNearestColor */
876 NULL
, /* pGetOutlineTextMetrics */
877 NULL
, /* pGetPixel */
878 NULL
, /* pGetSystemPaletteEntries */
879 NULL
, /* pGetTextCharsetInfo */
880 NULL
, /* pGetTextExtentExPoint */
881 NULL
, /* pGetTextExtentExPointI */
882 NULL
, /* pGetTextFace */
883 NULL
, /* pGetTextMetrics */
884 NULL
, /* pGradientFill */
885 NULL
, /* pIntersectClipRect */
886 NULL
, /* pInvertRgn */
887 emfpathdrv_LineTo
, /* pLineTo */
888 NULL
, /* pModifyWorldTransform */
889 emfpathdrv_MoveTo
, /* pMoveTo */
890 NULL
, /* pOffsetClipRgn */
891 NULL
, /* pOffsetViewportOrg */
892 NULL
, /* pOffsetWindowOrg */
893 NULL
, /* pPaintRgn */
895 emfpathdrv_Pie
, /* pPie */
896 emfpathdrv_PolyBezier
, /* pPolyBezier */
897 emfpathdrv_PolyBezierTo
, /* pPolyBezierTo */
898 emfpathdrv_PolyDraw
, /* pPolyDraw */
899 emfpathdrv_PolyPolygon
, /* pPolyPolygon */
900 emfpathdrv_PolyPolyline
, /* pPolyPolyline */
901 emfpathdrv_Polygon
, /* pPolygon */
902 emfpathdrv_Polyline
, /* pPolyline */
903 emfpathdrv_PolylineTo
, /* pPolylineTo */
904 NULL
, /* pPutImage */
905 NULL
, /* pRealizeDefaultPalette */
906 NULL
, /* pRealizePalette */
907 emfpathdrv_Rectangle
, /* pRectangle */
909 NULL
, /* pRestoreDC */
910 emfpathdrv_RoundRect
, /* pRoundRect */
912 NULL
, /* pScaleViewportExt */
913 NULL
, /* pScaleWindowExt */
914 NULL
, /* pSelectBitmap */
915 NULL
, /* pSelectBrush */
916 NULL
, /* pSelectClipPath */
917 NULL
, /* pSelectFont */
918 NULL
, /* pSelectPalette */
919 NULL
, /* pSelectPen */
920 NULL
, /* pSetArcDirection */
921 NULL
, /* pSetBkColor */
922 NULL
, /* pSetBkMode */
923 NULL
, /* pSetDCBrushColor */
924 NULL
, /* pSetDCPenColor */
925 NULL
, /* pSetDIBColorTable */
926 NULL
, /* pSetDIBitsToDevice */
927 NULL
, /* pSetDeviceClipping */
928 NULL
, /* pSetDeviceGammaRamp */
929 NULL
, /* pSetLayout */
930 NULL
, /* pSetMapMode */
931 NULL
, /* pSetMapperFlags */
932 NULL
, /* pSetPixel */
933 NULL
, /* pSetPolyFillMode */
935 NULL
, /* pSetRelAbs */
936 NULL
, /* pSetStretchBltMode */
937 NULL
, /* pSetTextAlign */
938 NULL
, /* pSetTextCharacterExtra */
939 NULL
, /* pSetTextColor */
940 NULL
, /* pSetTextJustification */
941 NULL
, /* pSetViewportExt */
942 NULL
, /* pSetViewportOrg */
943 NULL
, /* pSetWindowExt */
944 NULL
, /* pSetWindowOrg */
945 NULL
, /* pSetWorldTransform */
946 NULL
, /* pStartDoc */
947 NULL
, /* pStartPage */
948 NULL
, /* pStretchBlt */
949 NULL
, /* pStretchDIBits */
950 NULL
, /* pStrokeAndFillPath */
951 NULL
, /* pStrokePath */
952 NULL
, /* pUnrealizePalette */
953 NULL
, /* pWidenPath */
954 NULL
, /* wine_get_wgl_driver */
955 GDI_PRIORITY_PATH_DRV
+ 1 /* priority */