Wine-Devel
Threads by month
- ----- 2026 -----
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- 22 participants
- 84527 discussions
Fix a bug that Tally produces a blank print preview when images have to be scaled.
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/gdi32/enhmfdrv/bitblt.c | 85 ++++++++++++++++++++++++++++
dlls/gdi32/enhmfdrv/enhmetafiledrv.h | 2 +
dlls/gdi32/enhmfdrv/init.c | 2 +-
dlls/gdi32/tests/metafile.c | 4 +-
4 files changed, 89 insertions(+), 4 deletions(-)
diff --git a/dlls/gdi32/enhmfdrv/bitblt.c b/dlls/gdi32/enhmfdrv/bitblt.c
index 1fc5c0b1040..f0be2b52fc0 100644
--- a/dlls/gdi32/enhmfdrv/bitblt.c
+++ b/dlls/gdi32/enhmfdrv/bitblt.c
@@ -27,6 +27,91 @@
#include "enhmetafiledrv.h"
#include "wine/debug.h"
+BOOL CDECL EMFDRV_AlphaBlend( PHYSDEV dev_dst, struct bitblt_coords *dst, PHYSDEV dev_src,
+ struct bitblt_coords *src, BLENDFUNCTION func )
+{
+ UINT bits_size, bmi_size, emr_size, size, bpp;
+ BITMAPINFOHEADER *bmih;
+ EMRALPHABLEND *emr;
+ HBITMAP hbitmap;
+ BITMAP bitmap;
+ BOOL ret;
+
+ /* can't use a metafile DC as source */
+ if (dev_src->funcs == dev_dst->funcs)
+ return FALSE;
+
+ hbitmap = GetCurrentObject(dev_src->hdc, OBJ_BITMAP);
+ if (GetObjectW(hbitmap, sizeof(BITMAP), &bitmap) != sizeof(BITMAP))
+ return FALSE;
+
+ bpp = bitmap.bmPlanes * bitmap.bmBitsPixel;
+ bits_size = get_dib_stride(bitmap.bmWidth, bpp) * bitmap.bmHeight;
+ if (bpp <= 8)
+ bmi_size = sizeof(BITMAPINFOHEADER) + (1 << bpp) * sizeof(RGBQUAD);
+ else if (bpp == 16 || bpp == 32)
+ bmi_size = sizeof(BITMAPINFOHEADER) + 3 * sizeof(RGBQUAD);
+ else
+ bmi_size = sizeof(BITMAPINFOHEADER);
+ emr_size = sizeof(EMRALPHABLEND);
+ size = emr_size + bmi_size + bits_size;
+
+ emr = HeapAlloc(GetProcessHeap(), 0, size);
+ if (!emr)
+ return FALSE;
+
+ emr->emr.iType = EMR_ALPHABLEND;
+ emr->emr.nSize = size;
+ emr->rclBounds.left = dst->log_x;
+ emr->rclBounds.top = dst->log_y;
+ emr->rclBounds.right = dst->log_x + dst->log_width - 1;
+ emr->rclBounds.bottom = dst->log_y + dst->log_height - 1;
+ emr->xDest = dst->log_x;
+ emr->yDest = dst->log_y;
+ emr->cxDest = dst->log_width;
+ emr->cyDest = dst->log_height;
+ emr->xSrc = src->log_x;
+ emr->ySrc = src->log_y;
+ emr->cxSrc = src->log_width;
+ emr->cySrc = src->log_height;
+ emr->dwRop = *(DWORD *)&func;
+ GetTransform(dev_src->hdc, 0x204, &emr->xformSrc);
+ emr->crBkColorSrc = GetBkColor(dev_src->hdc);
+ emr->iUsageSrc = DIB_RGB_COLORS;
+ emr->offBmiSrc = emr_size;
+ emr->cbBmiSrc = bmi_size;
+ emr->offBitsSrc = emr_size + bmi_size;
+ emr->cbBitsSrc = bits_size;
+
+ bmih = (BITMAPINFOHEADER *)((BYTE *)emr + emr->offBmiSrc);
+ bmih->biSize = sizeof(BITMAPINFOHEADER);
+ bmih->biWidth = bitmap.bmWidth;
+ bmih->biHeight = bitmap.bmHeight;
+ bmih->biPlanes = bitmap.bmPlanes;
+ bmih->biBitCount = bpp;
+ bmih->biCompression = (bpp == 16 || bpp == 32) ? BI_BITFIELDS : BI_RGB;
+ bmih->biSizeImage = bits_size;
+ bmih->biYPelsPerMeter = 0;
+ bmih->biXPelsPerMeter = 0;
+ bmih->biClrUsed = bpp <= 8 ? 1 << bpp : 0;
+ bmih->biClrImportant = 0;
+
+ if (GetDIBits(dev_src->hdc, hbitmap, 0, (UINT)bmih->biHeight, (BYTE *)emr + emr->offBitsSrc,
+ (BITMAPINFO *)bmih, DIB_RGB_COLORS))
+ {
+ ret = EMFDRV_WriteRecord(dev_dst, (EMR *)emr);
+ if (ret)
+ EMFDRV_UpdateBBox(dev_dst, &emr->rclBounds);
+ }
+ else
+ {
+ ret = FALSE;
+ }
+
+ HeapFree(GetProcessHeap(), 0, emr);
+ return ret;
+}
+
BOOL CDECL EMFDRV_PatBlt( PHYSDEV dev, struct bitblt_coords *dst, DWORD rop )
{
EMRBITBLT emr;
diff --git a/dlls/gdi32/enhmfdrv/enhmetafiledrv.h b/dlls/gdi32/enhmfdrv/enhmetafiledrv.h
index ec83d29c735..253f96cd8ec 100644
--- a/dlls/gdi32/enhmfdrv/enhmetafiledrv.h
+++ b/dlls/gdi32/enhmfdrv/enhmetafiledrv.h
@@ -58,6 +58,8 @@ extern DWORD EMFDRV_CreateBrushIndirect( PHYSDEV dev, HBRUSH hBrush ) DECLSPEC_H
/* Metafile driver functions */
extern BOOL CDECL EMFDRV_AbortPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
+extern BOOL CDECL EMFDRV_AlphaBlend( PHYSDEV dev_dst, struct bitblt_coords *dst,
+ PHYSDEV dev_src, struct bitblt_coords *src, BLENDFUNCTION func ) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_AngleArc( PHYSDEV dev, INT x, INT y, DWORD radius, FLOAT start, FLOAT sweep ) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_Arc( PHYSDEV dev, INT left, INT top, INT right,
INT bottom, INT xstart, INT ystart, INT xend, INT yend ) DECLSPEC_HIDDEN;
diff --git a/dlls/gdi32/enhmfdrv/init.c b/dlls/gdi32/enhmfdrv/init.c
index cf9fb923633..07416db265e 100644
--- a/dlls/gdi32/enhmfdrv/init.c
+++ b/dlls/gdi32/enhmfdrv/init.c
@@ -38,7 +38,7 @@ static const struct gdi_dc_funcs emfdrv_driver =
{
NULL, /* pAbortDoc */
EMFDRV_AbortPath, /* pAbortPath */
- NULL, /* pAlphaBlend */
+ EMFDRV_AlphaBlend, /* pAlphaBlend */
EMFDRV_AngleArc, /* pAngleArc */
EMFDRV_Arc, /* pArc */
EMFDRV_ArcTo, /* pArcTo */
diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c
index ec9c7894574..9340e20444a 100644
--- a/dlls/gdi32/tests/metafile.c
+++ b/dlls/gdi32/tests/metafile.c
@@ -5001,15 +5001,13 @@ static void test_emf_AlphaBlend(void)
ret = BitBlt(hdc_bitmap, 0, 0, bitmap_width, bitmap_height, 0, 0, 0, BLACKNESS);
ok(ret, "Test %d: BitBlt failed, error %d\n", test_idx, GetLastError());
ret = GdiAlphaBlend(hdc_emf, 0, 0, bitmap_width, bitmap_height, hdc_bitmap, 0, 0, 400, 400, blend);
- todo_wine
ok(ret, "Test %d: GdiAlphaBlend failed, error %d\n", test_idx, GetLastError());
hemf = CloseEnhMetaFile(hdc_emf);
ok(!!hemf, "Test %d: CloseEnhMetaFile failed, %d\n", test_idx, GetLastError());
sprintf(comment, "test_emf_AlphaBlend() test %d", test_idx);
- if (ret)
- ret = compare_emf_bits(hemf, tests[test_idx].bits, tests[test_idx].bits_count, comment, FALSE);
+ ret = compare_emf_bits(hemf, tests[test_idx].bits, tests[test_idx].bits_count, comment, FALSE);
if (ret)
{
dump_emf_bits(hemf, comment);
--
2.27.0
2
3
[PATCH v3 5/5] gdi32: Reselect font and pen when changing world transforms for enhanced metafiles.
by Zhiyi Zhang April 19, 2021
by Zhiyi Zhang April 19, 2021
April 19, 2021
Reselect font and pen into enhanced metafile device contexts after world transform is changed so
that content can be drawn using the correct size. Also modifying the world transform for enhanced
metafiles doesn't generate EMR_SELECTOBJECT records according to winedump outputs.
Fix an issue that Tally may produce a print preview with a too large font or with a black side bar.
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/gdi32/dc.c | 2 +-
dlls/gdi32/enhmfdrv/dc.c | 78 ++++++++++++++++++++++++----
dlls/gdi32/enhmfdrv/enhmetafiledrv.h | 1 +
dlls/gdi32/enhmfdrv/init.c | 1 +
dlls/gdi32/enhmfdrv/objects.c | 2 +
dlls/gdi32/tests/metafile.c | 1 -
6 files changed, 72 insertions(+), 13 deletions(-)
diff --git a/dlls/gdi32/dc.c b/dlls/gdi32/dc.c
index eb9dbf85668..1b9138e6529 100644
--- a/dlls/gdi32/dc.c
+++ b/dlls/gdi32/dc.c
@@ -364,7 +364,7 @@ void DC_UpdateXforms( DC *dc )
/* Reselect the font and pen back into the dc so that the size
gets updated. */
if (linear_xform_cmp( &oldworld2vport, &dc->xformWorld2Vport ) &&
- !GdiIsMetaFileDC(dc->hSelf))
+ GetObjectType( dc->hSelf ) != OBJ_METADC)
{
SelectObject(dc->hSelf, dc->hFont);
SelectObject(dc->hSelf, dc->hPen);
diff --git a/dlls/gdi32/enhmfdrv/dc.c b/dlls/gdi32/enhmfdrv/dc.c
index 72b6afeee8b..1c87643ea96 100644
--- a/dlls/gdi32/enhmfdrv/dc.c
+++ b/dlls/gdi32/enhmfdrv/dc.c
@@ -235,19 +235,27 @@ INT CDECL EMFDRV_ExtSelectClipRgn( PHYSDEV dev, HRGN hrgn, INT mode )
INT CDECL EMFDRV_SetMapMode( PHYSDEV dev, INT mode )
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetMapMode );
+ EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
EMRSETMAPMODE emr;
+ INT ret;
+
emr.emr.iType = EMR_SETMAPMODE;
emr.emr.nSize = sizeof(emr);
emr.iMode = mode;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return 0;
- return next->funcs->pSetMapMode( next, mode );
+ physDev->modifying_transform++;
+ ret = next->funcs->pSetMapMode( next, mode );
+ physDev->modifying_transform--;
+ return ret;
}
BOOL CDECL EMFDRV_SetViewportExtEx( PHYSDEV dev, INT cx, INT cy, SIZE *size )
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetViewportExtEx );
+ EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
EMRSETVIEWPORTEXTEX emr;
+ BOOL ret;
emr.emr.iType = EMR_SETVIEWPORTEXTEX;
emr.emr.nSize = sizeof(emr);
@@ -255,13 +263,18 @@ BOOL CDECL EMFDRV_SetViewportExtEx( PHYSDEV dev, INT cx, INT cy, SIZE *size )
emr.szlExtent.cy = cy;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
- return next->funcs->pSetViewportExtEx( next, cx, cy, size );
+ physDev->modifying_transform++;
+ ret = next->funcs->pSetViewportExtEx( next, cx, cy, size );
+ physDev->modifying_transform--;
+ return ret;
}
BOOL CDECL EMFDRV_SetWindowExtEx( PHYSDEV dev, INT cx, INT cy, SIZE *size )
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetWindowExtEx );
+ EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
EMRSETWINDOWEXTEX emr;
+ BOOL ret;
emr.emr.iType = EMR_SETWINDOWEXTEX;
emr.emr.nSize = sizeof(emr);
@@ -269,13 +282,18 @@ BOOL CDECL EMFDRV_SetWindowExtEx( PHYSDEV dev, INT cx, INT cy, SIZE *size )
emr.szlExtent.cy = cy;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
- return next->funcs->pSetWindowExtEx( next, cx, cy, size );
+ physDev->modifying_transform++;
+ ret = next->funcs->pSetWindowExtEx( next, cx, cy, size );
+ physDev->modifying_transform--;
+ return ret;
}
BOOL CDECL EMFDRV_SetViewportOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetViewportOrgEx );
+ EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
EMRSETVIEWPORTORGEX emr;
+ BOOL ret;
emr.emr.iType = EMR_SETVIEWPORTORGEX;
emr.emr.nSize = sizeof(emr);
@@ -283,13 +301,18 @@ BOOL CDECL EMFDRV_SetViewportOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
emr.ptlOrigin.y = y;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
- return next->funcs->pSetViewportOrgEx( next, x, y, pt );
+ physDev->modifying_transform++;
+ ret = next->funcs->pSetViewportOrgEx( next, x, y, pt );
+ physDev->modifying_transform--;
+ return ret;
}
BOOL CDECL EMFDRV_SetWindowOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetWindowOrgEx );
+ EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
EMRSETWINDOWORGEX emr;
+ BOOL ret;
emr.emr.iType = EMR_SETWINDOWORGEX;
emr.emr.nSize = sizeof(emr);
@@ -297,13 +320,18 @@ BOOL CDECL EMFDRV_SetWindowOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
emr.ptlOrigin.y = y;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
- return next->funcs->pSetWindowOrgEx( next, x, y, pt );
+ physDev->modifying_transform++;
+ ret = next->funcs->pSetWindowOrgEx( next, x, y, pt );
+ physDev->modifying_transform--;
+ return ret;
}
BOOL CDECL EMFDRV_ScaleViewportExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNum, INT yDenom, SIZE *size )
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pScaleViewportExtEx );
+ EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
EMRSCALEVIEWPORTEXTEX emr;
+ BOOL ret;
emr.emr.iType = EMR_SCALEVIEWPORTEXTEX;
emr.emr.nSize = sizeof(emr);
@@ -313,7 +341,10 @@ BOOL CDECL EMFDRV_ScaleViewportExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNu
emr.yDenom = yDenom;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
- return next->funcs->pScaleViewportExtEx( next, xNum, xDenom, yNum, yDenom, size );
+ physDev->modifying_transform++;
+ ret = next->funcs->pScaleViewportExtEx( next, xNum, xDenom, yNum, yDenom, size );
+ physDev->modifying_transform--;
+ return ret;
}
BOOL CDECL EMFDRV_ScaleWindowExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNum, INT yDenom, SIZE *size )
@@ -335,32 +366,44 @@ BOOL CDECL EMFDRV_ScaleWindowExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNum,
DWORD CDECL EMFDRV_SetLayout( PHYSDEV dev, DWORD layout )
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetMapMode );
+ EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
EMRSETLAYOUT emr;
+ DWORD ret;
emr.emr.iType = EMR_SETLAYOUT;
emr.emr.nSize = sizeof(emr);
emr.iMode = layout;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return GDI_ERROR;
- return next->funcs->pSetLayout( next, layout );
+ physDev->modifying_transform++;
+ ret = next->funcs->pSetLayout( next, layout );
+ physDev->modifying_transform--;
+ return ret;
}
BOOL CDECL EMFDRV_SetWorldTransform( PHYSDEV dev, const XFORM *xform)
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetWorldTransform );
+ EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
EMRSETWORLDTRANSFORM emr;
+ BOOL ret;
emr.emr.iType = EMR_SETWORLDTRANSFORM;
emr.emr.nSize = sizeof(emr);
emr.xform = *xform;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
- return next->funcs->pSetWorldTransform( next, xform );
+ physDev->modifying_transform++;
+ ret = next->funcs->pSetWorldTransform( next, xform );
+ physDev->modifying_transform--;
+ return ret;
}
BOOL CDECL EMFDRV_ModifyWorldTransform( PHYSDEV dev, const XFORM *xform, DWORD mode)
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pModifyWorldTransform );
+ EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
EMRMODIFYWORLDTRANSFORM emr;
+ BOOL ret;
emr.emr.iType = EMR_MODIFYWORLDTRANSFORM;
emr.emr.nSize = sizeof(emr);
@@ -380,14 +423,19 @@ BOOL CDECL EMFDRV_ModifyWorldTransform( PHYSDEV dev, const XFORM *xform, DWORD m
emr.iMode = mode;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
- return next->funcs->pModifyWorldTransform( next, xform, mode );
+ physDev->modifying_transform++;
+ ret = next->funcs->pModifyWorldTransform( next, xform, mode );
+ physDev->modifying_transform--;
+ return ret;
}
BOOL CDECL EMFDRV_OffsetViewportOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pOffsetViewportOrgEx );
+ EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
EMRSETVIEWPORTORGEX emr;
POINT prev;
+ BOOL ret;
GetViewportOrgEx( dev->hdc, &prev );
@@ -397,14 +445,19 @@ BOOL CDECL EMFDRV_OffsetViewportOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
emr.ptlOrigin.y = prev.y + y;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
- return next->funcs->pOffsetViewportOrgEx( next, x, y, pt );
+ physDev->modifying_transform++;
+ ret = next->funcs->pOffsetViewportOrgEx( next, x, y, pt );
+ physDev->modifying_transform--;
+ return ret;
}
BOOL CDECL EMFDRV_OffsetWindowOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pOffsetWindowOrgEx );
+ EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
EMRSETWINDOWORGEX emr;
POINT prev;
+ BOOL ret;
GetWindowOrgEx( dev->hdc, &prev );
@@ -414,7 +467,10 @@ BOOL CDECL EMFDRV_OffsetWindowOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
emr.ptlOrigin.y = prev.y + y;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
- return next->funcs->pOffsetWindowOrgEx( next, x, y, pt );
+ physDev->modifying_transform++;
+ ret = next->funcs->pOffsetWindowOrgEx( next, x, y, pt );
+ physDev->modifying_transform--;
+ return ret;
}
DWORD CDECL EMFDRV_SetMapperFlags( PHYSDEV dev, DWORD flags )
diff --git a/dlls/gdi32/enhmfdrv/enhmetafiledrv.h b/dlls/gdi32/enhmfdrv/enhmetafiledrv.h
index 253f96cd8ec..fd463bd29e3 100644
--- a/dlls/gdi32/enhmfdrv/enhmetafiledrv.h
+++ b/dlls/gdi32/enhmfdrv/enhmetafiledrv.h
@@ -41,6 +41,7 @@ typedef struct
HBRUSH dc_brush;
HPEN dc_pen;
INT restoring; /* RestoreDC counter */
+ INT modifying_transform;/* Counter for functions that can change world transform */
BOOL path;
INT dev_caps[COLORMGMTCAPS + 1];
} EMFDRV_PDEVICE;
diff --git a/dlls/gdi32/enhmfdrv/init.c b/dlls/gdi32/enhmfdrv/init.c
index 07416db265e..6c41aa88feb 100644
--- a/dlls/gdi32/enhmfdrv/init.c
+++ b/dlls/gdi32/enhmfdrv/init.c
@@ -372,6 +372,7 @@ HDC WINAPI CreateEnhMetaFileW(
physDev->dc_brush = 0;
physDev->dc_pen = 0;
physDev->restoring = 0;
+ physDev->modifying_transform = 0;
physDev->path = FALSE;
if (hdc) /* if no ref, use current display */
diff --git a/dlls/gdi32/enhmfdrv/objects.c b/dlls/gdi32/enhmfdrv/objects.c
index e21dfe2a47a..a60ca1a3b82 100644
--- a/dlls/gdi32/enhmfdrv/objects.c
+++ b/dlls/gdi32/enhmfdrv/objects.c
@@ -285,6 +285,7 @@ HFONT CDECL EMFDRV_SelectFont( PHYSDEV dev, HFONT hFont, UINT *aa_flags )
int i;
if (physDev->restoring) goto done; /* don't output SelectObject records during RestoreDC */
+ if (physDev->modifying_transform) goto done; /* don't output SelectObject records when modifying the world transform */
/* If the object is a stock font object, do not need to create it.
* See definitions in wingdi.h for range of stock fonts.
@@ -370,6 +371,7 @@ HPEN CDECL EMFDRV_SelectPen(PHYSDEV dev, HPEN hPen, const struct brush_pattern *
int i;
if (physDev->restoring) return hPen; /* don't output SelectObject records during RestoreDC */
+ if (physDev->modifying_transform) return hPen; /* don't output SelectObject records when modifying the world transform */
/* If the object is a stock pen object, do not need to create it.
* See definitions in wingdi.h for range of stock pens.
diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c
index 545cdef69b6..ab823dd443d 100644
--- a/dlls/gdi32/tests/metafile.c
+++ b/dlls/gdi32/tests/metafile.c
@@ -5060,7 +5060,6 @@ static void test_emf_text_extents(void)
ok(ret, "GetTextExtentPoint32W failed, error %d\n", GetLastError());
ret = GetTextExtentPoint32W(emf_dc, L"W", 1, &size2);
ok(ret, "GetTextExtentPoint32W failed, error %d\n", GetLastError());
-todo_wine
ok(size2.cx == size.cx && size2.cy == size.cy, "Expected size %dx%d, got %dx%d\n",
size.cx, size.cy, size2.cx, size2.cy);
--
2.27.0
1
0
[PATCH v3 4/5] gdi32: Move common SetLayout() code to nulldrv_SetLayout().
by Zhiyi Zhang April 19, 2021
by Zhiyi Zhang April 19, 2021
April 19, 2021
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/gdi32/dc.c | 12 +-----------
dlls/gdi32/driver.c | 13 ++++++++++++-
dlls/gdi32/enhmfdrv/dc.c | 4 +++-
3 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/dlls/gdi32/dc.c b/dlls/gdi32/dc.c
index 830fabf6e78..eb9dbf85668 100644
--- a/dlls/gdi32/dc.c
+++ b/dlls/gdi32/dc.c
@@ -1922,17 +1922,7 @@ DWORD WINAPI SetLayout(HDC hdc, DWORD layout)
if (dc)
{
PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSetLayout );
- layout = physdev->funcs->pSetLayout( physdev, layout );
- if (layout != GDI_ERROR)
- {
- oldlayout = dc->layout;
- dc->layout = layout;
- if (layout != oldlayout)
- {
- if (layout & LAYOUT_RTL) dc->MapMode = MM_ANISOTROPIC;
- DC_UpdateXforms( dc );
- }
- }
+ oldlayout = physdev->funcs->pSetLayout( physdev, layout );
release_dc_ptr( dc );
}
diff --git a/dlls/gdi32/driver.c b/dlls/gdi32/driver.c
index 09b051cd6fa..a2ebd018bca 100644
--- a/dlls/gdi32/driver.c
+++ b/dlls/gdi32/driver.c
@@ -795,7 +795,18 @@ static void CDECL nulldrv_SetDeviceClipping( PHYSDEV dev, HRGN rgn )
static DWORD CDECL nulldrv_SetLayout( PHYSDEV dev, DWORD layout )
{
- return layout;
+ DC *dc = get_nulldrv_dc( dev );
+ DWORD old_layout;
+
+ old_layout = dc->layout;
+ dc->layout = layout;
+ if (layout != old_layout)
+ {
+ if (layout & LAYOUT_RTL) dc->MapMode = MM_ANISOTROPIC;
+ DC_UpdateXforms( dc );
+ }
+
+ return old_layout;
}
static BOOL CDECL nulldrv_SetDeviceGammaRamp( PHYSDEV dev, void *ramp )
diff --git a/dlls/gdi32/enhmfdrv/dc.c b/dlls/gdi32/enhmfdrv/dc.c
index 2a749418829..72b6afeee8b 100644
--- a/dlls/gdi32/enhmfdrv/dc.c
+++ b/dlls/gdi32/enhmfdrv/dc.c
@@ -334,12 +334,14 @@ BOOL CDECL EMFDRV_ScaleWindowExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNum,
DWORD CDECL EMFDRV_SetLayout( PHYSDEV dev, DWORD layout )
{
+ PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetMapMode );
EMRSETLAYOUT emr;
emr.emr.iType = EMR_SETLAYOUT;
emr.emr.nSize = sizeof(emr);
emr.iMode = layout;
- return EMFDRV_WriteRecord( dev, &emr.emr ) ? layout : GDI_ERROR;
+ if (!EMFDRV_WriteRecord( dev, &emr.emr )) return GDI_ERROR;
+ return next->funcs->pSetLayout( next, layout );
}
BOOL CDECL EMFDRV_SetWorldTransform( PHYSDEV dev, const XFORM *xform)
--
2.27.0
1
0
April 19, 2021
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/gdi32/tests/metafile.c | 51 +++++++++++++++++++++++++++++++++++++
1 file changed, 51 insertions(+)
diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c
index 9340e20444a..545cdef69b6 100644
--- a/dlls/gdi32/tests/metafile.c
+++ b/dlls/gdi32/tests/metafile.c
@@ -5023,6 +5023,56 @@ static void test_emf_AlphaBlend(void)
ReleaseDC(0, hdc);
}
+static void test_emf_text_extents(void)
+{
+ static const XFORM xform = {0.5f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f};
+ HFONT font, old_font, old_font2;
+ LOGFONTW logfont = {0};
+ HENHMETAFILE emf;
+ SIZE size, size2;
+ HDC dc, emf_dc;
+ BOOL ret;
+
+ dc = GetDC(0);
+ emf_dc = CreateEnhMetaFileW(dc, NULL, NULL, NULL);
+ ok(!!emf_dc, "CreateEnhMetaFileW failed, error %d\n", GetLastError());
+
+ logfont.lfWeight = FW_NORMAL;
+ logfont.lfHeight = 20;
+ lstrcpyW(logfont.lfFaceName, L"Tahoma");
+ font = CreateFontIndirectW(&logfont);
+ ok(!!font, "CreateFontIndirectW failed, error %d\n", GetLastError());
+
+ old_font = SelectObject(dc, font);
+ old_font2 = SelectObject(emf_dc, font);
+
+ ret = SetGraphicsMode(dc, GM_ADVANCED);
+ ok(ret, "SetGraphicsMode failed, error %d\n", GetLastError());
+ ret = SetGraphicsMode(emf_dc, GM_ADVANCED);
+ ok(ret, "SetGraphicsMode failed, error %d\n", GetLastError());
+
+ ret = ModifyWorldTransform(dc, &xform, MWT_RIGHTMULTIPLY);
+ ok(ret, "ModifyWorldTransform failed, error %d\n", GetLastError());
+ ret = ModifyWorldTransform(emf_dc, &xform, MWT_RIGHTMULTIPLY);
+ ok(ret, "ModifyWorldTransform failed, error %d\n", GetLastError());
+
+ ret = GetTextExtentPoint32W(dc, L"W", 1, &size);
+ ok(ret, "GetTextExtentPoint32W failed, error %d\n", GetLastError());
+ ret = GetTextExtentPoint32W(emf_dc, L"W", 1, &size2);
+ ok(ret, "GetTextExtentPoint32W failed, error %d\n", GetLastError());
+todo_wine
+ ok(size2.cx == size.cx && size2.cy == size.cy, "Expected size %dx%d, got %dx%d\n",
+ size.cx, size.cy, size2.cx, size2.cy);
+
+ SelectObject(emf_dc, old_font2);
+ SelectObject(dc, old_font);
+ DeleteObject(font);
+ emf = CloseEnhMetaFile(emf_dc);
+ ok(!!emf, "CloseEnhMetaFile failed, error %d\n", GetLastError());
+ DeleteEnhMetaFile(emf);
+ ReleaseDC(0, dc);
+}
+
START_TEST(metafile)
{
init_function_pointers();
@@ -5041,6 +5091,7 @@ START_TEST(metafile)
test_emf_PolyPolyline();
test_emf_GradientFill();
test_emf_WorldTransform();
+ test_emf_text_extents();
/* For win-format metafiles (mfdrv) */
test_mf_SaveDC();
--
2.27.0
1
0
Fix a bug that Tally produces a blank print preview when images have to be scaled.
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/gdi32/enhmfdrv/bitblt.c | 85 ++++++++++++++++++++++++++++
dlls/gdi32/enhmfdrv/enhmetafiledrv.h | 2 +
dlls/gdi32/enhmfdrv/init.c | 2 +-
dlls/gdi32/tests/metafile.c | 4 +-
4 files changed, 89 insertions(+), 4 deletions(-)
diff --git a/dlls/gdi32/enhmfdrv/bitblt.c b/dlls/gdi32/enhmfdrv/bitblt.c
index 1fc5c0b1040..f0be2b52fc0 100644
--- a/dlls/gdi32/enhmfdrv/bitblt.c
+++ b/dlls/gdi32/enhmfdrv/bitblt.c
@@ -27,6 +27,91 @@
#include "enhmetafiledrv.h"
#include "wine/debug.h"
+BOOL CDECL EMFDRV_AlphaBlend( PHYSDEV dev_dst, struct bitblt_coords *dst, PHYSDEV dev_src,
+ struct bitblt_coords *src, BLENDFUNCTION func )
+{
+ UINT bits_size, bmi_size, emr_size, size, bpp;
+ BITMAPINFOHEADER *bmih;
+ EMRALPHABLEND *emr;
+ HBITMAP hbitmap;
+ BITMAP bitmap;
+ BOOL ret;
+
+ /* can't use a metafile DC as source */
+ if (dev_src->funcs == dev_dst->funcs)
+ return FALSE;
+
+ hbitmap = GetCurrentObject(dev_src->hdc, OBJ_BITMAP);
+ if (GetObjectW(hbitmap, sizeof(BITMAP), &bitmap) != sizeof(BITMAP))
+ return FALSE;
+
+ bpp = bitmap.bmPlanes * bitmap.bmBitsPixel;
+ bits_size = get_dib_stride(bitmap.bmWidth, bpp) * bitmap.bmHeight;
+ if (bpp <= 8)
+ bmi_size = sizeof(BITMAPINFOHEADER) + (1 << bpp) * sizeof(RGBQUAD);
+ else if (bpp == 16 || bpp == 32)
+ bmi_size = sizeof(BITMAPINFOHEADER) + 3 * sizeof(RGBQUAD);
+ else
+ bmi_size = sizeof(BITMAPINFOHEADER);
+ emr_size = sizeof(EMRALPHABLEND);
+ size = emr_size + bmi_size + bits_size;
+
+ emr = HeapAlloc(GetProcessHeap(), 0, size);
+ if (!emr)
+ return FALSE;
+
+ emr->emr.iType = EMR_ALPHABLEND;
+ emr->emr.nSize = size;
+ emr->rclBounds.left = dst->log_x;
+ emr->rclBounds.top = dst->log_y;
+ emr->rclBounds.right = dst->log_x + dst->log_width - 1;
+ emr->rclBounds.bottom = dst->log_y + dst->log_height - 1;
+ emr->xDest = dst->log_x;
+ emr->yDest = dst->log_y;
+ emr->cxDest = dst->log_width;
+ emr->cyDest = dst->log_height;
+ emr->xSrc = src->log_x;
+ emr->ySrc = src->log_y;
+ emr->cxSrc = src->log_width;
+ emr->cySrc = src->log_height;
+ emr->dwRop = *(DWORD *)&func;
+ GetTransform(dev_src->hdc, 0x204, &emr->xformSrc);
+ emr->crBkColorSrc = GetBkColor(dev_src->hdc);
+ emr->iUsageSrc = DIB_RGB_COLORS;
+ emr->offBmiSrc = emr_size;
+ emr->cbBmiSrc = bmi_size;
+ emr->offBitsSrc = emr_size + bmi_size;
+ emr->cbBitsSrc = bits_size;
+
+ bmih = (BITMAPINFOHEADER *)((BYTE *)emr + emr->offBmiSrc);
+ bmih->biSize = sizeof(BITMAPINFOHEADER);
+ bmih->biWidth = bitmap.bmWidth;
+ bmih->biHeight = bitmap.bmHeight;
+ bmih->biPlanes = bitmap.bmPlanes;
+ bmih->biBitCount = bpp;
+ bmih->biCompression = (bpp == 16 || bpp == 32) ? BI_BITFIELDS : BI_RGB;
+ bmih->biSizeImage = bits_size;
+ bmih->biYPelsPerMeter = 0;
+ bmih->biXPelsPerMeter = 0;
+ bmih->biClrUsed = bpp <= 8 ? 1 << bpp : 0;
+ bmih->biClrImportant = 0;
+
+ if (GetDIBits(dev_src->hdc, hbitmap, 0, (UINT)bmih->biHeight, (BYTE *)emr + emr->offBitsSrc,
+ (BITMAPINFO *)bmih, DIB_RGB_COLORS))
+ {
+ ret = EMFDRV_WriteRecord(dev_dst, (EMR *)emr);
+ if (ret)
+ EMFDRV_UpdateBBox(dev_dst, &emr->rclBounds);
+ }
+ else
+ {
+ ret = FALSE;
+ }
+
+ HeapFree(GetProcessHeap(), 0, emr);
+ return ret;
+}
+
BOOL CDECL EMFDRV_PatBlt( PHYSDEV dev, struct bitblt_coords *dst, DWORD rop )
{
EMRBITBLT emr;
diff --git a/dlls/gdi32/enhmfdrv/enhmetafiledrv.h b/dlls/gdi32/enhmfdrv/enhmetafiledrv.h
index ec83d29c735..253f96cd8ec 100644
--- a/dlls/gdi32/enhmfdrv/enhmetafiledrv.h
+++ b/dlls/gdi32/enhmfdrv/enhmetafiledrv.h
@@ -58,6 +58,8 @@ extern DWORD EMFDRV_CreateBrushIndirect( PHYSDEV dev, HBRUSH hBrush ) DECLSPEC_H
/* Metafile driver functions */
extern BOOL CDECL EMFDRV_AbortPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
+extern BOOL CDECL EMFDRV_AlphaBlend( PHYSDEV dev_dst, struct bitblt_coords *dst,
+ PHYSDEV dev_src, struct bitblt_coords *src, BLENDFUNCTION func ) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_AngleArc( PHYSDEV dev, INT x, INT y, DWORD radius, FLOAT start, FLOAT sweep ) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_Arc( PHYSDEV dev, INT left, INT top, INT right,
INT bottom, INT xstart, INT ystart, INT xend, INT yend ) DECLSPEC_HIDDEN;
diff --git a/dlls/gdi32/enhmfdrv/init.c b/dlls/gdi32/enhmfdrv/init.c
index cf9fb923633..07416db265e 100644
--- a/dlls/gdi32/enhmfdrv/init.c
+++ b/dlls/gdi32/enhmfdrv/init.c
@@ -38,7 +38,7 @@ static const struct gdi_dc_funcs emfdrv_driver =
{
NULL, /* pAbortDoc */
EMFDRV_AbortPath, /* pAbortPath */
- NULL, /* pAlphaBlend */
+ EMFDRV_AlphaBlend, /* pAlphaBlend */
EMFDRV_AngleArc, /* pAngleArc */
EMFDRV_Arc, /* pArc */
EMFDRV_ArcTo, /* pArcTo */
diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c
index ec9c7894574..9340e20444a 100644
--- a/dlls/gdi32/tests/metafile.c
+++ b/dlls/gdi32/tests/metafile.c
@@ -5001,15 +5001,13 @@ static void test_emf_AlphaBlend(void)
ret = BitBlt(hdc_bitmap, 0, 0, bitmap_width, bitmap_height, 0, 0, 0, BLACKNESS);
ok(ret, "Test %d: BitBlt failed, error %d\n", test_idx, GetLastError());
ret = GdiAlphaBlend(hdc_emf, 0, 0, bitmap_width, bitmap_height, hdc_bitmap, 0, 0, 400, 400, blend);
- todo_wine
ok(ret, "Test %d: GdiAlphaBlend failed, error %d\n", test_idx, GetLastError());
hemf = CloseEnhMetaFile(hdc_emf);
ok(!!hemf, "Test %d: CloseEnhMetaFile failed, %d\n", test_idx, GetLastError());
sprintf(comment, "test_emf_AlphaBlend() test %d", test_idx);
- if (ret)
- ret = compare_emf_bits(hemf, tests[test_idx].bits, tests[test_idx].bits_count, comment, FALSE);
+ ret = compare_emf_bits(hemf, tests[test_idx].bits, tests[test_idx].bits_count, comment, FALSE);
if (ret)
{
dump_emf_bits(hemf, comment);
--
2.27.0
1
0
[PATCH v3 1/5] gdi32/tests: Test GdiAlphaBlend() for enhanced metafiles.
by Zhiyi Zhang April 19, 2021
by Zhiyi Zhang April 19, 2021
April 19, 2021
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
v2: Supersede 203796~203800. Added SetLayout tests for Windows Metafiles to show that
world transform changes shouldn't generate META_SELECTOBJECT records. So in patch 6/6,
only the condition check for emf is removed. For wmf, if we need to remove the same
limit, we need to avoid generating META_SELECTOBJECT records when changing world
transform similar to emf. However, wmf can only change world transform via SetLayout
and MFDRV_SetLayout is not implemented at the moment.
v3: Supersede 204064~204069. Remove the SetLayout tests due to failures on Wine.
I will resubmit them with a MFDRV_SetLayout implementation later.
dlls/gdi32/tests/metafile.c | 713 +++++++++++++++++++++++++++++++++++-
1 file changed, 712 insertions(+), 1 deletion(-)
diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c
index 648e9369803..ec9c7894574 100644
--- a/dlls/gdi32/tests/metafile.c
+++ b/dlls/gdi32/tests/metafile.c
@@ -991,7 +991,7 @@ static void test_mf_SaveDC(void)
/* with the nominal results. */
/* Maximum size of sample metafiles in bytes. */
-#define MF_BUFSIZE 1024
+#define MF_BUFSIZE 2048
/* 8x8 bitmap data for a pattern brush */
static const unsigned char SAMPLE_PATTERN_BRUSH[] = {
@@ -4315,6 +4315,716 @@ static void test_emf_WorldTransform(void)
}
}
+static const unsigned char EMF_ALPHABLEND_1BIT[] =
+{
+ 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x4f, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00,
+ 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
+ 0x90, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x07, 0x00, 0x00, 0xd0, 0x03, 0x00, 0x00,
+ 0xfc, 0x01, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x60, 0xc0, 0x07, 0x00,
+ 0xb9, 0xf0, 0x03, 0x00, 0x4c, 0x00, 0x00, 0x00,
+ 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x62, 0x00, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x72, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0a, 0xd7, 0xa3, 0x3b,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0a, 0xd7, 0x23, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x30, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00,
+ 0x90, 0x01, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00
+};
+
+static const unsigned char EMF_ALPHABLEND_4BIT[] =
+{
+ 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x4f, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00,
+ 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
+ 0xc8, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x07, 0x00, 0x00, 0xd0, 0x03, 0x00, 0x00,
+ 0xfc, 0x01, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x60, 0xc0, 0x07, 0x00,
+ 0xb9, 0xf0, 0x03, 0x00, 0x4c, 0x00, 0x00, 0x00,
+ 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x62, 0x00, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x72, 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0a, 0xd7, 0xa3, 0x3b,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0a, 0xd7, 0x23, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x68, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00,
+ 0x90, 0x01, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00
+};
+
+static const unsigned char EMF_ALPHABLEND_8BIT[] =
+{
+ 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x4f, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00,
+ 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
+ 0x88, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x07, 0x00, 0x00, 0xd0, 0x03, 0x00, 0x00,
+ 0xfc, 0x01, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x60, 0xc0, 0x07, 0x00,
+ 0xb9, 0xf0, 0x03, 0x00, 0x4c, 0x00, 0x00, 0x00,
+ 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x62, 0x00, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x72, 0x00, 0x00, 0x00, 0xa4, 0x04, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0a, 0xd7, 0xa3, 0x3b,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0a, 0xd7, 0x23, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x28, 0x04, 0x00, 0x00, 0x94, 0x04, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00,
+ 0x90, 0x01, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00
+};
+
+static const unsigned char EMF_ALPHABLEND_16BIT[] =
+{
+ 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x4f, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00,
+ 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
+ 0xa4, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xc0, 0x03, 0x00, 0x00, 0xd0, 0x03, 0x00, 0x00,
+ 0xfe, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x30, 0xe0, 0x03, 0x00,
+ 0xb9, 0xf0, 0x03, 0x00, 0x4c, 0x00, 0x00, 0x00,
+ 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x62, 0x00, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x72, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0a, 0xd7, 0xa3, 0x3b,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0a, 0xd7, 0x23, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x34, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00,
+ 0x90, 0x01, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0xe0, 0x07, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x00, 0x00
+};
+
+static const unsigned char EMF_ALPHABLEND_16BIT_555[] =
+{
+ 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x4f, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00,
+ 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
+ 0xa4, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x07, 0x00, 0x00, 0xd0, 0x03, 0x00, 0x00,
+ 0xfc, 0x01, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x60, 0xc0, 0x07, 0x00,
+ 0xb9, 0xf0, 0x03, 0x00, 0x4c, 0x00, 0x00, 0x00,
+ 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x62, 0x00, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x72, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0a, 0xd7, 0xa3, 0x3b,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0a, 0xd7, 0x23, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x34, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00,
+ 0x90, 0x01, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00,
+ 0xe0, 0x03, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x00, 0x00
+};
+
+static const unsigned char EMF_ALPHABLEND_24BIT[] =
+{
+ 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x4f, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00,
+ 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
+ 0xa8, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x07, 0x00, 0x00, 0xd0, 0x03, 0x00, 0x00,
+ 0xfc, 0x01, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x60, 0xc0, 0x07, 0x00,
+ 0xb9, 0xf0, 0x03, 0x00, 0x4c, 0x00, 0x00, 0x00,
+ 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x62, 0x00, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x72, 0x00, 0x00, 0x00, 0xc4, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0a, 0xd7, 0xa3, 0x3b,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0a, 0xd7, 0x23, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x28, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00,
+ 0x30, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00,
+ 0x90, 0x01, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00
+};
+
+static const unsigned char EMF_ALPHABLEND_32BIT_888[] =
+{
+ 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x4f, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00,
+ 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
+ 0xc4, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x07, 0x00, 0x00, 0xd0, 0x03, 0x00, 0x00,
+ 0xfc, 0x01, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x60, 0xc0, 0x07, 0x00,
+ 0xb9, 0xf0, 0x03, 0x00, 0x4c, 0x00, 0x00, 0x00,
+ 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x62, 0x00, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x72, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0a, 0xd7, 0xa3, 0x3b,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0a, 0xd7, 0x23, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x34, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00,
+ 0x90, 0x01, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
+ 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x00, 0x00
+};
+
+static const unsigned char EMF_ALPHABLEND_32BIT[] =
+{
+ 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x4f, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00,
+ 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
+ 0xc4, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x07, 0x00, 0x00, 0xd0, 0x03, 0x00, 0x00,
+ 0xfc, 0x01, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x60, 0xc0, 0x07, 0x00,
+ 0xb9, 0xf0, 0x03, 0x00, 0x4c, 0x00, 0x00, 0x00,
+ 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x62, 0x00, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x72, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0a, 0xd7, 0xa3, 0x3b,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0a, 0xd7, 0x23, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x34, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00,
+ 0x90, 0x01, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
+ 0xe0, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x00, 0x00
+};
+
+static void test_emf_AlphaBlend(void)
+{
+ static const XFORM xform = {0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f};
+ static const BLENDFUNCTION blend = {AC_SRC_OVER, 0, 128, 0};
+ static const int bitmap_width = 4, bitmap_height = 4;
+ unsigned char bmi_buffer[FIELD_OFFSET(BITMAPINFO, bmiColors[256])];
+ BITMAPINFO *bmi = (BITMAPINFO *)bmi_buffer;
+ HDC hdc, hdc_emf, hdc_emf2, hdc_bitmap;
+ HBITMAP hbitmap, old_hbitmap;
+ HENHMETAFILE hemf, hemf2;
+ int ret, test_idx;
+ char comment[64];
+ void *bits;
+
+ static const struct
+ {
+ WORD bpp;
+ WORD compression;
+ const void *bits;
+ size_t bits_count;
+ DWORD used_color_count;
+ DWORD color_count;
+ RGBQUAD colors[3];
+ }
+ tests[] =
+ {
+ {1, BI_RGB, EMF_ALPHABLEND_1BIT, sizeof(EMF_ALPHABLEND_1BIT), 1, 1, {{0xff, 0xff, 0xff}}},
+ {4, BI_RGB, EMF_ALPHABLEND_4BIT, sizeof(EMF_ALPHABLEND_4BIT), 1, 1, {{0xff, 0xff, 0xff}}},
+ {8, BI_RGB, EMF_ALPHABLEND_8BIT, sizeof(EMF_ALPHABLEND_8BIT), 1, 1, {{0xff, 0xff, 0xff}}},
+ {16, BI_RGB, EMF_ALPHABLEND_16BIT_555, sizeof(EMF_ALPHABLEND_16BIT_555)},
+ {24, BI_RGB, EMF_ALPHABLEND_24BIT, sizeof(EMF_ALPHABLEND_24BIT)},
+ {32, BI_RGB, EMF_ALPHABLEND_32BIT_888, sizeof(EMF_ALPHABLEND_32BIT_888)},
+ {16, BI_BITFIELDS, EMF_ALPHABLEND_16BIT, sizeof(EMF_ALPHABLEND_16BIT), 0, 3, {{0x00, 0xf8, 0x00}, {0xe0, 0x07, 0x00}, {0x1f, 0x00, 0x00}}},
+ {32, BI_BITFIELDS, EMF_ALPHABLEND_32BIT, sizeof(EMF_ALPHABLEND_32BIT), 0, 3, {{0x00, 0x00, 0xff}, {0xe0, 0xff, 0x00}, {0xff, 0x00, 0x00}}},
+ };
+
+ hdc = GetDC(0);
+
+ /* Test that source DC cannot be an enhanced metafile */
+ hdc_emf = CreateEnhMetaFileW(hdc, NULL, NULL, NULL);
+ ok(!!hdc_emf, "CreateEnhMetaFileW failed, error %d\n", GetLastError());
+ hdc_emf2 = CreateEnhMetaFileW(hdc, NULL, NULL, NULL);
+ ok(!!hdc_emf2, "CreateEnhMetaFileW failed, error %d\n", GetLastError());
+
+ ret = GdiAlphaBlend(hdc_emf, 0, 0, 1, 1, hdc_emf2, 0, 0, 1, 1, blend);
+ ok(!ret, "GdiAlphaBlend succeeded\n");
+
+ hemf2 = CloseEnhMetaFile(hdc_emf2);
+ ok(!!hemf2, "CloseEnhMetaFile failed, error %d\n", GetLastError());
+ hemf = CloseEnhMetaFile(hdc_emf);
+ ok(!!hemf, "CloseEnhMetaFile failed, error %d\n", GetLastError());
+ DeleteEnhMetaFile(hemf2);
+ DeleteEnhMetaFile(hemf);
+
+ /* Test AlphaBlend with different format of bitmaps */
+ for (test_idx = 0; test_idx < ARRAY_SIZE(tests); ++test_idx)
+ {
+ memset(bmi_buffer, 0, sizeof(bmi_buffer));
+ bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
+ bmi->bmiHeader.biHeight = bitmap_width;
+ bmi->bmiHeader.biWidth = bitmap_height;
+ bmi->bmiHeader.biBitCount = tests[test_idx].bpp;
+ bmi->bmiHeader.biPlanes = 1;
+ bmi->bmiHeader.biCompression = tests[test_idx].compression;
+ bmi->bmiHeader.biClrUsed = tests[test_idx].used_color_count;
+ memcpy(bmi->bmiColors, tests[test_idx].colors, sizeof(RGBQUAD) * tests[test_idx].color_count);
+
+ hbitmap = CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
+ ok(!!hbitmap, "Test %d: CreateDIBSection failed, error %d\n", test_idx, GetLastError());
+ hdc_bitmap = CreateCompatibleDC(hdc);
+ ok(!!hdc_bitmap, "Test %d: CreateCompatibleDC failed, error %d\n", test_idx, GetLastError());
+ old_hbitmap = SelectObject(hdc_bitmap, hbitmap);
+
+ SetBkColor(hdc_bitmap, RGB(0xff, 0xff, 0xff));
+ ret = SetGraphicsMode(hdc_bitmap, GM_ADVANCED);
+ ok(ret, "Test %d: SetGraphicsMode failed, error %d\n", test_idx, GetLastError());
+ ret = SetWorldTransform(hdc_bitmap, &xform);
+ ok(ret, "Test %d: SetWorldTransform failed, error %d\n", test_idx, GetLastError());
+ ret = SetMapMode(hdc_bitmap, MM_ANISOTROPIC);
+ ok(ret, "Test %d: SetMapMode failed, error %d\n", test_idx, GetLastError());
+ ret = SetWindowOrgEx(hdc_bitmap, 0, 0, NULL);
+ ok(ret, "Test %d: SetWindowOrgEx failed, error %d\n", test_idx, GetLastError());
+ ret = SetWindowExtEx(hdc_bitmap, 400, 400, NULL);
+ ok(ret, "Test %d: SetWindowExtEx failed, error %d\n", test_idx, GetLastError());
+ ret = SetViewportOrgEx(hdc_bitmap, 0, 0, NULL);
+ ok(ret, "Test %d: SetViewportOrgEx failed, error %d\n", test_idx, GetLastError());
+ ret = SetViewportExtEx(hdc_bitmap, bitmap_width, bitmap_height, NULL);
+ ok(ret, "Test %d: SetViewportExtEx failed, error %d\n", test_idx, GetLastError());
+
+ hdc_emf = CreateEnhMetaFileW(hdc, NULL, NULL, NULL);
+ ok(!!hdc_emf, "Test %d: CreateEnhMetaFileW failed, error %d\n", test_idx, GetLastError());
+
+ ret = BitBlt(hdc_emf, 0, 0, bitmap_width, bitmap_height, 0, 0, 0, WHITENESS);
+ ok(ret, "Test %d: BitBlt failed, error %d\n", test_idx, GetLastError());
+ ret = BitBlt(hdc_bitmap, 0, 0, bitmap_width, bitmap_height, 0, 0, 0, BLACKNESS);
+ ok(ret, "Test %d: BitBlt failed, error %d\n", test_idx, GetLastError());
+ ret = GdiAlphaBlend(hdc_emf, 0, 0, bitmap_width, bitmap_height, hdc_bitmap, 0, 0, 400, 400, blend);
+ todo_wine
+ ok(ret, "Test %d: GdiAlphaBlend failed, error %d\n", test_idx, GetLastError());
+
+ hemf = CloseEnhMetaFile(hdc_emf);
+ ok(!!hemf, "Test %d: CloseEnhMetaFile failed, %d\n", test_idx, GetLastError());
+
+ sprintf(comment, "test_emf_AlphaBlend() test %d", test_idx);
+ if (ret)
+ ret = compare_emf_bits(hemf, tests[test_idx].bits, tests[test_idx].bits_count, comment, FALSE);
+ if (ret)
+ {
+ dump_emf_bits(hemf, comment);
+ dump_emf_records(hemf, comment);
+ }
+
+ DeleteEnhMetaFile(hemf);
+ SelectObject(hdc_bitmap, old_hbitmap);
+ DeleteDC(hdc_bitmap);
+ DeleteObject(hbitmap);
+ }
+
+ ReleaseDC(0, hdc);
+}
+
START_TEST(metafile)
{
init_function_pointers();
@@ -4323,6 +5033,7 @@ START_TEST(metafile)
test_ExtTextOut();
test_ExtTextOutScale();
test_SaveDC();
+ test_emf_AlphaBlend();
test_emf_BitBlt();
test_emf_DCBrush();
test_emf_ExtTextOut_on_path();
--
2.27.0
1
0
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/user32/user_private.h | 10 ----------
1 file changed, 10 deletions(-)
diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h
index dfd52421e66..5f8059a12a0 100644
--- a/dlls/user32/user_private.h
+++ b/dlls/user32/user_private.h
@@ -381,14 +381,4 @@ struct png_funcs
#define assert(expr) ((void)0)
#endif
-static inline WCHAR *heap_strdupW(const WCHAR *src)
-{
- WCHAR *dst;
- unsigned len;
- if (!src) return NULL;
- len = (lstrlenW(src) + 1) * sizeof(WCHAR);
- if ((dst = heap_alloc(len))) memcpy(dst, src, len);
- return dst;
-}
-
#endif /* __WINE_USER_PRIVATE_H */
--
2.31.0
1
0
[PATCH v2 6/6] gdi32: Reselect font and pen when changing world transforms for enhanced metafiles.
by Zhiyi Zhang April 19, 2021
by Zhiyi Zhang April 19, 2021
April 19, 2021
Reselect font and pen into enhanced metafile device contexts after world transform is changed so
that content can be drawn using the correct size. Also modifying the world transform for enhanced
metafiles doesn't generate EMR_SELECTOBJECT records according to winedump outputs.
Fix an issue that Tally may produce a print preview with a too large font or with a black side bar.
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/gdi32/dc.c | 2 +-
dlls/gdi32/enhmfdrv/dc.c | 78 ++++++++++++++++++++++++----
dlls/gdi32/enhmfdrv/enhmetafiledrv.h | 1 +
dlls/gdi32/enhmfdrv/init.c | 1 +
dlls/gdi32/enhmfdrv/objects.c | 2 +
dlls/gdi32/tests/metafile.c | 1 -
6 files changed, 72 insertions(+), 13 deletions(-)
diff --git a/dlls/gdi32/dc.c b/dlls/gdi32/dc.c
index eb9dbf85668..1b9138e6529 100644
--- a/dlls/gdi32/dc.c
+++ b/dlls/gdi32/dc.c
@@ -364,7 +364,7 @@ void DC_UpdateXforms( DC *dc )
/* Reselect the font and pen back into the dc so that the size
gets updated. */
if (linear_xform_cmp( &oldworld2vport, &dc->xformWorld2Vport ) &&
- !GdiIsMetaFileDC(dc->hSelf))
+ GetObjectType( dc->hSelf ) != OBJ_METADC)
{
SelectObject(dc->hSelf, dc->hFont);
SelectObject(dc->hSelf, dc->hPen);
diff --git a/dlls/gdi32/enhmfdrv/dc.c b/dlls/gdi32/enhmfdrv/dc.c
index 72b6afeee8b..1c87643ea96 100644
--- a/dlls/gdi32/enhmfdrv/dc.c
+++ b/dlls/gdi32/enhmfdrv/dc.c
@@ -235,19 +235,27 @@ INT CDECL EMFDRV_ExtSelectClipRgn( PHYSDEV dev, HRGN hrgn, INT mode )
INT CDECL EMFDRV_SetMapMode( PHYSDEV dev, INT mode )
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetMapMode );
+ EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
EMRSETMAPMODE emr;
+ INT ret;
+
emr.emr.iType = EMR_SETMAPMODE;
emr.emr.nSize = sizeof(emr);
emr.iMode = mode;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return 0;
- return next->funcs->pSetMapMode( next, mode );
+ physDev->modifying_transform++;
+ ret = next->funcs->pSetMapMode( next, mode );
+ physDev->modifying_transform--;
+ return ret;
}
BOOL CDECL EMFDRV_SetViewportExtEx( PHYSDEV dev, INT cx, INT cy, SIZE *size )
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetViewportExtEx );
+ EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
EMRSETVIEWPORTEXTEX emr;
+ BOOL ret;
emr.emr.iType = EMR_SETVIEWPORTEXTEX;
emr.emr.nSize = sizeof(emr);
@@ -255,13 +263,18 @@ BOOL CDECL EMFDRV_SetViewportExtEx( PHYSDEV dev, INT cx, INT cy, SIZE *size )
emr.szlExtent.cy = cy;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
- return next->funcs->pSetViewportExtEx( next, cx, cy, size );
+ physDev->modifying_transform++;
+ ret = next->funcs->pSetViewportExtEx( next, cx, cy, size );
+ physDev->modifying_transform--;
+ return ret;
}
BOOL CDECL EMFDRV_SetWindowExtEx( PHYSDEV dev, INT cx, INT cy, SIZE *size )
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetWindowExtEx );
+ EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
EMRSETWINDOWEXTEX emr;
+ BOOL ret;
emr.emr.iType = EMR_SETWINDOWEXTEX;
emr.emr.nSize = sizeof(emr);
@@ -269,13 +282,18 @@ BOOL CDECL EMFDRV_SetWindowExtEx( PHYSDEV dev, INT cx, INT cy, SIZE *size )
emr.szlExtent.cy = cy;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
- return next->funcs->pSetWindowExtEx( next, cx, cy, size );
+ physDev->modifying_transform++;
+ ret = next->funcs->pSetWindowExtEx( next, cx, cy, size );
+ physDev->modifying_transform--;
+ return ret;
}
BOOL CDECL EMFDRV_SetViewportOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetViewportOrgEx );
+ EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
EMRSETVIEWPORTORGEX emr;
+ BOOL ret;
emr.emr.iType = EMR_SETVIEWPORTORGEX;
emr.emr.nSize = sizeof(emr);
@@ -283,13 +301,18 @@ BOOL CDECL EMFDRV_SetViewportOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
emr.ptlOrigin.y = y;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
- return next->funcs->pSetViewportOrgEx( next, x, y, pt );
+ physDev->modifying_transform++;
+ ret = next->funcs->pSetViewportOrgEx( next, x, y, pt );
+ physDev->modifying_transform--;
+ return ret;
}
BOOL CDECL EMFDRV_SetWindowOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetWindowOrgEx );
+ EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
EMRSETWINDOWORGEX emr;
+ BOOL ret;
emr.emr.iType = EMR_SETWINDOWORGEX;
emr.emr.nSize = sizeof(emr);
@@ -297,13 +320,18 @@ BOOL CDECL EMFDRV_SetWindowOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
emr.ptlOrigin.y = y;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
- return next->funcs->pSetWindowOrgEx( next, x, y, pt );
+ physDev->modifying_transform++;
+ ret = next->funcs->pSetWindowOrgEx( next, x, y, pt );
+ physDev->modifying_transform--;
+ return ret;
}
BOOL CDECL EMFDRV_ScaleViewportExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNum, INT yDenom, SIZE *size )
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pScaleViewportExtEx );
+ EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
EMRSCALEVIEWPORTEXTEX emr;
+ BOOL ret;
emr.emr.iType = EMR_SCALEVIEWPORTEXTEX;
emr.emr.nSize = sizeof(emr);
@@ -313,7 +341,10 @@ BOOL CDECL EMFDRV_ScaleViewportExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNu
emr.yDenom = yDenom;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
- return next->funcs->pScaleViewportExtEx( next, xNum, xDenom, yNum, yDenom, size );
+ physDev->modifying_transform++;
+ ret = next->funcs->pScaleViewportExtEx( next, xNum, xDenom, yNum, yDenom, size );
+ physDev->modifying_transform--;
+ return ret;
}
BOOL CDECL EMFDRV_ScaleWindowExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNum, INT yDenom, SIZE *size )
@@ -335,32 +366,44 @@ BOOL CDECL EMFDRV_ScaleWindowExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNum,
DWORD CDECL EMFDRV_SetLayout( PHYSDEV dev, DWORD layout )
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetMapMode );
+ EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
EMRSETLAYOUT emr;
+ DWORD ret;
emr.emr.iType = EMR_SETLAYOUT;
emr.emr.nSize = sizeof(emr);
emr.iMode = layout;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return GDI_ERROR;
- return next->funcs->pSetLayout( next, layout );
+ physDev->modifying_transform++;
+ ret = next->funcs->pSetLayout( next, layout );
+ physDev->modifying_transform--;
+ return ret;
}
BOOL CDECL EMFDRV_SetWorldTransform( PHYSDEV dev, const XFORM *xform)
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetWorldTransform );
+ EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
EMRSETWORLDTRANSFORM emr;
+ BOOL ret;
emr.emr.iType = EMR_SETWORLDTRANSFORM;
emr.emr.nSize = sizeof(emr);
emr.xform = *xform;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
- return next->funcs->pSetWorldTransform( next, xform );
+ physDev->modifying_transform++;
+ ret = next->funcs->pSetWorldTransform( next, xform );
+ physDev->modifying_transform--;
+ return ret;
}
BOOL CDECL EMFDRV_ModifyWorldTransform( PHYSDEV dev, const XFORM *xform, DWORD mode)
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pModifyWorldTransform );
+ EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
EMRMODIFYWORLDTRANSFORM emr;
+ BOOL ret;
emr.emr.iType = EMR_MODIFYWORLDTRANSFORM;
emr.emr.nSize = sizeof(emr);
@@ -380,14 +423,19 @@ BOOL CDECL EMFDRV_ModifyWorldTransform( PHYSDEV dev, const XFORM *xform, DWORD m
emr.iMode = mode;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
- return next->funcs->pModifyWorldTransform( next, xform, mode );
+ physDev->modifying_transform++;
+ ret = next->funcs->pModifyWorldTransform( next, xform, mode );
+ physDev->modifying_transform--;
+ return ret;
}
BOOL CDECL EMFDRV_OffsetViewportOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pOffsetViewportOrgEx );
+ EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
EMRSETVIEWPORTORGEX emr;
POINT prev;
+ BOOL ret;
GetViewportOrgEx( dev->hdc, &prev );
@@ -397,14 +445,19 @@ BOOL CDECL EMFDRV_OffsetViewportOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
emr.ptlOrigin.y = prev.y + y;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
- return next->funcs->pOffsetViewportOrgEx( next, x, y, pt );
+ physDev->modifying_transform++;
+ ret = next->funcs->pOffsetViewportOrgEx( next, x, y, pt );
+ physDev->modifying_transform--;
+ return ret;
}
BOOL CDECL EMFDRV_OffsetWindowOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pOffsetWindowOrgEx );
+ EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
EMRSETWINDOWORGEX emr;
POINT prev;
+ BOOL ret;
GetWindowOrgEx( dev->hdc, &prev );
@@ -414,7 +467,10 @@ BOOL CDECL EMFDRV_OffsetWindowOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
emr.ptlOrigin.y = prev.y + y;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
- return next->funcs->pOffsetWindowOrgEx( next, x, y, pt );
+ physDev->modifying_transform++;
+ ret = next->funcs->pOffsetWindowOrgEx( next, x, y, pt );
+ physDev->modifying_transform--;
+ return ret;
}
DWORD CDECL EMFDRV_SetMapperFlags( PHYSDEV dev, DWORD flags )
diff --git a/dlls/gdi32/enhmfdrv/enhmetafiledrv.h b/dlls/gdi32/enhmfdrv/enhmetafiledrv.h
index 253f96cd8ec..fd463bd29e3 100644
--- a/dlls/gdi32/enhmfdrv/enhmetafiledrv.h
+++ b/dlls/gdi32/enhmfdrv/enhmetafiledrv.h
@@ -41,6 +41,7 @@ typedef struct
HBRUSH dc_brush;
HPEN dc_pen;
INT restoring; /* RestoreDC counter */
+ INT modifying_transform;/* Counter for functions that can change world transform */
BOOL path;
INT dev_caps[COLORMGMTCAPS + 1];
} EMFDRV_PDEVICE;
diff --git a/dlls/gdi32/enhmfdrv/init.c b/dlls/gdi32/enhmfdrv/init.c
index 07416db265e..6c41aa88feb 100644
--- a/dlls/gdi32/enhmfdrv/init.c
+++ b/dlls/gdi32/enhmfdrv/init.c
@@ -372,6 +372,7 @@ HDC WINAPI CreateEnhMetaFileW(
physDev->dc_brush = 0;
physDev->dc_pen = 0;
physDev->restoring = 0;
+ physDev->modifying_transform = 0;
physDev->path = FALSE;
if (hdc) /* if no ref, use current display */
diff --git a/dlls/gdi32/enhmfdrv/objects.c b/dlls/gdi32/enhmfdrv/objects.c
index e21dfe2a47a..a60ca1a3b82 100644
--- a/dlls/gdi32/enhmfdrv/objects.c
+++ b/dlls/gdi32/enhmfdrv/objects.c
@@ -285,6 +285,7 @@ HFONT CDECL EMFDRV_SelectFont( PHYSDEV dev, HFONT hFont, UINT *aa_flags )
int i;
if (physDev->restoring) goto done; /* don't output SelectObject records during RestoreDC */
+ if (physDev->modifying_transform) goto done; /* don't output SelectObject records when modifying the world transform */
/* If the object is a stock font object, do not need to create it.
* See definitions in wingdi.h for range of stock fonts.
@@ -370,6 +371,7 @@ HPEN CDECL EMFDRV_SelectPen(PHYSDEV dev, HPEN hPen, const struct brush_pattern *
int i;
if (physDev->restoring) return hPen; /* don't output SelectObject records during RestoreDC */
+ if (physDev->modifying_transform) return hPen; /* don't output SelectObject records when modifying the world transform */
/* If the object is a stock pen object, do not need to create it.
* See definitions in wingdi.h for range of stock pens.
diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c
index f9bd5259ab9..584ff7cd7ed 100644
--- a/dlls/gdi32/tests/metafile.c
+++ b/dlls/gdi32/tests/metafile.c
@@ -5060,7 +5060,6 @@ static void test_emf_text_extents(void)
ok(ret, "GetTextExtentPoint32W failed, error %d\n", GetLastError());
ret = GetTextExtentPoint32W(emf_dc, L"W", 1, &size2);
ok(ret, "GetTextExtentPoint32W failed, error %d\n", GetLastError());
-todo_wine
ok(size2.cx == size.cx && size2.cy == size.cy, "Expected size %dx%d, got %dx%d\n",
size.cx, size.cy, size2.cx, size2.cy);
--
2.27.0
2
1
[PATCH v2 5/6] gdi32: Move common SetLayout() code to nulldrv_SetLayout().
by Zhiyi Zhang April 19, 2021
by Zhiyi Zhang April 19, 2021
April 19, 2021
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/gdi32/dc.c | 12 +-----------
dlls/gdi32/driver.c | 13 ++++++++++++-
dlls/gdi32/enhmfdrv/dc.c | 4 +++-
3 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/dlls/gdi32/dc.c b/dlls/gdi32/dc.c
index 830fabf6e78..eb9dbf85668 100644
--- a/dlls/gdi32/dc.c
+++ b/dlls/gdi32/dc.c
@@ -1922,17 +1922,7 @@ DWORD WINAPI SetLayout(HDC hdc, DWORD layout)
if (dc)
{
PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSetLayout );
- layout = physdev->funcs->pSetLayout( physdev, layout );
- if (layout != GDI_ERROR)
- {
- oldlayout = dc->layout;
- dc->layout = layout;
- if (layout != oldlayout)
- {
- if (layout & LAYOUT_RTL) dc->MapMode = MM_ANISOTROPIC;
- DC_UpdateXforms( dc );
- }
- }
+ oldlayout = physdev->funcs->pSetLayout( physdev, layout );
release_dc_ptr( dc );
}
diff --git a/dlls/gdi32/driver.c b/dlls/gdi32/driver.c
index 09b051cd6fa..a2ebd018bca 100644
--- a/dlls/gdi32/driver.c
+++ b/dlls/gdi32/driver.c
@@ -795,7 +795,18 @@ static void CDECL nulldrv_SetDeviceClipping( PHYSDEV dev, HRGN rgn )
static DWORD CDECL nulldrv_SetLayout( PHYSDEV dev, DWORD layout )
{
- return layout;
+ DC *dc = get_nulldrv_dc( dev );
+ DWORD old_layout;
+
+ old_layout = dc->layout;
+ dc->layout = layout;
+ if (layout != old_layout)
+ {
+ if (layout & LAYOUT_RTL) dc->MapMode = MM_ANISOTROPIC;
+ DC_UpdateXforms( dc );
+ }
+
+ return old_layout;
}
static BOOL CDECL nulldrv_SetDeviceGammaRamp( PHYSDEV dev, void *ramp )
diff --git a/dlls/gdi32/enhmfdrv/dc.c b/dlls/gdi32/enhmfdrv/dc.c
index 2a749418829..72b6afeee8b 100644
--- a/dlls/gdi32/enhmfdrv/dc.c
+++ b/dlls/gdi32/enhmfdrv/dc.c
@@ -334,12 +334,14 @@ BOOL CDECL EMFDRV_ScaleWindowExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNum,
DWORD CDECL EMFDRV_SetLayout( PHYSDEV dev, DWORD layout )
{
+ PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetMapMode );
EMRSETLAYOUT emr;
emr.emr.iType = EMR_SETLAYOUT;
emr.emr.nSize = sizeof(emr);
emr.iMode = layout;
- return EMFDRV_WriteRecord( dev, &emr.emr ) ? layout : GDI_ERROR;
+ if (!EMFDRV_WriteRecord( dev, &emr.emr )) return GDI_ERROR;
+ return next->funcs->pSetLayout( next, layout );
}
BOOL CDECL EMFDRV_SetWorldTransform( PHYSDEV dev, const XFORM *xform)
--
2.27.0
2
1
April 19, 2021
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/gdi32/tests/metafile.c | 45 +++++++++++++++++++++++++++++++++++++
1 file changed, 45 insertions(+)
diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c
index 545cdef69b6..f9bd5259ab9 100644
--- a/dlls/gdi32/tests/metafile.c
+++ b/dlls/gdi32/tests/metafile.c
@@ -5073,6 +5073,50 @@ todo_wine
ReleaseDC(0, dc);
}
+static const unsigned char MF_SETLAYOUT_BITS[] =
+{
+/* Winedump output. Note that there is no META_SELECTOBJECT records after META_SETLAYOUT.
+ *
+ * METAHEADER 00000012
+ * type 1 header_size 0x12 version 0x300 size 0x22 object_count 0 max_record_size 0xa parameter_count 0
+ * 0001 0009 0300 0011 0000 0000 0005 0000
+ * 0000
+ * META_SETLAYOUT 0000000a
+ * 0001 0000
+ * META_EOF 00000006
+ */
+ 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x11, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x49, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00
+};
+
+static void test_mf_SetLayout(void)
+{
+ HMETAFILE mf;
+ HDC mf_dc;
+ int ret;
+
+ mf_dc = CreateMetaFileW(NULL);
+ ok(!!mf_dc, "CreateMetaFileW failed, error %d\n", GetLastError());
+
+ SetLayout(mf_dc, LAYOUT_RTL);
+
+ mf = CloseMetaFile(mf_dc);
+ ok(!!mf, "CloseMetaFile failed, error %d\n", GetLastError());
+
+ ret = compare_mf_bits(mf, MF_SETLAYOUT_BITS, sizeof(MF_SETLAYOUT_BITS), "mf_SetLayout");
+ todo_wine ok(!ret, "Bits mismatch\n");
+ if (ret)
+ {
+ dump_mf_bits(mf, "mf_SetLayout");
+ EnumMetaFile(0, mf, mf_enum_proc, 0);
+ }
+
+ DeleteMetaFile(mf);
+}
+
START_TEST(metafile)
{
init_function_pointers();
@@ -5104,6 +5148,7 @@ START_TEST(metafile)
test_mf_ExtTextOut_on_path();
test_mf_clipping();
test_mf_GetPath();
+ test_mf_SetLayout();
/* For metafile conversions */
test_mf_conversions();
--
2.27.0
2
1