gdi32: Simplify computation of the DIB header size for internal BITMAPINFO structures.
[wine/multimedia.git] / dlls / gdi32 / enhmfdrv / dc.c
blob86ad961fe61c56966dc47d3a92c16d30ea847850
1 /*
2 * Enhanced MetaFile driver dc value functions
4 * Copyright 1999 Huw D M Davies
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.
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.
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
21 #include "enhmfdrv/enhmetafiledrv.h"
22 #include "wine/debug.h"
24 WINE_DEFAULT_DEBUG_CHANNEL(enhmetafile);
26 INT EMFDRV_SaveDC( PHYSDEV dev )
28 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSaveDC );
29 INT ret = next->funcs->pSaveDC( next );
31 if (ret)
33 EMRSAVEDC emr;
34 emr.emr.iType = EMR_SAVEDC;
35 emr.emr.nSize = sizeof(emr);
36 EMFDRV_WriteRecord( dev, &emr.emr );
38 return ret;
41 BOOL EMFDRV_RestoreDC( PHYSDEV dev, INT level )
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;
49 emr.emr.iType = EMR_RESTOREDC;
50 emr.emr.nSize = sizeof(emr);
52 if (level < 0)
53 emr.iRelative = level;
54 else
55 emr.iRelative = level - dc->saveLevel - 1;
56 release_dc_ptr( dc );
58 physDev->restoring++;
59 ret = next->funcs->pRestoreDC( next, level );
60 physDev->restoring--;
62 if (ret) EMFDRV_WriteRecord( dev, &emr.emr );
63 return ret;
66 UINT EMFDRV_SetTextAlign( PHYSDEV dev, UINT align )
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;
75 BOOL EMFDRV_SetTextJustification(PHYSDEV dev, INT nBreakExtra, INT nBreakCount)
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);
85 INT EMFDRV_SetBkMode( PHYSDEV dev, INT mode )
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;
94 COLORREF EMFDRV_SetBkColor( PHYSDEV dev, COLORREF color )
96 EMRSETBKCOLOR emr;
97 EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;
99 if (physDev->restoring) return color; /* don't output records during RestoreDC */
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;
108 COLORREF EMFDRV_SetTextColor( PHYSDEV dev, COLORREF color )
110 EMRSETTEXTCOLOR emr;
111 EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;
113 if (physDev->restoring) return color; /* don't output records during RestoreDC */
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;
121 INT EMFDRV_SetROP2( PHYSDEV dev, INT rop )
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;
130 INT EMFDRV_SetPolyFillMode( PHYSDEV dev, INT mode )
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;
139 INT EMFDRV_SetStretchBltMode( PHYSDEV dev, INT mode )
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;
148 INT EMFDRV_SetArcDirection(PHYSDEV dev, INT arcDirection)
150 EMRSETARCDIRECTION emr;
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;
158 INT EMFDRV_ExcludeClipRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom )
160 EMREXCLUDECLIPRECT emr;
161 emr.emr.iType = EMR_EXCLUDECLIPRECT;
162 emr.emr.nSize = sizeof(emr);
163 emr.rclClip.left = left;
164 emr.rclClip.top = top;
165 emr.rclClip.right = right;
166 emr.rclClip.bottom = bottom;
167 return EMFDRV_WriteRecord( dev, &emr.emr );
170 INT EMFDRV_IntersectClipRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom)
172 EMRINTERSECTCLIPRECT emr;
173 emr.emr.iType = EMR_INTERSECTCLIPRECT;
174 emr.emr.nSize = sizeof(emr);
175 emr.rclClip.left = left;
176 emr.rclClip.top = top;
177 emr.rclClip.right = right;
178 emr.rclClip.bottom = bottom;
179 return EMFDRV_WriteRecord( dev, &emr.emr );
182 INT EMFDRV_OffsetClipRgn( PHYSDEV dev, INT x, INT y )
184 EMROFFSETCLIPRGN emr;
185 emr.emr.iType = EMR_OFFSETCLIPRGN;
186 emr.emr.nSize = sizeof(emr);
187 emr.ptlOffset.x = x;
188 emr.ptlOffset.y = y;
189 return EMFDRV_WriteRecord( dev, &emr.emr );
192 INT EMFDRV_ExtSelectClipRgn( PHYSDEV dev, HRGN hrgn, INT mode )
194 EMREXTSELECTCLIPRGN *emr;
195 DWORD size, rgnsize;
196 BOOL ret;
198 if (!hrgn)
200 if (mode != RGN_COPY) return ERROR;
201 rgnsize = 0;
203 else rgnsize = GetRegionData( hrgn, 0, NULL );
205 size = rgnsize + offsetof(EMREXTSELECTCLIPRGN,RgnData);
206 emr = HeapAlloc( GetProcessHeap(), 0, size );
207 if (rgnsize) GetRegionData( hrgn, rgnsize, (RGNDATA *)&emr->RgnData );
209 emr->emr.iType = EMR_EXTSELECTCLIPRGN;
210 emr->emr.nSize = size;
211 emr->cbRgnData = rgnsize;
212 emr->iMode = mode;
214 ret = EMFDRV_WriteRecord( dev, &emr->emr );
215 HeapFree( GetProcessHeap(), 0, emr );
216 return ret ? SIMPLEREGION : ERROR;
219 INT EMFDRV_SetMapMode( PHYSDEV dev, INT mode )
221 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetMapMode );
222 EMRSETMAPMODE emr;
223 emr.emr.iType = EMR_SETMAPMODE;
224 emr.emr.nSize = sizeof(emr);
225 emr.iMode = mode;
227 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return 0;
228 return next->funcs->pSetMapMode( next, mode );
231 BOOL EMFDRV_SetViewportExtEx( PHYSDEV dev, INT cx, INT cy, SIZE *size )
233 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetViewportExtEx );
234 EMRSETVIEWPORTEXTEX emr;
236 emr.emr.iType = EMR_SETVIEWPORTEXTEX;
237 emr.emr.nSize = sizeof(emr);
238 emr.szlExtent.cx = cx;
239 emr.szlExtent.cy = cy;
241 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
242 return next->funcs->pSetViewportExtEx( next, cx, cy, size );
245 BOOL EMFDRV_SetWindowExtEx( PHYSDEV dev, INT cx, INT cy, SIZE *size )
247 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetWindowExtEx );
248 EMRSETWINDOWEXTEX emr;
250 emr.emr.iType = EMR_SETWINDOWEXTEX;
251 emr.emr.nSize = sizeof(emr);
252 emr.szlExtent.cx = cx;
253 emr.szlExtent.cy = cy;
255 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return 0;
256 return next->funcs->pSetWindowExtEx( next, cx, cy, size );
259 BOOL EMFDRV_SetViewportOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
261 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetViewportOrgEx );
262 EMRSETVIEWPORTORGEX emr;
264 emr.emr.iType = EMR_SETVIEWPORTORGEX;
265 emr.emr.nSize = sizeof(emr);
266 emr.ptlOrigin.x = x;
267 emr.ptlOrigin.y = y;
269 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return 0;
270 return next->funcs->pSetViewportOrgEx( next, x, y, pt );
273 BOOL EMFDRV_SetWindowOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
275 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetWindowOrgEx );
276 EMRSETWINDOWORGEX emr;
278 emr.emr.iType = EMR_SETWINDOWORGEX;
279 emr.emr.nSize = sizeof(emr);
280 emr.ptlOrigin.x = x;
281 emr.ptlOrigin.y = y;
283 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return 0;
284 return next->funcs->pSetWindowOrgEx( next, x, y, pt );
287 BOOL EMFDRV_ScaleViewportExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNum, INT yDenom, SIZE *size )
289 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pScaleViewportExtEx );
290 EMRSCALEVIEWPORTEXTEX emr;
292 emr.emr.iType = EMR_SCALEVIEWPORTEXTEX;
293 emr.emr.nSize = sizeof(emr);
294 emr.xNum = xNum;
295 emr.xDenom = xDenom;
296 emr.yNum = yNum;
297 emr.yDenom = yDenom;
299 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return 0;
300 return next->funcs->pScaleViewportExtEx( next, xNum, xDenom, yNum, yDenom, size );
303 BOOL EMFDRV_ScaleWindowExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNum, INT yDenom, SIZE *size )
305 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pScaleWindowExtEx );
306 EMRSCALEWINDOWEXTEX emr;
308 emr.emr.iType = EMR_SCALEWINDOWEXTEX;
309 emr.emr.nSize = sizeof(emr);
310 emr.xNum = xNum;
311 emr.xDenom = xDenom;
312 emr.yNum = yNum;
313 emr.yDenom = yDenom;
315 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return 0;
316 return next->funcs->pScaleWindowExtEx( next, xNum, xDenom, yNum, yDenom, size );
319 DWORD EMFDRV_SetLayout( PHYSDEV dev, DWORD layout )
321 EMRSETLAYOUT emr;
323 emr.emr.iType = EMR_SETLAYOUT;
324 emr.emr.nSize = sizeof(emr);
325 emr.iMode = layout;
326 return EMFDRV_WriteRecord( dev, &emr.emr ) ? layout : GDI_ERROR;
329 BOOL EMFDRV_SetWorldTransform( PHYSDEV dev, const XFORM *xform)
331 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetWorldTransform );
332 EMRSETWORLDTRANSFORM emr;
334 emr.emr.iType = EMR_SETWORLDTRANSFORM;
335 emr.emr.nSize = sizeof(emr);
336 emr.xform = *xform;
338 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
339 return next->funcs->pSetWorldTransform( next, xform );
342 BOOL EMFDRV_ModifyWorldTransform( PHYSDEV dev, const XFORM *xform, DWORD mode)
344 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pModifyWorldTransform );
345 EMRMODIFYWORLDTRANSFORM emr;
347 emr.emr.iType = EMR_MODIFYWORLDTRANSFORM;
348 emr.emr.nSize = sizeof(emr);
349 emr.xform = *xform;
350 emr.iMode = mode;
352 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
353 return next->funcs->pModifyWorldTransform( next, xform, mode );
356 BOOL EMFDRV_OffsetViewportOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
358 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pOffsetViewportOrgEx );
359 EMRSETVIEWPORTORGEX emr;
360 POINT prev;
362 GetViewportOrgEx( dev->hdc, &prev );
364 emr.emr.iType = EMR_SETVIEWPORTORGEX;
365 emr.emr.nSize = sizeof(emr);
366 emr.ptlOrigin.x = prev.x + x;
367 emr.ptlOrigin.y = prev.y + y;
369 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return 0;
370 return next->funcs->pOffsetViewportOrgEx( next, x, y, pt );
373 BOOL EMFDRV_OffsetWindowOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
375 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pOffsetWindowOrgEx );
376 EMRSETWINDOWORGEX emr;
377 POINT prev;
379 GetWindowOrgEx( dev->hdc, &prev );
381 emr.emr.iType = EMR_SETWINDOWORGEX;
382 emr.emr.nSize = sizeof(emr);
383 emr.ptlOrigin.x = prev.x + x;
384 emr.ptlOrigin.y = prev.y + y;
386 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return 0;
387 return next->funcs->pOffsetWindowOrgEx( next, x, y, pt );
390 DWORD EMFDRV_SetMapperFlags( PHYSDEV dev, DWORD flags )
392 EMRSETMAPPERFLAGS emr;
394 emr.emr.iType = EMR_SETMAPPERFLAGS;
395 emr.emr.nSize = sizeof(emr);
396 emr.dwFlags = flags;
398 return EMFDRV_WriteRecord( dev, &emr.emr ) ? flags : GDI_ERROR;
401 BOOL EMFDRV_AbortPath( PHYSDEV dev )
403 EMRABORTPATH emr;
405 emr.emr.iType = EMR_ABORTPATH;
406 emr.emr.nSize = sizeof(emr);
408 return EMFDRV_WriteRecord( dev, &emr.emr );
411 BOOL EMFDRV_BeginPath( PHYSDEV dev )
413 EMRBEGINPATH emr;
415 emr.emr.iType = EMR_BEGINPATH;
416 emr.emr.nSize = sizeof(emr);
418 return EMFDRV_WriteRecord( dev, &emr.emr );
421 BOOL EMFDRV_CloseFigure( PHYSDEV dev )
423 EMRCLOSEFIGURE emr;
425 emr.emr.iType = EMR_CLOSEFIGURE;
426 emr.emr.nSize = sizeof(emr);
428 return EMFDRV_WriteRecord( dev, &emr.emr );
431 BOOL EMFDRV_EndPath( PHYSDEV dev )
433 EMRENDPATH emr;
435 emr.emr.iType = EMR_ENDPATH;
436 emr.emr.nSize = sizeof(emr);
438 return EMFDRV_WriteRecord( dev, &emr.emr );
441 BOOL EMFDRV_FillPath( PHYSDEV dev )
443 EMRFILLPATH emr;
445 emr.emr.iType = EMR_FILLPATH;
446 emr.emr.nSize = sizeof(emr);
447 FIXME("Bounds\n");
448 emr.rclBounds.left = 0;
449 emr.rclBounds.top = 0;
450 emr.rclBounds.right = 0;
451 emr.rclBounds.bottom = 0;
452 return EMFDRV_WriteRecord( dev, &emr.emr );
455 BOOL EMFDRV_FlattenPath( PHYSDEV dev )
457 EMRFLATTENPATH emr;
459 emr.emr.iType = EMR_FLATTENPATH;
460 emr.emr.nSize = sizeof(emr);
462 return EMFDRV_WriteRecord( dev, &emr.emr );
465 BOOL EMFDRV_SelectClipPath( PHYSDEV dev, INT iMode )
467 EMRSELECTCLIPPATH emr;
469 emr.emr.iType = EMR_SELECTCLIPPATH;
470 emr.emr.nSize = sizeof(emr);
471 emr.iMode = iMode;
473 return EMFDRV_WriteRecord( dev, &emr.emr );
476 BOOL EMFDRV_StrokeAndFillPath( PHYSDEV dev )
478 EMRSTROKEANDFILLPATH emr;
480 emr.emr.iType = EMR_STROKEANDFILLPATH;
481 emr.emr.nSize = sizeof(emr);
482 FIXME("Bounds\n");
483 emr.rclBounds.left = 0;
484 emr.rclBounds.top = 0;
485 emr.rclBounds.right = 0;
486 emr.rclBounds.bottom = 0;
487 return EMFDRV_WriteRecord( dev, &emr.emr );
490 BOOL EMFDRV_StrokePath( PHYSDEV dev )
492 EMRSTROKEPATH emr;
494 emr.emr.iType = EMR_STROKEPATH;
495 emr.emr.nSize = sizeof(emr);
496 FIXME("Bounds\n");
497 emr.rclBounds.left = 0;
498 emr.rclBounds.top = 0;
499 emr.rclBounds.right = 0;
500 emr.rclBounds.bottom = 0;
501 return EMFDRV_WriteRecord( dev, &emr.emr );
504 BOOL EMFDRV_WidenPath( PHYSDEV dev )
506 EMRWIDENPATH emr;
508 emr.emr.iType = EMR_WIDENPATH;
509 emr.emr.nSize = sizeof(emr);
511 return EMFDRV_WriteRecord( dev, &emr.emr );
514 INT EMFDRV_GetDeviceCaps(PHYSDEV dev, INT cap)
516 EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*) dev;
518 switch(cap) {
520 case HORZRES:
521 return physDev->horzres;
522 case VERTRES:
523 return physDev->vertres;
524 case LOGPIXELSX:
525 return physDev->logpixelsx;
526 case LOGPIXELSY:
527 return physDev->logpixelsy;
528 case HORZSIZE:
529 return physDev->horzsize;
530 case VERTSIZE:
531 return physDev->vertsize;
532 case BITSPIXEL:
533 return physDev->bitspixel;
534 case TEXTCAPS:
535 return physDev->textcaps;
536 case RASTERCAPS:
537 return physDev->rastercaps;
538 case TECHNOLOGY:
539 return physDev->technology;
540 case PLANES:
541 return physDev->planes;
542 case NUMCOLORS:
543 return physDev->numcolors;
544 case CURVECAPS:
545 return (CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES | CC_WIDE |
546 CC_STYLED | CC_WIDESTYLED | CC_INTERIORS | CC_ROUNDRECT);
547 case LINECAPS:
548 return (LC_POLYLINE | LC_MARKER | LC_POLYMARKER | LC_WIDE |
549 LC_STYLED | LC_WIDESTYLED | LC_INTERIORS);
550 case POLYGONALCAPS:
551 return (PC_POLYGON | PC_RECTANGLE | PC_WINDPOLYGON | PC_SCANLINE |
552 PC_WIDE | PC_STYLED | PC_WIDESTYLED | PC_INTERIORS);
553 default:
554 FIXME("Unimplemented cap %d\n", cap);
555 return 0;