Fix handling of relative state indices in RestoreDC.
[wine] / dlls / gdi / 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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     EMRSAVEDC emr;
29     emr.emr.iType = EMR_SAVEDC;
30     emr.emr.nSize = sizeof(emr);
31     return EMFDRV_WriteRecord( dev, &emr.emr );
32 }
33
34 BOOL EMFDRV_RestoreDC( PHYSDEV dev, INT level )
35 {
36     EMFDRV_PDEVICE* physDev = (EMFDRV_PDEVICE*)dev;
37     EMRRESTOREDC emr;
38
39     emr.emr.iType = EMR_RESTOREDC;
40     emr.emr.nSize = sizeof(emr);
41
42     if (level < 0)
43         emr.iRelative = level;
44     else
45         emr.iRelative = level - physDev->dc->saveLevel - 1;
46
47     EMFDRV_WriteRecord( dev, &emr.emr );
48
49     return TRUE;
50 }
51
52 UINT EMFDRV_SetTextAlign( PHYSDEV dev, UINT align )
53 {
54     EMRSETTEXTALIGN emr;
55     emr.emr.iType = EMR_SETTEXTALIGN;
56     emr.emr.nSize = sizeof(emr);
57     emr.iMode = align;
58     return EMFDRV_WriteRecord( dev, &emr.emr );
59 }
60
61 BOOL EMFDRV_SetTextJustification(PHYSDEV dev, INT nBreakExtra, INT nBreakCount)
62 {
63     EMRSETTEXTJUSTIFICATION emr;
64     emr.emr.iType = EMR_SETTEXTJUSTIFICATION;
65     emr.emr.nSize = sizeof(emr);
66     emr.nBreakExtra = nBreakExtra;
67     emr.nBreakCount = nBreakCount;
68     return EMFDRV_WriteRecord(dev, &emr.emr);
69 }
70
71 INT EMFDRV_SetBkMode( PHYSDEV dev, INT mode )
72 {
73     EMRSETBKMODE emr;
74     emr.emr.iType = EMR_SETBKMODE;
75     emr.emr.nSize = sizeof(emr);
76     emr.iMode = mode;
77     return EMFDRV_WriteRecord( dev, &emr.emr );
78 }
79
80 INT EMFDRV_SetROP2( PHYSDEV dev, INT rop )
81 {
82     EMRSETROP2 emr;
83     emr.emr.iType = EMR_SETROP2;
84     emr.emr.nSize = sizeof(emr);
85     emr.iMode = rop;
86     return EMFDRV_WriteRecord( dev, &emr.emr );
87 }
88
89 INT EMFDRV_SetPolyFillMode( PHYSDEV dev, INT mode )
90 {
91     EMRSETPOLYFILLMODE emr;
92     emr.emr.iType = EMR_SETPOLYFILLMODE;
93     emr.emr.nSize = sizeof(emr);
94     emr.iMode = mode;
95     return EMFDRV_WriteRecord( dev, &emr.emr );
96 }
97
98 INT EMFDRV_SetStretchBltMode( PHYSDEV dev, INT mode )
99 {
100     EMRSETSTRETCHBLTMODE emr;
101     emr.emr.iType = EMR_SETSTRETCHBLTMODE;
102     emr.emr.nSize = sizeof(emr);
103     emr.iMode = mode;
104     return EMFDRV_WriteRecord( dev, &emr.emr );
105 }
106
107 INT EMFDRV_ExcludeClipRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom )
108 {
109     EMREXCLUDECLIPRECT emr;
110     emr.emr.iType      = EMR_EXCLUDECLIPRECT;
111     emr.emr.nSize      = sizeof(emr);
112     emr.rclClip.left   = left;
113     emr.rclClip.top    = top;
114     emr.rclClip.right  = right;
115     emr.rclClip.bottom = bottom;
116     return EMFDRV_WriteRecord( dev, &emr.emr );
117 }
118
119 INT EMFDRV_IntersectClipRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom)
120 {
121     EMRINTERSECTCLIPRECT emr;
122     emr.emr.iType      = EMR_INTERSECTCLIPRECT;
123     emr.emr.nSize      = sizeof(emr);
124     emr.rclClip.left   = left;
125     emr.rclClip.top    = top;
126     emr.rclClip.right  = right;
127     emr.rclClip.bottom = bottom;
128     return EMFDRV_WriteRecord( dev, &emr.emr );
129 }
130
131 INT EMFDRV_OffsetClipRgn( PHYSDEV dev, INT x, INT y )
132 {
133     EMROFFSETCLIPRGN emr;
134     emr.emr.iType   = EMR_OFFSETCLIPRGN;
135     emr.emr.nSize   = sizeof(emr);
136     emr.ptlOffset.x = x;
137     emr.ptlOffset.y = y;
138     return EMFDRV_WriteRecord( dev, &emr.emr );
139 }
140
141 INT EMFDRV_ExtSelectClipRgn( PHYSDEV dev, HRGN hrgn, INT mode )
142 {
143     EMREXTSELECTCLIPRGN *emr;
144     DWORD size, rgnsize;
145     BOOL ret;
146
147     if (!hrgn)
148     {
149         if (mode != RGN_COPY) return ERROR;
150         rgnsize = 0;
151     }
152     else rgnsize = GetRegionData( hrgn, 0, NULL );
153
154     size = rgnsize + offsetof(EMREXTSELECTCLIPRGN,RgnData);
155     emr = HeapAlloc( GetProcessHeap(), 0, size );
156     if (rgnsize) GetRegionData( hrgn, rgnsize, (RGNDATA *)&emr->RgnData );
157
158     emr->emr.iType = EMR_EXTSELECTCLIPRGN;
159     emr->emr.nSize = size;
160     emr->cbRgnData = rgnsize;
161     emr->iMode     = mode;
162
163     ret = EMFDRV_WriteRecord( dev, &emr->emr );
164     HeapFree( GetProcessHeap(), 0, emr );
165     return ret ? SIMPLEREGION : ERROR;
166 }
167
168 DWORD EMFDRV_SetMapperFlags( PHYSDEV dev, DWORD flags )
169 {
170     EMRSETMAPPERFLAGS emr;
171
172     emr.emr.iType = EMR_SETMAPPERFLAGS;
173     emr.emr.nSize = sizeof(emr);
174     emr.dwFlags   = flags;
175
176     return EMFDRV_WriteRecord( dev, &emr.emr );
177 }
178
179 BOOL EMFDRV_AbortPath( PHYSDEV dev )
180 {
181     EMRABORTPATH emr;
182
183     emr.emr.iType = EMR_ABORTPATH;
184     emr.emr.nSize = sizeof(emr);
185
186     return EMFDRV_WriteRecord( dev, &emr.emr );
187 }
188
189 BOOL EMFDRV_BeginPath( PHYSDEV dev )
190 {
191     EMRBEGINPATH emr;
192
193     emr.emr.iType = EMR_BEGINPATH;
194     emr.emr.nSize = sizeof(emr);
195
196     return EMFDRV_WriteRecord( dev, &emr.emr );
197 }
198
199 BOOL EMFDRV_CloseFigure( PHYSDEV dev )
200 {
201     EMRCLOSEFIGURE emr;
202
203     emr.emr.iType = EMR_CLOSEFIGURE;
204     emr.emr.nSize = sizeof(emr);
205
206     return EMFDRV_WriteRecord( dev, &emr.emr );
207 }
208
209 BOOL EMFDRV_EndPath( PHYSDEV dev )
210 {
211     EMRENDPATH emr;
212
213     emr.emr.iType = EMR_ENDPATH;
214     emr.emr.nSize = sizeof(emr);
215
216     return EMFDRV_WriteRecord( dev, &emr.emr );
217 }
218
219 BOOL EMFDRV_FillPath( PHYSDEV dev )
220 {
221     EMRFILLPATH emr;
222
223     emr.emr.iType = EMR_FILLPATH;
224     emr.emr.nSize = sizeof(emr);
225     FIXME("Bounds\n");
226     emr.rclBounds.left = 0;
227     emr.rclBounds.top = 0;
228     emr.rclBounds.right = 0;
229     emr.rclBounds.bottom = 0;
230     return EMFDRV_WriteRecord( dev, &emr.emr );
231 }
232
233 BOOL EMFDRV_FlattenPath( PHYSDEV dev )
234 {
235     EMRFLATTENPATH emr;
236
237     emr.emr.iType = EMR_FLATTENPATH;
238     emr.emr.nSize = sizeof(emr);
239
240     return EMFDRV_WriteRecord( dev, &emr.emr );
241 }
242
243 BOOL EMFDRV_SelectClipPath( PHYSDEV dev, INT iMode )
244 {
245     EMRSELECTCLIPPATH emr;
246
247     emr.emr.iType = EMR_SELECTCLIPPATH;
248     emr.emr.nSize = sizeof(emr);
249     emr.iMode = iMode;
250
251     return EMFDRV_WriteRecord( dev, &emr.emr );
252 }
253
254 BOOL EMFDRV_StrokeAndFillPath( PHYSDEV dev )
255 {
256     EMRSTROKEANDFILLPATH emr;
257
258     emr.emr.iType = EMR_STROKEANDFILLPATH;
259     emr.emr.nSize = sizeof(emr);
260     FIXME("Bounds\n");
261     emr.rclBounds.left = 0;
262     emr.rclBounds.top = 0;
263     emr.rclBounds.right = 0;
264     emr.rclBounds.bottom = 0;
265     return EMFDRV_WriteRecord( dev, &emr.emr );
266 }
267
268 BOOL EMFDRV_StrokePath( PHYSDEV dev )
269 {
270     EMRSTROKEPATH emr;
271
272     emr.emr.iType = EMR_STROKEPATH;
273     emr.emr.nSize = sizeof(emr);
274     FIXME("Bounds\n");
275     emr.rclBounds.left = 0;
276     emr.rclBounds.top = 0;
277     emr.rclBounds.right = 0;
278     emr.rclBounds.bottom = 0;
279     return EMFDRV_WriteRecord( dev, &emr.emr );
280 }
281
282 BOOL EMFDRV_WidenPath( PHYSDEV dev )
283 {
284     EMRWIDENPATH emr;
285
286     emr.emr.iType = EMR_WIDENPATH;
287     emr.emr.nSize = sizeof(emr);
288
289     return EMFDRV_WriteRecord( dev, &emr.emr );
290 }
291
292 INT EMFDRV_GetDeviceCaps(PHYSDEV dev, INT cap)
293 {
294     EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*) dev;
295
296     switch(cap) {
297
298     case HORZRES:
299         return physDev->horzres;
300     case VERTRES:
301         return physDev->vertres;
302     case LOGPIXELSX:
303         return physDev->logpixelsx;
304     case LOGPIXELSY:
305         return physDev->logpixelsy;
306     case HORZSIZE:
307         return physDev->horzsize;
308     case VERTSIZE:
309         return physDev->vertsize;
310     case BITSPIXEL:
311         return physDev->bitspixel;
312     case TEXTCAPS:
313         return physDev->textcaps;
314     case RASTERCAPS:
315         return physDev->rastercaps;
316     case TECHNOLOGY:
317         return physDev->technology;
318     case PLANES:
319         return physDev->planes;
320
321     default:
322         FIXME("Unimplemented cap %d\n", cap);
323         return 0;
324
325     }
326 }