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 BOOL
EMFDC_SaveDC( DC_ATTR
*dc_attr
)
28 emr
.emr
.iType
= EMR_SAVEDC
;
29 emr
.emr
.nSize
= sizeof(emr
);
30 return EMFDRV_WriteRecord( dc_attr
->emf
, &emr
.emr
);
33 BOOL CDECL
EMFDRV_RestoreDC( PHYSDEV dev
, INT level
)
35 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pRestoreDC
);
36 EMFDRV_PDEVICE
* physDev
= get_emf_physdev( dev
);
37 DC
*dc
= get_physdev_dc( dev
);
41 emr
.emr
.iType
= EMR_RESTOREDC
;
42 emr
.emr
.nSize
= sizeof(emr
);
45 emr
.iRelative
= level
;
47 emr
.iRelative
= level
- dc
->saveLevel
- 1;
50 ret
= next
->funcs
->pRestoreDC( next
, level
);
53 if (ret
) EMFDRV_WriteRecord( dev
, &emr
.emr
);
57 BOOL
EMFDC_SetTextAlign( DC_ATTR
*dc_attr
, UINT align
)
60 emr
.emr
.iType
= EMR_SETTEXTALIGN
;
61 emr
.emr
.nSize
= sizeof(emr
);
63 return EMFDRV_WriteRecord( dc_attr
->emf
, &emr
.emr
);
66 BOOL CDECL
EMFDRV_SetTextJustification(PHYSDEV dev
, INT nBreakExtra
, INT nBreakCount
)
68 EMRSETTEXTJUSTIFICATION emr
;
69 emr
.emr
.iType
= EMR_SETTEXTJUSTIFICATION
;
70 emr
.emr
.nSize
= sizeof(emr
);
71 emr
.nBreakExtra
= nBreakExtra
;
72 emr
.nBreakCount
= nBreakCount
;
73 return EMFDRV_WriteRecord(dev
, &emr
.emr
);
76 BOOL
EMFDC_SetBkMode( DC_ATTR
*dc_attr
, INT mode
)
79 emr
.emr
.iType
= EMR_SETBKMODE
;
80 emr
.emr
.nSize
= sizeof(emr
);
82 return EMFDRV_WriteRecord( dc_attr
->emf
, &emr
.emr
);
85 COLORREF CDECL
EMFDRV_SetBkColor( PHYSDEV dev
, COLORREF color
)
88 EMFDRV_PDEVICE
*physDev
= get_emf_physdev( dev
);
90 if (physDev
->restoring
) return color
; /* don't output records during RestoreDC */
92 emr
.emr
.iType
= EMR_SETBKCOLOR
;
93 emr
.emr
.nSize
= sizeof(emr
);
95 return EMFDRV_WriteRecord( dev
, &emr
.emr
) ? color
: CLR_INVALID
;
99 COLORREF CDECL
EMFDRV_SetTextColor( PHYSDEV dev
, COLORREF color
)
102 EMFDRV_PDEVICE
*physDev
= get_emf_physdev( dev
);
104 if (physDev
->restoring
) return color
; /* don't output records during RestoreDC */
106 emr
.emr
.iType
= EMR_SETTEXTCOLOR
;
107 emr
.emr
.nSize
= sizeof(emr
);
109 return EMFDRV_WriteRecord( dev
, &emr
.emr
) ? color
: CLR_INVALID
;
112 BOOL
EMFDC_SetROP2( DC_ATTR
*dc_attr
, INT rop
)
115 emr
.emr
.iType
= EMR_SETROP2
;
116 emr
.emr
.nSize
= sizeof(emr
);
118 return EMFDRV_WriteRecord( dc_attr
->emf
, &emr
.emr
);
121 BOOL
EMFDC_SetPolyFillMode( DC_ATTR
*dc_attr
, INT mode
)
123 EMRSETPOLYFILLMODE emr
;
124 emr
.emr
.iType
= EMR_SETPOLYFILLMODE
;
125 emr
.emr
.nSize
= sizeof(emr
);
127 return EMFDRV_WriteRecord( dc_attr
->emf
, &emr
.emr
);
130 BOOL
EMFDC_SetStretchBltMode( DC_ATTR
*dc_attr
, INT mode
)
132 EMRSETSTRETCHBLTMODE emr
;
133 emr
.emr
.iType
= EMR_SETSTRETCHBLTMODE
;
134 emr
.emr
.nSize
= sizeof(emr
);
136 return EMFDRV_WriteRecord( dc_attr
->emf
, &emr
.emr
);
139 BOOL
EMFDC_SetArcDirection( DC_ATTR
*dc_attr
, INT dir
)
141 EMRSETARCDIRECTION emr
;
143 emr
.emr
.iType
= EMR_SETARCDIRECTION
;
144 emr
.emr
.nSize
= sizeof(emr
);
145 emr
.iArcDirection
= dir
;
146 return EMFDRV_WriteRecord( dc_attr
->emf
, &emr
.emr
);
149 INT
EMFDC_ExcludeClipRect( DC_ATTR
*dc_attr
, INT left
, INT top
, INT right
, INT bottom
)
151 EMREXCLUDECLIPRECT emr
;
153 emr
.emr
.iType
= EMR_EXCLUDECLIPRECT
;
154 emr
.emr
.nSize
= sizeof(emr
);
155 emr
.rclClip
.left
= left
;
156 emr
.rclClip
.top
= top
;
157 emr
.rclClip
.right
= right
;
158 emr
.rclClip
.bottom
= bottom
;
159 return EMFDRV_WriteRecord( dc_attr
->emf
, &emr
.emr
);
162 BOOL
EMFDC_IntersectClipRect( DC_ATTR
*dc_attr
, INT left
, INT top
, INT right
, INT bottom
)
164 EMRINTERSECTCLIPRECT emr
;
166 emr
.emr
.iType
= EMR_INTERSECTCLIPRECT
;
167 emr
.emr
.nSize
= sizeof(emr
);
168 emr
.rclClip
.left
= left
;
169 emr
.rclClip
.top
= top
;
170 emr
.rclClip
.right
= right
;
171 emr
.rclClip
.bottom
= bottom
;
172 return EMFDRV_WriteRecord( dc_attr
->emf
, &emr
.emr
);
175 BOOL
EMFDC_OffsetClipRgn( DC_ATTR
*dc_attr
, INT x
, INT y
)
177 EMROFFSETCLIPRGN emr
;
179 emr
.emr
.iType
= EMR_OFFSETCLIPRGN
;
180 emr
.emr
.nSize
= sizeof(emr
);
183 return EMFDRV_WriteRecord( dc_attr
->emf
, &emr
.emr
);
186 BOOL
EMFDC_ExtSelectClipRgn( DC_ATTR
*dc_attr
, HRGN hrgn
, INT mode
)
188 EMREXTSELECTCLIPRGN
*emr
;
194 if (mode
!= RGN_COPY
) return ERROR
;
197 else rgnsize
= NtGdiGetRegionData( hrgn
, 0, NULL
);
199 size
= rgnsize
+ offsetof(EMREXTSELECTCLIPRGN
,RgnData
);
200 emr
= HeapAlloc( GetProcessHeap(), 0, size
);
201 if (rgnsize
) NtGdiGetRegionData( hrgn
, rgnsize
, (RGNDATA
*)&emr
->RgnData
);
203 emr
->emr
.iType
= EMR_EXTSELECTCLIPRGN
;
204 emr
->emr
.nSize
= size
;
205 emr
->cbRgnData
= rgnsize
;
208 ret
= EMFDRV_WriteRecord( dc_attr
->emf
, &emr
->emr
);
209 HeapFree( GetProcessHeap(), 0, emr
);
213 INT CDECL
EMFDRV_SetMapMode( PHYSDEV dev
, INT mode
)
215 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pSetMapMode
);
216 EMFDRV_PDEVICE
*physDev
= get_emf_physdev( dev
);
220 emr
.emr
.iType
= EMR_SETMAPMODE
;
221 emr
.emr
.nSize
= sizeof(emr
);
224 if (!EMFDRV_WriteRecord( dev
, &emr
.emr
)) return 0;
225 physDev
->modifying_transform
++;
226 ret
= next
->funcs
->pSetMapMode( next
, mode
);
227 physDev
->modifying_transform
--;
231 BOOL CDECL
EMFDRV_SetViewportExtEx( PHYSDEV dev
, INT cx
, INT cy
, SIZE
*size
)
233 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pSetViewportExtEx
);
234 EMFDRV_PDEVICE
*physDev
= get_emf_physdev( dev
);
235 EMRSETVIEWPORTEXTEX emr
;
238 emr
.emr
.iType
= EMR_SETVIEWPORTEXTEX
;
239 emr
.emr
.nSize
= sizeof(emr
);
240 emr
.szlExtent
.cx
= cx
;
241 emr
.szlExtent
.cy
= cy
;
243 if (!EMFDRV_WriteRecord( dev
, &emr
.emr
)) return FALSE
;
244 physDev
->modifying_transform
++;
245 ret
= next
->funcs
->pSetViewportExtEx( next
, cx
, cy
, size
);
246 physDev
->modifying_transform
--;
250 BOOL CDECL
EMFDRV_SetWindowExtEx( PHYSDEV dev
, INT cx
, INT cy
, SIZE
*size
)
252 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pSetWindowExtEx
);
253 EMFDRV_PDEVICE
*physDev
= get_emf_physdev( dev
);
254 EMRSETWINDOWEXTEX emr
;
257 emr
.emr
.iType
= EMR_SETWINDOWEXTEX
;
258 emr
.emr
.nSize
= sizeof(emr
);
259 emr
.szlExtent
.cx
= cx
;
260 emr
.szlExtent
.cy
= cy
;
262 if (!EMFDRV_WriteRecord( dev
, &emr
.emr
)) return FALSE
;
263 physDev
->modifying_transform
++;
264 ret
= next
->funcs
->pSetWindowExtEx( next
, cx
, cy
, size
);
265 physDev
->modifying_transform
--;
269 BOOL CDECL
EMFDRV_SetViewportOrgEx( PHYSDEV dev
, INT x
, INT y
, POINT
*pt
)
271 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pSetViewportOrgEx
);
272 EMFDRV_PDEVICE
*physDev
= get_emf_physdev( dev
);
273 EMRSETVIEWPORTORGEX emr
;
276 emr
.emr
.iType
= EMR_SETVIEWPORTORGEX
;
277 emr
.emr
.nSize
= sizeof(emr
);
281 if (!EMFDRV_WriteRecord( dev
, &emr
.emr
)) return FALSE
;
282 physDev
->modifying_transform
++;
283 ret
= next
->funcs
->pSetViewportOrgEx( next
, x
, y
, pt
);
284 physDev
->modifying_transform
--;
288 BOOL CDECL
EMFDRV_SetWindowOrgEx( PHYSDEV dev
, INT x
, INT y
, POINT
*pt
)
290 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pSetWindowOrgEx
);
291 EMFDRV_PDEVICE
*physDev
= get_emf_physdev( dev
);
292 EMRSETWINDOWORGEX emr
;
295 emr
.emr
.iType
= EMR_SETWINDOWORGEX
;
296 emr
.emr
.nSize
= sizeof(emr
);
300 if (!EMFDRV_WriteRecord( dev
, &emr
.emr
)) return FALSE
;
301 physDev
->modifying_transform
++;
302 ret
= next
->funcs
->pSetWindowOrgEx( next
, x
, y
, pt
);
303 physDev
->modifying_transform
--;
307 BOOL CDECL
EMFDRV_ScaleViewportExtEx( PHYSDEV dev
, INT xNum
, INT xDenom
, INT yNum
, INT yDenom
, SIZE
*size
)
309 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pScaleViewportExtEx
);
310 EMFDRV_PDEVICE
*physDev
= get_emf_physdev( dev
);
311 EMRSCALEVIEWPORTEXTEX emr
;
314 emr
.emr
.iType
= EMR_SCALEVIEWPORTEXTEX
;
315 emr
.emr
.nSize
= sizeof(emr
);
321 if (!EMFDRV_WriteRecord( dev
, &emr
.emr
)) return FALSE
;
322 physDev
->modifying_transform
++;
323 ret
= next
->funcs
->pScaleViewportExtEx( next
, xNum
, xDenom
, yNum
, yDenom
, size
);
324 physDev
->modifying_transform
--;
328 BOOL CDECL
EMFDRV_ScaleWindowExtEx( PHYSDEV dev
, INT xNum
, INT xDenom
, INT yNum
, INT yDenom
, SIZE
*size
)
330 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pScaleWindowExtEx
);
331 EMRSCALEWINDOWEXTEX emr
;
333 emr
.emr
.iType
= EMR_SCALEWINDOWEXTEX
;
334 emr
.emr
.nSize
= sizeof(emr
);
340 if (!EMFDRV_WriteRecord( dev
, &emr
.emr
)) return FALSE
;
341 return next
->funcs
->pScaleWindowExtEx( next
, xNum
, xDenom
, yNum
, yDenom
, size
);
344 DWORD CDECL
EMFDRV_SetLayout( PHYSDEV dev
, DWORD layout
)
346 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pSetLayout
);
347 EMFDRV_PDEVICE
*physDev
= get_emf_physdev( dev
);
351 emr
.emr
.iType
= EMR_SETLAYOUT
;
352 emr
.emr
.nSize
= sizeof(emr
);
354 if (!EMFDRV_WriteRecord( dev
, &emr
.emr
)) return GDI_ERROR
;
355 physDev
->modifying_transform
++;
356 ret
= next
->funcs
->pSetLayout( next
, layout
);
357 physDev
->modifying_transform
--;
361 BOOL CDECL
EMFDRV_SetWorldTransform( PHYSDEV dev
, const XFORM
*xform
)
363 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pSetWorldTransform
);
364 EMFDRV_PDEVICE
*physDev
= get_emf_physdev( dev
);
365 EMRSETWORLDTRANSFORM emr
;
368 emr
.emr
.iType
= EMR_SETWORLDTRANSFORM
;
369 emr
.emr
.nSize
= sizeof(emr
);
372 if (!EMFDRV_WriteRecord( dev
, &emr
.emr
)) return FALSE
;
373 physDev
->modifying_transform
++;
374 ret
= next
->funcs
->pSetWorldTransform( next
, xform
);
375 physDev
->modifying_transform
--;
379 BOOL CDECL
EMFDRV_ModifyWorldTransform( PHYSDEV dev
, const XFORM
*xform
, DWORD mode
)
381 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pModifyWorldTransform
);
382 EMFDRV_PDEVICE
*physDev
= get_emf_physdev( dev
);
383 EMRMODIFYWORLDTRANSFORM emr
;
386 emr
.emr
.iType
= EMR_MODIFYWORLDTRANSFORM
;
387 emr
.emr
.nSize
= sizeof(emr
);
388 if (mode
== MWT_IDENTITY
)
390 emr
.xform
.eM11
= 1.0f
;
391 emr
.xform
.eM12
= 0.0f
;
392 emr
.xform
.eM21
= 0.0f
;
393 emr
.xform
.eM22
= 1.0f
;
394 emr
.xform
.eDx
= 0.0f
;
395 emr
.xform
.eDy
= 0.0f
;
403 if (!EMFDRV_WriteRecord( dev
, &emr
.emr
)) return FALSE
;
404 physDev
->modifying_transform
++;
405 ret
= next
->funcs
->pModifyWorldTransform( next
, xform
, mode
);
406 physDev
->modifying_transform
--;
410 BOOL CDECL
EMFDRV_OffsetViewportOrgEx( PHYSDEV dev
, INT x
, INT y
, POINT
*pt
)
412 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pOffsetViewportOrgEx
);
413 EMFDRV_PDEVICE
*physDev
= get_emf_physdev( dev
);
414 EMRSETVIEWPORTORGEX emr
;
418 GetViewportOrgEx( dev
->hdc
, &prev
);
420 emr
.emr
.iType
= EMR_SETVIEWPORTORGEX
;
421 emr
.emr
.nSize
= sizeof(emr
);
422 emr
.ptlOrigin
.x
= prev
.x
+ x
;
423 emr
.ptlOrigin
.y
= prev
.y
+ y
;
425 if (!EMFDRV_WriteRecord( dev
, &emr
.emr
)) return FALSE
;
426 physDev
->modifying_transform
++;
427 ret
= next
->funcs
->pOffsetViewportOrgEx( next
, x
, y
, pt
);
428 physDev
->modifying_transform
--;
432 BOOL CDECL
EMFDRV_OffsetWindowOrgEx( PHYSDEV dev
, INT x
, INT y
, POINT
*pt
)
434 PHYSDEV next
= GET_NEXT_PHYSDEV( dev
, pOffsetWindowOrgEx
);
435 EMFDRV_PDEVICE
*physDev
= get_emf_physdev( dev
);
436 EMRSETWINDOWORGEX emr
;
440 GetWindowOrgEx( dev
->hdc
, &prev
);
442 emr
.emr
.iType
= EMR_SETWINDOWORGEX
;
443 emr
.emr
.nSize
= sizeof(emr
);
444 emr
.ptlOrigin
.x
= prev
.x
+ x
;
445 emr
.ptlOrigin
.y
= prev
.y
+ y
;
447 if (!EMFDRV_WriteRecord( dev
, &emr
.emr
)) return FALSE
;
448 physDev
->modifying_transform
++;
449 ret
= next
->funcs
->pOffsetWindowOrgEx( next
, x
, y
, pt
);
450 physDev
->modifying_transform
--;
454 DWORD CDECL
EMFDRV_SetMapperFlags( PHYSDEV dev
, DWORD flags
)
456 EMRSETMAPPERFLAGS emr
;
458 emr
.emr
.iType
= EMR_SETMAPPERFLAGS
;
459 emr
.emr
.nSize
= sizeof(emr
);
462 return EMFDRV_WriteRecord( dev
, &emr
.emr
) ? flags
: GDI_ERROR
;
465 BOOL
EMFDC_AbortPath( DC_ATTR
*dc_attr
)
467 EMFDRV_PDEVICE
*emf
= dc_attr
->emf
;
470 emr
.emr
.iType
= EMR_ABORTPATH
;
471 emr
.emr
.nSize
= sizeof(emr
);
474 return EMFDRV_WriteRecord( dc_attr
->emf
, &emr
.emr
);
477 BOOL
EMFDC_BeginPath( DC_ATTR
*dc_attr
)
479 EMFDRV_PDEVICE
*emf
= dc_attr
->emf
;
482 emr
.emr
.iType
= EMR_BEGINPATH
;
483 emr
.emr
.nSize
= sizeof(emr
);
485 if (!EMFDRV_WriteRecord( &emf
->dev
, &emr
.emr
)) return FALSE
;
490 BOOL
EMFDC_CloseFigure( DC_ATTR
*dc_attr
)
494 emr
.emr
.iType
= EMR_CLOSEFIGURE
;
495 emr
.emr
.nSize
= sizeof(emr
);
497 return EMFDRV_WriteRecord( dc_attr
->emf
, &emr
.emr
);
500 BOOL
EMFDC_EndPath( DC_ATTR
*dc_attr
)
502 EMFDRV_PDEVICE
*emf
= dc_attr
->emf
;
505 emr
.emr
.iType
= EMR_ENDPATH
;
506 emr
.emr
.nSize
= sizeof(emr
);
509 return EMFDRV_WriteRecord( &emf
->dev
, &emr
.emr
);
512 BOOL CDECL
EMFDRV_FlattenPath( PHYSDEV dev
)
516 emr
.emr
.iType
= EMR_FLATTENPATH
;
517 emr
.emr
.nSize
= sizeof(emr
);
519 return EMFDRV_WriteRecord( dev
, &emr
.emr
);
522 BOOL CDECL
EMFDRV_SelectClipPath( PHYSDEV dev
, INT iMode
)
524 EMRSELECTCLIPPATH emr
;
528 emr
.emr
.iType
= EMR_SELECTCLIPPATH
;
529 emr
.emr
.nSize
= sizeof(emr
);
532 if (!EMFDRV_WriteRecord( dev
, &emr
.emr
)) return FALSE
;
533 hrgn
= PathToRegion( dev
->hdc
);
536 ret
= NtGdiExtSelectClipRgn( dev
->hdc
, hrgn
, iMode
);
537 DeleteObject( hrgn
);
542 BOOL CDECL
EMFDRV_WidenPath( PHYSDEV dev
)
546 emr
.emr
.iType
= EMR_WIDENPATH
;
547 emr
.emr
.nSize
= sizeof(emr
);
549 return EMFDRV_WriteRecord( dev
, &emr
.emr
);
552 INT CDECL
EMFDRV_GetDeviceCaps(PHYSDEV dev
, INT cap
)
554 EMFDRV_PDEVICE
*physDev
= get_emf_physdev( dev
);
556 if (cap
>= 0 && cap
< ARRAY_SIZE( physDev
->dev_caps
))
557 return physDev
->dev_caps
[cap
];