Release 1.5.29.
[wine] / dlls / gdi32 / enhmfdrv / dc.c
1 /*
2  * Enhanced MetaFile driver dc value functions
3  *
4  * Copyright 1999 Huw D M Davies
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include "enhmfdrv/enhmetafiledrv.h"
22 #include "wine/debug.h"
23
24 WINE_DEFAULT_DEBUG_CHANNEL(enhmetafile);
25
26 INT EMFDRV_SaveDC( PHYSDEV dev )
27 {
28     PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSaveDC );
29     INT ret = next->funcs->pSaveDC( next );
30
31     if (ret)
32     {
33         EMRSAVEDC emr;
34         emr.emr.iType = EMR_SAVEDC;
35         emr.emr.nSize = sizeof(emr);
36         EMFDRV_WriteRecord( dev, &emr.emr );
37     }
38     return ret;
39 }
40
41 BOOL EMFDRV_RestoreDC( PHYSDEV dev, INT level )
42 {
43     PHYSDEV next = GET_NEXT_PHYSDEV( dev, pRestoreDC );
44     EMFDRV_PDEVICE* physDev = (EMFDRV_PDEVICE*)dev;
45     DC *dc = get_dc_ptr( dev->hdc );
46     EMRRESTOREDC emr;
47     BOOL ret;
48
49     emr.emr.iType = EMR_RESTOREDC;
50     emr.emr.nSize = sizeof(emr);
51
52     if (level < 0)
53         emr.iRelative = level;
54     else
55         emr.iRelative = level - dc->saveLevel - 1;
56     release_dc_ptr( dc );
57
58     physDev->restoring++;
59     ret = next->funcs->pRestoreDC( next, level );
60     physDev->restoring--;
61
62     if (ret) EMFDRV_WriteRecord( dev, &emr.emr );
63     return ret;
64 }
65
66 UINT EMFDRV_SetTextAlign( PHYSDEV dev, UINT align )
67 {
68     EMRSETTEXTALIGN emr;
69     emr.emr.iType = EMR_SETTEXTALIGN;
70     emr.emr.nSize = sizeof(emr);
71     emr.iMode = align;
72     return EMFDRV_WriteRecord( dev, &emr.emr ) ? align : GDI_ERROR;
73 }
74
75 BOOL EMFDRV_SetTextJustification(PHYSDEV dev, INT nBreakExtra, INT nBreakCount)
76 {
77     EMRSETTEXTJUSTIFICATION emr;
78     emr.emr.iType = EMR_SETTEXTJUSTIFICATION;
79     emr.emr.nSize = sizeof(emr);
80     emr.nBreakExtra = nBreakExtra;
81     emr.nBreakCount = nBreakCount;
82     return EMFDRV_WriteRecord(dev, &emr.emr);
83 }
84
85 INT EMFDRV_SetBkMode( PHYSDEV dev, INT mode )
86 {
87     EMRSETBKMODE emr;
88     emr.emr.iType = EMR_SETBKMODE;
89     emr.emr.nSize = sizeof(emr);
90     emr.iMode = mode;
91     return EMFDRV_WriteRecord( dev, &emr.emr ) ? mode : 0;
92 }
93
94 COLORREF EMFDRV_SetBkColor( PHYSDEV dev, COLORREF color )
95 {
96     EMRSETBKCOLOR emr;
97     EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;
98
99     if (physDev->restoring) return color;  /* don't output records during RestoreDC */
100
101     emr.emr.iType = EMR_SETBKCOLOR;
102     emr.emr.nSize = sizeof(emr);
103     emr.crColor = color;
104     return EMFDRV_WriteRecord( dev, &emr.emr ) ? color : CLR_INVALID;
105 }
106
107
108 COLORREF EMFDRV_SetTextColor( PHYSDEV dev, COLORREF color )
109 {
110     EMRSETTEXTCOLOR emr;
111     EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;
112
113     if (physDev->restoring) return color;  /* don't output records during RestoreDC */
114
115     emr.emr.iType = EMR_SETTEXTCOLOR;
116     emr.emr.nSize = sizeof(emr);
117     emr.crColor = color;
118     return EMFDRV_WriteRecord( dev, &emr.emr ) ? color : CLR_INVALID;
119 }
120
121 INT EMFDRV_SetROP2( PHYSDEV dev, INT rop )
122 {
123     EMRSETROP2 emr;
124     emr.emr.iType = EMR_SETROP2;
125     emr.emr.nSize = sizeof(emr);
126     emr.iMode = rop;
127     return EMFDRV_WriteRecord( dev, &emr.emr ) ? rop : 0;
128 }
129
130 INT EMFDRV_SetPolyFillMode( PHYSDEV dev, INT mode )
131 {
132     EMRSETPOLYFILLMODE emr;
133     emr.emr.iType = EMR_SETPOLYFILLMODE;
134     emr.emr.nSize = sizeof(emr);
135     emr.iMode = mode;
136     return EMFDRV_WriteRecord( dev, &emr.emr ) ? mode : 0;
137 }
138
139 INT EMFDRV_SetStretchBltMode( PHYSDEV dev, INT mode )
140 {
141     EMRSETSTRETCHBLTMODE emr;
142     emr.emr.iType = EMR_SETSTRETCHBLTMODE;
143     emr.emr.nSize = sizeof(emr);
144     emr.iMode = mode;
145     return EMFDRV_WriteRecord( dev, &emr.emr ) ? mode : 0;
146 }
147
148 INT EMFDRV_SetArcDirection(PHYSDEV dev, INT arcDirection)
149 {
150     EMRSETARCDIRECTION emr;
151
152     emr.emr.iType = EMR_SETARCDIRECTION;
153     emr.emr.nSize = sizeof(emr);
154     emr.iArcDirection = arcDirection;
155     return EMFDRV_WriteRecord(dev, &emr.emr) ? arcDirection : 0;
156 }
157
158 INT EMFDRV_ExcludeClipRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom )
159 {
160     PHYSDEV next = GET_NEXT_PHYSDEV( dev, pExcludeClipRect );
161     EMREXCLUDECLIPRECT emr;
162
163     emr.emr.iType      = EMR_EXCLUDECLIPRECT;
164     emr.emr.nSize      = sizeof(emr);
165     emr.rclClip.left   = left;
166     emr.rclClip.top    = top;
167     emr.rclClip.right  = right;
168     emr.rclClip.bottom = bottom;
169     if (!EMFDRV_WriteRecord( dev, &emr.emr )) return ERROR;
170     return next->funcs->pExcludeClipRect( next, left, top, right, bottom );
171 }
172
173 INT EMFDRV_IntersectClipRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom)
174 {
175     PHYSDEV next = GET_NEXT_PHYSDEV( dev, pIntersectClipRect );
176     EMRINTERSECTCLIPRECT emr;
177
178     emr.emr.iType      = EMR_INTERSECTCLIPRECT;
179     emr.emr.nSize      = sizeof(emr);
180     emr.rclClip.left   = left;
181     emr.rclClip.top    = top;
182     emr.rclClip.right  = right;
183     emr.rclClip.bottom = bottom;
184     if (!EMFDRV_WriteRecord( dev, &emr.emr )) return ERROR;
185     return next->funcs->pIntersectClipRect( next, left, top, right, bottom );
186 }
187
188 INT EMFDRV_OffsetClipRgn( PHYSDEV dev, INT x, INT y )
189 {
190     PHYSDEV next = GET_NEXT_PHYSDEV( dev, pOffsetClipRgn );
191     EMROFFSETCLIPRGN emr;
192
193     emr.emr.iType   = EMR_OFFSETCLIPRGN;
194     emr.emr.nSize   = sizeof(emr);
195     emr.ptlOffset.x = x;
196     emr.ptlOffset.y = y;
197     if (!EMFDRV_WriteRecord( dev, &emr.emr )) return ERROR;
198     return next->funcs->pOffsetClipRgn( next, x, y );
199 }
200
201 INT EMFDRV_ExtSelectClipRgn( PHYSDEV dev, HRGN hrgn, INT mode )
202 {
203     PHYSDEV next = GET_NEXT_PHYSDEV( dev, pExtSelectClipRgn );
204     EMREXTSELECTCLIPRGN *emr;
205     DWORD size, rgnsize;
206     BOOL ret;
207
208     if (!hrgn)
209     {
210         if (mode != RGN_COPY) return ERROR;
211         rgnsize = 0;
212     }
213     else rgnsize = GetRegionData( hrgn, 0, NULL );
214
215     size = rgnsize + offsetof(EMREXTSELECTCLIPRGN,RgnData);
216     emr = HeapAlloc( GetProcessHeap(), 0, size );
217     if (rgnsize) GetRegionData( hrgn, rgnsize, (RGNDATA *)&emr->RgnData );
218
219     emr->emr.iType = EMR_EXTSELECTCLIPRGN;
220     emr->emr.nSize = size;
221     emr->cbRgnData = rgnsize;
222     emr->iMode     = mode;
223
224     ret = EMFDRV_WriteRecord( dev, &emr->emr );
225     HeapFree( GetProcessHeap(), 0, emr );
226     return ret ? next->funcs->pExtSelectClipRgn( next, hrgn, mode ) : ERROR;
227 }
228
229 INT EMFDRV_SetMapMode( PHYSDEV dev, INT mode )
230 {
231     PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetMapMode );
232     EMRSETMAPMODE emr;
233     emr.emr.iType = EMR_SETMAPMODE;
234     emr.emr.nSize = sizeof(emr);
235     emr.iMode = mode;
236
237     if (!EMFDRV_WriteRecord( dev, &emr.emr )) return 0;
238     return next->funcs->pSetMapMode( next, mode );
239 }
240
241 BOOL EMFDRV_SetViewportExtEx( PHYSDEV dev, INT cx, INT cy, SIZE *size )
242 {
243     PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetViewportExtEx );
244     EMRSETVIEWPORTEXTEX emr;
245
246     emr.emr.iType = EMR_SETVIEWPORTEXTEX;
247     emr.emr.nSize = sizeof(emr);
248     emr.szlExtent.cx = cx;
249     emr.szlExtent.cy = cy;
250
251     if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
252     return next->funcs->pSetViewportExtEx( next, cx, cy, size );
253 }
254
255 BOOL EMFDRV_SetWindowExtEx( PHYSDEV dev, INT cx, INT cy, SIZE *size )
256 {
257     PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetWindowExtEx );
258     EMRSETWINDOWEXTEX emr;
259
260     emr.emr.iType = EMR_SETWINDOWEXTEX;
261     emr.emr.nSize = sizeof(emr);
262     emr.szlExtent.cx = cx;
263     emr.szlExtent.cy = cy;
264
265     if (!EMFDRV_WriteRecord( dev, &emr.emr )) return 0;
266     return next->funcs->pSetWindowExtEx( next, cx, cy, size );
267 }
268
269 BOOL EMFDRV_SetViewportOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
270 {
271     PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetViewportOrgEx );
272     EMRSETVIEWPORTORGEX emr;
273
274     emr.emr.iType = EMR_SETVIEWPORTORGEX;
275     emr.emr.nSize = sizeof(emr);
276     emr.ptlOrigin.x = x;
277     emr.ptlOrigin.y = y;
278
279     if (!EMFDRV_WriteRecord( dev, &emr.emr )) return 0;
280     return next->funcs->pSetViewportOrgEx( next, x, y, pt );
281 }
282
283 BOOL EMFDRV_SetWindowOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
284 {
285     PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetWindowOrgEx );
286     EMRSETWINDOWORGEX emr;
287
288     emr.emr.iType = EMR_SETWINDOWORGEX;
289     emr.emr.nSize = sizeof(emr);
290     emr.ptlOrigin.x = x;
291     emr.ptlOrigin.y = y;
292
293     if (!EMFDRV_WriteRecord( dev, &emr.emr )) return 0;
294     return next->funcs->pSetWindowOrgEx( next, x, y, pt );
295 }
296
297 BOOL EMFDRV_ScaleViewportExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNum, INT yDenom, SIZE *size )
298 {
299     PHYSDEV next = GET_NEXT_PHYSDEV( dev, pScaleViewportExtEx );
300     EMRSCALEVIEWPORTEXTEX emr;
301
302     emr.emr.iType = EMR_SCALEVIEWPORTEXTEX;
303     emr.emr.nSize = sizeof(emr);
304     emr.xNum      = xNum;
305     emr.xDenom    = xDenom;
306     emr.yNum      = yNum;
307     emr.yDenom    = yDenom;
308
309     if (!EMFDRV_WriteRecord( dev, &emr.emr )) return 0;
310     return next->funcs->pScaleViewportExtEx( next, xNum, xDenom, yNum, yDenom, size );
311 }
312
313 BOOL EMFDRV_ScaleWindowExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNum, INT yDenom, SIZE *size )
314 {
315     PHYSDEV next = GET_NEXT_PHYSDEV( dev, pScaleWindowExtEx );
316     EMRSCALEWINDOWEXTEX emr;
317
318     emr.emr.iType = EMR_SCALEWINDOWEXTEX;
319     emr.emr.nSize = sizeof(emr);
320     emr.xNum      = xNum;
321     emr.xDenom    = xDenom;
322     emr.yNum      = yNum;
323     emr.yDenom    = yDenom;
324
325     if (!EMFDRV_WriteRecord( dev, &emr.emr )) return 0;
326     return next->funcs->pScaleWindowExtEx( next, xNum, xDenom, yNum, yDenom, size );
327 }
328
329 DWORD EMFDRV_SetLayout( PHYSDEV dev, DWORD layout )
330 {
331     EMRSETLAYOUT emr;
332
333     emr.emr.iType = EMR_SETLAYOUT;
334     emr.emr.nSize = sizeof(emr);
335     emr.iMode = layout;
336     return EMFDRV_WriteRecord( dev, &emr.emr ) ? layout : GDI_ERROR;
337 }
338
339 BOOL EMFDRV_SetWorldTransform( PHYSDEV dev, const XFORM *xform)
340 {
341     PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetWorldTransform );
342     EMRSETWORLDTRANSFORM emr;
343
344     emr.emr.iType = EMR_SETWORLDTRANSFORM;
345     emr.emr.nSize = sizeof(emr);
346     emr.xform = *xform;
347
348     if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
349     return next->funcs->pSetWorldTransform( next, xform );
350 }
351
352 BOOL EMFDRV_ModifyWorldTransform( PHYSDEV dev, const XFORM *xform, DWORD mode)
353 {
354     PHYSDEV next = GET_NEXT_PHYSDEV( dev, pModifyWorldTransform );
355     EMRMODIFYWORLDTRANSFORM emr;
356
357     emr.emr.iType = EMR_MODIFYWORLDTRANSFORM;
358     emr.emr.nSize = sizeof(emr);
359     emr.xform = *xform;
360     emr.iMode = mode;
361
362     if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
363     return next->funcs->pModifyWorldTransform( next, xform, mode );
364 }
365
366 BOOL EMFDRV_OffsetViewportOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
367 {
368     PHYSDEV next = GET_NEXT_PHYSDEV( dev, pOffsetViewportOrgEx );
369     EMRSETVIEWPORTORGEX emr;
370     POINT prev;
371
372     GetViewportOrgEx( dev->hdc, &prev );
373
374     emr.emr.iType = EMR_SETVIEWPORTORGEX;
375     emr.emr.nSize = sizeof(emr);
376     emr.ptlOrigin.x = prev.x + x;
377     emr.ptlOrigin.y = prev.y + y;
378
379     if (!EMFDRV_WriteRecord( dev, &emr.emr )) return 0;
380     return next->funcs->pOffsetViewportOrgEx( next, x, y, pt );
381 }
382
383 BOOL EMFDRV_OffsetWindowOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
384 {
385     PHYSDEV next = GET_NEXT_PHYSDEV( dev, pOffsetWindowOrgEx );
386     EMRSETWINDOWORGEX emr;
387     POINT prev;
388
389     GetWindowOrgEx( dev->hdc, &prev );
390
391     emr.emr.iType = EMR_SETWINDOWORGEX;
392     emr.emr.nSize = sizeof(emr);
393     emr.ptlOrigin.x = prev.x + x;
394     emr.ptlOrigin.y = prev.y + y;
395
396     if (!EMFDRV_WriteRecord( dev, &emr.emr )) return 0;
397     return next->funcs->pOffsetWindowOrgEx( next, x, y, pt );
398 }
399
400 DWORD EMFDRV_SetMapperFlags( PHYSDEV dev, DWORD flags )
401 {
402     EMRSETMAPPERFLAGS emr;
403
404     emr.emr.iType = EMR_SETMAPPERFLAGS;
405     emr.emr.nSize = sizeof(emr);
406     emr.dwFlags   = flags;
407
408     return EMFDRV_WriteRecord( dev, &emr.emr ) ? flags : GDI_ERROR;
409 }
410
411 BOOL EMFDRV_AbortPath( PHYSDEV dev )
412 {
413     EMRABORTPATH emr;
414
415     emr.emr.iType = EMR_ABORTPATH;
416     emr.emr.nSize = sizeof(emr);
417
418     return EMFDRV_WriteRecord( dev, &emr.emr );
419 }
420
421 BOOL EMFDRV_BeginPath( PHYSDEV dev )
422 {
423     EMRBEGINPATH emr;
424
425     emr.emr.iType = EMR_BEGINPATH;
426     emr.emr.nSize = sizeof(emr);
427
428     return EMFDRV_WriteRecord( dev, &emr.emr );
429 }
430
431 BOOL EMFDRV_CloseFigure( PHYSDEV dev )
432 {
433     EMRCLOSEFIGURE emr;
434
435     emr.emr.iType = EMR_CLOSEFIGURE;
436     emr.emr.nSize = sizeof(emr);
437
438     return EMFDRV_WriteRecord( dev, &emr.emr );
439 }
440
441 BOOL EMFDRV_EndPath( PHYSDEV dev )
442 {
443     EMRENDPATH emr;
444
445     emr.emr.iType = EMR_ENDPATH;
446     emr.emr.nSize = sizeof(emr);
447
448     return EMFDRV_WriteRecord( dev, &emr.emr );
449 }
450
451 BOOL EMFDRV_FillPath( PHYSDEV dev )
452 {
453     EMRFILLPATH emr;
454
455     emr.emr.iType = EMR_FILLPATH;
456     emr.emr.nSize = sizeof(emr);
457     FIXME("Bounds\n");
458     emr.rclBounds.left = 0;
459     emr.rclBounds.top = 0;
460     emr.rclBounds.right = 0;
461     emr.rclBounds.bottom = 0;
462     return EMFDRV_WriteRecord( dev, &emr.emr );
463 }
464
465 BOOL EMFDRV_FlattenPath( PHYSDEV dev )
466 {
467     EMRFLATTENPATH emr;
468
469     emr.emr.iType = EMR_FLATTENPATH;
470     emr.emr.nSize = sizeof(emr);
471
472     return EMFDRV_WriteRecord( dev, &emr.emr );
473 }
474
475 BOOL EMFDRV_SelectClipPath( PHYSDEV dev, INT iMode )
476 {
477     PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSelectClipPath );
478     EMRSELECTCLIPPATH emr;
479
480     emr.emr.iType = EMR_SELECTCLIPPATH;
481     emr.emr.nSize = sizeof(emr);
482     emr.iMode = iMode;
483
484     if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
485     return next->funcs->pSelectClipPath( next, iMode );
486 }
487
488 BOOL EMFDRV_StrokeAndFillPath( PHYSDEV dev )
489 {
490     EMRSTROKEANDFILLPATH emr;
491
492     emr.emr.iType = EMR_STROKEANDFILLPATH;
493     emr.emr.nSize = sizeof(emr);
494     FIXME("Bounds\n");
495     emr.rclBounds.left = 0;
496     emr.rclBounds.top = 0;
497     emr.rclBounds.right = 0;
498     emr.rclBounds.bottom = 0;
499     return EMFDRV_WriteRecord( dev, &emr.emr );
500 }
501
502 BOOL EMFDRV_StrokePath( PHYSDEV dev )
503 {
504     EMRSTROKEPATH emr;
505
506     emr.emr.iType = EMR_STROKEPATH;
507     emr.emr.nSize = sizeof(emr);
508     FIXME("Bounds\n");
509     emr.rclBounds.left = 0;
510     emr.rclBounds.top = 0;
511     emr.rclBounds.right = 0;
512     emr.rclBounds.bottom = 0;
513     return EMFDRV_WriteRecord( dev, &emr.emr );
514 }
515
516 BOOL EMFDRV_WidenPath( PHYSDEV dev )
517 {
518     EMRWIDENPATH emr;
519
520     emr.emr.iType = EMR_WIDENPATH;
521     emr.emr.nSize = sizeof(emr);
522
523     return EMFDRV_WriteRecord( dev, &emr.emr );
524 }
525
526 INT EMFDRV_GetDeviceCaps(PHYSDEV dev, INT cap)
527 {
528     EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*) dev;
529
530     return GetDeviceCaps( physDev->ref_dc, cap );
531 }