- Sync/Port Wine Enhanced/Metafile code. This is a fix for CORE-12888.
- Wine made this difficult to port and keep the whole file unchanged for syncing.

svn path=/trunk/; revision=75292
This commit is contained in:
James Tabor 2017-07-06 18:52:22 +00:00
parent 3b7b8b89b3
commit b1f132e660
17 changed files with 1596 additions and 238 deletions

View file

@ -97,7 +97,6 @@ struct gdi_dc_funcs
BOOL (*pFontIsLinked)(PHYSDEV);
BOOL (*pFrameRgn)(PHYSDEV,HRGN,HBRUSH,INT,INT);
BOOL (*pGdiComment)(PHYSDEV,UINT,const BYTE*);
BOOL (*pGdiRealizationInfo)(PHYSDEV,void*);
UINT (*pGetBoundsRect)(PHYSDEV,RECT*,UINT);
BOOL (*pGetCharABCWidths)(PHYSDEV,UINT,UINT,LPABC);
BOOL (*pGetCharABCWidthsI)(PHYSDEV,UINT,UINT,WORD*,LPABC);
@ -105,6 +104,7 @@ struct gdi_dc_funcs
INT (*pGetDeviceCaps)(PHYSDEV,INT);
BOOL (*pGetDeviceGammaRamp)(PHYSDEV,LPVOID);
DWORD (*pGetFontData)(PHYSDEV,DWORD,DWORD,LPVOID,DWORD);
BOOL (*pGdiFontRealizationInfo)(PHYSDEV,void*);
DWORD (*pGetFontUnicodeRanges)(PHYSDEV,LPGLYPHSET);
DWORD (*pGetGlyphIndices)(PHYSDEV,LPCWSTR,INT,LPWORD,DWORD);
DWORD (*pGetGlyphOutline)(PHYSDEV,UINT,UINT,LPGLYPHMETRICS,DWORD,LPVOID,const MAT2*);
@ -213,7 +213,7 @@ static inline PHYSDEV get_physdev_entry_point( PHYSDEV dev, size_t offset )
#define GET_NEXT_PHYSDEV(dev,func) \
get_physdev_entry_point( (dev)->next, FIELD_OFFSET(struct gdi_dc_funcs,func))
/*
static inline void push_dc_driver( PHYSDEV *dev, PHYSDEV physdev, const struct gdi_dc_funcs *funcs )
{
while ((*dev)->funcs->priority > funcs->priority) dev = &(*dev)->next;
@ -222,7 +222,7 @@ static inline void push_dc_driver( PHYSDEV *dev, PHYSDEV physdev, const struct g
physdev->hdc = (*dev)->hdc;
*dev = physdev;
}
*/
/* support for window surfaces */
struct window_surface;

View file

