gdi32: Use NtGdiExtSelectClipRgn for ExtSelectClipRgn implementation.
[wine.git] / dlls / gdi32 / enhmfdrv / dc.c
bloba0eb0c33344e20e9559c11b27271550eeac6a993
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 BOOL EMFDC_SaveDC( DC_ATTR *dc_attr )
27 EMRSAVEDC emr;
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 );
38 EMRRESTOREDC emr;
39 BOOL ret;
41 emr.emr.iType = EMR_RESTOREDC;
42 emr.emr.nSize = sizeof(emr);
44 if (level < 0)
45 emr.iRelative = level;
46 else
47 emr.iRelative = level - dc->saveLevel - 1;
49 physDev->restoring++;
50 ret = next->funcs->pRestoreDC( next, level );
51 physDev->restoring--;
53 if (ret) EMFDRV_WriteRecord( dev, &emr.emr );
54 return ret;
57 BOOL EMFDC_SetTextAlign( DC_ATTR *dc_attr, UINT align )
59 EMRSETTEXTALIGN emr;
60 emr.emr.iType = EMR_SETTEXTALIGN;
61 emr.emr.nSize = sizeof(emr);
62 emr.iMode = align;
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 )
78 EMRSETBKMODE emr;
79 emr.emr.iType = EMR_SETBKMODE;
80 emr.emr.nSize = sizeof(emr);
81 emr.iMode = mode;
82 return EMFDRV_WriteRecord( dc_attr->emf, &emr.emr );
85 COLORREF CDECL EMFDRV_SetBkColor( PHYSDEV dev, COLORREF color )
87 EMRSETBKCOLOR emr;
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);
94 emr.crColor = color;
95 return EMFDRV_WriteRecord( dev, &emr.emr ) ? color : CLR_INVALID;
99 COLORREF CDECL EMFDRV_SetTextColor( PHYSDEV dev, COLORREF color )
101 EMRSETTEXTCOLOR emr;
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);
108 emr.crColor = color;
109 return EMFDRV_WriteRecord( dev, &emr.emr ) ? color : CLR_INVALID;
112 BOOL EMFDC_SetROP2( DC_ATTR *dc_attr, INT rop )
114 EMRSETROP2 emr;
115 emr.emr.iType = EMR_SETROP2;
116 emr.emr.nSize = sizeof(emr);
117 emr.iMode = rop;
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);
126 emr.iMode = mode;
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);
135 emr.iMode = mode;
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);
181 emr.ptlOffset.x = x;
182 emr.ptlOffset.y = y;
183 return EMFDRV_WriteRecord( dc_attr->emf, &emr.emr );
186 BOOL EMFDC_ExtSelectClipRgn( DC_ATTR *dc_attr, HRGN hrgn, INT mode )
188 EMREXTSELECTCLIPRGN *emr;
189 DWORD size, rgnsize;
190 BOOL ret;
192 if (!hrgn)
194 if (mode != RGN_COPY) return ERROR;
195 rgnsize = 0;
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;
206 emr->iMode = mode;
208 ret = EMFDRV_WriteRecord( dc_attr->emf, &emr->emr );
209 HeapFree( GetProcessHeap(), 0, emr );
210 return ret;
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 );
217 EMRSETMAPMODE emr;
218 INT ret;
220 emr.emr.iType = EMR_SETMAPMODE;
221 emr.emr.nSize = sizeof(emr);
222 emr.iMode = mode;
224 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return 0;
225 physDev->modifying_transform++;
226 ret = next->funcs->pSetMapMode( next, mode );
227 physDev->modifying_transform--;
228 return ret;
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;
236 BOOL ret;
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--;
247 return ret;
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;
255 BOOL ret;
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--;
266 return ret;
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;
274 BOOL ret;
276 emr.emr.iType = EMR_SETVIEWPORTORGEX;
277 emr.emr.nSize = sizeof(emr);
278 emr.ptlOrigin.x = x;
279 emr.ptlOrigin.y = y;
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--;
285 return ret;
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;
293 BOOL ret;
295 emr.emr.iType = EMR_SETWINDOWORGEX;
296 emr.emr.nSize = sizeof(emr);
297 emr.ptlOrigin.x = x;
298 emr.ptlOrigin.y = y;
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--;
304 return ret;
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;
312 BOOL ret;
314 emr.emr.iType = EMR_SCALEVIEWPORTEXTEX;
315 emr.emr.nSize = sizeof(emr);
316 emr.xNum = xNum;
317 emr.xDenom = xDenom;
318 emr.yNum = yNum;
319 emr.yDenom = yDenom;
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--;
325 return ret;
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);
335 emr.xNum = xNum;
336 emr.xDenom = xDenom;
337 emr.yNum = yNum;
338 emr.yDenom = yDenom;
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 );
348 EMRSETLAYOUT emr;
349 DWORD ret;
351 emr.emr.iType = EMR_SETLAYOUT;
352 emr.emr.nSize = sizeof(emr);
353 emr.iMode = layout;
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--;
358 return ret;
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;
366 BOOL ret;
368 emr.emr.iType = EMR_SETWORLDTRANSFORM;
369 emr.emr.nSize = sizeof(emr);
370 emr.xform = *xform;
372 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
373 physDev->modifying_transform++;
374 ret = next->funcs->pSetWorldTransform( next, xform );
375 physDev->modifying_transform--;
376 return ret;
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;
384 BOOL ret;
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;
397 else
399 emr.xform = *xform;
401 emr.iMode = mode;
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--;
407 return ret;
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;
415 POINT prev;
416 BOOL ret;
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--;
429 return ret;
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;
437 POINT prev;
438 BOOL ret;
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--;
451 return ret;
454 DWORD CDECL EMFDRV_SetMapperFlags( PHYSDEV dev, DWORD flags )
456 EMRSETMAPPERFLAGS emr;
458 emr.emr.iType = EMR_SETMAPPERFLAGS;
459 emr.emr.nSize = sizeof(emr);
460 emr.dwFlags = flags;
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;
468 EMRABORTPATH emr;
470 emr.emr.iType = EMR_ABORTPATH;
471 emr.emr.nSize = sizeof(emr);
473 emf->path = FALSE;
474 return EMFDRV_WriteRecord( dc_attr->emf, &emr.emr );
477 BOOL EMFDC_BeginPath( DC_ATTR *dc_attr )
479 EMFDRV_PDEVICE *emf = dc_attr->emf;
480 EMRBEGINPATH emr;
482 emr.emr.iType = EMR_BEGINPATH;
483 emr.emr.nSize = sizeof(emr);
485 if (!EMFDRV_WriteRecord( &emf->dev, &emr.emr )) return FALSE;
486 emf->path = TRUE;
487 return TRUE;
490 BOOL EMFDC_CloseFigure( DC_ATTR *dc_attr )
492 EMRCLOSEFIGURE emr;
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;
503 EMRENDPATH emr;
505 emr.emr.iType = EMR_ENDPATH;
506 emr.emr.nSize = sizeof(emr);
508 emf->path = FALSE;
509 return EMFDRV_WriteRecord( &emf->dev, &emr.emr );
512 BOOL CDECL EMFDRV_FlattenPath( PHYSDEV dev )
514 EMRFLATTENPATH emr;
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;
525 BOOL ret = FALSE;
526 HRGN hrgn;
528 emr.emr.iType = EMR_SELECTCLIPPATH;
529 emr.emr.nSize = sizeof(emr);
530 emr.iMode = iMode;
532 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
533 hrgn = PathToRegion( dev->hdc );
534 if (hrgn)
536 ret = NtGdiExtSelectClipRgn( dev->hdc, hrgn, iMode );
537 DeleteObject( hrgn );
539 return ret;
542 BOOL CDECL EMFDRV_WidenPath( PHYSDEV dev )
544 EMRWIDENPATH emr;
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];
558 return 0;