gdi32: Add null driver entry point for world transform functions, and move them to...
[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 CDECL EMFDRV_SaveDC( PHYSDEV dev )
27 {
28     EMFDRV_PDEVICE* physDev = (EMFDRV_PDEVICE*)dev;
29     INT ret = save_dc_state( physDev->hdc );
30     EMRSAVEDC emr;
31
32     if (ret)
33     {
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 CDECL EMFDRV_RestoreDC( PHYSDEV dev, INT level )
42 {
43     EMFDRV_PDEVICE* physDev = (EMFDRV_PDEVICE*)dev;
44     DC *dc = get_dc_ptr( physDev->hdc );
45     EMRRESTOREDC emr;
46     BOOL ret;
47
48     emr.emr.iType = EMR_RESTOREDC;
49     emr.emr.nSize = sizeof(emr);
50
51     if (level < 0)
52         emr.iRelative = level;
53     else
54         emr.iRelative = level - dc->saveLevel - 1;
55     release_dc_ptr( dc );
56
57     physDev->restoring++;
58     ret = restore_dc_state( physDev->hdc, level );
59     physDev->restoring--;
60
61     if (ret) EMFDRV_WriteRecord( dev, &emr.emr );
62     return ret;
63 }
64
65 UINT CDECL EMFDRV_SetTextAlign( PHYSDEV dev, UINT align )
66 {
67     EMRSETTEXTALIGN emr;
68     emr.emr.iType = EMR_SETTEXTALIGN;
69     emr.emr.nSize = sizeof(emr);
70     emr.iMode = align;
71     return EMFDRV_WriteRecord( dev, &emr.emr ) ? align : GDI_ERROR;
72 }
73
74 BOOL CDECL EMFDRV_SetTextJustification(PHYSDEV dev, INT nBreakExtra, INT nBreakCount)
75 {
76     EMRSETTEXTJUSTIFICATION emr;
77     emr.emr.iType = EMR_SETTEXTJUSTIFICATION;
78     emr.emr.nSize = sizeof(emr);
79     emr.nBreakExtra = nBreakExtra;
80     emr.nBreakCount = nBreakCount;
81     return EMFDRV_WriteRecord(dev, &emr.emr);
82 }
83
84 INT CDECL EMFDRV_SetBkMode( PHYSDEV dev, INT mode )
85 {
86     EMRSETBKMODE emr;
87     emr.emr.iType = EMR_SETBKMODE;
88     emr.emr.nSize = sizeof(emr);
89     emr.iMode = mode;
90     return EMFDRV_WriteRecord( dev, &emr.emr ) ? mode : 0;
91 }
92
93 COLORREF CDECL EMFDRV_SetBkColor( PHYSDEV dev, COLORREF color )
94 {
95     EMRSETBKCOLOR emr;
96     EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;
97
98     if (physDev->restoring) return color;  /* don't output records during RestoreDC */
99
100     emr.emr.iType = EMR_SETBKCOLOR;
101     emr.emr.nSize = sizeof(emr);
102     emr.crColor = color;
103     return EMFDRV_WriteRecord( dev, &emr.emr ) ? color : CLR_INVALID;
104 }
105
106
107 COLORREF CDECL EMFDRV_SetTextColor( PHYSDEV dev, COLORREF color )
108 {
109     EMRSETTEXTCOLOR emr;
110     EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;
111
112     if (physDev->restoring) return color;  /* don't output records during RestoreDC */
113
114     emr.emr.iType = EMR_SETTEXTCOLOR;
115     emr.emr.nSize = sizeof(emr);
116     emr.crColor = color;
117     return EMFDRV_WriteRecord( dev, &emr.emr ) ? color : CLR_INVALID;
118 }
119
120 INT CDECL EMFDRV_SetROP2( PHYSDEV dev, INT rop )
121 {
122     EMRSETROP2 emr;
123     emr.emr.iType = EMR_SETROP2;
124     emr.emr.nSize = sizeof(emr);
125     emr.iMode = rop;
126     return EMFDRV_WriteRecord( dev, &emr.emr ) ? rop : 0;
127 }
128
129 INT CDECL EMFDRV_SetPolyFillMode( PHYSDEV dev, INT mode )
130 {
131     EMRSETPOLYFILLMODE emr;
132     emr.emr.iType = EMR_SETPOLYFILLMODE;
133     emr.emr.nSize = sizeof(emr);
134     emr.iMode = mode;
135     return EMFDRV_WriteRecord( dev, &emr.emr ) ? mode : 0;
136 }
137
138 INT CDECL EMFDRV_SetStretchBltMode( PHYSDEV dev, INT mode )
139 {
140     EMRSETSTRETCHBLTMODE emr;
141     emr.emr.iType = EMR_SETSTRETCHBLTMODE;
142     emr.emr.nSize = sizeof(emr);
143     emr.iMode = mode;
144     return EMFDRV_WriteRecord( dev, &emr.emr ) ? mode : 0;
145 }
146
147 INT CDECL EMFDRV_SetArcDirection(PHYSDEV dev, INT arcDirection)
148 {
149     EMRSETARCDIRECTION emr;
150
151     emr.emr.iType = EMR_SETARCDIRECTION;
152     emr.emr.nSize = sizeof(emr);
153     emr.iArcDirection = arcDirection;
154     return EMFDRV_WriteRecord(dev, &emr.emr) ? arcDirection : 0;
155 }
156
157 INT CDECL EMFDRV_ExcludeClipRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom )
158 {
159     EMREXCLUDECLIPRECT emr;
160     emr.emr.iType      = EMR_EXCLUDECLIPRECT;
161     emr.emr.nSize      = sizeof(emr);
162     emr.rclClip.left   = left;
163     emr.rclClip.top    = top;
164     emr.rclClip.right  = right;
165     emr.rclClip.bottom = bottom;
166     return EMFDRV_WriteRecord( dev, &emr.emr );
167 }
168
169 INT CDECL EMFDRV_IntersectClipRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom)
170 {
171     EMRINTERSECTCLIPRECT emr;
172     emr.emr.iType      = EMR_INTERSECTCLIPRECT;
173     emr.emr.nSize      = sizeof(emr);
174     emr.rclClip.left   = left;
175     emr.rclClip.top    = top;
176     emr.rclClip.right  = right;
177     emr.rclClip.bottom = bottom;
178     return EMFDRV_WriteRecord( dev, &emr.emr );
179 }
180
181 INT CDECL EMFDRV_OffsetClipRgn( PHYSDEV dev, INT x, INT y )
182 {
183     EMROFFSETCLIPRGN emr;
184     emr.emr.iType   = EMR_OFFSETCLIPRGN;
185     emr.emr.nSize   = sizeof(emr);
186     emr.ptlOffset.x = x;
187     emr.ptlOffset.y = y;
188     return EMFDRV_WriteRecord( dev, &emr.emr );
189 }
190
191 INT CDECL EMFDRV_ExtSelectClipRgn( PHYSDEV dev, HRGN hrgn, INT mode )
192 {
193     EMREXTSELECTCLIPRGN *emr;
194     DWORD size, rgnsize;
195     BOOL ret;
196
197     if (!hrgn)
198     {
199         if (mode != RGN_COPY) return ERROR;
200         rgnsize = 0;
201     }
202     else rgnsize = GetRegionData( hrgn, 0, NULL );
203
204     size = rgnsize + offsetof(EMREXTSELECTCLIPRGN,RgnData);
205     emr = HeapAlloc( GetProcessHeap(), 0, size );
206     if (rgnsize) GetRegionData( hrgn, rgnsize, (RGNDATA *)&emr->RgnData );
207
208     emr->emr.iType = EMR_EXTSELECTCLIPRGN;
209     emr->emr.nSize = size;
210     emr->cbRgnData = rgnsize;
211     emr->iMode     = mode;
212
213     ret = EMFDRV_WriteRecord( dev, &emr->emr );
214     HeapFree( GetProcessHeap(), 0, emr );
215     return ret ? SIMPLEREGION : ERROR;
216 }
217
218 INT CDECL EMFDRV_SetMapMode( PHYSDEV dev, INT mode )
219 {
220     PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetMapMode );
221     EMRSETMAPMODE emr;
222     emr.emr.iType = EMR_SETMAPMODE;
223     emr.emr.nSize = sizeof(emr);
224     emr.iMode = mode;
225
226     if (!EMFDRV_WriteRecord( dev, &emr.emr )) return 0;
227     return next->funcs->pSetMapMode( next, mode );
228 }
229
230 BOOL CDECL EMFDRV_SetViewportExtEx( PHYSDEV dev, INT cx, INT cy, SIZE *size )
231 {
232     PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetViewportExtEx );
233     EMRSETVIEWPORTEXTEX emr;
234
235     emr.emr.iType = EMR_SETVIEWPORTEXTEX;
236     emr.emr.nSize = sizeof(emr);
237     emr.szlExtent.cx = cx;
238     emr.szlExtent.cy = cy;
239
240     if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
241     return next->funcs->pSetViewportExtEx( next, cx, cy, size );
242 }
243
244 BOOL CDECL EMFDRV_SetWindowExtEx( PHYSDEV dev, INT cx, INT cy, SIZE *size )
245 {
246     PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetWindowExtEx );
247     EMRSETWINDOWEXTEX emr;
248
249     emr.emr.iType = EMR_SETWINDOWEXTEX;
250     emr.emr.nSize = sizeof(emr);
251     emr.szlExtent.cx = cx;
252     emr.szlExtent.cy = cy;
253
254     if (!EMFDRV_WriteRecord( dev, &emr.emr )) return 0;
255     return next->funcs->pSetWindowExtEx( next, cx, cy, size );
256 }
257
258 BOOL CDECL EMFDRV_SetViewportOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
259 {
260     PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetViewportOrgEx );
261     EMRSETVIEWPORTORGEX emr;
262
263     emr.emr.iType = EMR_SETVIEWPORTORGEX;
264     emr.emr.nSize = sizeof(emr);
265     emr.ptlOrigin.x = x;
266     emr.ptlOrigin.y = y;
267
268     if (!EMFDRV_WriteRecord( dev, &emr.emr )) return 0;
269     return next->funcs->pSetViewportOrgEx( next, x, y, pt );
270 }
271
272 BOOL CDECL EMFDRV_SetWindowOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
273 {
274     PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetWindowOrgEx );
275     EMRSETWINDOWORGEX emr;
276
277     emr.emr.iType = EMR_SETWINDOWORGEX;
278     emr.emr.nSize = sizeof(emr);
279     emr.ptlOrigin.x = x;
280     emr.ptlOrigin.y = y;
281
282     if (!EMFDRV_WriteRecord( dev, &emr.emr )) return 0;
283     return next->funcs->pSetWindowOrgEx( next, x, y, pt );
284 }
285
286 BOOL CDECL EMFDRV_ScaleViewportExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNum, INT yDenom, SIZE *size )
287 {
288     PHYSDEV next = GET_NEXT_PHYSDEV( dev, pScaleViewportExtEx );
289     EMRSCALEVIEWPORTEXTEX emr;
290
291     emr.emr.iType = EMR_SCALEVIEWPORTEXTEX;
292     emr.emr.nSize = sizeof(emr);
293     emr.xNum      = xNum;
294     emr.xDenom    = xDenom;
295     emr.yNum      = yNum;
296     emr.yDenom    = yDenom;
297
298     if (!EMFDRV_WriteRecord( dev, &emr.emr )) return 0;
299     return next->funcs->pScaleViewportExtEx( next, xNum, xDenom, yNum, yDenom, size );
300 }
301
302 BOOL CDECL EMFDRV_ScaleWindowExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNum, INT yDenom, SIZE *size )
303 {
304     PHYSDEV next = GET_NEXT_PHYSDEV( dev, pScaleWindowExtEx );
305     EMRSCALEWINDOWEXTEX emr;
306
307     emr.emr.iType = EMR_SCALEWINDOWEXTEX;
308     emr.emr.nSize = sizeof(emr);
309     emr.xNum      = xNum;
310     emr.xDenom    = xDenom;
311     emr.yNum      = yNum;
312     emr.yDenom    = yDenom;
313
314     if (!EMFDRV_WriteRecord( dev, &emr.emr )) return 0;
315     return next->funcs->pScaleWindowExtEx( next, xNum, xDenom, yNum, yDenom, size );
316 }
317
318 DWORD CDECL EMFDRV_SetLayout( PHYSDEV dev, DWORD layout )
319 {
320     EMRSETLAYOUT emr;
321
322     emr.emr.iType = EMR_SETLAYOUT;
323     emr.emr.nSize = sizeof(emr);
324     emr.iMode = layout;
325     return EMFDRV_WriteRecord( dev, &emr.emr ) ? layout : GDI_ERROR;
326 }
327
328 BOOL CDECL EMFDRV_SetWorldTransform( PHYSDEV dev, const XFORM *xform)
329 {
330     PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetWorldTransform );
331     EMRSETWORLDTRANSFORM emr;
332
333     emr.emr.iType = EMR_SETWORLDTRANSFORM;
334     emr.emr.nSize = sizeof(emr);
335     emr.xform = *xform;
336
337     if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
338     return next->funcs->pSetWorldTransform( next, xform );
339 }
340
341 BOOL CDECL EMFDRV_ModifyWorldTransform( PHYSDEV dev, const XFORM *xform, DWORD mode)
342 {
343     PHYSDEV next = GET_NEXT_PHYSDEV( dev, pModifyWorldTransform );
344     EMRMODIFYWORLDTRANSFORM emr;
345
346     emr.emr.iType = EMR_MODIFYWORLDTRANSFORM;
347     emr.emr.nSize = sizeof(emr);
348     emr.xform = *xform;
349     emr.iMode = mode;
350
351     if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
352     return next->funcs->pModifyWorldTransform( next, xform, mode );
353 }
354
355 BOOL CDECL EMFDRV_OffsetViewportOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
356 {
357     PHYSDEV next = GET_NEXT_PHYSDEV( dev, pOffsetViewportOrgEx );
358     EMRSETVIEWPORTORGEX emr;
359     EMFDRV_PDEVICE* physDev = (EMFDRV_PDEVICE*)dev;
360
361     GetViewportOrgEx(physDev->hdc, pt);
362
363     emr.emr.iType = EMR_SETVIEWPORTORGEX;
364     emr.emr.nSize = sizeof(emr);
365     emr.ptlOrigin.x = pt->x + x;
366     emr.ptlOrigin.y = pt->y + y;
367
368     if (!EMFDRV_WriteRecord( dev, &emr.emr )) return 0;
369     return next->funcs->pOffsetViewportOrgEx( next, x, y, pt );
370 }
371
372 BOOL CDECL EMFDRV_OffsetWindowOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
373 {
374     PHYSDEV next = GET_NEXT_PHYSDEV( dev, pOffsetWindowOrgEx );
375     EMRSETWINDOWORGEX emr;
376     EMFDRV_PDEVICE* physDev = (EMFDRV_PDEVICE*)dev;
377
378     GetWindowOrgEx(physDev->hdc, pt);
379
380     emr.emr.iType = EMR_SETWINDOWORGEX;
381     emr.emr.nSize = sizeof(emr);
382     emr.ptlOrigin.x = pt->x + x;
383     emr.ptlOrigin.y = pt->y + y;
384
385     if (!EMFDRV_WriteRecord( dev, &emr.emr )) return 0;
386     return next->funcs->pOffsetWindowOrgEx( next, x, y, pt );
387 }
388
389 DWORD CDECL EMFDRV_SetMapperFlags( PHYSDEV dev, DWORD flags )
390 {
391     EMRSETMAPPERFLAGS emr;
392
393     emr.emr.iType = EMR_SETMAPPERFLAGS;
394     emr.emr.nSize = sizeof(emr);
395     emr.dwFlags   = flags;
396
397     return EMFDRV_WriteRecord( dev, &emr.emr ) ? flags : GDI_ERROR;
398 }
399
400 BOOL CDECL EMFDRV_AbortPath( PHYSDEV dev )
401 {
402     EMRABORTPATH emr;
403
404     emr.emr.iType = EMR_ABORTPATH;
405     emr.emr.nSize = sizeof(emr);
406
407     return EMFDRV_WriteRecord( dev, &emr.emr );
408 }
409
410 BOOL CDECL EMFDRV_BeginPath( PHYSDEV dev )
411 {
412     EMRBEGINPATH emr;
413
414     emr.emr.iType = EMR_BEGINPATH;
415     emr.emr.nSize = sizeof(emr);
416
417     return EMFDRV_WriteRecord( dev, &emr.emr );
418 }
419
420 BOOL CDECL EMFDRV_CloseFigure( PHYSDEV dev )
421 {
422     EMRCLOSEFIGURE emr;
423
424     emr.emr.iType = EMR_CLOSEFIGURE;
425     emr.emr.nSize = sizeof(emr);
426
427     return EMFDRV_WriteRecord( dev, &emr.emr );
428 }
429
430 BOOL CDECL EMFDRV_EndPath( PHYSDEV dev )
431 {
432     EMRENDPATH emr;
433
434     emr.emr.iType = EMR_ENDPATH;
435     emr.emr.nSize = sizeof(emr);
436
437     return EMFDRV_WriteRecord( dev, &emr.emr );
438 }
439
440 BOOL CDECL EMFDRV_FillPath( PHYSDEV dev )
441 {
442     EMRFILLPATH emr;
443
444     emr.emr.iType = EMR_FILLPATH;
445     emr.emr.nSize = sizeof(emr);
446     FIXME("Bounds\n");
447     emr.rclBounds.left = 0;
448     emr.rclBounds.top = 0;
449     emr.rclBounds.right = 0;
450     emr.rclBounds.bottom = 0;
451     return EMFDRV_WriteRecord( dev, &emr.emr );
452 }
453
454 BOOL CDECL EMFDRV_FlattenPath( PHYSDEV dev )
455 {
456     EMRFLATTENPATH emr;
457
458     emr.emr.iType = EMR_FLATTENPATH;
459     emr.emr.nSize = sizeof(emr);
460
461     return EMFDRV_WriteRecord( dev, &emr.emr );
462 }
463
464 BOOL CDECL EMFDRV_SelectClipPath( PHYSDEV dev, INT iMode )
465 {
466     EMRSELECTCLIPPATH emr;
467
468     emr.emr.iType = EMR_SELECTCLIPPATH;
469     emr.emr.nSize = sizeof(emr);
470     emr.iMode = iMode;
471
472     return EMFDRV_WriteRecord( dev, &emr.emr );
473 }
474
475 BOOL CDECL EMFDRV_StrokeAndFillPath( PHYSDEV dev )
476 {
477     EMRSTROKEANDFILLPATH emr;
478
479     emr.emr.iType = EMR_STROKEANDFILLPATH;
480     emr.emr.nSize = sizeof(emr);
481     FIXME("Bounds\n");
482     emr.rclBounds.left = 0;
483     emr.rclBounds.top = 0;
484     emr.rclBounds.right = 0;
485     emr.rclBounds.bottom = 0;
486     return EMFDRV_WriteRecord( dev, &emr.emr );
487 }
488
489 BOOL CDECL EMFDRV_StrokePath( PHYSDEV dev )
490 {
491     EMRSTROKEPATH emr;
492
493     emr.emr.iType = EMR_STROKEPATH;
494     emr.emr.nSize = sizeof(emr);
495     FIXME("Bounds\n");
496     emr.rclBounds.left = 0;
497     emr.rclBounds.top = 0;
498     emr.rclBounds.right = 0;
499     emr.rclBounds.bottom = 0;
500     return EMFDRV_WriteRecord( dev, &emr.emr );
501 }
502
503 BOOL CDECL EMFDRV_WidenPath( PHYSDEV dev )
504 {
505     EMRWIDENPATH emr;
506
507     emr.emr.iType = EMR_WIDENPATH;
508     emr.emr.nSize = sizeof(emr);
509
510     return EMFDRV_WriteRecord( dev, &emr.emr );
511 }
512
513 INT CDECL EMFDRV_GetDeviceCaps(PHYSDEV dev, INT cap)
514 {
515     EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*) dev;
516
517     switch(cap) {
518
519     case HORZRES:
520         return physDev->horzres;
521     case VERTRES:
522         return physDev->vertres;
523     case LOGPIXELSX:
524         return physDev->logpixelsx;
525     case LOGPIXELSY:
526         return physDev->logpixelsy;
527     case HORZSIZE:
528         return physDev->horzsize;
529     case VERTSIZE:
530         return physDev->vertsize;
531     case BITSPIXEL:
532         return physDev->bitspixel;
533     case TEXTCAPS:
534         return physDev->textcaps;
535     case RASTERCAPS:
536         return physDev->rastercaps;
537     case TECHNOLOGY:
538         return physDev->technology;
539     case PLANES:
540         return physDev->planes;
541     case NUMCOLORS:
542         return physDev->numcolors;
543     default:
544         FIXME("Unimplemented cap %d\n", cap);
545         return 0;
546     }
547 }