@ -1038,8 +1038,21 @@ BOOL
WINAPI
GdiAddGlsBounds(HDC hdc,LPRECT prc)
{
//FIXME: Lookup what 0x8000 means
return NtGdiSetBoundsRect(hdc, prc, 0x8000 | DCB_ACCUMULATE ) ? TRUE : FALSE;
return NtGdiSetBoundsRect(hdc, prc, DCB_WINDOWMGR|DCB_ACCUMULATE ) ? TRUE : FALSE;
}
BOOL
WINAPI
GetBoundsRectAlt(HDC hdc,LPRECT prc,UINT flags)
{
return NtGdiGetBoundsRect(hdc, prc, flags);
}
BOOL
WINAPI
SetBoundsRectAlt(HDC hdc,LPRECT prc,UINT flags)
{
return NtGdiSetBoundsRect(hdc, prc, flags );
}
/*

View file

@ -8,6 +8,7 @@ include_directories(
list(APPEND SOURCE
enhmetafile.c
metafile.c
path.c
enhmfdrv/bitblt.c
enhmfdrv/dc.c
enhmfdrv/graphics.c

View file

@ -547,7 +547,6 @@ static void EMF_Update_MF_Xform(HDC hdc, const enum_emh_data *info)
if (!SetWorldTransform(hdc, &final_trans))
{
__debugbreak();
SetWorldTransform(hdc, &final_trans);
ERR("World transform failed!\n");
}
}
@ -1140,9 +1139,9 @@ BOOL WINAPI PlayEnhMetaFileRecord(
rc.top = pExtTextOutA->emrtext.rcl.top;
rc.right = pExtTextOutA->emrtext.rcl.right;
rc.bottom = pExtTextOutA->emrtext.rcl.bottom;
TRACE("EMR_EXTTEXTOUTA: x,y = %d, %d. rect = %d, %d - %d, %d. flags %08x\n",
TRACE("EMR_EXTTEXTOUTA: x,y = %d, %d. rect = %s. flags %08x\n",
pExtTextOutA->emrtext.ptlReference.x, pExtTextOutA->emrtext.ptlReference.y,
rc.left, rc.top, rc.right, rc.bottom, pExtTextOutA->emrtext.fOptions);
wine_dbgstr_rect(&rc), pExtTextOutA->emrtext.fOptions);
old_mode = SetGraphicsMode(hdc, pExtTextOutA->iGraphicsMode);
/* Reselect the font back into the dc so that the transformation
@ -1176,9 +1175,9 @@ BOOL WINAPI PlayEnhMetaFileRecord(
rc.top = pExtTextOutW->emrtext.rcl.top;
rc.right = pExtTextOutW->emrtext.rcl.right;
rc.bottom = pExtTextOutW->emrtext.rcl.bottom;
TRACE("EMR_EXTTEXTOUTW: x,y = %d, %d. rect = %d, %d - %d, %d. flags %08x\n",
TRACE("EMR_EXTTEXTOUTW: x,y = %d, %d. rect = %s. flags %08x\n",
pExtTextOutW->emrtext.ptlReference.x, pExtTextOutW->emrtext.ptlReference.y,
rc.left, rc.top, rc.right, rc.bottom, pExtTextOutW->emrtext.fOptions);
wine_dbgstr_rect(&rc), pExtTextOutW->emrtext.fOptions);
old_mode = SetGraphicsMode(hdc, pExtTextOutW->iGraphicsMode);
/* Reselect the font back into the dc so that the transformation
@ -1232,13 +1231,18 @@ BOOL WINAPI PlayEnhMetaFileRecord(
case EMR_EXTSELECTCLIPRGN:
{
const EMREXTSELECTCLIPRGN *lpRgn = (const EMREXTSELECTCLIPRGN *)mr;
#ifdef __REACTOS__
const RGNDATA *pRgnData = (const RGNDATA *)lpRgn->RgnData;
DWORD dwSize = sizeof(RGNDATAHEADER) + pRgnData->rdh.nCount * sizeof(RECT);
#endif
HRGN hRgn = 0;
if (mr->nSize >= sizeof(*lpRgn) + sizeof(RGNDATAHEADER))
#ifdef __REACTOS__
hRgn = ExtCreateRegion( &info->init_transform, dwSize, pRgnData );
#else
hRgn = ExtCreateRegion( &info->init_transform, 0, (const RGNDATA *)lpRgn->RgnData );
#endif
ExtSelectClipRgn(hdc, hRgn, (INT)(lpRgn->iMode));
/* ExtSelectClipRgn created a copy of the region */
DeleteObject(hRgn);
@ -1824,6 +1828,7 @@ BOOL WINAPI PlayEnhMetaFileRecord(
HBITMAP hBmp = 0, hBmpOld = 0;
const BITMAPINFO *pbi = (const BITMAPINFO *)((const BYTE *)mr + pBitBlt->offBmiSrc);
SetGraphicsMode(hdcSrc, GM_ADVANCED);
SetWorldTransform(hdcSrc, &pBitBlt->xformSrc);
hBrush = CreateSolidBrush(pBitBlt->crBkColorSrc);
@ -1866,6 +1871,7 @@ BOOL WINAPI PlayEnhMetaFileRecord(
HBITMAP hBmp = 0, hBmpOld = 0;
const BITMAPINFO *pbi = (const BITMAPINFO *)((const BYTE *)mr + pStretchBlt->offBmiSrc);
SetGraphicsMode(hdcSrc, GM_ADVANCED);
SetWorldTransform(hdcSrc, &pStretchBlt->xformSrc);
hBrush = CreateSolidBrush(pStretchBlt->crBkColorSrc);
@ -1908,6 +1914,7 @@ BOOL WINAPI PlayEnhMetaFileRecord(
const BITMAPINFO *pbi = (const BITMAPINFO *)((const BYTE *)mr + pAlphaBlend->offBmiSrc);
void *bits;
SetGraphicsMode(hdcSrc, GM_ADVANCED);
SetWorldTransform(hdcSrc, &pAlphaBlend->xformSrc);
hBmp = CreateDIBSection(hdc, pbi, pAlphaBlend->iUsageSrc, &bits, NULL, 0);
@ -1933,6 +1940,7 @@ BOOL WINAPI PlayEnhMetaFileRecord(
HBITMAP hBmp, hBmpOld, hBmpMask;
const BITMAPINFO *pbi;
SetGraphicsMode(hdcSrc, GM_ADVANCED);
SetWorldTransform(hdcSrc, &pMaskBlt->xformSrc);
hBrush = CreateSolidBrush(pMaskBlt->crBkColorSrc);
@ -1981,6 +1989,7 @@ BOOL WINAPI PlayEnhMetaFileRecord(
const BITMAPINFO *pbi;
POINT pts[3];
SetGraphicsMode(hdcSrc, GM_ADVANCED);
SetWorldTransform(hdcSrc, &pPlgBlt->xformSrc);
pts[0].x = pPlgBlt->aptlDest[0].x; pts[0].y = pPlgBlt->aptlDest[0].y;
@ -2179,6 +2188,14 @@ BOOL WINAPI PlayEnhMetaFileRecord(
break;
}
case EMR_GRADIENTFILL:
{
EMRGRADIENTFILL *grad = (EMRGRADIENTFILL *)mr;
GdiGradientFill( hdc, grad->Ver, grad->nVer, grad->Ver + grad->nVer,
grad->nTri, grad->ulMode );
break;
}
case EMR_POLYDRAW16:
case EMR_GLSRECORD:
case EMR_GLSBOUNDEDRECORD:
@ -2192,7 +2209,6 @@ BOOL WINAPI PlayEnhMetaFileRecord(
case EMR_SETICMPROFILEA:
case EMR_SETICMPROFILEW:
case EMR_TRANSPARENTBLT:
case EMR_GRADIENTFILL:
case EMR_SETLINKEDUFI:
case EMR_COLORMATCHTOTARGETW:
case EMR_CREATECOLORSPACEW:
@ -2206,8 +2222,7 @@ BOOL WINAPI PlayEnhMetaFileRecord(
tmprc.left = tmprc.top = 0;
tmprc.right = tmprc.bottom = 1000;
LPtoDP(hdc, (POINT*)&tmprc, 2);
TRACE("L:0,0 - 1000,1000 -> D:%d,%d - %d,%d\n", tmprc.left,
tmprc.top, tmprc.right, tmprc.bottom);
TRACE("L:0,0 - 1000,1000 -> D:%s\n", wine_dbgstr_rect(&tmprc));
return TRUE;
}
@ -2375,8 +2390,7 @@ BOOL WINAPI EnumEnhMetaFile(
double xSrcPixSize, ySrcPixSize, xscale, yscale;
XFORM xform;
TRACE("rect: %d,%d - %d,%d. rclFrame: %d,%d - %d,%d\n",
lpRect->left, lpRect->top, lpRect->right, lpRect->bottom,
TRACE("rect: %s. rclFrame: (%d,%d)-(%d,%d)\n", wine_dbgstr_rect(lpRect),
emh->rclFrame.left, emh->rclFrame.top, emh->rclFrame.right,
emh->rclFrame.bottom);

View file

@ -122,7 +122,11 @@ BOOL EMFDRV_StretchBlt( PHYSDEV devDst, struct bitblt_coords *dst,
pEMR->dwRop = rop;
pEMR->xSrc = src->log_x;
pEMR->ySrc = src->log_y;
GetWorldTransform(devSrc->hdc, &pEMR->xformSrc);
#ifdef __REACTOS__
NtGdiGetTransform(devSrc->hdc, GdiWorldSpaceToDeviceSpace, &pEMR->xformSrc);
#else
GetTransform(devSrc->hdc, 0x204, &pEMR->xformSrc);
#endif
pEMR->crBkColorSrc = GetBkColor(devSrc->hdc);
pEMR->iUsageSrc = DIB_RGB_COLORS;
pEMR->offBmiSrc = emrSize;

View file

@ -2,6 +2,7 @@
* Enhanced MetaFile driver dc value functions
*
* Copyright 1999 Huw D M Davies
* Copyright 2016 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -18,10 +19,16 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <assert.h>
#include "enhmfdrv/enhmetafiledrv.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(enhmetafile);
/* get the emf physdev from the path physdev */
static inline PHYSDEV get_emfdev( PHYSDEV path )
{
return &CONTAINING_RECORD( path, EMFDRV_PDEVICE, pathdev )->dev;
}
static const struct gdi_dc_funcs emfpath_driver;
INT EMFDRV_SaveDC( PHYSDEV dev )
{
@ -41,8 +48,8 @@ INT EMFDRV_SaveDC( PHYSDEV dev )
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 );
EMFDRV_PDEVICE* physDev = get_emf_physdev( dev );
DC *dc = get_physdev_dc( dev );
EMRRESTOREDC emr;
BOOL ret;
@ -53,7 +60,6 @@ BOOL EMFDRV_RestoreDC( PHYSDEV dev, INT level )
emr.iRelative = level;
else
emr.iRelative = level - dc->saveLevel - 1;
release_dc_ptr( dc );
physDev->restoring++;
ret = next->funcs->pRestoreDC( next, level );
@ -94,7 +100,7 @@ INT EMFDRV_SetBkMode( PHYSDEV dev, INT mode )
COLORREF EMFDRV_SetBkColor( PHYSDEV dev, COLORREF color )
{
EMRSETBKCOLOR emr;
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
if (physDev->restoring) return color; /* don't output records during RestoreDC */
@ -108,7 +114,7 @@ COLORREF EMFDRV_SetBkColor( PHYSDEV dev, COLORREF color )
COLORREF EMFDRV_SetTextColor( PHYSDEV dev, COLORREF color )
{
EMRSETTEXTCOLOR emr;
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
if (physDev->restoring) return color; /* don't output records during RestoreDC */
@ -420,12 +426,21 @@ BOOL EMFDRV_AbortPath( PHYSDEV dev )
BOOL EMFDRV_BeginPath( PHYSDEV dev )
{
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pBeginPath );
EMRBEGINPATH emr;
DC *dc = get_physdev_dc( dev );
emr.emr.iType = EMR_BEGINPATH;
emr.emr.nSize = sizeof(emr);
return EMFDRV_WriteRecord( dev, &emr.emr );
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
if (physDev->path) return TRUE; /* already open */
if (!next->funcs->pBeginPath( next )) return FALSE;
push_dc_driver( &dc->physDev, &physDev->pathdev, &emfpath_driver );
physDev->path = TRUE;
return TRUE;
}
BOOL EMFDRV_CloseFigure( PHYSDEV dev )
@ -435,7 +450,8 @@ BOOL EMFDRV_CloseFigure( PHYSDEV dev )
emr.emr.iType = EMR_CLOSEFIGURE;
emr.emr.nSize = sizeof(emr);
return EMFDRV_WriteRecord( dev, &emr.emr );
EMFDRV_WriteRecord( dev, &emr.emr );
return FALSE; /* always fails without a path */
}
BOOL EMFDRV_EndPath( PHYSDEV dev )
@ -445,21 +461,8 @@ BOOL EMFDRV_EndPath( PHYSDEV dev )
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 );
EMFDRV_WriteRecord( dev, &emr.emr );
return FALSE; /* always fails without a path */
}
BOOL EMFDRV_FlattenPath( PHYSDEV dev )
@ -474,43 +477,24 @@ BOOL EMFDRV_FlattenPath( PHYSDEV dev )
BOOL EMFDRV_SelectClipPath( PHYSDEV dev, INT iMode )
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSelectClipPath );
// PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSelectClipPath ); This HACK breaks test_emf_clipping
EMRSELECTCLIPPATH emr;
// BOOL ret = FALSE;
// HRGN hrgn;
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 );
/* hrgn = PathToRegion( dev->hdc );
if (hrgn)
{
ret = next->funcs->pExtSelectClipRgn( next, hrgn, iMode );
DeleteObject( hrgn );
} ERR("EMFDRV_SelectClipPath ret %d\n",ret);
return ret;*/
return TRUE;
}
BOOL EMFDRV_WidenPath( PHYSDEV dev )
@ -525,7 +509,448 @@ BOOL EMFDRV_WidenPath( PHYSDEV dev )
INT EMFDRV_GetDeviceCaps(PHYSDEV dev, INT cap)
{
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*) dev;
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
return GetDeviceCaps( physDev->ref_dc, cap );
}
/***********************************************************************
* emfpathdrv_AbortPath
*/
static BOOL emfpathdrv_AbortPath( PHYSDEV dev )
{
PHYSDEV emfdev = get_emfdev( dev );
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pAbortPath );
DC *dc = get_physdev_dc( dev );
emfpath_driver.pDeleteDC( pop_dc_driver( dc, &emfpath_driver ));
emfdev->funcs->pAbortPath( emfdev );
return next->funcs->pAbortPath( next );
}
/***********************************************************************
* emfpathdrv_AngleArc
*/
static BOOL emfpathdrv_AngleArc( PHYSDEV dev, INT x, INT y, DWORD radius, FLOAT start, FLOAT sweep )
{
PHYSDEV emfdev = get_emfdev( dev );
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pAngleArc );
return (emfdev->funcs->pAngleArc( emfdev, x, y, radius, start, sweep ) &&
next->funcs->pAngleArc( next, x, y, radius, start, sweep ));
}
/***********************************************************************
* emfpathdrv_Arc
*/
static BOOL emfpathdrv_Arc( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend )
{
PHYSDEV emfdev = get_emfdev( dev );
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pArc );
return (emfdev->funcs->pArc( emfdev, left, top, right, bottom, xstart, ystart, xend, yend ) &&
next->funcs->pArc( next, left, top, right, bottom, xstart, ystart, xend, yend ));
}
/***********************************************************************
* emfpathdrv_ArcTo
*/
static BOOL emfpathdrv_ArcTo( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend )
{
PHYSDEV emfdev = get_emfdev( dev );
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pArcTo );
return (emfdev->funcs->pArcTo( emfdev, left, top, right, bottom, xstart, ystart, xend, yend ) &&
next->funcs->pArcTo( next, left, top, right, bottom, xstart, ystart, xend, yend ));
}
/***********************************************************************
* emfpathdrv_BeginPath
*/
static BOOL emfpathdrv_BeginPath( PHYSDEV dev )
{
PHYSDEV emfdev = get_emfdev( dev );
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pBeginPath );
return (emfdev->funcs->pBeginPath( emfdev ) && next->funcs->pBeginPath( next ));
}
/***********************************************************************
* emfpathdrv_Chord
*/
static BOOL emfpathdrv_Chord( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend )
{
PHYSDEV emfdev = get_emfdev( dev );
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pChord );
return (emfdev->funcs->pChord( emfdev, left, top, right, bottom, xstart, ystart, xend, yend ) &&
next->funcs->pChord( next, left, top, right, bottom, xstart, ystart, xend, yend ));
}
/***********************************************************************
* emfpathdrv_CloseFigure
*/
static BOOL emfpathdrv_CloseFigure( PHYSDEV dev )
{
PHYSDEV emfdev = get_emfdev( dev );
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pCloseFigure );
emfdev->funcs->pCloseFigure( emfdev );
return next->funcs->pCloseFigure( next );
}
/***********************************************************************
* emfpathdrv_CreateDC
*/
static BOOL emfpathdrv_CreateDC( PHYSDEV *dev, LPCWSTR driver, LPCWSTR device,
LPCWSTR output, const DEVMODEW *devmode )
{
assert( 0 ); /* should never be called */
return TRUE;
}
/*************************************************************
* emfpathdrv_DeleteDC
*/
static BOOL emfpathdrv_DeleteDC( PHYSDEV dev )
{
EMFDRV_PDEVICE *physdev = (EMFDRV_PDEVICE *)get_emfdev( dev );
physdev->path = FALSE;
return TRUE;
}
/***********************************************************************
* emfpathdrv_Ellipse
*/
static BOOL emfpathdrv_Ellipse( PHYSDEV dev, INT x1, INT y1, INT x2, INT y2 )
{
PHYSDEV emfdev = get_emfdev( dev );
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pEllipse );
return (emfdev->funcs->pEllipse( emfdev, x1, y1, x2, y2 ) &&
next->funcs->pEllipse( next, x1, y1, x2, y2 ));
}
/***********************************************************************
* emfpathdrv_EndPath
*/
static BOOL emfpathdrv_EndPath( PHYSDEV dev )
{
PHYSDEV emfdev = get_emfdev( dev );
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pEndPath );
DC *dc = get_physdev_dc( dev );
emfpath_driver.pDeleteDC( pop_dc_driver( dc, &emfpath_driver ));
emfdev->funcs->pEndPath( emfdev );
return next->funcs->pEndPath( next );
}
/***********************************************************************
* emfpathdrv_ExtTextOut
*/
static BOOL emfpathdrv_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags, const RECT *rect,
LPCWSTR str, UINT count, const INT *dx )
{
PHYSDEV emfdev = get_emfdev( dev );
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pExtTextOut );
return (emfdev->funcs->pExtTextOut( emfdev, x, y, flags, rect, str, count, dx ) &&
next->funcs->pExtTextOut( next, x, y, flags, rect, str, count, dx ));
}
/***********************************************************************
* emfpathdrv_LineTo
*/
static BOOL emfpathdrv_LineTo( PHYSDEV dev, INT x, INT y )
{
PHYSDEV emfdev = get_emfdev( dev );
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pLineTo );
return (emfdev->funcs->pLineTo( emfdev, x, y ) && next->funcs->pLineTo( next, x, y ));
}
/***********************************************************************
* emfpathdrv_MoveTo
*/
static BOOL emfpathdrv_MoveTo( PHYSDEV dev, INT x, INT y )
{
PHYSDEV emfdev = get_emfdev( dev );
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pMoveTo );
return (emfdev->funcs->pMoveTo( emfdev, x, y ) && next->funcs->pMoveTo( next, x, y ));
}
/***********************************************************************
* emfpathdrv_Pie
*/
static BOOL emfpathdrv_Pie( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend )
{
PHYSDEV emfdev = get_emfdev( dev );
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPie );
return (emfdev->funcs->pPie( emfdev, left, top, right, bottom, xstart, ystart, xend, yend ) &&
next->funcs->pPie( next, left, top, right, bottom, xstart, ystart, xend, yend ));
}
/***********************************************************************
* emfpathdrv_PolyBezier
*/
static BOOL emfpathdrv_PolyBezier( PHYSDEV dev, const POINT *pts, DWORD count )
{
PHYSDEV emfdev = get_emfdev( dev );
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolyBezier );
return (emfdev->funcs->pPolyBezier( emfdev, pts, count ) &&
next->funcs->pPolyBezier( next, pts, count ));
}
/***********************************************************************
* emfpathdrv_PolyBezierTo
*/
static BOOL emfpathdrv_PolyBezierTo( PHYSDEV dev, const POINT *pts, DWORD count )
{
PHYSDEV emfdev = get_emfdev( dev );
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolyBezierTo );
return (emfdev->funcs->pPolyBezierTo( emfdev, pts, count ) &&
next->funcs->pPolyBezierTo( next, pts, count ));
}
/***********************************************************************
* emfpathdrv_PolyDraw
*/
static BOOL emfpathdrv_PolyDraw( PHYSDEV dev, const POINT *pts, const BYTE *types, DWORD count )
{
PHYSDEV emfdev = get_emfdev( dev );
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolyDraw );
return (emfdev->funcs->pPolyDraw( emfdev, pts, types, count ) &&
next->funcs->pPolyDraw( next, pts, types, count ));
}
/***********************************************************************
* emfpathdrv_PolyPolygon
*/
static BOOL emfpathdrv_PolyPolygon( PHYSDEV dev, const POINT *pts, const INT *counts, UINT polygons )
{
PHYSDEV emfdev = get_emfdev( dev );
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolyPolygon );
return (emfdev->funcs->pPolyPolygon( emfdev, pts, counts, polygons ) &&
next->funcs->pPolyPolygon( next, pts, counts, polygons ));
}
/***********************************************************************
* emfpathdrv_PolyPolyline
*/
static BOOL emfpathdrv_PolyPolyline( PHYSDEV dev, const POINT *pts, const DWORD *counts, DWORD polylines )
{
PHYSDEV emfdev = get_emfdev( dev );
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolyPolyline );
return (emfdev->funcs->pPolyPolyline( emfdev, pts, counts, polylines ) &&
next->funcs->pPolyPolyline( next, pts, counts, polylines ));
}
/***********************************************************************
* emfpathdrv_Polygon
*/
static BOOL emfpathdrv_Polygon( PHYSDEV dev, const POINT *pts, INT count )
{
PHYSDEV emfdev = get_emfdev( dev );
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolygon );
return (emfdev->funcs->pPolygon( emfdev, pts, count ) &&
next->funcs->pPolygon( next, pts, count ));
}
/***********************************************************************
* emfpathdrv_Polyline
*/
static BOOL emfpathdrv_Polyline( PHYSDEV dev, const POINT *pts, INT count )
{
PHYSDEV emfdev = get_emfdev( dev );
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolyline );
return (emfdev->funcs->pPolyline( emfdev, pts, count ) &&
next->funcs->pPolyline( next, pts, count ));
}
/***********************************************************************
* emfpathdrv_PolylineTo
*/
static BOOL emfpathdrv_PolylineTo( PHYSDEV dev, const POINT *pts, INT count )
{
PHYSDEV emfdev = get_emfdev( dev );
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolylineTo );
return (emfdev->funcs->pPolylineTo( emfdev, pts, count ) &&
next->funcs->pPolylineTo( next, pts, count ));
}
/***********************************************************************
* emfpathdrv_Rectangle
*/
static BOOL emfpathdrv_Rectangle( PHYSDEV dev, INT x1, INT y1, INT x2, INT y2 )
{
PHYSDEV emfdev = get_emfdev( dev );
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pRectangle );
return (emfdev->funcs->pRectangle( emfdev, x1, y1, x2, y2 ) &&
next->funcs->pRectangle( next, x1, y1, x2, y2 ));
}
/***********************************************************************
* emfpathdrv_RoundRect
*/
static BOOL emfpathdrv_RoundRect( PHYSDEV dev, INT x1, INT y1, INT x2, INT y2,
INT ell_width, INT ell_height )
{
PHYSDEV emfdev = get_emfdev( dev );
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pRoundRect );
return (emfdev->funcs->pRoundRect( emfdev, x1, y1, x2, y2, ell_width, ell_height ) &&
next->funcs->pRoundRect( next, x1, y1, x2, y2, ell_width, ell_height ));
}
static const struct gdi_dc_funcs emfpath_driver =
{
NULL, /* pAbortDoc */
emfpathdrv_AbortPath, /* pAbortPath */
NULL, /* pAlphaBlend */
emfpathdrv_AngleArc, /* pAngleArc */
emfpathdrv_Arc, /* pArc */
emfpathdrv_ArcTo, /* pArcTo */
emfpathdrv_BeginPath, /* pBeginPath */
NULL, /* pBlendImage */
emfpathdrv_Chord, /* pChord */
emfpathdrv_CloseFigure, /* pCloseFigure */
NULL, /* pCreateCompatibleDC */
emfpathdrv_CreateDC, /* pCreateDC */
emfpathdrv_DeleteDC, /* pDeleteDC */
NULL, /* pDeleteObject */
NULL, /* pDeviceCapabilities */
emfpathdrv_Ellipse, /* pEllipse */
NULL, /* pEndDoc */
NULL, /* pEndPage */
emfpathdrv_EndPath, /* pEndPath */
NULL, /* pEnumFonts */
NULL, /* pEnumICMProfiles */
NULL, /* pExcludeClipRect */
NULL, /* pExtDeviceMode */
NULL, /* pExtEscape */
NULL, /* pExtFloodFill */
NULL, /* pExtSelectClipRgn */
emfpathdrv_ExtTextOut, /* pExtTextOut */
NULL, /* pFillPath */
NULL, /* pFillRgn */
NULL, /* pFlattenPath */
NULL, /* pFontIsLinked */
NULL, /* pFrameRgn */
NULL, /* pGdiComment */
NULL, /* pGetBoundsRect */
NULL, /* pGetCharABCWidths */
NULL, /* pGetCharABCWidthsI */
NULL, /* pGetCharWidth */
#ifdef __REACTOS__
EMFDRV_GetDeviceCaps, //// Work around HACK.
#else
NULL, /* pGetDeviceCaps */
#endif
NULL, /* pGetDeviceGammaRamp */
NULL, /* pGetFontData */
NULL, /* pGetFontRealizationInfo */
NULL, /* pGetFontUnicodeRanges */
NULL, /* pGetGlyphIndices */
NULL, /* pGetGlyphOutline */
NULL, /* pGetICMProfile */
NULL, /* pGetImage */
NULL, /* pGetKerningPairs */
NULL, /* pGetNearestColor */
NULL, /* pGetOutlineTextMetrics */
NULL, /* pGetPixel */
NULL, /* pGetSystemPaletteEntries */
NULL, /* pGetTextCharsetInfo */
NULL, /* pGetTextExtentExPoint */
NULL, /* pGetTextExtentExPointI */
NULL, /* pGetTextFace */
NULL, /* pGetTextMetrics */
NULL, /* pGradientFill */
NULL, /* pIntersectClipRect */
NULL, /* pInvertRgn */
emfpathdrv_LineTo, /* pLineTo */
NULL, /* pModifyWorldTransform */
emfpathdrv_MoveTo, /* pMoveTo */
NULL, /* pOffsetClipRgn */
NULL, /* pOffsetViewportOrg */
NULL, /* pOffsetWindowOrg */
NULL, /* pPaintRgn */
NULL, /* pPatBlt */
emfpathdrv_Pie, /* pPie */
emfpathdrv_PolyBezier, /* pPolyBezier */
emfpathdrv_PolyBezierTo, /* pPolyBezierTo */
emfpathdrv_PolyDraw, /* pPolyDraw */
emfpathdrv_PolyPolygon, /* pPolyPolygon */
emfpathdrv_PolyPolyline, /* pPolyPolyline */
emfpathdrv_Polygon, /* pPolygon */
emfpathdrv_Polyline, /* pPolyline */
emfpathdrv_PolylineTo, /* pPolylineTo */
NULL, /* pPutImage */
NULL, /* pRealizeDefaultPalette */
NULL, /* pRealizePalette */
emfpathdrv_Rectangle, /* pRectangle */
NULL, /* pResetDC */
NULL, /* pRestoreDC */
emfpathdrv_RoundRect, /* pRoundRect */
NULL, /* pSaveDC */
NULL, /* pScaleViewportExt */
NULL, /* pScaleWindowExt */
NULL, /* pSelectBitmap */
NULL, /* pSelectBrush */
NULL, /* pSelectClipPath */
NULL, /* pSelectFont */
NULL, /* pSelectPalette */
NULL, /* pSelectPen */
NULL, /* pSetArcDirection */
NULL, /* pSetBkColor */
NULL, /* pSetBkMode */
NULL, /* pSetDCBrushColor */
NULL, /* pSetDCPenColor */
NULL, /* pSetDIBColorTable */
NULL, /* pSetDIBitsToDevice */
NULL, /* pSetDeviceClipping */
NULL, /* pSetDeviceGammaRamp */
NULL, /* pSetLayout */
NULL, /* pSetMapMode */
NULL, /* pSetMapperFlags */
NULL, /* pSetPixel */
NULL, /* pSetPolyFillMode */
NULL, /* pSetROP2 */
NULL, /* pSetRelAbs */
NULL, /* pSetStretchBltMode */
NULL, /* pSetTextAlign */
NULL, /* pSetTextCharacterExtra */
NULL, /* pSetTextColor */
NULL, /* pSetTextJustification */
NULL, /* pSetViewportExt */
NULL, /* pSetViewportOrg */
NULL, /* pSetWindowExt */
NULL, /* pSetWindowOrg */
NULL, /* pSetWorldTransform */
NULL, /* pStartDoc */
NULL, /* pStartPage */
NULL, /* pStretchBlt */
NULL, /* pStretchDIBits */
NULL, /* pStrokeAndFillPath */
NULL, /* pStrokePath */
NULL, /* pUnrealizePalette */
NULL, /* pWidenPath */
NULL, /* wine_get_wgl_driver */
GDI_PRIORITY_PATH_DRV + 1 /* priority */
};

