| /* |
| * Enhanced MetaFile driver dc value functions |
| * |
| * Copyright 1999 Huw D M Davies |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2.1 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this library; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA |
| */ |
| |
| #include "enhmfdrv/enhmetafiledrv.h" |
| #include "wine/debug.h" |
| |
| WINE_DEFAULT_DEBUG_CHANNEL(enhmetafile); |
| |
| INT EMFDRV_SaveDC( PHYSDEV dev ) |
| { |
| PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSaveDC ); |
| INT ret = next->funcs->pSaveDC( next ); |
| |
| if (ret) |
| { |
| EMRSAVEDC emr; |
| emr.emr.iType = EMR_SAVEDC; |
| emr.emr.nSize = sizeof(emr); |
| EMFDRV_WriteRecord( dev, &emr.emr ); |
| } |
| return ret; |
| } |
| |
| BOOL EMFDRV_RestoreDC( PHYSDEV dev, INT level ) |
| { |
| PHYSDEV next = GET_NEXT_PHYSDEV( dev, pRestoreDC ); |
| EMFDRV_PDEVICE* physDev = (EMFDRV_PDEVICE*)dev; |
| DC *dc = get_dc_ptr( dev->hdc ); |
| EMRRESTOREDC emr; |
| BOOL ret; |
| |
| emr.emr.iType = EMR_RESTOREDC; |
| emr.emr.nSize = sizeof(emr); |
| |
| if (level < 0) |
| emr.iRelative = level; |
| else |
| emr.iRelative = level - dc->saveLevel - 1; |
| release_dc_ptr( dc ); |
| |
| physDev->restoring++; |
| ret = next->funcs->pRestoreDC( next, level ); |
| physDev->restoring--; |
| |
| if (ret) EMFDRV_WriteRecord( dev, &emr.emr ); |
| return ret; |
| } |
| |
| UINT EMFDRV_SetTextAlign( PHYSDEV dev, UINT align ) |
| { |
| EMRSETTEXTALIGN emr; |
| emr.emr.iType = EMR_SETTEXTALIGN; |
| emr.emr.nSize = sizeof(emr); |
| emr.iMode = align; |
| return EMFDRV_WriteRecord( dev, &emr.emr ) ? align : GDI_ERROR; |
| } |
| |
| BOOL EMFDRV_SetTextJustification(PHYSDEV dev, INT nBreakExtra, INT nBreakCount) |
| { |
| EMRSETTEXTJUSTIFICATION emr; |
| emr.emr.iType = EMR_SETTEXTJUSTIFICATION; |
| emr.emr.nSize = sizeof(emr); |
| emr.nBreakExtra = nBreakExtra; |
| emr.nBreakCount = nBreakCount; |
| return EMFDRV_WriteRecord(dev, &emr.emr); |
| } |
| |
| INT EMFDRV_SetBkMode( PHYSDEV dev, INT mode ) |
| { |
| EMRSETBKMODE emr; |
| emr.emr.iType = EMR_SETBKMODE; |
| emr.emr.nSize = sizeof(emr); |
| emr.iMode = mode; |
| return EMFDRV_WriteRecord( dev, &emr.emr ) ? mode : 0; |
| } |
| |
| COLORREF EMFDRV_SetBkColor( PHYSDEV dev, COLORREF color ) |
| { |
| EMRSETBKCOLOR emr; |
| EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev; |
| |
| if (physDev->restoring) return color; /* don't output records during RestoreDC */ |
| |
| emr.emr.iType = EMR_SETBKCOLOR; |
| emr.emr.nSize = sizeof(emr); |
| emr.crColor = color; |
| return EMFDRV_WriteRecord( dev, &emr.emr ) ? color : CLR_INVALID; |
| } |
| |
| |
| COLORREF EMFDRV_SetTextColor( PHYSDEV dev, COLORREF color ) |
| { |
| EMRSETTEXTCOLOR emr; |
| EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev; |
| |
| if (physDev->restoring) return color; /* don't output records during RestoreDC */ |
| |
| emr.emr.iType = EMR_SETTEXTCOLOR; |
| emr.emr.nSize = sizeof(emr); |
| emr.crColor = color; |
| return EMFDRV_WriteRecord( dev, &emr.emr ) ? color : CLR_INVALID; |
| } |
| |
| INT EMFDRV_SetROP2( PHYSDEV dev, INT rop ) |
| { |
| EMRSETROP2 emr; |
| emr.emr.iType = EMR_SETROP2; |
| emr.emr.nSize = sizeof(emr); |
| emr.iMode = rop; |
| return EMFDRV_WriteRecord( dev, &emr.emr ) ? rop : 0; |
| } |
| |
| INT EMFDRV_SetPolyFillMode( PHYSDEV dev, INT mode ) |
| { |
| EMRSETPOLYFILLMODE emr; |
| emr.emr.iType = EMR_SETPOLYFILLMODE; |
| emr.emr.nSize = sizeof(emr); |
| emr.iMode = mode; |
| return EMFDRV_WriteRecord( dev, &emr.emr ) ? mode : 0; |
| } |
| |
| INT EMFDRV_SetStretchBltMode( PHYSDEV dev, INT mode ) |
| { |
| EMRSETSTRETCHBLTMODE emr; |
| emr.emr.iType = EMR_SETSTRETCHBLTMODE; |
| emr.emr.nSize = sizeof(emr); |
| emr.iMode = mode; |
| return EMFDRV_WriteRecord( dev, &emr.emr ) ? mode : 0; |
| } |
| |
| INT EMFDRV_SetArcDirection(PHYSDEV dev, INT arcDirection) |
| { |
| EMRSETARCDIRECTION emr; |
| |
| emr.emr.iType = EMR_SETARCDIRECTION; |
| emr.emr.nSize = sizeof(emr); |
| emr.iArcDirection = arcDirection; |
| return EMFDRV_WriteRecord(dev, &emr.emr) ? arcDirection : 0; |
| } |
| |
| INT EMFDRV_ExcludeClipRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom ) |
| { |
| PHYSDEV next = GET_NEXT_PHYSDEV( dev, pExcludeClipRect ); |
| EMREXCLUDECLIPRECT emr; |
| |
| emr.emr.iType = EMR_EXCLUDECLIPRECT; |
| emr.emr.nSize = sizeof(emr); |
| emr.rclClip.left = left; |
| emr.rclClip.top = top; |
| emr.rclClip.right = right; |
| emr.rclClip.bottom = bottom; |
| if (!EMFDRV_WriteRecord( dev, &emr.emr )) return ERROR; |
| return next->funcs->pExcludeClipRect( next, left, top, right, bottom ); |
| } |
| |
| INT EMFDRV_IntersectClipRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom) |
| { |
| PHYSDEV next = GET_NEXT_PHYSDEV( dev, pIntersectClipRect ); |
| EMRINTERSECTCLIPRECT emr; |
| |
| emr.emr.iType = EMR_INTERSECTCLIPRECT; |
| emr.emr.nSize = sizeof(emr); |
| emr.rclClip.left = left; |
| emr.rclClip.top = top; |
| emr.rclClip.right = right; |
| emr.rclClip.bottom = bottom; |
| if (!EMFDRV_WriteRecord( dev, &emr.emr )) return ERROR; |
| return next->funcs->pIntersectClipRect( next, left, top, right, bottom ); |
| } |
| |
| INT EMFDRV_OffsetClipRgn( PHYSDEV dev, INT x, INT y ) |
| { |
| PHYSDEV next = GET_NEXT_PHYSDEV( dev, pOffsetClipRgn ); |
| EMROFFSETCLIPRGN emr; |
| |
| emr.emr.iType = EMR_OFFSETCLIPRGN; |
| emr.emr.nSize = sizeof(emr); |
| emr.ptlOffset.x = x; |
| emr.ptlOffset.y = y; |
| if (!EMFDRV_WriteRecord( dev, &emr.emr )) return ERROR; |
| return next->funcs->pOffsetClipRgn( next, x, y ); |
| } |
| |
| INT EMFDRV_ExtSelectClipRgn( PHYSDEV dev, HRGN hrgn, INT mode ) |
| { |
| PHYSDEV next = GET_NEXT_PHYSDEV( dev, pExtSelectClipRgn ); |
| EMREXTSELECTCLIPRGN *emr; |
| DWORD size, rgnsize; |
| BOOL ret; |
| |
| if (!hrgn) |
| { |
| if (mode != RGN_COPY) return ERROR; |
| rgnsize = 0; |
| } |
| else rgnsize = GetRegionData( hrgn, 0, NULL ); |
| |
| size = rgnsize + offsetof(EMREXTSELECTCLIPRGN,RgnData); |
| emr = HeapAlloc( GetProcessHeap(), 0, size ); |
| if (rgnsize) GetRegionData( hrgn, rgnsize, (RGNDATA *)&emr->RgnData ); |
| |
| emr->emr.iType = EMR_EXTSELECTCLIPRGN; |
| emr->emr.nSize = size; |
| emr->cbRgnData = rgnsize; |
| emr->iMode = mode; |
| |
| ret = EMFDRV_WriteRecord( dev, &emr->emr ); |
| HeapFree( GetProcessHeap(), 0, emr ); |
| return ret ? next->funcs->pExtSelectClipRgn( next, hrgn, mode ) : ERROR; |
| } |
| |
| INT EMFDRV_SetMapMode( PHYSDEV dev, INT mode ) |
| { |
| PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetMapMode ); |
| EMRSETMAPMODE emr; |
| emr.emr.iType = EMR_SETMAPMODE; |
| emr.emr.nSize = sizeof(emr); |
| emr.iMode = mode; |
| |
| if (!EMFDRV_WriteRecord( dev, &emr.emr )) return 0; |
| return next->funcs->pSetMapMode( next, mode ); |
| } |
| |
| BOOL EMFDRV_SetViewportExtEx( PHYSDEV dev, INT cx, INT cy, SIZE *size ) |
| { |
| PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetViewportExtEx ); |
| EMRSETVIEWPORTEXTEX emr; |
| |
| emr.emr.iType = EMR_SETVIEWPORTEXTEX; |
| emr.emr.nSize = sizeof(emr); |
| emr.szlExtent.cx = cx; |
| emr.szlExtent.cy = cy; |
| |
| if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE; |
| return next->funcs->pSetViewportExtEx( next, cx, cy, size ); |
| } |
| |
| BOOL EMFDRV_SetWindowExtEx( PHYSDEV dev, INT cx, INT cy, SIZE *size ) |
| { |
| PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetWindowExtEx ); |
| EMRSETWINDOWEXTEX emr; |
| |
| emr.emr.iType = EMR_SETWINDOWEXTEX; |
| emr.emr.nSize = sizeof(emr); |
| emr.szlExtent.cx = cx; |
| emr.szlExtent.cy = cy; |
| |
| if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE; |
| return next->funcs->pSetWindowExtEx( next, cx, cy, size ); |
| } |
| |
| BOOL EMFDRV_SetViewportOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt ) |
| { |
| PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetViewportOrgEx ); |
| EMRSETVIEWPORTORGEX emr; |
| |
| emr.emr.iType = EMR_SETVIEWPORTORGEX; |
| emr.emr.nSize = sizeof(emr); |
| emr.ptlOrigin.x = x; |
| emr.ptlOrigin.y = y; |
| |
| if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE; |
| return next->funcs->pSetViewportOrgEx( next, x, y, pt ); |
| } |
| |
| BOOL EMFDRV_SetWindowOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt ) |
| { |
| PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetWindowOrgEx ); |
| EMRSETWINDOWORGEX emr; |
| |
| emr.emr.iType = EMR_SETWINDOWORGEX; |
| emr.emr.nSize = sizeof(emr); |
| emr.ptlOrigin.x = x; |
| emr.ptlOrigin.y = y; |
| |
| if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE; |
| return next->funcs->pSetWindowOrgEx( next, x, y, pt ); |
| } |
| |
| BOOL EMFDRV_ScaleViewportExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNum, INT yDenom, SIZE *size ) |
| { |
| PHYSDEV next = GET_NEXT_PHYSDEV( dev, pScaleViewportExtEx ); |
| EMRSCALEVIEWPORTEXTEX emr; |
| |
| emr.emr.iType = EMR_SCALEVIEWPORTEXTEX; |
| emr.emr.nSize = sizeof(emr); |
| emr.xNum = xNum; |
| emr.xDenom = xDenom; |
| emr.yNum = yNum; |
| emr.yDenom = yDenom; |
| |
| if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE; |
| return next->funcs->pScaleViewportExtEx( next, xNum, xDenom, yNum, yDenom, size ); |
| } |
| |
| BOOL EMFDRV_ScaleWindowExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNum, INT yDenom, SIZE *size ) |
| { |
| PHYSDEV next = GET_NEXT_PHYSDEV( dev, pScaleWindowExtEx ); |
| EMRSCALEWINDOWEXTEX emr; |
| |
| emr.emr.iType = EMR_SCALEWINDOWEXTEX; |
| emr.emr.nSize = sizeof(emr); |
| emr.xNum = xNum; |
| emr.xDenom = xDenom; |
| emr.yNum = yNum; |
| emr.yDenom = yDenom; |
| |
| if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE; |
| return next->funcs->pScaleWindowExtEx( next, xNum, xDenom, yNum, yDenom, size ); |
| } |
| |
| DWORD EMFDRV_SetLayout( PHYSDEV dev, DWORD layout ) |
| { |
| EMRSETLAYOUT emr; |
| |
| emr.emr.iType = EMR_SETLAYOUT; |
| emr.emr.nSize = sizeof(emr); |
| emr.iMode = layout; |
| return EMFDRV_WriteRecord( dev, &emr.emr ) ? layout : GDI_ERROR; |
| } |
| |
| BOOL EMFDRV_SetWorldTransform( PHYSDEV dev, const XFORM *xform) |
| { |
| PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetWorldTransform ); |
| EMRSETWORLDTRANSFORM emr; |
| |
| emr.emr.iType = EMR_SETWORLDTRANSFORM; |
| emr.emr.nSize = sizeof(emr); |
| emr.xform = *xform; |
| |
| if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE; |
| return next->funcs->pSetWorldTransform( next, xform ); |
| } |
| |
| BOOL EMFDRV_ModifyWorldTransform( PHYSDEV dev, const XFORM *xform, DWORD mode) |
| { |
| PHYSDEV next = GET_NEXT_PHYSDEV( dev, pModifyWorldTransform ); |
| EMRMODIFYWORLDTRANSFORM emr; |
| |
| emr.emr.iType = EMR_MODIFYWORLDTRANSFORM; |
| emr.emr.nSize = sizeof(emr); |
| emr.xform = *xform; |
| emr.iMode = mode; |
| |
| if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE; |
| return next->funcs->pModifyWorldTransform( next, xform, mode ); |
| } |
| |
| BOOL EMFDRV_OffsetViewportOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt ) |
| { |
| PHYSDEV next = GET_NEXT_PHYSDEV( dev, pOffsetViewportOrgEx ); |
| EMRSETVIEWPORTORGEX emr; |
| POINT prev; |
| |
| GetViewportOrgEx( dev->hdc, &prev ); |
| |
| emr.emr.iType = EMR_SETVIEWPORTORGEX; |
| emr.emr.nSize = sizeof(emr); |
| emr.ptlOrigin.x = prev.x + x; |
| emr.ptlOrigin.y = prev.y + y; |
| |
| if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE; |
| return next->funcs->pOffsetViewportOrgEx( next, x, y, pt ); |
| } |
| |
| BOOL EMFDRV_OffsetWindowOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt ) |
| { |
| PHYSDEV next = GET_NEXT_PHYSDEV( dev, pOffsetWindowOrgEx ); |
| EMRSETWINDOWORGEX emr; |
| POINT prev; |
| |
| GetWindowOrgEx( dev->hdc, &prev ); |
| |
| emr.emr.iType = EMR_SETWINDOWORGEX; |
| emr.emr.nSize = sizeof(emr); |
| emr.ptlOrigin.x = prev.x + x; |
| emr.ptlOrigin.y = prev.y + y; |
| |
| if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE; |
| return next->funcs->pOffsetWindowOrgEx( next, x, y, pt ); |
| } |
| |
| DWORD EMFDRV_SetMapperFlags( PHYSDEV dev, DWORD flags ) |
| { |
| EMRSETMAPPERFLAGS emr; |
| |
| emr.emr.iType = EMR_SETMAPPERFLAGS; |
| emr.emr.nSize = sizeof(emr); |
| emr.dwFlags = flags; |
| |
| return EMFDRV_WriteRecord( dev, &emr.emr ) ? flags : GDI_ERROR; |
| } |
| |
| BOOL EMFDRV_AbortPath( PHYSDEV dev ) |
| { |
| EMRABORTPATH emr; |
| |
| emr.emr.iType = EMR_ABORTPATH; |
| emr.emr.nSize = sizeof(emr); |
| |
| return EMFDRV_WriteRecord( dev, &emr.emr ); |
| } |
| |
| BOOL EMFDRV_BeginPath( PHYSDEV dev ) |
| { |
| EMRBEGINPATH emr; |
| |
| emr.emr.iType = EMR_BEGINPATH; |
| emr.emr.nSize = sizeof(emr); |
| |
| return EMFDRV_WriteRecord( dev, &emr.emr ); |
| } |
| |
| BOOL EMFDRV_CloseFigure( PHYSDEV dev ) |
| { |
| EMRCLOSEFIGURE emr; |
| |
| emr.emr.iType = EMR_CLOSEFIGURE; |
| emr.emr.nSize = sizeof(emr); |
| |
| return EMFDRV_WriteRecord( dev, &emr.emr ); |
| } |
| |
| BOOL EMFDRV_EndPath( PHYSDEV dev ) |
| { |
| EMRENDPATH emr; |
| |
| emr.emr.iType = EMR_ENDPATH; |
| emr.emr.nSize = sizeof(emr); |
| |
| return EMFDRV_WriteRecord( dev, &emr.emr ); |
| } |
| |
| BOOL EMFDRV_FillPath( PHYSDEV dev ) |
| { |
| EMRFILLPATH emr; |
| |
| emr.emr.iType = EMR_FILLPATH; |
| emr.emr.nSize = sizeof(emr); |
| FIXME("Bounds\n"); |
| emr.rclBounds.left = 0; |
| emr.rclBounds.top = 0; |
| emr.rclBounds.right = 0; |
| emr.rclBounds.bottom = 0; |
| return EMFDRV_WriteRecord( dev, &emr.emr ); |
| } |
| |
| BOOL EMFDRV_FlattenPath( PHYSDEV dev ) |
| { |
| EMRFLATTENPATH emr; |
| |
| emr.emr.iType = EMR_FLATTENPATH; |
| emr.emr.nSize = sizeof(emr); |
| |
| return EMFDRV_WriteRecord( dev, &emr.emr ); |
| } |
| |
| BOOL EMFDRV_SelectClipPath( PHYSDEV dev, INT iMode ) |
| { |
| PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSelectClipPath ); |
| EMRSELECTCLIPPATH emr; |
| |
| emr.emr.iType = EMR_SELECTCLIPPATH; |
| emr.emr.nSize = sizeof(emr); |
| emr.iMode = iMode; |
| |
| if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE; |
| return next->funcs->pSelectClipPath( next, iMode ); |
| } |
| |
| BOOL EMFDRV_StrokeAndFillPath( PHYSDEV dev ) |
| { |
| EMRSTROKEANDFILLPATH emr; |
| |
| emr.emr.iType = EMR_STROKEANDFILLPATH; |
| emr.emr.nSize = sizeof(emr); |
| FIXME("Bounds\n"); |
| emr.rclBounds.left = 0; |
| emr.rclBounds.top = 0; |
| emr.rclBounds.right = 0; |
| emr.rclBounds.bottom = 0; |
| return EMFDRV_WriteRecord( dev, &emr.emr ); |
| } |
| |
| BOOL EMFDRV_StrokePath( PHYSDEV dev ) |
| { |
| EMRSTROKEPATH emr; |
| |
| emr.emr.iType = EMR_STROKEPATH; |
| emr.emr.nSize = sizeof(emr); |
| FIXME("Bounds\n"); |
| emr.rclBounds.left = 0; |
| emr.rclBounds.top = 0; |
| emr.rclBounds.right = 0; |
| emr.rclBounds.bottom = 0; |
| return EMFDRV_WriteRecord( dev, &emr.emr ); |
| } |
| |
| BOOL EMFDRV_WidenPath( PHYSDEV dev ) |
| { |
| EMRWIDENPATH emr; |
| |
| emr.emr.iType = EMR_WIDENPATH; |
| emr.emr.nSize = sizeof(emr); |
| |
| return EMFDRV_WriteRecord( dev, &emr.emr ); |
| } |
| |
| INT EMFDRV_GetDeviceCaps(PHYSDEV dev, INT cap) |
| { |
| EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*) dev; |
| |
| return GetDeviceCaps( physDev->ref_dc, cap ); |
| } |