mfplat: Read queue subscriber within the critical section.
[wine/zf.git] / dlls / gdi32 / enhmfdrv / dc.c
blob2a749418829d20f8fcd294901dee80babd93ab60
1 /*
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
22 #include <assert.h>
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 );
38 if (ret)
40 EMRSAVEDC emr;
41 emr.emr.iType = EMR_SAVEDC;
42 emr.emr.nSize = sizeof(emr);
43 EMFDRV_WriteRecord( dev, &emr.emr );
45 return ret;
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 );
53 EMRRESTOREDC emr;
54 BOOL ret;
56 emr.emr.iType = EMR_RESTOREDC;
57 emr.emr.nSize = sizeof(emr);
59 if (level < 0)
60 emr.iRelative = level;
61 else
62 emr.iRelative = level - dc->saveLevel - 1;
64 physDev->restoring++;
65 ret = next->funcs->pRestoreDC( next, level );
66 physDev->restoring--;
68 if (ret) EMFDRV_WriteRecord( dev, &emr.emr );
69 return ret;
72 UINT CDECL EMFDRV_SetTextAlign( PHYSDEV dev, UINT align )
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;
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 )
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;
100 COLORREF CDECL EMFDRV_SetBkColor( PHYSDEV dev, COLORREF color )
102 EMRSETBKCOLOR emr;
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);
109 emr.crColor = color;
110 return EMFDRV_WriteRecord( dev, &emr.emr ) ? color : CLR_INVALID;
114 COLORREF CDECL EMFDRV_SetTextColor( PHYSDEV dev, COLORREF color )
116 EMRSETTEXTCOLOR emr;
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);
123 emr.crColor = color;
124 return EMFDRV_WriteRecord( dev, &emr.emr ) ? color : CLR_INVALID;
127 INT CDECL EMFDRV_SetROP2( PHYSDEV dev, INT rop )
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;
136 INT CDECL EMFDRV_SetPolyFillMode( PHYSDEV dev, INT mode )
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;
145 INT CDECL EMFDRV_SetStretchBltMode( PHYSDEV dev, INT mode )
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;
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);
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 );
207 INT CDECL EMFDRV_ExtSelectClipRgn( PHYSDEV dev, HRGN hrgn, INT mode )
209 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pExtSelectClipRgn );
210 EMREXTSELECTCLIPRGN *emr;
211 DWORD size, rgnsize;
212 BOOL ret;
214 if (!hrgn)
216 if (mode != RGN_COPY) return ERROR;
217 rgnsize = 0;
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;
228 emr->iMode = mode;
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 );
238 EMRSETMAPMODE emr;
239 emr.emr.iType = EMR_SETMAPMODE;
240 emr.emr.nSize = sizeof(emr);
241 emr.iMode = mode;
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);
282 emr.ptlOrigin.x = x;
283 emr.ptlOrigin.y = y;
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);
296 emr.ptlOrigin.x = x;
297 emr.ptlOrigin.y = y;
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);
310 emr.xNum = xNum;
311 emr.xDenom = xDenom;
312 emr.yNum = yNum;
313 emr.yDenom = yDenom;
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);
326 emr.xNum = xNum;
327 emr.xDenom = xDenom;
328 emr.yNum = yNum;
329 emr.yDenom = yDenom;
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 )
337 EMRSETLAYOUT emr;
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;
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);
352 emr.xform = *xform;
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;
374 else
376 emr.xform = *xform;
378 emr.iMode = mode;
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;
388 POINT prev;
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;
405 POINT prev;
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);
424 emr.dwFlags = flags;
426 return EMFDRV_WriteRecord( dev, &emr.emr ) ? flags : GDI_ERROR;
429 BOOL CDECL EMFDRV_AbortPath( PHYSDEV dev )
431 EMRABORTPATH emr;
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 );
443 EMRBEGINPATH emr;
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;
455 return TRUE;
458 BOOL CDECL EMFDRV_CloseFigure( PHYSDEV dev )
460 EMRCLOSEFIGURE emr;
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 )
471 EMRENDPATH emr;
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 )
482 EMRFLATTENPATH emr;
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;
494 BOOL ret = FALSE;
495 HRGN hrgn;
497 emr.emr.iType = EMR_SELECTCLIPPATH;
498 emr.emr.nSize = sizeof(emr);
499 emr.iMode = iMode;
501 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
502 hrgn = PathToRegion( dev->hdc );
503 if (hrgn)
505 ret = next->funcs->pExtSelectClipRgn( next, hrgn, iMode );
506 DeleteObject( hrgn );
508 return ret;
511 BOOL CDECL EMFDRV_WidenPath( PHYSDEV dev )
513 EMRWIDENPATH emr;
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];
527 return 0;
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 /***********************************************************************
558 * emfpathdrv_Arc
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 /***********************************************************************
571 * emfpathdrv_ArcTo
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 /***********************************************************************
595 * emfpathdrv_Chord
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 */
626 return TRUE;
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;
637 return TRUE;
640 /***********************************************************************
641 * emfpathdrv_Ellipse
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 /***********************************************************************
653 * emfpathdrv_EndPath
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 /***********************************************************************
680 * emfpathdrv_LineTo
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 /***********************************************************************
691 * emfpathdrv_MoveTo
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 /***********************************************************************
702 * emfpathdrv_Pie
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 /***********************************************************************
775 * emfpathdrv_Polygon
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 */
854 NULL, /* pEndDoc */
855 NULL, /* pEndPage */
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 */
866 NULL, /* pFillRgn */
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 */
905 NULL, /* pPatBlt */
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 */
919 NULL, /* pResetDC */
920 NULL, /* pRestoreDC */
921 emfpathdrv_RoundRect, /* pRoundRect */
922 NULL, /* pSaveDC */
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 */
945 NULL, /* pSetROP2 */
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 */