View file

@ -33,6 +33,7 @@
typedef struct
{
struct gdi_physdev dev;
struct gdi_physdev pathdev;
ENHMETAHEADER *emh; /* Pointer to enhanced metafile header */
UINT handles_size, cur_handles;
HGDIOBJ *handles;
@ -58,8 +59,11 @@ extern DWORD EMFDRV_CreateBrushIndirect( PHYSDEV dev, HBRUSH hBrush ) DECLSPEC_H
/* Metafile driver functions */
extern BOOL EMFDRV_AbortPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_AngleArc( PHYSDEV dev, INT x, INT y, DWORD radius, FLOAT start, FLOAT sweep ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_Arc( PHYSDEV dev, INT left, INT top, INT right,
INT bottom, INT xstart, INT ystart, INT xend, INT yend ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_ArcTo( PHYSDEV dev, INT left, INT top, INT right,
INT bottom, INT xstart, INT ystart, INT xend, INT yend ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_BeginPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_BitBlt( PHYSDEV devDst, INT xDst, INT yDst, INT width, INT height,
PHYSDEV devSrc, INT xSrc, INT ySrc, DWORD rop ) DECLSPEC_HIDDEN;
@ -80,6 +84,8 @@ extern BOOL EMFDRV_FlattenPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_FrameRgn( PHYSDEV dev, HRGN hrgn, HBRUSH hbrush, INT width, INT height ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_GdiComment( PHYSDEV dev, UINT bytes, const BYTE *buffer ) DECLSPEC_HIDDEN;
extern INT EMFDRV_GetDeviceCaps( PHYSDEV dev, INT cap ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_GradientFill( PHYSDEV dev, TRIVERTEX *vert_array, ULONG nvert,
void *grad_array, ULONG ngrad, ULONG mode ) DECLSPEC_HIDDEN;
extern INT EMFDRV_IntersectClipRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_InvertRgn( PHYSDEV dev, HRGN hrgn ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_LineTo( PHYSDEV dev, INT x, INT y ) DECLSPEC_HIDDEN;
@ -94,10 +100,12 @@ extern BOOL EMFDRV_Pie( PHYSDEV dev, INT left, INT top, INT right, INT botto
INT xstart, INT ystart, INT xend, INT yend ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_PolyBezier( PHYSDEV dev, const POINT *pts, DWORD count ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_PolyBezierTo( PHYSDEV dev, const POINT *pts, DWORD count ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_PolyDraw( PHYSDEV dev, const POINT *pts, const BYTE *types, DWORD count ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_PolyPolygon( PHYSDEV dev, const POINT* pt, const INT* counts, UINT polys) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_PolyPolyline( PHYSDEV dev, const POINT* pt, const DWORD* counts, DWORD polys) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_Polygon( PHYSDEV dev, const POINT* pt, INT count ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_Polyline( PHYSDEV dev, const POINT* pt,INT count) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_PolylineTo( PHYSDEV dev, const POINT* pt,INT count) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_Rectangle( PHYSDEV dev, INT left, INT top, INT right, INT bottom) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_RestoreDC( PHYSDEV dev, INT level ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_RoundRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom,

View file

@ -69,10 +69,14 @@ static void *store_points( POINTL *dest, const POINT *pts, UINT count, BOOL shor
}
/* compute the bounds of an array of points, optionally including the current position */
#ifdef __REACTOS__
static void get_points_bounds( RECTL *bounds, const POINT *pts, UINT count, HDC hdc )
#else
static void get_points_bounds( RECTL *bounds, const POINT *pts, UINT count, DC *dc )
#endif
{
UINT i;
#ifdef __REACTOS__
if (hdc)
{
POINT cur_pt;
@ -80,6 +84,13 @@ static void get_points_bounds( RECTL *bounds, const POINT *pts, UINT count, HDC
bounds->left = bounds->right = cur_pt.x;
bounds->top = bounds->bottom = cur_pt.y;
}
#else
if (dc)
{
bounds->left = bounds->right = dc->cur_pos.x;
bounds->top = bounds->bottom = dc->cur_pos.y;
}
#endif
else if (count)
{
bounds->left = bounds->right = pts[0].x;
@ -96,6 +107,66 @@ static void get_points_bounds( RECTL *bounds, const POINT *pts, UINT count, HDC
}
}
/* helper for path stroke and fill functions */
#ifdef __REACTOS__
static BOOL emfdrv_stroke_and_fill_path( PHYSDEV dev, INT type )
{
EMRSTROKEANDFILLPATH emr;
LPPOINT Points;
LPBYTE Types;
INT nSize;
emr.emr.iType = type;
emr.emr.nSize = sizeof(emr);
nSize = GetPath(dev->hdc, NULL, NULL, 0);
if (nSize != -1)
{
Points = HeapAlloc( GetProcessHeap(), 0, nSize*sizeof(POINT) );
Types = HeapAlloc( GetProcessHeap(), 0, nSize*sizeof(BYTE) );
GetPath(dev->hdc, Points, Types, nSize);
get_points_bounds( &emr.rclBounds, Points, nSize, 0 );
HeapFree( GetProcessHeap(), 0, Points );
HeapFree( GetProcessHeap(), 0, Types );
TRACE("GetBounds l %d t %d r %d b %d\n",emr.rclBounds.left, emr.rclBounds.top, emr.rclBounds.right, emr.rclBounds.bottom);
}
else emr.rclBounds = empty_bounds;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
if (nSize == -1 ) return FALSE;
EMFDRV_UpdateBBox( dev, &emr.rclBounds );
return TRUE;
}
#else
static BOOL emfdrv_stroke_and_fill_path( PHYSDEV dev, INT type )
{
DC *dc = get_physdev_dc( dev );
EMRSTROKEANDFILLPATH emr;
struct gdi_path *path;
POINT *points;
BYTE *flags;
emr.emr.iType = type;
emr.emr.nSize = sizeof(emr);
if ((path = get_gdi_flat_path( dc, NULL )))
{
int count = get_gdi_path_data( path, &points, &flags );
get_points_bounds( &emr.rclBounds, points, count, 0 );
free_gdi_path( path );
}
else emr.rclBounds = empty_bounds;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
if (!path) return FALSE;
EMFDRV_UpdateBBox( dev, &emr.rclBounds );
return TRUE;
}
#endif
/**********************************************************************
* EMFDRV_MoveTo
*/
@ -116,6 +187,10 @@ BOOL EMFDRV_MoveTo(PHYSDEV dev, INT x, INT y)
*/
BOOL EMFDRV_LineTo( PHYSDEV dev, INT x, INT y )
{
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
#ifndef __REACTOS__
DC *dc = get_physdev_dc( dev );
#endif
POINT pt;
EMRLINETO emr;
RECTL bounds;
@ -127,15 +202,18 @@ BOOL EMFDRV_LineTo( PHYSDEV dev, INT x, INT y )
if(!EMFDRV_WriteRecord( dev, &emr.emr ))
return FALSE;
#ifdef __REACTOS__
GetCurrentPositionEx( dev->hdc, &pt );
#else
pt = dc->cur_pos;
#endif
bounds.left = min(x, pt.x);
bounds.top = min(y, pt.y);
bounds.right = max(x, pt.x);
bounds.bottom = max(y, pt.y);
EMFDRV_UpdateBBox( dev, &bounds );
if(!physDev->path)
EMFDRV_UpdateBBox( dev, &bounds );
return TRUE;
}
@ -148,6 +226,10 @@ static BOOL
EMFDRV_ArcChordPie( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend, DWORD iType )
{
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
#ifndef __REACTOS__
DC *dc = get_physdev_dc( dev );
#endif
INT temp, xCentre, yCentre, i;
double angleStart, angleEnd;
double xinterStart, yinterStart, xinterEnd, yinterEnd;
@ -158,8 +240,11 @@ EMFDRV_ArcChordPie( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
if(left > right) {temp = left; left = right; right = temp;}
if(top > bottom) {temp = top; top = bottom; bottom = temp;}
#ifdef __REACTOS__
if(GetGraphicsMode(dev->hdc) == GM_COMPATIBLE) {
#else
if(dc->GraphicsMode == GM_COMPATIBLE) {
#endif
right--;
bottom--;
}
@ -237,9 +322,23 @@ EMFDRV_ArcChordPie( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
if(bounds.top > yCentre) bounds.top = yCentre;
else if(bounds.bottom < yCentre) bounds.bottom = yCentre;
}
if (iType == EMR_ARCTO)
{
POINT pt;
#ifdef __REACTOS__
GetCurrentPositionEx( dev->hdc, &pt );
#else
pt = dc->cur_pos;
#endif
bounds.left = min( bounds.left, pt.x );
bounds.top = min( bounds.top, pt.y );
bounds.right = max( bounds.right, pt.x );
bounds.bottom = max( bounds.bottom, pt.y );
}
if(!EMFDRV_WriteRecord( dev, &emr.emr ))
return FALSE;
EMFDRV_UpdateBBox( dev, &bounds );
if(!physDev->path)
EMFDRV_UpdateBBox( dev, &bounds );
return TRUE;
}
@ -254,6 +353,16 @@ BOOL EMFDRV_Arc( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
xend, yend, EMR_ARC );
}
/***********************************************************************
* EMFDRV_ArcTo
*/
BOOL EMFDRV_ArcTo( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend )
{
return EMFDRV_ArcChordPie( dev, left, top, right, bottom, xstart, ystart,
xend, yend, EMR_ARCTO );
}
/***********************************************************************
* EMFDRV_Pie
*/
@ -275,11 +384,33 @@ BOOL EMFDRV_Chord( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
xend, yend, EMR_CHORD );
}
/***********************************************************************
* EMFDRV_AngleArc
*/
BOOL EMFDRV_AngleArc( PHYSDEV dev, INT x, INT y, DWORD radius, FLOAT start, FLOAT sweep )
{
EMRANGLEARC emr;
emr.emr.iType = EMR_ANGLEARC;
emr.emr.nSize = sizeof( emr );
emr.ptlCenter.x = x;
emr.ptlCenter.y = y;
emr.nRadius = radius;
emr.eStartAngle = start;
emr.eSweepAngle = sweep;
return EMFDRV_WriteRecord( dev, &emr.emr );
}
/***********************************************************************
* EMFDRV_Ellipse
*/
BOOL EMFDRV_Ellipse( PHYSDEV dev, INT left, INT top, INT right, INT bottom )
{
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
#ifndef __REACTOS__
DC *dc = get_physdev_dc( dev );
#endif
EMRELLIPSE emr;
INT temp;
@ -289,8 +420,11 @@ BOOL EMFDRV_Ellipse( PHYSDEV dev, INT left, INT top, INT right, INT bottom )
if(left > right) {temp = left; left = right; right = temp;}
if(top > bottom) {temp = top; top = bottom; bottom = temp;}
if(GetGraphicsMode( dev->hdc ) == GM_COMPATIBLE) {
#ifdef __REACTOS__
if(GetGraphicsMode(dev->hdc) == GM_COMPATIBLE) {
#else
if(dc->GraphicsMode == GM_COMPATIBLE) {
#endif
right--;
bottom--;
}
@ -302,7 +436,8 @@ BOOL EMFDRV_Ellipse( PHYSDEV dev, INT left, INT top, INT right, INT bottom )
emr.rclBox.right = right;
emr.rclBox.bottom = bottom;
EMFDRV_UpdateBBox( dev, &emr.rclBox );
if(!physDev->path)
EMFDRV_UpdateBBox( dev, &emr.rclBox );
return EMFDRV_WriteRecord( dev, &emr.emr );
}
@ -311,6 +446,10 @@ BOOL EMFDRV_Ellipse( PHYSDEV dev, INT left, INT top, INT right, INT bottom )
*/
BOOL EMFDRV_Rectangle(PHYSDEV dev, INT left, INT top, INT right, INT bottom)
{
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
#ifndef __REACTOS__
DC *dc = get_physdev_dc( dev );
#endif
EMRRECTANGLE emr;
INT temp;
@ -320,8 +459,11 @@ BOOL EMFDRV_Rectangle(PHYSDEV dev, INT left, INT top, INT right, INT bottom)
if(left > right) {temp = left; left = right; right = temp;}
if(top > bottom) {temp = top; top = bottom; bottom = temp;}
if(GetGraphicsMode( dev->hdc ) == GM_COMPATIBLE) {
#ifdef __REACTOS__
if(GetGraphicsMode(dev->hdc) == GM_COMPATIBLE) {
#else
if(dc->GraphicsMode == GM_COMPATIBLE) {
#endif
right--;
bottom--;
}
@ -333,7 +475,8 @@ BOOL EMFDRV_Rectangle(PHYSDEV dev, INT left, INT top, INT right, INT bottom)
emr.rclBox.right = right;
emr.rclBox.bottom = bottom;
EMFDRV_UpdateBBox( dev, &emr.rclBox );
if(!physDev->path)
EMFDRV_UpdateBBox( dev, &emr.rclBox );
return EMFDRV_WriteRecord( dev, &emr.emr );
}
@ -343,6 +486,10 @@ BOOL EMFDRV_Rectangle(PHYSDEV dev, INT left, INT top, INT right, INT bottom)
BOOL EMFDRV_RoundRect( PHYSDEV dev, INT left, INT top, INT right,
INT bottom, INT ell_width, INT ell_height )
{
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
#ifndef __REACTOS__
DC *dc = get_physdev_dc( dev );
#endif
EMRROUNDRECT emr;
INT temp;
@ -350,8 +497,11 @@ BOOL EMFDRV_RoundRect( PHYSDEV dev, INT left, INT top, INT right,
if(left > right) {temp = left; left = right; right = temp;}
if(top > bottom) {temp = top; top = bottom; bottom = temp;}
if(GetGraphicsMode( dev->hdc ) == GM_COMPATIBLE) {
#ifdef __REACTOS__
if(GetGraphicsMode(dev->hdc) == GM_COMPATIBLE) {
#else
if(dc->GraphicsMode == GM_COMPATIBLE) {
#endif
right--;
bottom--;
}
@ -365,7 +515,8 @@ BOOL EMFDRV_RoundRect( PHYSDEV dev, INT left, INT top, INT right,
emr.szlCorner.cx = ell_width;
emr.szlCorner.cy = ell_height;
EMFDRV_UpdateBBox( dev, &emr.rclBox );
if(!physDev->path)
EMFDRV_UpdateBBox( dev, &emr.rclBox );
return EMFDRV_WriteRecord( dev, &emr.emr );
}
@ -400,93 +551,35 @@ COLORREF EMFDRV_SetPixel( PHYSDEV dev, INT x, INT y, COLORREF color )
static BOOL
EMFDRV_Polylinegon( PHYSDEV dev, const POINT* pt, INT count, DWORD iType )
{
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
#ifndef __REACTOS__
DC *dc = get_physdev_dc( dev );
#endif
EMRPOLYLINE *emr;
DWORD size;
INT i;
BOOL ret;
BOOL ret, use_small_emr = can_use_short_points( pt, count );
size = sizeof(EMRPOLYLINE) + sizeof(POINTL) * (count - 1);
size = use_small_emr ? offsetof( EMRPOLYLINE16, apts[count] ) : offsetof( EMRPOLYLINE, aptl[count] );
emr = HeapAlloc( GetProcessHeap(), 0, size );
emr->emr.iType = iType;
emr->emr.iType = use_small_emr ? iType + EMR_POLYLINE16 - EMR_POLYLINE : iType;
emr->emr.nSize = size;
emr->rclBounds.left = emr->rclBounds.right = pt[0].x;
emr->rclBounds.top = emr->rclBounds.bottom = pt[0].y;
for(i = 1; i < count; i++) {
if(pt[i].x < emr->rclBounds.left)
emr->rclBounds.left = pt[i].x;
else if(pt[i].x > emr->rclBounds.right)
emr->rclBounds.right = pt[i].x;
if(pt[i].y < emr->rclBounds.top)
emr->rclBounds.top = pt[i].y;
else if(pt[i].y > emr->rclBounds.bottom)
emr->rclBounds.bottom = pt[i].y;
}
emr->cptl = count;
memcpy(emr->aptl, pt, count * sizeof(POINTL));
store_points( emr->aptl, pt, count, use_small_emr );
if (!physDev->path)
get_points_bounds( &emr->rclBounds, pt, count,
#ifdef __REACTOS__
(iType == EMR_POLYBEZIERTO || iType == EMR_POLYLINETO) ? dev->hdc : 0 );
#else
(iType == EMR_POLYBEZIERTO || iType == EMR_POLYLINETO) ? dc : 0 );
#endif
else
emr->rclBounds = empty_bounds;
ret = EMFDRV_WriteRecord( dev, &emr->emr );
if(ret)
EMFDRV_UpdateBBox( dev, &emr->rclBounds );
HeapFree( GetProcessHeap(), 0, emr );
return ret;
}
/**********************************************************************
* EMFDRV_Polylinegon16
*
* Helper for EMFDRV_Poly{line|gon}
*
* This is not a legacy function!
* We are using SHORT integers to save space.
*/
static BOOL
EMFDRV_Polylinegon16( PHYSDEV dev, const POINT* pt, INT count, DWORD iType )
{
EMRPOLYLINE16 *emr;
DWORD size;
INT i;
BOOL ret;
/* check whether all points fit in the SHORT int POINT structure */
for(i = 0; i < count; i++) {
if( ((pt[i].x+0x8000) & ~0xffff ) ||
((pt[i].y+0x8000) & ~0xffff ) )
return FALSE;
}
size = sizeof(EMRPOLYLINE16) + sizeof(POINTS) * (count - 1);
emr = HeapAlloc( GetProcessHeap(), 0, size );
emr->emr.iType = iType;
emr->emr.nSize = size;
emr->rclBounds.left = emr->rclBounds.right = pt[0].x;
emr->rclBounds.top = emr->rclBounds.bottom = pt[0].y;
for(i = 1; i < count; i++) {
if(pt[i].x < emr->rclBounds.left)
emr->rclBounds.left = pt[i].x;
else if(pt[i].x > emr->rclBounds.right)
emr->rclBounds.right = pt[i].x;
if(pt[i].y < emr->rclBounds.top)
emr->rclBounds.top = pt[i].y;
else if(pt[i].y > emr->rclBounds.bottom)
emr->rclBounds.bottom = pt[i].y;
}
emr->cpts = count;
for(i = 0; i < count; i++ ) {
emr->apts[i].x = pt[i].x;
emr->apts[i].y = pt[i].y;
}
ret = EMFDRV_WriteRecord( dev, &emr->emr );
if(ret)
if (ret && !physDev->path)
EMFDRV_UpdateBBox( dev, &emr->rclBounds );
HeapFree( GetProcessHeap(), 0, emr );
return ret;
@ -498,19 +591,23 @@ EMFDRV_Polylinegon16( PHYSDEV dev, const POINT* pt, INT count, DWORD iType )
*/
BOOL EMFDRV_Polyline( PHYSDEV dev, const POINT* pt, INT count )
{
if( EMFDRV_Polylinegon16( dev, pt, count, EMR_POLYLINE16 ) )
return TRUE;
return EMFDRV_Polylinegon( dev, pt, count, EMR_POLYLINE );
}
/**********************************************************************
* EMFDRV_PolylineTo
*/
BOOL EMFDRV_PolylineTo( PHYSDEV dev, const POINT* pt, INT count )
{
return EMFDRV_Polylinegon( dev, pt, count, EMR_POLYLINETO );
}
/**********************************************************************
* EMFDRV_Polygon
*/
BOOL EMFDRV_Polygon( PHYSDEV dev, const POINT* pt, INT count )
{
if(count < 2) return FALSE;
if( EMFDRV_Polylinegon16( dev, pt, count, EMR_POLYGON16 ) )
return TRUE;
return EMFDRV_Polylinegon( dev, pt, count, EMR_POLYGON );
}
@ -519,8 +616,6 @@ BOOL EMFDRV_Polygon( PHYSDEV dev, const POINT* pt, INT count )
*/
BOOL EMFDRV_PolyBezier( PHYSDEV dev, const POINT *pts, DWORD count )
{
if(EMFDRV_Polylinegon16( dev, pts, count, EMR_POLYBEZIER16 ))
return TRUE;
return EMFDRV_Polylinegon( dev, pts, count, EMR_POLYBEZIER );
}
@ -529,8 +624,6 @@ BOOL EMFDRV_PolyBezier( PHYSDEV dev, const POINT *pts, DWORD count )
*/
BOOL EMFDRV_PolyBezierTo( PHYSDEV dev, const POINT *pts, DWORD count )
{
if(EMFDRV_Polylinegon16( dev, pts, count, EMR_POLYBEZIERTO16 ))
return TRUE;
return EMFDRV_Polylinegon( dev, pts, count, EMR_POLYBEZIERTO );
}
@ -611,6 +704,43 @@ BOOL EMFDRV_PolyPolygon( PHYSDEV dev, const POINT* pt, const INT* counts, UINT p
}
/**********************************************************************
* EMFDRV_PolyDraw
*/
BOOL EMFDRV_PolyDraw( PHYSDEV dev, const POINT *pts, const BYTE *types, DWORD count )
{
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
EMRPOLYDRAW *emr;
BOOL ret;
BYTE *types_dest;
BOOL use_small_emr = can_use_short_points( pts, count );
DWORD size;
size = use_small_emr ? offsetof( EMRPOLYDRAW16, apts[count] ) : offsetof( EMRPOLYDRAW, aptl[count] );
size += (count + 3) & ~3;
if (!(emr = HeapAlloc( GetProcessHeap(), 0, size ))) return FALSE;
emr->emr.iType = use_small_emr ? EMR_POLYDRAW16 : EMR_POLYDRAW;
emr->emr.nSize = size;
emr->cptl = count;
types_dest = store_points( emr->aptl, pts, count, use_small_emr );
memcpy( types_dest, types, count );
if (count & 3) memset( types_dest + count, 0, 4 - (count & 3) );
if (!physDev->path)
get_points_bounds( &emr->rclBounds, pts, count, 0 );
else
emr->rclBounds = empty_bounds;
ret = EMFDRV_WriteRecord( dev, &emr->emr );
if (ret && !physDev->path) EMFDRV_UpdateBBox( dev, &emr->rclBounds );
HeapFree( GetProcessHeap(), 0, emr );
return ret;
}
/**********************************************************************
* EMFDRV_ExtFloodFill
*/
@ -753,13 +883,22 @@ BOOL EMFDRV_InvertRgn( PHYSDEV dev, HRGN hrgn )
BOOL EMFDRV_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags, const RECT *lprect,
LPCWSTR str, UINT count, const INT *lpDx )
{
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
#ifndef __REACTOS__
DC *dc = get_physdev_dc( dev );
#endif
EMREXTTEXTOUTW *pemr;
DWORD nSize;
BOOL ret;
int textHeight = 0;
int textWidth = 0;
#ifdef __REACTOS__
const UINT textAlign = GetTextAlign( dev->hdc );
const INT graphicsMode = GetGraphicsMode( dev->hdc );
#else
const UINT textAlign = dc->textAlign;
const INT graphicsMode = dc->GraphicsMode;
#endif
FLOAT exScale, eyScale;
nSize = sizeof(*pemr) + ((count+1) & ~1) * sizeof(WCHAR) + count * sizeof(INT);
@ -834,13 +973,14 @@ BOOL EMFDRV_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags, const RECT *lprec
}
}
if (!lprect)
if (physDev->path)
{
pemr->rclBounds.left = pemr->rclBounds.top = 0;
pemr->rclBounds.right = pemr->rclBounds.bottom = -1;
goto no_bounds;
}
/* FIXME: handle font escapement */
switch (textAlign & (TA_LEFT | TA_RIGHT | TA_CENTER)) {
case TA_CENTER: {
pemr->rclBounds.left = x - (textWidth / 2) - 1;
@ -886,3 +1026,81 @@ no_bounds:
HeapFree( GetProcessHeap(), 0, pemr );
return ret;
}
/**********************************************************************
* EMFDRV_GradientFill
*/
BOOL EMFDRV_GradientFill( PHYSDEV dev, TRIVERTEX *vert_array, ULONG nvert,
void *grad_array, ULONG ngrad, ULONG mode )
{
EMRGRADIENTFILL *emr;
ULONG i, pt, size, num_pts = ngrad * (mode == GRADIENT_FILL_TRIANGLE ? 3 : 2);
const ULONG *pts = (const ULONG *)grad_array;
BOOL ret;
size = FIELD_OFFSET(EMRGRADIENTFILL, Ver[nvert]) + num_pts * sizeof(pts[0]);
emr = HeapAlloc( GetProcessHeap(), 0, size );
if (!emr) return FALSE;
for (i = 0; i < num_pts; i++)
{
pt = pts[i];
if (i == 0)
{
emr->rclBounds.left = emr->rclBounds.right = vert_array[pt].x;
emr->rclBounds.top = emr->rclBounds.bottom = vert_array[pt].y;
}
else
{
if (vert_array[pt].x < emr->rclBounds.left)
emr->rclBounds.left = vert_array[pt].x;
else if (vert_array[pt].x > emr->rclBounds.right)
emr->rclBounds.right = vert_array[pt].x;
if (vert_array[pt].y < emr->rclBounds.top)
emr->rclBounds.top = vert_array[pt].y;
else if (vert_array[pt].y > emr->rclBounds.bottom)
emr->rclBounds.bottom = vert_array[pt].y;
}
}
emr->rclBounds.right--;
emr->rclBounds.bottom--;
emr->emr.iType = EMR_GRADIENTFILL;
emr->emr.nSize = size;
emr->nVer = nvert;
emr->nTri = ngrad;
emr->ulMode = mode;
memcpy( emr->Ver, vert_array, nvert * sizeof(vert_array[0]) );
memcpy( emr->Ver + nvert, pts, num_pts * sizeof(pts[0]) );
EMFDRV_UpdateBBox( dev, &emr->rclBounds );
ret = EMFDRV_WriteRecord( dev, &emr->emr );
HeapFree( GetProcessHeap(), 0, emr );
return ret;
}
/**********************************************************************
* EMFDRV_FillPath
*/
BOOL EMFDRV_FillPath( PHYSDEV dev )
{
return emfdrv_stroke_and_fill_path( dev, EMR_FILLPATH );
}
/**********************************************************************
* EMFDRV_StrokeAndFillPath
*/
BOOL EMFDRV_StrokeAndFillPath( PHYSDEV dev )
{
return emfdrv_stroke_and_fill_path( dev, EMR_STROKEANDFILLPATH );
}
/**********************************************************************
* EMFDRV_StrokePath
*/
BOOL EMFDRV_StrokePath( PHYSDEV dev )
{
return emfdrv_stroke_and_fill_path( dev, EMR_STROKEPATH );
}

View file

@ -34,14 +34,14 @@ WINE_DEFAULT_DEBUG_CHANNEL(enhmetafile);
static BOOL EMFDRV_DeleteDC( PHYSDEV dev );
static const struct gdi_dc_funcs EMFDRV_Funcs =
static const struct gdi_dc_funcs emfdrv_driver =
{
NULL, /* pAbortDoc */
EMFDRV_AbortPath, /* pAbortPath */
NULL, /* pAlphaBlend */
NULL, /* pAngleArc */
EMFDRV_AngleArc, /* pAngleArc */
EMFDRV_Arc, /* pArc */
NULL, /* pArcTo */
EMFDRV_ArcTo, /* pArcTo */
EMFDRV_BeginPath, /* pBeginPath */
NULL, /* pBlendImage */
EMFDRV_Chord, /* pChord */
@ -69,7 +69,6 @@ static const struct gdi_dc_funcs EMFDRV_Funcs =
NULL, /* pFontIsLinked */
EMFDRV_FrameRgn, /* pFrameRgn */
EMFDRV_GdiComment, /* pGdiComment */
NULL, /* pGdiRealizationInfo */
NULL, /* pGetBoundsRect */
NULL, /* pGetCharABCWidths */
NULL, /* pGetCharABCWidthsI */
@ -77,6 +76,7 @@ static const struct gdi_dc_funcs EMFDRV_Funcs =
EMFDRV_GetDeviceCaps, /* pGetDeviceCaps */
NULL, /* pGetDeviceGammaRamp */
NULL, /* pGetFontData */
NULL, /* pGetFontRealizationInfo */
NULL, /* pGetFontUnicodeRanges */
NULL, /* pGetGlyphIndices */
NULL, /* pGetGlyphOutline */
@ -92,7 +92,7 @@ static const struct gdi_dc_funcs EMFDRV_Funcs =
NULL, /* pGetTextExtentExPointI */
NULL, /* pGetTextFace */
NULL, /* pGetTextMetrics */
NULL, /* pGradientFill */
EMFDRV_GradientFill, /* pGradientFill */
EMFDRV_IntersectClipRect, /* pIntersectClipRect */
EMFDRV_InvertRgn, /* pInvertRgn */
EMFDRV_LineTo, /* pLineTo */
@ -106,12 +106,12 @@ static const struct gdi_dc_funcs EMFDRV_Funcs =
EMFDRV_Pie, /* pPie */
EMFDRV_PolyBezier, /* pPolyBezier */
EMFDRV_PolyBezierTo, /* pPolyBezierTo */
NULL, /* pPolyDraw */
EMFDRV_PolyDraw, /* pPolyDraw */
EMFDRV_PolyPolygon, /* pPolyPolygon */
EMFDRV_PolyPolyline, /* pPolyPolyline */
EMFDRV_Polygon, /* pPolygon */
EMFDRV_Polyline, /* pPolyline */
NULL, /* pPolylineTo */
EMFDRV_PolylineTo, /* pPolylineTo */
NULL, /* pPutImage */
NULL, /* pRealizeDefaultPalette */
NULL, /* pRealizePalette */
@ -172,10 +172,10 @@ static const struct gdi_dc_funcs EMFDRV_Funcs =
*/
static BOOL EMFDRV_DeleteDC( PHYSDEV dev )
{
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
UINT index;
if (physDev->emh) HeapFree( GetProcessHeap(), 0, physDev->emh );
HeapFree( GetProcessHeap(), 0, physDev->emh );
for(index = 0; index < physDev->handles_size; index++)
if(physDev->handles[index])
GDI_hdc_not_using_object(physDev->handles[index], dev->hdc);
@ -195,7 +195,7 @@ BOOL EMFDRV_WriteRecord( PHYSDEV dev, EMR *emr )
DWORD len;
DWORD bytes_written;
ENHMETAHEADER *emh;
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
TRACE("record %d, size %d %s\n",
emr->iType, emr->nSize, physDev->hFile ? "(to disk)" : "");
@ -229,7 +229,7 @@ BOOL EMFDRV_WriteRecord( PHYSDEV dev, EMR *emr )
*/
void EMFDRV_UpdateBBox( PHYSDEV dev, RECTL *rect )
{
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
RECTL *bounds = &physDev->emh->rclBounds;
RECTL vportRect = *rect;
@ -319,11 +319,11 @@ HDC WINAPI CreateEnhMetaFileW(
DWORD size = 0, length = 0;
DWORD bytes_written;
TRACE("%s\n", debugstr_w(filename) );
TRACE("(%p %s %s %s)\n", hdc, debugstr_w(filename), wine_dbgstr_rect(rect), debugstr_w(description) );
if (!(dc = alloc_dc_ptr( OBJ_ENHMETADC ))) return 0;
physDev = HeapAlloc(GetProcessHeap(),0,sizeof(*physDev));
physDev = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*physDev));
if (!physDev) {
free_dc_ptr( dc );
return 0;
@ -342,7 +342,7 @@ HDC WINAPI CreateEnhMetaFileW(
return 0;
}
push_dc_driver( &dc->physDev, &physDev->dev, &EMFDRV_Funcs );
push_dc_driver( &dc->physDev, &physDev->dev, &emfdrv_driver );
physDev->handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, HANDLE_LIST_INC * sizeof(physDev->handles[0]));
physDev->handles_size = HANDLE_LIST_INC;
@ -352,6 +352,7 @@ HDC WINAPI CreateEnhMetaFileW(
physDev->dc_pen = 0;
physDev->screen_dc = 0;
physDev->restoring = 0;
physDev->path = FALSE;
if (hdc) /* if no ref, use current display */
physDev->ref_dc = hdc;
else
@ -449,7 +450,7 @@ HENHMETAFILE WINAPI CloseEnhMetaFile(HDC hdc) /* [in] metafile DC */
release_dc_ptr( dc );
return NULL;
}
physDev = (EMFDRV_PDEVICE *)dc->physDev;
physDev = get_emf_physdev( find_dc_driver( dc, &emfdrv_driver ));
if(dc->saveLevel)
RestoreDC(hdc, 1);
@ -463,7 +464,7 @@ HENHMETAFILE WINAPI CloseEnhMetaFile(HDC hdc) /* [in] metafile DC */
emr.nPalEntries = 0;
emr.offPalEntries = FIELD_OFFSET(EMREOF, nSizeLast);
emr.nSizeLast = emr.emr.nSize;
EMFDRV_WriteRecord( dc->physDev, &emr.emr );
EMFDRV_WriteRecord( &physDev->dev, &emr.emr );
/* Update rclFrame if not initialized in CreateEnhMetaFile */
if(physDev->emh->rclFrame.left > physDev->emh->rclFrame.right) {

View file

@ -34,7 +34,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(enhmetafile);
*/
static UINT EMFDRV_AddHandle( PHYSDEV dev, HGDIOBJ obj )
{
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
UINT index;
for(index = 0; index < physDev->handles_size; index++)
@ -59,7 +59,7 @@ static UINT EMFDRV_AddHandle( PHYSDEV dev, HGDIOBJ obj )
*/
static UINT EMFDRV_FindObject( PHYSDEV dev, HGDIOBJ obj )
{
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*) dev;
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
UINT index;
for(index = 0; index < physDev->handles_size; index++)
@ -77,7 +77,7 @@ static UINT EMFDRV_FindObject( PHYSDEV dev, HGDIOBJ obj )
BOOL EMFDRV_DeleteObject( PHYSDEV dev, HGDIOBJ obj )
{
EMRDELETEOBJECT emr;
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*) dev;
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
UINT index;
BOOL ret = TRUE;
@ -136,8 +136,11 @@ DWORD EMFDRV_CreateBrushIndirect( PHYSDEV dev, HBRUSH hBrush )
case BS_DIBPATTERN:
{
EMRCREATEDIBPATTERNBRUSHPT *emr;
char buffer[sizeof(BITMAPINFO) + 255 * sizeof(RGBQUAD)]; // ros!
//char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
#ifdef __REACTOS__
char buffer[sizeof(BITMAPINFO) + 255 * sizeof(RGBQUAD)]; // ros
#else
char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
#endif
BITMAPINFO *info = (BITMAPINFO *)buffer;
DWORD info_size;
void *bits;
@ -162,7 +165,7 @@ DWORD EMFDRV_CreateBrushIndirect( PHYSDEV dev, HBRUSH hBrush )
emr->emr.iType = EMR_CREATEMONOBRUSH;
usage = DIB_PAL_MONO;
/* FIXME: There is an extra DWORD written by native before the BMI.
* Not sure what its meant to contain.
* Not sure what it's meant to contain.
*/
emr->offBmi = sizeof( EMRCREATEDIBPATTERNBRUSHPT ) + sizeof(DWORD);
emr->cbBmi = sizeof( BITMAPINFOHEADER );
@ -201,7 +204,7 @@ DWORD EMFDRV_CreateBrushIndirect( PHYSDEV dev, HBRUSH hBrush )
*/
HBRUSH EMFDRV_SelectBrush( PHYSDEV dev, HBRUSH hBrush, const struct brush_pattern *pattern )
{
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*)dev;
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
EMRSELECTOBJECT emr;
DWORD index;
int i;
@ -280,7 +283,7 @@ static BOOL EMFDRV_CreateFontIndirect(PHYSDEV dev, HFONT hFont )
*/
HFONT EMFDRV_SelectFont( PHYSDEV dev, HFONT hFont, UINT *aa_flags )
{
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*)dev;
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
EMRSELECTOBJECT emr;
DWORD index;
int i;
@ -365,7 +368,7 @@ static DWORD EMFDRV_CreatePenIndirect(PHYSDEV dev, HPEN hPen)
*/
HPEN EMFDRV_SelectPen(PHYSDEV dev, HPEN hPen, const struct brush_pattern *pattern )
{
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*)dev;
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
EMRSELECTOBJECT emr;
DWORD index;
int i;
@ -433,7 +436,7 @@ static DWORD EMFDRV_CreatePalette(PHYSDEV dev, HPALETTE hPal)
*/
HPALETTE EMFDRV_SelectPalette( PHYSDEV dev, HPALETTE hPal, BOOL force )
{
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*)dev;
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
EMRSELECTPALETTE emr;
DWORD index;
@ -463,12 +466,17 @@ found:
*/
COLORREF EMFDRV_SetDCBrushColor( PHYSDEV dev, COLORREF color )
{
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*)dev;
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
#ifndef __REACTOS__
DC *dc = get_physdev_dc( dev );
#endif
EMRSELECTOBJECT emr;
DWORD index;
#ifdef __REACTOS__
if (GetCurrentObject( dev->hdc, OBJ_BRUSH ) != GetStockObject( DC_BRUSH )) return color;
#else
if (dc->hBrush != GetStockObject( DC_BRUSH )) return color;
#endif
if (physDev->dc_brush) DeleteObject( physDev->dc_brush );
if (!(physDev->dc_brush = CreateSolidBrush( color ))) return CLR_INVALID;
if (!(index = EMFDRV_CreateBrushIndirect(dev, physDev->dc_brush ))) return CLR_INVALID;
@ -484,13 +492,18 @@ COLORREF EMFDRV_SetDCBrushColor( PHYSDEV dev, COLORREF color )
*/
COLORREF EMFDRV_SetDCPenColor( PHYSDEV dev, COLORREF color )
{
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*)dev;
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
#ifndef __REACTOS__
DC *dc = get_physdev_dc( dev );
#endif
EMRSELECTOBJECT emr;
DWORD index;
LOGPEN logpen = { PS_SOLID, { 0, 0 }, color };
#ifdef __REACTOS__
if (GetCurrentObject( dev->hdc, OBJ_PEN ) != GetStockObject( DC_PEN )) return color;
#else
if (dc->hPen != GetStockObject( DC_PEN )) return color;
#endif
if (physDev->dc_pen) DeleteObject( physDev->dc_pen );
if (!(physDev->dc_pen = CreatePenIndirect( &logpen ))) return CLR_INVALID;
if (!(index = EMFDRV_CreatePenIndirect(dev, physDev->dc_pen))) return CLR_INVALID;

View file

@ -55,16 +55,18 @@ struct gdi_obj_funcs
typedef struct tagWINEDC
{
HDC hdc;
struct gdi_physdev NullPhysDev;
PHYSDEV physDev; /* current top of the physdev stack */
LONG refcount; /* thread refcount */
INT saveLevel;
struct gdi_physdev NullPhysDev;
HFONT hFont;
HBRUSH hBrush;
HPEN hPen;
HPALETTE hPalette;
} WINEDC, DC;
WINEDC* get_physdev_dc( PHYSDEV dev );
/* brush.c */
extern BOOL get_brush_bitmap_info( HBRUSH handle, BITMAPINFO *info, void **bits, UINT *usage ) DECLSPEC_HIDDEN;
@ -119,6 +121,27 @@ extern UINT WINAPI GDIRealizePalette( HDC hdc ) DECLSPEC_HIDDEN;
#define EMR_SETLINKEDUFI 119
#define GET_DC_PHYSDEV(dc,func) \
get_physdev_entry_point( (dc)->physDev, FIELD_OFFSET(struct gdi_dc_funcs,func))
static inline PHYSDEV pop_dc_driver( DC *dc, const struct gdi_dc_funcs *funcs )
{
PHYSDEV dev, *pdev = &dc->physDev;
while (*pdev && (*pdev)->funcs != funcs) pdev = &(*pdev)->next;
if (!*pdev) return NULL;
dev = *pdev;
*pdev = dev->next;
return dev;
}
static inline PHYSDEV find_dc_driver( DC *dc, const struct gdi_dc_funcs *funcs )
{
PHYSDEV dev;
for (dev = dc->physDev; dev; dev = dev->next) if (dev->funcs == funcs) return dev;
return NULL;
}
/* Undocumented value for DIB's iUsage: Indicates a mono DIB w/o pal entries */
#define DIB_PAL_MONO 2
@ -145,6 +168,9 @@ static inline int get_dib_info_size( const BITMAPINFO *info, UINT coloruse )
return FIELD_OFFSET( BITMAPINFO, bmiColors[info->bmiHeader.biClrUsed] );
}
#define GdiWorldSpaceToDeviceSpace 0x204
BOOL APIENTRY NtGdiGetTransform( _In_ HDC hdc, _In_ DWORD iXform, _Out_ LPXFORM pxf);
/* Special sauce for reactos */
#define GDIRealizePalette RealizePalette
#define GDISelectPalette SelectPalette

View file

@ -56,8 +56,11 @@
#include "wingdi.h"
#include "winreg.h"
#include "winnls.h"
#ifdef __REACTOS__
#include "wine/winternl.h"
#else
#include "winternl.h"
#endif
#include "gdi_private.h"
#include "wine/debug.h"

View file

@ -161,7 +161,7 @@ INT MFDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst,
/***********************************************************************
* MFDRV_SetDIBitsToDeivce
* MFDRV_SetDIBitsToDevice
*/
INT MFDRV_SetDIBitsToDevice( PHYSDEV dev, INT xDst, INT yDst, DWORD cx,
DWORD cy, INT xSrc, INT ySrc, UINT startscan,

View file

@ -132,7 +132,6 @@ static const struct gdi_dc_funcs MFDRV_Funcs =
NULL, /* pFontIsLinked */
MFDRV_FrameRgn, /* pFrameRgn */
NULL, /* pGdiComment */
NULL, /* pGdiRealizationInfo */
MFDRV_GetBoundsRect, /* pGetBoundsRect */
NULL, /* pGetCharABCWidths */
NULL, /* pGetCharABCWidthsI */
@ -140,6 +139,7 @@ static const struct gdi_dc_funcs MFDRV_Funcs =
MFDRV_GetDeviceCaps, /* pGetDeviceCaps */
NULL, /* pGetDeviceGammaRamp */
NULL, /* pGetFontData */
NULL, /* pGetFontRealizationInfo */
NULL, /* pGetFontUnicodeRanges */
NULL, /* pGetGlyphIndices */
NULL, /* pGetGlyphOutline */

View file

@ -176,8 +176,11 @@ INT16 MFDRV_CreateBrushIndirect(PHYSDEV dev, HBRUSH hBrush )
case BS_PATTERN:
case BS_DIBPATTERN:
{
#ifdef __REACTOS__
char buffer[sizeof(BITMAPINFO) + 255 * sizeof(RGBQUAD)]; // ros
//char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
#else
char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
#endif
BITMAPINFO *dst_info, *src_info = (BITMAPINFO *)buffer;
DWORD info_size;
char *dst_ptr;

View file

@ -0,0 +1,570 @@
//
//
// Do not remove this file, "Justin Case" future maintenance issues with Path arises.......
//
//
#include <precomp.h>
#include "gdi_private.h"
#define NDEBUG
#include <debug.h>
WINEDC *get_nulldrv_dc( PHYSDEV dev );
const struct gdi_dc_funcs path_driver DECLSPEC_HIDDEN;
struct path_physdev
{
struct gdi_physdev dev;
//struct gdi_path *path;
BOOL HasPathHook;
};
static inline struct path_physdev *get_path_physdev( PHYSDEV dev )
{
return CONTAINING_RECORD( dev, struct path_physdev, dev );
}
/***********************************************************************
* pathdrv_BeginPath
*/
static BOOL pathdrv_BeginPath( PHYSDEV dev )
{
DPRINT("pathdrv_BeginPath dev %p\n",dev);
return TRUE;
}
/***********************************************************************
* pathdrv_AbortPath
*/
static BOOL pathdrv_AbortPath( PHYSDEV dev )
{
DC *dc = get_physdev_dc( dev );
DPRINT("pathdrv_AbortPath dev %p\n",dev);
path_driver.pDeleteDC( pop_dc_driver( dc, &path_driver ));
return TRUE;
}
/***********************************************************************
* pathdrv_EndPath
*/
static BOOL pathdrv_EndPath( PHYSDEV dev )
{
struct path_physdev *physdev = get_path_physdev( dev );
DC *dc = get_physdev_dc( dev );
DPRINT("pathdrv_EndPath dev %p\n",dev);
pop_dc_driver( dc, &path_driver );
HeapFree( GetProcessHeap(), 0, physdev );
return TRUE;
}
/***********************************************************************
* pathdrv_CreateDC
*/
static BOOL pathdrv_CreateDC( PHYSDEV *dev, LPCWSTR driver, LPCWSTR device,
LPCWSTR output, const DEVMODEW *devmode )
{
struct path_physdev *physdev = HeapAlloc( GetProcessHeap(), 0, sizeof(*physdev) );
DPRINT("pathdrv_CreateDC dev %p\n",dev);
if (!physdev) return FALSE;
push_dc_driver( dev, &physdev->dev, &path_driver );
return TRUE;
}
/*************************************************************
* pathdrv_DeleteDC
*/
static BOOL pathdrv_DeleteDC( PHYSDEV dev )
{
struct path_physdev *physdev = get_path_physdev( dev );
DPRINT("pathdrv_DeleteDC dev %p\n",dev);
HeapFree( GetProcessHeap(), 0, physdev );
return TRUE;
}
/*************************************************************
* pathdrv_MoveTo
*/
static BOOL pathdrv_MoveTo( PHYSDEV dev, INT x, INT y )
{
// struct path_physdev *physdev = get_path_physdev( dev );
// DC *dc = get_physdev_dc( dev );
DPRINT("pathdrv_MoveTo dev %p\n",dev);
return TRUE;
}
/*************************************************************
* pathdrv_LineTo
*/
static BOOL pathdrv_LineTo( PHYSDEV dev, INT x, INT y )
{
// struct path_physdev *physdev = get_path_physdev( dev );
// DC *dc = get_physdev_dc( dev );
DPRINT("pathdrv_LineTo dev %p\n",dev);
return TRUE;
}
/*************************************************************
* pathdrv_Rectangle
*/
static BOOL pathdrv_Rectangle( PHYSDEV dev, INT x1, INT y1, INT x2, INT y2 )
{
// struct path_physdev *physdev = get_path_physdev( dev );
// DC *dc = get_physdev_dc( dev );
DPRINT("pathdrv_Rectangle dev %p\n",dev);
return TRUE;
}
/*************************************************************
* pathdrv_RoundRect
*/
static BOOL pathdrv_RoundRect( PHYSDEV dev, INT x1, INT y1, INT x2, INT y2, INT ell_width, INT ell_height )
{
// struct path_physdev *physdev = get_path_physdev( dev );
// DC *dc = get_physdev_dc( dev );
DPRINT("pathdrv_RoundRect dev %p\n",dev);
return TRUE;
}
/*************************************************************
* pathdrv_Ellipse
*/
static BOOL pathdrv_Ellipse( PHYSDEV dev, INT x1, INT y1, INT x2, INT y2 )
{
// struct path_physdev *physdev = get_path_physdev( dev );
// DC *dc = get_physdev_dc( dev );
DPRINT("pathdrv_Ellipse dev %p\n",dev);
return TRUE;
}
/*************************************************************
* pathdrv_AngleArc
*/
static BOOL pathdrv_AngleArc( PHYSDEV dev, INT x, INT y, DWORD radius, FLOAT eStartAngle, FLOAT eSweepAngle)
{
DPRINT("pathdrv_AngleArc dev %p\n",dev);
return TRUE;
}
/*************************************************************
* pathdrv_Arc
*/
static BOOL pathdrv_Arc( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend )
{
// DC *dc = get_physdev_dc( dev );
DPRINT("pathdrv_Arc dev %p\n",dev);
return TRUE;
}
/*************************************************************
* pathdrv_ArcTo
*/
static BOOL pathdrv_ArcTo( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend )
{
// DC *dc = get_physdev_dc( dev );
DPRINT("pathdrv_ArcTo dev %p\n",dev);
return TRUE;
}
/*************************************************************
* pathdrv_Chord
*/
static BOOL pathdrv_Chord( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend )
{
// DC *dc = get_physdev_dc( dev );
DPRINT("pathdrv_Chord dev %p\n",dev);
return TRUE;
}
/*************************************************************
* pathdrv_Pie
*/
static BOOL pathdrv_Pie( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend )
{
// DC *dc = get_physdev_dc( dev );
DPRINT("pathdrv_Pie dev %p\n",dev);
return TRUE;
}
/*************************************************************
* pathdrv_PolyBezierTo
*/
static BOOL pathdrv_PolyBezierTo( PHYSDEV dev, const POINT *pts, DWORD cbPoints )
{
// struct path_physdev *physdev = get_path_physdev( dev );
// DC *dc = get_physdev_dc( dev );
DPRINT("pathdrv_PolyBezierTo dev %p\n",dev);
return TRUE;
}
/*************************************************************
* pathdrv_PolyBezier
*/
static BOOL pathdrv_PolyBezier( PHYSDEV dev, const POINT *pts, DWORD cbPoints )
{
// struct path_physdev *physdev = get_path_physdev( dev );
// DC *dc = get_physdev_dc( dev );
DPRINT("pathdrv_PolyBezier dev %p\n",dev);
return TRUE;
}
/*************************************************************
* pathdrv_PolyDraw
*/
static BOOL pathdrv_PolyDraw( PHYSDEV dev, const POINT *pts, const BYTE *types, DWORD cbPoints )
{
// struct path_physdev *physdev = get_path_physdev( dev );
// DC *dc = get_physdev_dc( dev );
DPRINT("pathdrv_PolyDraw dev %p\n",dev);
return TRUE;
}
/*************************************************************
* pathdrv_Polyline
*/
static BOOL pathdrv_Polyline( PHYSDEV dev, const POINT *pts, INT count )
{
// struct path_physdev *physdev = get_path_physdev( dev );
// DC *dc = get_physdev_dc( dev );
DPRINT("pathdrv_PolyLine dev %p\n",dev);
return TRUE;
}
/*************************************************************
* pathdrv_PolylineTo
*/
static BOOL pathdrv_PolylineTo( PHYSDEV dev, const POINT *pts, INT count )
{
// struct path_physdev *physdev = get_path_physdev( dev );
// DC *dc = get_physdev_dc( dev );
DPRINT("pathdrv_PolyLineTo dev %p\n",dev);
return TRUE;
}
/*************************************************************
* pathdrv_Polygon
*/
static BOOL pathdrv_Polygon( PHYSDEV dev, const POINT *pts, INT count )
{
// struct path_physdev *physdev = get_path_physdev( dev );
// DC *dc = get_physdev_dc( dev );
DPRINT("pathdrv_Polygon dev %p\n",dev);
return TRUE;
}
/*************************************************************
* pathdrv_PolyPolygon
*/
static BOOL pathdrv_PolyPolygon( PHYSDEV dev, const POINT* pts, const INT* counts, UINT polygons )
{
// struct path_physdev *physdev = get_path_physdev( dev );
// DC *dc = get_physdev_dc( dev );
DPRINT("pathdrv_PolyPolygon dev %p\n",dev);
return TRUE;
}
/*************************************************************
* pathdrv_PolyPolyline
*/
static BOOL pathdrv_PolyPolyline( PHYSDEV dev, const POINT* pts, const DWORD* counts, DWORD polylines )
{
// struct path_physdev *physdev = get_path_physdev( dev );
// DC *dc = get_physdev_dc( dev );
DPRINT("pathdrv_PolyPolyline dev %p\n",dev);
return TRUE;
}
/*************************************************************
* pathdrv_ExtTextOut
*/
static BOOL pathdrv_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags, const RECT *lprc,
LPCWSTR str, UINT count, const INT *dx )
{
// struct path_physdev *physdev = get_path_physdev( dev );
DPRINT("pathdrv_ExtTextOut dev %p\n",dev);
return TRUE;
}
/*************************************************************
* pathdrv_CloseFigure
*/
static BOOL pathdrv_CloseFigure( PHYSDEV dev )
{
// struct path_physdev *physdev = get_path_physdev( dev );
DPRINT("pathdrv_CloseFigure dev %p\n",dev);
return TRUE;
}
/***********************************************************************
* null driver fallback implementations
*/
BOOL nulldrv_BeginPath( PHYSDEV dev )
{
DC *dc = get_nulldrv_dc( dev );
struct path_physdev *physdev;
if (!path_driver.pCreateDC( &dc->physDev, NULL, NULL, NULL, NULL ))
{
return FALSE;
}
physdev = get_path_physdev( find_dc_driver( dc, &path_driver ));
physdev->HasPathHook = TRUE;
DPRINT("nulldrv_BeginPath dev %p\n",dev);
DPRINT("nulldrv_BeginPath pd %p\n",physdev);
return TRUE;
}
BOOL nulldrv_EndPath( PHYSDEV dev )
{
DPRINT("nulldrv_EndPath dev %p\n",dev);
SetLastError( ERROR_CAN_NOT_COMPLETE );
return FALSE;
}
BOOL nulldrv_AbortPath( PHYSDEV dev )
{
//DC *dc = get_nulldrv_dc( dev );
DPRINT("nulldrv_AbortPath dev %p\n",dev);
//if (dc->path) free_gdi_path( dc->path );
//dc->path = NULL;
return TRUE;
}
BOOL nulldrv_CloseFigure( PHYSDEV dev )
{
DPRINT("nulldrv_CloseFigure dev %p\n",dev);
SetLastError( ERROR_CAN_NOT_COMPLETE );
return FALSE;
}
BOOL nulldrv_SelectClipPath( PHYSDEV dev, INT mode )
{
BOOL ret = FALSE;
HRGN hrgn = PathToRegion( dev->hdc );
DPRINT("nulldrv_SelectClipPath dev %p\n",dev);
if (hrgn)
{
ret = ExtSelectClipRgn( dev->hdc, hrgn, mode ) != ERROR;
DeleteObject( hrgn );
}
return ret;
// return TRUE;
}
BOOL nulldrv_FillPath( PHYSDEV dev )
{
DPRINT("nulldrv_FillPath dev %p\n",dev);
//if (GetPath( dev->hdc, NULL, NULL, 0 ) == -1) return FALSE;
//AbortPath( dev->hdc );
return TRUE;
}
BOOL nulldrv_StrokeAndFillPath( PHYSDEV dev )
{
DPRINT("nulldrv_StrokeAndFillPath dev %p\n",dev);
//if (GetPath( dev->hdc, NULL, NULL, 0 ) == -1) return FALSE;
//AbortPath( dev->hdc );
return TRUE;
}
BOOL nulldrv_StrokePath( PHYSDEV dev )
{
DPRINT("nulldrv_StrokePath dev %p\n",dev);
//if (GetPath( dev->hdc, NULL, NULL, 0 ) == -1) return FALSE;
//AbortPath( dev->hdc );
return TRUE;
}
BOOL nulldrv_FlattenPath( PHYSDEV dev )
{
/* DC *dc = get_nulldrv_dc( dev );
struct gdi_path *path; */
DPRINT("nulldrv_FlattenPath dev %p\n",dev);
/* if (!dc->path)
{
SetLastError( ERROR_CAN_NOT_COMPLETE );
return FALSE;
}
if (!(path = PATH_FlattenPath( dc->path ))) return FALSE;
free_gdi_path( dc->path );
dc->path = path;*/
return TRUE;
}
BOOL nulldrv_WidenPath( PHYSDEV dev )
{
/* DC *dc = get_nulldrv_dc( dev );
struct gdi_path *path;*/
DPRINT("nulldrv_WidenPath dev %p\n",dev);
/* if (!dc->path)
{
SetLastError( ERROR_CAN_NOT_COMPLETE );
return FALSE;
}
if (!(path = PATH_WidenPath( dc ))) return FALSE;
free_gdi_path( dc->path );
dc->path = path;*/
return TRUE;
}
const struct gdi_dc_funcs path_driver =
{
NULL, /* pAbortDoc */
pathdrv_AbortPath, /* pAbortPath */
NULL, /* pAlphaBlend */
pathdrv_AngleArc, /* pAngleArc */
pathdrv_Arc, /* pArc */
pathdrv_ArcTo, /* pArcTo */
pathdrv_BeginPath, /* pBeginPath */
NULL, /* pBlendImage */
pathdrv_Chord, /* pChord */
pathdrv_CloseFigure, /* pCloseFigure */
NULL, /* pCreateCompatibleDC */
pathdrv_CreateDC, /* pCreateDC */
pathdrv_DeleteDC, /* pDeleteDC */
NULL, /* pDeleteObject */
NULL, /* pDeviceCapabilities */
pathdrv_Ellipse, /* pEllipse */
NULL, /* pEndDoc */
NULL, /* pEndPage */
pathdrv_EndPath, /* pEndPath */
NULL, /* pEnumFonts */
NULL, /* pEnumICMProfiles */
NULL, /* pExcludeClipRect */
NULL, /* pExtDeviceMode */
NULL, /* pExtEscape */
NULL, /* pExtFloodFill */
NULL, /* pExtSelectClipRgn */
pathdrv_ExtTextOut, /* pExtTextOut */
NULL, /* pFillPath */
NULL, /* pFillRgn */
NULL, /* pFlattenPath */
NULL, /* pFontIsLinked */
NULL, /* pFrameRgn */
NULL, /* pGdiComment */
NULL, /* pGetBoundsRect */
NULL, /* pGetCharABCWidths */
NULL, /* pGetCharABCWidthsI */
NULL, /* pGetCharWidth */
NULL, /* pGetDeviceCaps */
NULL, /* pGetDeviceGammaRamp */
NULL, /* pGetFontData */
NULL, /* pGetFontRealizationInfo */
NULL, /* pGetFontUnicodeRanges */
NULL, /* pGetGlyphIndices */
NULL, /* pGetGlyphOutline */
NULL, /* pGetICMProfile */
NULL, /* pGetImage */
NULL, /* pGetKerningPairs */
NULL, /* pGetNearestColor */
NULL, /* pGetOutlineTextMetrics */
NULL, /* pGetPixel */
NULL, /* pGetSystemPaletteEntries */
NULL, /* pGetTextCharsetInfo */
NULL, /* pGetTextExtentExPoint */
NULL, /* pGetTextExtentExPointI */
NULL, /* pGetTextFace */
NULL, /* pGetTextMetrics */
NULL, /* pGradientFill */
NULL, /* pIntersectClipRect */
NULL, /* pInvertRgn */
pathdrv_LineTo, /* pLineTo */
NULL, /* pModifyWorldTransform */
pathdrv_MoveTo, /* pMoveTo */
NULL, /* pOffsetClipRgn */
NULL, /* pOffsetViewportOrg */
NULL, /* pOffsetWindowOrg */
NULL, /* pPaintRgn */
NULL, /* pPatBlt */
pathdrv_Pie, /* pPie */
pathdrv_PolyBezier, /* pPolyBezier */
pathdrv_PolyBezierTo, /* pPolyBezierTo */
pathdrv_PolyDraw, /* pPolyDraw */
pathdrv_PolyPolygon, /* pPolyPolygon */
pathdrv_PolyPolyline, /* pPolyPolyline */
pathdrv_Polygon, /* pPolygon */
pathdrv_Polyline, /* pPolyline */
pathdrv_PolylineTo, /* pPolylineTo */
NULL, /* pPutImage */
NULL, /* pRealizeDefaultPalette */
NULL, /* pRealizePalette */
pathdrv_Rectangle, /* pRectangle */
NULL, /* pResetDC */
NULL, /* pRestoreDC */
pathdrv_RoundRect, /* pRoundRect */
NULL, /* pSaveDC */
NULL, /* pScaleViewportExt */
NULL, /* pScaleWindowExt */
NULL, /* pSelectBitmap */
NULL, /* pSelectBrush */
NULL, /* pSelectClipPath */
NULL, /* pSelectFont */
NULL, /* pSelectPalette */
NULL, /* pSelectPen */
NULL, /* pSetArcDirection */
NULL, /* pSetBkColor */
NULL, /* pSetBkMode */
NULL, /* pSetDCBrushColor */
NULL, /* pSetDCPenColor */
NULL, /* pSetDIBColorTable */
NULL, /* pSetDIBitsToDevice */
NULL, /* pSetDeviceClipping */
NULL, /* pSetDeviceGammaRamp */
NULL, /* pSetLayout */
NULL, /* pSetMapMode */
NULL, /* pSetMapperFlags */
NULL, /* pSetPixel */
NULL, /* pSetPolyFillMode */
NULL, /* pSetROP2 */
NULL, /* pSetRelAbs */
NULL, /* pSetStretchBltMode */
NULL, /* pSetTextAlign */
NULL, /* pSetTextCharacterExtra */
NULL, /* pSetTextColor */
NULL, /* pSetTextJustification */
NULL, /* pSetViewportExt */
NULL, /* pSetViewportOrg */
NULL, /* pSetWindowExt */
NULL, /* pSetWindowOrg */
NULL, /* pSetWorldTransform */
NULL, /* pStartDoc */
NULL, /* pStartPage */
NULL, /* pStretchBlt */
NULL, /* pStretchDIBits */
NULL, /* pStrokeAndFillPath */
NULL, /* pStrokePath */
NULL, /* pUnrealizePalette */
NULL, /* pWidenPath */
NULL, /* wine_get_wgl_driver */
GDI_PRIORITY_PATH_DRV /* priority */
};

View file

@ -6,11 +6,26 @@
#define NDEBUG
#include <debug.h>
WINEDC *get_nulldrv_dc( PHYSDEV dev );
BOOL nulldrv_BeginPath( PHYSDEV dev );
BOOL nulldrv_EndPath( PHYSDEV dev );
BOOL nulldrv_AbortPath( PHYSDEV dev );
BOOL nulldrv_CloseFigure( PHYSDEV dev );
BOOL nulldrv_SelectClipPath( PHYSDEV dev, INT mode );
BOOL nulldrv_FillPath( PHYSDEV dev );
BOOL nulldrv_StrokeAndFillPath( PHYSDEV dev );
BOOL nulldrv_StrokePath( PHYSDEV dev );
BOOL nulldrv_FlattenPath( PHYSDEV dev );
BOOL nulldrv_WidenPath( PHYSDEV dev );
static INT i = 0;
static
INT_PTR
NULL_Unused()
{
DPRINT1("NULL_Unused\n");
DPRINT1("NULL_Unused %d\n",i);
// __debugbreak();
return 0;
}
@ -31,15 +46,16 @@ static INT NULL_ExcludeClipRect(PHYSDEV dev, INT left, INT top, INT right, INT
static const struct gdi_dc_funcs DummyPhysDevFuncs =
{
(PVOID)NULL_Unused, //INT (*pAbortDoc)(PHYSDEV);
(PVOID)NULL_Unused, //BOOL (*pAbortPath)(PHYSDEV);
nulldrv_AbortPath, //BOOL (*pAbortPath)(PHYSDEV);
(PVOID)NULL_Unused, //BOOL (*pAlphaBlend)(PHYSDEV,struct bitblt_coords*,PHYSDEV,struct bitblt_coords*,BLENDFUNCTION);
(PVOID)NULL_Unused, //BOOL (*pAngleArc)(PHYSDEV,INT,INT,DWORD,FLOAT,FLOAT);
(PVOID)NULL_Unused, //BOOL (*pArc)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT);
(PVOID)NULL_Unused, //BOOL (*pArcTo)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT);
(PVOID)NULL_Unused, //BOOL (*pBeginPath)(PHYSDEV);
nulldrv_BeginPath, //BOOL (*pBeginPath)(PHYSDEV);
(PVOID)NULL_Unused, //DWORD (*pBlendImage)(PHYSDEV,BITMAPINFO*,const struct gdi_image_bits*,struct bitblt_coords*,struct bitblt_coords*,BLENDFUNCTION);
(PVOID)NULL_Unused, //BOOL (*pChord)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT);
(PVOID)NULL_Unused, //BOOL (*pCloseFigure)(PHYSDEV);
nulldrv_CloseFigure, //BOOL (*pCloseFigure)(PHYSDEV);
(PVOID)NULL_Unused, //BOOL (*pCreateCompatibleDC)(PHYSDEV,PHYSDEV*);
(PVOID)NULL_Unused, //BOOL (*pCreateDC)(PHYSDEV*,LPCWSTR,LPCWSTR,LPCWSTR,const DEVMODEW*);
(PVOID)NULL_Unused, //BOOL (*pDeleteDC)(PHYSDEV);
@ -48,8 +64,9 @@ static const struct gdi_dc_funcs DummyPhysDevFuncs =
(PVOID)NULL_Unused, //BOOL (*pEllipse)(PHYSDEV,INT,INT,INT,INT);
(PVOID)NULL_Unused, //INT (*pEndDoc)(PHYSDEV);
(PVOID)NULL_Unused, //INT (*pEndPage)(PHYSDEV);
(PVOID)NULL_Unused, //BOOL (*pEndPath)(PHYSDEV);
nulldrv_EndPath, //BOOL (*pEndPath)(PHYSDEV);
(PVOID)NULL_Unused, //BOOL (*pEnumFonts)(PHYSDEV,LPLOGFONTW,FONTENUMPROCW,LPARAM);
(PVOID)NULL_Unused, //INT (*pEnumICMProfiles)(PHYSDEV,ICMENUMPROCW,LPARAM);
NULL_ExcludeClipRect, //INT (*pExcludeClipRect)(PHYSDEV,INT,INT,INT,INT);
(PVOID)NULL_Unused, //INT (*pExtDeviceMode)(LPSTR,HWND,LPDEVMODEA,LPSTR,LPSTR,LPDEVMODEA,LPSTR,DWORD);
@ -57,13 +74,13 @@ static const struct gdi_dc_funcs DummyPhysDevFuncs =
(PVOID)NULL_Unused, //BOOL (*pExtFloodFill)(PHYSDEV,INT,INT,COLORREF,UINT);
NULL_ExtSelectClipRgn, //INT (*pExtSelectClipRgn)(PHYSDEV,HRGN,INT);
(PVOID)NULL_Unused, //BOOL (*pExtTextOut)(PHYSDEV,INT,INT,UINT,const RECT*,LPCWSTR,UINT,const INT*);
(PVOID)NULL_Unused, //BOOL (*pFillPath)(PHYSDEV);
nulldrv_FillPath, //BOOL (*pFillPath)(PHYSDEV);
(PVOID)NULL_Unused, //BOOL (*pFillRgn)(PHYSDEV,HRGN,HBRUSH);
(PVOID)NULL_Unused, //BOOL (*pFlattenPath)(PHYSDEV);
nulldrv_FlattenPath, //BOOL (*pFlattenPath)(PHYSDEV);
(PVOID)NULL_Unused, //BOOL (*pFontIsLinked)(PHYSDEV);
(PVOID)NULL_Unused, //BOOL (*pFrameRgn)(PHYSDEV,HRGN,HBRUSH,INT,INT);
(PVOID)NULL_Unused, //BOOL (*pGdiComment)(PHYSDEV,UINT,const BYTE*);
(PVOID)NULL_Unused, //BOOL (*pGdiRealizationInfo)(PHYSDEV,void*);
(PVOID)NULL_Unused, //UINT (*pGetBoundsRect)(PHYSDEV,RECT*,UINT);
(PVOID)NULL_Unused, //BOOL (*pGetCharABCWidths)(PHYSDEV,UINT,UINT,LPABC);
(PVOID)NULL_Unused, //BOOL (*pGetCharABCWidthsI)(PHYSDEV,UINT,UINT,WORD*,LPABC);
@ -71,6 +88,7 @@ static const struct gdi_dc_funcs DummyPhysDevFuncs =
(PVOID)NULL_Unused, //INT (*pGetDeviceCaps)(PHYSDEV,INT);
(PVOID)NULL_Unused, //BOOL (*pGetDeviceGammaRamp)(PHYSDEV,LPVOID);
(PVOID)NULL_Unused, //DWORD (*pGetFontData)(PHYSDEV,DWORD,DWORD,LPVOID,DWORD);
(PVOID)NULL_Unused, //BOOL (*pGetFontRealizationInfo)(PHYSDEV,void*);
(PVOID)NULL_Unused, //DWORD (*pGetFontUnicodeRanges)(PHYSDEV,LPGLYPHSET);
(PVOID)NULL_Unused, //DWORD (*pGetGlyphIndices)(PHYSDEV,LPCWSTR,INT,LPWORD,DWORD);
(PVOID)NULL_Unused, //DWORD (*pGetGlyphOutline)(PHYSDEV,UINT,UINT,LPGLYPHMETRICS,DWORD,LPVOID,const MAT2*);
@ -111,15 +129,15 @@ static const struct gdi_dc_funcs DummyPhysDevFuncs =
(PVOID)NULL_Unused, //UINT (*pRealizePalette)(PHYSDEV,HPALETTE,BOOL);
(PVOID)NULL_Unused, //BOOL (*pRectangle)(PHYSDEV,INT,INT,INT,INT);
(PVOID)NULL_Unused, //HDC (*pResetDC)(PHYSDEV,const DEVMODEW*);
NULL_RestoreDC, //BOOL (*pRestoreDC)(PHYSDEV,INT);
NULL_RestoreDC, //BOOL (*pRestoreDC)(PHYSDEV,INT);
(PVOID)NULL_Unused, //BOOL (*pRoundRect)(PHYSDEV,INT,INT,INT,INT,INT,INT);
NULL_SaveDC, //INT (*pSaveDC)(PHYSDEV);
NULL_SaveDC, //INT (*pSaveDC)(PHYSDEV);
(PVOID)NULL_Unused, //BOOL (*pScaleViewportExtEx)(PHYSDEV,INT,INT,INT,INT,SIZE*);
(PVOID)NULL_Unused, //BOOL (*pScaleWindowExtEx)(PHYSDEV,INT,INT,INT,INT,SIZE*);
(PVOID)NULL_Unused, //HBITMAP (*pSelectBitmap)(PHYSDEV,HBITMAP);
(PVOID)NULL_Unused, //HBRUSH (*pSelectBrush)(PHYSDEV,HBRUSH,const struct brush_pattern*);
(PVOID)NULL_Unused, //BOOL (*pSelectClipPath)(PHYSDEV,INT);
NULL_SelectFont, //HFONT (*pSelectFont)(PHYSDEV,HFONT,UINT*);
nulldrv_SelectClipPath, //BOOL (*pSelectClipPath)(PHYSDEV,INT);
NULL_SelectFont, //HFONT (*pSelectFont)(PHYSDEV,HFONT,UINT*);
(PVOID)NULL_Unused, //HPALETTE (*pSelectPalette)(PHYSDEV,HPALETTE,BOOL);
(PVOID)NULL_Unused, //HPEN (*pSelectPen)(PHYSDEV,HPEN,const struct brush_pattern*);
(PVOID)NULL_Unused, //INT (*pSetArcDirection)(PHYSDEV,INT);
@ -132,7 +150,7 @@ static const struct gdi_dc_funcs DummyPhysDevFuncs =
(PVOID)NULL_Unused, //VOID (*pSetDeviceClipping)(PHYSDEV,HRGN);
(PVOID)NULL_Unused, //BOOL (*pSetDeviceGammaRamp)(PHYSDEV,LPVOID);
(PVOID)NULL_Unused, //DWORD (*pSetLayout)(PHYSDEV,DWORD);
NULL_SetMapMode, //INT (*pSetMapMode)(PHYSDEV,INT);
NULL_SetMapMode, //INT (*pSetMapMode)(PHYSDEV,INT);
(PVOID)NULL_Unused, //DWORD (*pSetMapperFlags)(PHYSDEV,DWORD);
(PVOID)NULL_Unused, //COLORREF (*pSetPixel)(PHYSDEV,INT,INT,COLORREF);
(PVOID)NULL_Unused, //INT (*pSetPolyFillMode)(PHYSDEV,INT);
@ -152,14 +170,26 @@ static const struct gdi_dc_funcs DummyPhysDevFuncs =
(PVOID)NULL_Unused, //INT (*pStartPage)(PHYSDEV);
(PVOID)NULL_Unused, //BOOL (*pStretchBlt)(PHYSDEV,struct bitblt_coords*,PHYSDEV,struct bitblt_coords*,DWORD);
(PVOID)NULL_Unused, //INT (*pStretchDIBits)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT,const void*,BITMAPINFO*,UINT,DWORD);
(PVOID)NULL_Unused, //BOOL (*pStrokeAndFillPath)(PHYSDEV);
(PVOID)NULL_Unused, //BOOL (*pStrokePath)(PHYSDEV);
nulldrv_StrokeAndFillPath, //BOOL (*pStrokeAndFillPath)(PHYSDEV);
nulldrv_StrokePath, //BOOL (*pStrokePath)(PHYSDEV);
(PVOID)NULL_Unused, //BOOL (*pUnrealizePalette)(HPALETTE);
(PVOID)NULL_Unused, //BOOL (*pWidenPath)(PHYSDEV);
nulldrv_WidenPath, //BOOL (*pWidenPath)(PHYSDEV);
(PVOID)NULL_Unused, //struct opengl_funcs * (*wine_get_wgl_driver)(PHYSDEV,UINT);
0 // UINT priority;
};
WINEDC *get_nulldrv_dc( PHYSDEV dev )
{
return CONTAINING_RECORD( dev, WINEDC, NullPhysDev );
}
WINEDC* get_physdev_dc( PHYSDEV dev )
{
while (dev->funcs != &DummyPhysDevFuncs)
dev = dev->next;
return get_nulldrv_dc( dev );
}
static
GDILOOBJTYPE
ConvertObjectType(
@ -368,6 +398,7 @@ push_dc_driver_ros(
PHYSDEV physdev,
const struct gdi_dc_funcs *funcs)
{
while ((*dev)->funcs->priority > funcs->priority) dev = &(*dev)->next;
physdev->funcs = funcs;
physdev->next = *dev;
physdev->hdc = CONTAINING_RECORD(dev, WINEDC, physDev)->hdc;
@ -691,6 +722,15 @@ DRIVER_SelectBrush(PHYSDEV physdev, HBRUSH hbrush, const struct brush_pattern *p
return hOldBrush;
}
static
HRGN
DRIVER_PathToRegion(PHYSDEV physdev)
{
DPRINT1("DRIVER_PathToRegion\n");
return (HRGN)physdev->funcs->pAbortPath( physdev );
}
static
DWORD_PTR
DRIVER_Dispatch(
@ -858,10 +898,8 @@ DRIVER_Dispatch(
_va_arg_n(argptr, const POINT*, 0),
_va_arg_n(argptr, DWORD, 1));
case DCFUNC_PolyDraw:
DPRINT1("DCFUNC_PolyDraw not implemented\n");
return FALSE;
return physdev->funcs->pPolyDraw(physdev,
_va_arg_n(argptr, const POINT*, 1),
return physdev->funcs->pPolyDraw(physdev,
_va_arg_n(argptr, const POINT*, 0),
_va_arg_n(argptr, const BYTE*, 1),
_va_arg_n(argptr, DWORD, 2));
case DCFUNC_Polygon:
@ -873,8 +911,6 @@ DRIVER_Dispatch(
_va_arg_n(argptr, const POINT*, 0),
_va_arg_n(argptr, INT, 1));
case DCFUNC_PolylineTo:
DPRINT1("DCFUNC_PolylineTo not implemented\n");
return FALSE;
return physdev->funcs->pPolylineTo(physdev,
_va_arg_n(argptr, const POINT*, 0),
_va_arg_n(argptr, INT, 1));
@ -1027,15 +1063,36 @@ DRIVER_Dispatch(
return physdev->funcs->pStrokePath(physdev);
case DCFUNC_WidenPath:
return physdev->funcs->pWidenPath(physdev);
case DCFUNC_AngleArc:
return physdev->funcs->pAngleArc(physdev,
_va_arg_n(argptr, INT, 0),
_va_arg_n(argptr, INT, 1),
_va_arg_n(argptr, DWORD, 2),
_va_arg_n(argptr, FLOAT, 3),
_va_arg_n(argptr, FLOAT, 4 ));
case DCFUNC_ArcTo:
return physdev->funcs->pArcTo(physdev,
_va_arg_n(argptr, INT, 0),
_va_arg_n(argptr, INT, 1),
_va_arg_n(argptr, INT, 2),
_va_arg_n(argptr, INT, 3),
_va_arg_n(argptr, INT, 4),
_va_arg_n(argptr, INT, 5),
_va_arg_n(argptr, INT, 6),
_va_arg_n(argptr, INT, 7));
case DCFUNC_GradientFill:
return physdev->funcs->pGradientFill(physdev,
_va_arg_n(argptr, TRIVERTEX *, 0),
_va_arg_n(argptr, ULONG, 1),
_va_arg_n(argptr, void *, 2),
_va_arg_n(argptr, ULONG , 3),
_va_arg_n(argptr, ULONG , 4));
case DCFUNC_PathToRegion:
return (DWORD_PTR)DRIVER_PathToRegion(physdev);
/* These are not implemented in wine */
case DCFUNC_AlphaBlend:
case DCFUNC_AngleArc:
case DCFUNC_ArcTo:
case DCFUNC_GradientFill:
case DCFUNC_MaskBlt:
case DCFUNC_PathToRegion:
case DCFUNC_PlgBlt:
case DCFUNC_TransparentBlt:
UNIMPLEMENTED;
@ -1074,9 +1131,11 @@ METADC_Dispatch(
return TRUE;
}
i = eFunction;
va_start(argptr, hdc);
*pdwResult = DRIVER_Dispatch(physdev, eFunction, argptr);
va_end(argptr);
i = 0;
/* Return TRUE to indicate that we want to return from the parent */
return ((GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_METADC16_TYPE) ||