Index: reactos/sdk/include/psdk/wingdi.h =================================================================== --- reactos/sdk/include/psdk/wingdi.h (revision 75228) +++ reactos/sdk/include/psdk/wingdi.h (working copy) @@ -2765,6 +2765,14 @@ COLOR16 Blue; COLOR16 Alpha; } TRIVERTEX, *PTRIVERTEX, *LPTRIVERTEX; +typedef struct tagEMRGRADIENTFILL { + EMR emr; + RECTL rclBounds; + DWORD nVer; + DWORD nTri; + ULONG ulMode; + TRIVERTEX Ver[1]; +} EMRGRADIENTFILL, *PEMRGRADIENTFILL; typedef struct _GRADIENT_TRIANGLE { ULONG Vertex1; ULONG Vertex2; Index: reactos/win32ss/gdi/gdi32/include/wine/gdi_driver.h =================================================================== --- reactos/win32ss/gdi/gdi32/include/wine/gdi_driver.h (revision 75228) +++ reactos/win32ss/gdi/gdi32/include/wine/gdi_driver.h (working copy) @@ -97,7 +97,6 @@ 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 @@ 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*); Index: reactos/win32ss/gdi/gdi32/wine/enhmfdrv/bitblt.c =================================================================== --- reactos/win32ss/gdi/gdi32/wine/enhmfdrv/bitblt.c (revision 75228) +++ reactos/win32ss/gdi/gdi32/wine/enhmfdrv/bitblt.c (working copy) @@ -122,7 +122,11 @@ pEMR->dwRop = rop; pEMR->xSrc = src->log_x; pEMR->ySrc = src->log_y; +#ifdef __REACTOS__ GetWorldTransform(devSrc->hdc, &pEMR->xformSrc); +#else + GetTransform(devSrc->hdc, 0x204, &pEMR->xformSrc); +#endif pEMR->crBkColorSrc = GetBkColor(devSrc->hdc); pEMR->iUsageSrc = DIB_RGB_COLORS; pEMR->offBmiSrc = emrSize; Index: reactos/win32ss/gdi/gdi32/wine/enhmfdrv/dc.c =================================================================== --- reactos/win32ss/gdi/gdi32/wine/enhmfdrv/dc.c (revision 75228) +++ reactos/win32ss/gdi/gdi32/wine/enhmfdrv/dc.c (working copy) @@ -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,11 +19,17 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include #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 ) { PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSaveDC ); @@ -41,8 +48,12 @@ BOOL EMFDRV_RestoreDC( PHYSDEV dev, INT level ) { PHYSDEV next = GET_NEXT_PHYSDEV( dev, pRestoreDC ); - EMFDRV_PDEVICE* physDev = (EMFDRV_PDEVICE*)dev; + EMFDRV_PDEVICE* physDev = get_emf_physdev( dev ); +#ifdef __REACTOS__ DC *dc = get_dc_ptr( dev->hdc ); +#else + DC *dc = get_physdev_dc( dev ); +#endif EMRRESTOREDC emr; BOOL ret; @@ -53,7 +64,6 @@ emr.iRelative = level; else emr.iRelative = level - dc->saveLevel - 1; - release_dc_ptr( dc ); physDev->restoring++; ret = next->funcs->pRestoreDC( next, level ); @@ -94,7 +104,7 @@ 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 +118,7 @@ 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 +430,24 @@ BOOL EMFDRV_BeginPath( PHYSDEV dev ) { + EMFDRV_PDEVICE *physDev = get_emf_physdev( dev ); + PHYSDEV next = GET_NEXT_PHYSDEV( dev, pBeginPath ); EMRBEGINPATH emr; - +#ifdef __REACTOS__ + DC *dc = get_dc_ptr( dev->hdc ); +#else + DC *dc = get_physdev_dc( dev ); +#endif 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 +457,8 @@ 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,23 +468,10 @@ emr.emr.iType = EMR_ENDPATH; 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_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; @@ -476,6 +486,8 @@ { PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSelectClipPath ); EMRSELECTCLIPPATH emr; + BOOL ret = FALSE; + HRGN hrgn; emr.emr.iType = EMR_SELECTCLIPPATH; emr.emr.nSize = sizeof(emr); @@ -482,50 +494,472 @@ emr.iMode = iMode; if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE; - return next->funcs->pSelectClipPath( next, iMode ); + hrgn = PathToRegion( dev->hdc ); + if (hrgn) + { + ret = next->funcs->pExtSelectClipRgn( next, hrgn, iMode ); + DeleteObject( hrgn ); + } + return ret; } -BOOL EMFDRV_StrokeAndFillPath( PHYSDEV dev ) +BOOL EMFDRV_WidenPath( PHYSDEV dev ) { - EMRSTROKEANDFILLPATH emr; + EMRWIDENPATH emr; - emr.emr.iType = EMR_STROKEANDFILLPATH; + emr.emr.iType = EMR_WIDENPATH; 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 ) +INT EMFDRV_GetDeviceCaps(PHYSDEV dev, INT cap) { - EMRSTROKEPATH emr; + EMFDRV_PDEVICE *physDev = get_emf_physdev( dev ); - 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 ); + return GetDeviceCaps( physDev->ref_dc, cap ); } -BOOL EMFDRV_WidenPath( PHYSDEV dev ) + +/*********************************************************************** + * emfpathdrv_AbortPath + */ +static BOOL emfpathdrv_AbortPath( PHYSDEV dev ) { - EMRWIDENPATH emr; + PHYSDEV emfdev = get_emfdev( dev ); + PHYSDEV next = GET_NEXT_PHYSDEV( dev, pAbortPath ); +#ifdef __REACTOS__ + DC *dc = get_dc_ptr( dev->hdc ); +#else + DC *dc = get_physdev_dc( dev ); +#endif + emfpath_driver.pDeleteDC( pop_dc_driver( dc, &emfpath_driver )); + emfdev->funcs->pAbortPath( emfdev ); + return next->funcs->pAbortPath( next ); +} - emr.emr.iType = EMR_WIDENPATH; - emr.emr.nSize = sizeof(emr); +/*********************************************************************** + * 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 EMFDRV_WriteRecord( dev, &emr.emr ); + return (emfdev->funcs->pAngleArc( emfdev, x, y, radius, start, sweep ) && + next->funcs->pAngleArc( next, x, y, radius, start, sweep )); } -INT EMFDRV_GetDeviceCaps(PHYSDEV dev, INT cap) +/*********************************************************************** + * emfpathdrv_Arc + */ +static BOOL emfpathdrv_Arc( PHYSDEV dev, INT left, INT top, INT right, INT bottom, + INT xstart, INT ystart, INT xend, INT yend ) { - EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*) dev; + PHYSDEV emfdev = get_emfdev( dev ); + PHYSDEV next = GET_NEXT_PHYSDEV( dev, pArc ); - return GetDeviceCaps( physDev->ref_dc, cap ); + 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 ); +#ifdef __REACTOS__ + DC *dc = get_dc_ptr( dev->hdc ); +#else + DC *dc = get_physdev_dc( dev ); +#endif + 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 */ + 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 */ + 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 */ +}; Index: reactos/win32ss/gdi/gdi32/wine/enhmfdrv/enhmetafiledrv.h =================================================================== --- reactos/win32ss/gdi/gdi32/wine/enhmfdrv/enhmetafiledrv.h (revision 75228) +++ reactos/win32ss/gdi/gdi32/wine/enhmfdrv/enhmetafiledrv.h (working copy) @@ -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 @@ /* 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_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 @@ 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, Index: reactos/win32ss/gdi/gdi32/wine/enhmfdrv/graphics.c =================================================================== --- reactos/win32ss/gdi/gdi32/wine/enhmfdrv/graphics.c (revision 75228) +++ reactos/win32ss/gdi/gdi32/wine/enhmfdrv/graphics.c (working copy) @@ -69,10 +69,14 @@ } /* 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 @@ 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,34 @@ } } +#ifndef __REACTOS__ +/* helper for path stroke and fill functions */ +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 +155,10 @@ */ 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 +170,18 @@ 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 +194,10 @@ 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 +208,11 @@ 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 +290,23 @@ 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; } @@ -255,6 +322,16 @@ } /*********************************************************************** + * 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 */ BOOL EMFDRV_Pie( PHYSDEV dev, INT left, INT top, INT right, INT bottom, @@ -276,10 +353,32 @@ } /*********************************************************************** + * 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 +388,11 @@ 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 +404,8 @@ 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 +414,10 @@ */ 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 +427,11 @@ 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 +443,8 @@ 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 +454,10 @@ 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 +465,11 @@ 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 +483,8 @@ 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,36 +519,35 @@ 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->cptl = count; - emr->rclBounds.left = emr->rclBounds.right = pt[0].x; - emr->rclBounds.top = emr->rclBounds.bottom = pt[0].y; + store_points( emr->aptl, pt, count, use_small_emr ); - 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; - } + 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; - emr->cptl = count; - memcpy(emr->aptl, pt, count * sizeof(POINTL)); - ret = EMFDRV_WriteRecord( dev, &emr->emr ); - if(ret) + if (ret && !physDev->path) EMFDRV_UpdateBBox( dev, &emr->rclBounds ); HeapFree( GetProcessHeap(), 0, emr ); return ret; @@ -437,70 +555,19 @@ /********************************************************************** - * EMFDRV_Polylinegon16 - * - * Helper for EMFDRV_Poly{line|gon} - * - * This is not a legacy function! - * We are using SHORT integers to save space. + * EMFDRV_Polyline */ -static BOOL -EMFDRV_Polylinegon16( PHYSDEV dev, const POINT* pt, INT count, DWORD iType ) +BOOL EMFDRV_Polyline( PHYSDEV dev, const POINT* pt, INT count ) { - 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) - EMFDRV_UpdateBBox( dev, &emr->rclBounds ); - HeapFree( GetProcessHeap(), 0, emr ); - return ret; + return EMFDRV_Polylinegon( dev, pt, count, EMR_POLYLINE ); } - /********************************************************************** - * EMFDRV_Polyline + * EMFDRV_PolylineTo */ -BOOL EMFDRV_Polyline( PHYSDEV dev, const POINT* pt, INT count ) +BOOL EMFDRV_PolylineTo( 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 ); + return EMFDRV_Polylinegon( dev, pt, count, EMR_POLYLINETO ); } /********************************************************************** @@ -509,8 +576,6 @@ 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 +584,6 @@ */ 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 +592,6 @@ */ 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 ); } @@ -612,6 +673,43 @@ /********************************************************************** + * 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 */ BOOL EMFDRV_ExtFloodFill( PHYSDEV dev, INT x, INT y, COLORREF color, UINT fillType ) @@ -753,13 +851,22 @@ 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,7 +941,7 @@ } } - if (!lprect) + if (physDev->path) { pemr->rclBounds.left = pemr->rclBounds.top = 0; pemr->rclBounds.right = pemr->rclBounds.bottom = -1; @@ -841,6 +948,7 @@ 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 +994,132 @@ 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 ) +{ +#ifdef __REACTOS__ + EMRFILLPATH emr; + RECT rc; + C_ASSERT(sizeof(emr.rclBounds) == sizeof(rc)); + + emr.emr.iType = EMR_FILLPATH; + emr.emr.nSize = sizeof(emr); + + GetClipBox(dev->hdc, &rc); + LPtoDP(dev->hdc, (LPPOINT)&rc, 2); + + memcpy(&emr.rclBounds, &rc, sizeof(rc)); + if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE; + EMFDRV_UpdateBBox( dev, &emr.rclBounds ); + return TRUE; +#else + return emfdrv_stroke_and_fill_path( dev, EMR_FILLPATH ); +#endif +} + +/********************************************************************** + * EMFDRV_StrokeAndFillPath + */ +BOOL EMFDRV_StrokeAndFillPath( PHYSDEV dev ) +{ +#ifdef __REACTOS__ + EMRSTROKEANDFILLPATH emr; + RECT rc; + C_ASSERT(sizeof(emr.rclBounds) == sizeof(rc)); + + emr.emr.iType = EMR_STROKEANDFILLPATH; + emr.emr.nSize = sizeof(emr); + + GetClipBox(dev->hdc, &rc); + LPtoDP(dev->hdc, (LPPOINT)&rc, 2); + + memcpy(&emr.rclBounds, &rc, sizeof(rc)); + if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE; + EMFDRV_UpdateBBox( dev, &emr.rclBounds ); + return TRUE; +#else + return emfdrv_stroke_and_fill_path( dev, EMR_STROKEANDFILLPATH ); +#endif +} + +/********************************************************************** + * EMFDRV_StrokePath + */ +BOOL EMFDRV_StrokePath( PHYSDEV dev ) +{ +#ifdef __REACTOS__ + EMRSTROKEPATH emr; + RECT rc; + C_ASSERT(sizeof(emr.rclBounds) == sizeof(rc)); + + emr.emr.iType = EMR_STROKEPATH; + emr.emr.nSize = sizeof(emr); + + GetClipBox(dev->hdc, &rc); + LPtoDP(dev->hdc, (LPPOINT)&rc, 2); + + memcpy(&emr.rclBounds, &rc, sizeof(rc)); + if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE; + EMFDRV_UpdateBBox( dev, &emr.rclBounds ); + return TRUE; +#else + return emfdrv_stroke_and_fill_path( dev, EMR_STROKEPATH ); +#endif +} Index: reactos/win32ss/gdi/gdi32/wine/enhmfdrv/init.c =================================================================== --- reactos/win32ss/gdi/gdi32/wine/enhmfdrv/init.c (revision 75228) +++ reactos/win32ss/gdi/gdi32/wine/enhmfdrv/init.c (working copy) @@ -34,14 +34,14 @@ 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 @@ NULL, /* pFontIsLinked */ EMFDRV_FrameRgn, /* pFrameRgn */ EMFDRV_GdiComment, /* pGdiComment */ - NULL, /* pGdiRealizationInfo */ NULL, /* pGetBoundsRect */ NULL, /* pGetCharABCWidths */ NULL, /* pGetCharABCWidthsI */ @@ -77,6 +76,7 @@ EMFDRV_GetDeviceCaps, /* pGetDeviceCaps */ NULL, /* pGetDeviceGammaRamp */ NULL, /* pGetFontData */ + NULL, /* pGetFontRealizationInfo */ NULL, /* pGetFontUnicodeRanges */ NULL, /* pGetGlyphIndices */ NULL, /* pGetGlyphOutline */ @@ -92,7 +92,7 @@ NULL, /* pGetTextExtentExPointI */ NULL, /* pGetTextFace */ NULL, /* pGetTextMetrics */ - NULL, /* pGradientFill */ + EMFDRV_GradientFill, /* pGradientFill */ EMFDRV_IntersectClipRect, /* pIntersectClipRect */ EMFDRV_InvertRgn, /* pInvertRgn */ EMFDRV_LineTo, /* pLineTo */ @@ -106,12 +106,12 @@ 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 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 @@ 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 @@ */ 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,7 +319,7 @@ 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; @@ -342,7 +342,7 @@ 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 @@ 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 @@ 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 @@ 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) { Index: reactos/win32ss/gdi/gdi32/wine/enhmfdrv/objects.c =================================================================== --- reactos/win32ss/gdi/gdi32/wine/enhmfdrv/objects.c (revision 75228) +++ reactos/win32ss/gdi/gdi32/wine/enhmfdrv/objects.c (working copy) @@ -34,7 +34,7 @@ */ 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_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 @@ 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 @@ 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 @@ 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 @@ */ 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 @@ */ 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 @@ */ 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 @@ */ 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 @@ */ 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_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; Index: reactos/win32ss/gdi/gdi32/wine/gdi_private.h =================================================================== --- reactos/win32ss/gdi/gdi32/wine/gdi_private.h (revision 75228) +++ reactos/win32ss/gdi/gdi32/wine/gdi_private.h (working copy) @@ -119,6 +119,27 @@ #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 Index: reactos/win32ss/gdi/gdi32/wine/mfdrv/bitblt.c =================================================================== --- reactos/win32ss/gdi/gdi32/wine/mfdrv/bitblt.c (revision 75228) +++ reactos/win32ss/gdi/gdi32/wine/mfdrv/bitblt.c (working copy) @@ -161,7 +161,7 @@ /*********************************************************************** - * MFDRV_SetDIBitsToDeivce + * MFDRV_SetDIBitsToDevice */ INT MFDRV_SetDIBitsToDevice( PHYSDEV dev, INT xDst, INT yDst, DWORD cx, DWORD cy, INT xSrc, INT ySrc, UINT startscan, Index: reactos/win32ss/gdi/gdi32/wine/mfdrv/init.c =================================================================== --- reactos/win32ss/gdi/gdi32/wine/mfdrv/init.c (revision 75228) +++ reactos/win32ss/gdi/gdi32/wine/mfdrv/init.c (working copy) @@ -132,7 +132,6 @@ NULL, /* pFontIsLinked */ MFDRV_FrameRgn, /* pFrameRgn */ NULL, /* pGdiComment */ - NULL, /* pGdiRealizationInfo */ MFDRV_GetBoundsRect, /* pGetBoundsRect */ NULL, /* pGetCharABCWidths */ NULL, /* pGetCharABCWidthsI */ @@ -140,6 +139,7 @@ MFDRV_GetDeviceCaps, /* pGetDeviceCaps */ NULL, /* pGetDeviceGammaRamp */ NULL, /* pGetFontData */ + NULL, /* pGetFontRealizationInfo */ NULL, /* pGetFontUnicodeRanges */ NULL, /* pGetGlyphIndices */ NULL, /* pGetGlyphOutline */ Index: reactos/win32ss/gdi/gdi32/wine/mfdrv/objects.c =================================================================== --- reactos/win32ss/gdi/gdi32/wine/mfdrv/objects.c (revision 75228) +++ reactos/win32ss/gdi/gdi32/wine/mfdrv/objects.c (working copy) @@ -176,8 +176,11 @@ case BS_PATTERN: case BS_DIBPATTERN: { +#if __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; Index: reactos/win32ss/gdi/gdi32/wine/rosglue.c =================================================================== --- reactos/win32ss/gdi/gdi32/wine/rosglue.c (revision 75228) +++ reactos/win32ss/gdi/gdi32/wine/rosglue.c (working copy) @@ -63,7 +63,6 @@ (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 +70,7 @@ (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*);