gdi32-Path_Metafile: Update patchset and fix some test failures.

This commit is contained in:
Sebastian Lackner 2016-02-20 11:30:33 +01:00
parent 858ca1d0f3
commit 83071bc1dc
5 changed files with 631 additions and 93 deletions

View File

@ -1,91 +0,0 @@
From 58997b0ea80c550b399bddb5d2a1629ec8c5c6b5 Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Thu, 18 Feb 2016 12:18:01 +0100
Subject: gdi32: Add support for paths on a metafile HDC.
---
dlls/gdi32/enhmfdrv/dc.c | 4 +++-
dlls/gdi32/path.c | 20 +++++++++++++++++++-
dlls/gdi32/tests/metafile.c | 2 +-
3 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/dlls/gdi32/enhmfdrv/dc.c b/dlls/gdi32/enhmfdrv/dc.c
index cbf3f5c..a92cf4d 100644
--- a/dlls/gdi32/enhmfdrv/dc.c
+++ b/dlls/gdi32/enhmfdrv/dc.c
@@ -420,12 +420,14 @@ BOOL EMFDRV_AbortPath( PHYSDEV dev )
BOOL EMFDRV_BeginPath( PHYSDEV dev )
{
+ PHYSDEV next = GET_NEXT_PHYSDEV( dev, pBeginPath );
EMRBEGINPATH emr;
emr.emr.iType = EMR_BEGINPATH;
emr.emr.nSize = sizeof(emr);
- return EMFDRV_WriteRecord( dev, &emr.emr );
+ if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
+ return next->funcs->pBeginPath( next );
}
BOOL EMFDRV_CloseFigure( PHYSDEV dev )
diff --git a/dlls/gdi32/path.c b/dlls/gdi32/path.c
index e09cd0b..166b6b2 100644
--- a/dlls/gdi32/path.c
+++ b/dlls/gdi32/path.c
@@ -804,13 +804,23 @@ static BOOL pathdrv_EndPath( PHYSDEV dev )
{
struct path_physdev *physdev = get_path_physdev( dev );
DC *dc = get_dc_ptr( dev->hdc );
+ BOOL ret = TRUE;
+ DWORD type;
if (!dc) return FALSE;
+
+ type = GetObjectType(dev->hdc);
+ if (type == OBJ_METADC || type == OBJ_ENHMETADC)
+ {
+ PHYSDEV next = GET_NEXT_PHYSDEV( dev, pEndPath );
+ ret = next->funcs->pEndPath( next );
+ }
+
dc->path = physdev->path;
pop_dc_driver( dc, &path_driver );
HeapFree( GetProcessHeap(), 0, physdev );
release_dc_ptr( dc );
- return TRUE;
+ return ret;
}
@@ -1513,6 +1523,14 @@ static BOOL pathdrv_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags, const REC
struct path_physdev *physdev = get_path_physdev( dev );
unsigned int idx, ggo_flags = GGO_NATIVE;
POINT offset = {0, 0};
+ DWORD type;
+
+ type = GetObjectType(dev->hdc);
+ if (type == OBJ_METADC || type == OBJ_ENHMETADC)
+ {
+ PHYSDEV next = GET_NEXT_PHYSDEV( dev, pExtTextOut );
+ return next->funcs->pExtTextOut( next, x, y, flags, lprc, str, count, dx );
+ }
if (!count) return TRUE;
if (flags & ETO_GLYPH_INDEX) ggo_flags |= GGO_GLYPH_INDEX;
diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c
index f464720..865853e 100644
--- a/dlls/gdi32/tests/metafile.c
+++ b/dlls/gdi32/tests/metafile.c
@@ -3422,7 +3422,7 @@ static void test_emf_GetPath(void)
EndPath(hdcMetafile);
size = GetPath(hdcMetafile, NULL, NULL, 0);
- todo_wine ok( size == 9, "GetPath returned %d.\n", size);
+ ok( size == 9, "GetPath returned %d.\n", size);
hemf = CloseEnhMetaFile(hdcMetafile);
ok(hemf != 0, "CloseEnhMetaFile error %d\n", GetLastError());
--
2.7.0

View File

@ -0,0 +1,171 @@
From e9e959a5ad7964f0f7546d0306b46342f46be4bd Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Sat, 20 Feb 2016 15:21:00 +0800
Subject: gdi32/tests: Add some additional tests for ExtExtOut on a path for an
EMF DC.
---
dlls/gdi32/tests/metafile.c | 119 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 119 insertions(+)
diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c
index f464720..9247ac7 100644
--- a/dlls/gdi32/tests/metafile.c
+++ b/dlls/gdi32/tests/metafile.c
@@ -1101,6 +1101,44 @@ static const unsigned char EMF_TEXTOUT_ON_PATH_BITS[] =
0x14, 0x00, 0x00, 0x00
};
+static const unsigned char EMF_TEXTOUT_OUTLINE_ON_PATH_BITS[] =
+{
+ 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff,
+ 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
+ 0x0c, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x90, 0x06, 0x00, 0x00, 0x1a, 0x04, 0x00, 0x00,
+ 0x51, 0x02, 0x00, 0x00, 0x72, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x1a, 0x0b, 0x09, 0x00,
+ 0xf0, 0xa6, 0x05, 0x00, 0x25, 0x00, 0x00, 0x00,
+ 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x80,
+ 0x3b, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x54, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x01, 0x00, 0x00, 0x00, 0xc3, 0x30, 0x0d, 0x42,
+ 0xcf, 0xf3, 0x0c, 0x42, 0x0b, 0x00, 0x00, 0x00,
+ 0x16, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x54, 0x00, 0x00, 0x00, 0x54, 0x00, 0x65, 0x00,
+ 0x73, 0x00, 0x74, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x0c, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
+ 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x80,
+ 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x00, 0x00
+};
+
static const unsigned char MF_LINETO_BITS[] = {
0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x11, 0x00,
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
@@ -2224,6 +2262,8 @@ static void test_emf_ExtTextOut_on_path(void)
HDC hdcDisplay, hdcMetafile;
HENHMETAFILE hMetafile;
BOOL ret;
+ LOGFONTA lf;
+ HFONT hFont;
static const INT dx[4] = { 3, 5, 8, 12 };
/* Win9x doesn't play EMFs on invisible windows */
@@ -2234,6 +2274,20 @@ static void test_emf_ExtTextOut_on_path(void)
hdcDisplay = GetDC(hwnd);
ok(hdcDisplay != 0, "GetDC error %d\n", GetLastError());
+ /* with default font */
+ ret = BeginPath(hdcDisplay);
+ ok(ret, "BeginPath error %d\n", GetLastError());
+
+ ret = ExtTextOutA(hdcDisplay, 11, 22, 0, NULL, "Test", 4, dx);
+todo_wine
+ ok(ret, "ExtTextOut error %d\n", GetLastError());
+
+ ret = EndPath(hdcDisplay);
+ ok(ret, "EndPath error %d\n", GetLastError());
+
+ ret = GetPath(hdcDisplay, NULL, NULL, 0);
+ ok(!ret, "expected 0, got %d\n", ret);
+
hdcMetafile = CreateEnhMetaFileA(hdcDisplay, NULL, NULL, NULL);
ok(hdcMetafile != 0, "CreateEnhMetaFileA error %d\n", GetLastError());
@@ -2246,6 +2300,10 @@ static void test_emf_ExtTextOut_on_path(void)
ret = EndPath(hdcMetafile);
ok(ret, "EndPath error %d\n", GetLastError());
+ ret = GetPath(hdcMetafile, NULL, NULL, 0);
+todo_wine
+ ok(!ret, "expected 0, got %d\n", ret);
+
hMetafile = CloseEnhMetaFile(hdcMetafile);
ok(hMetafile != 0, "CloseEnhMetaFile error %d\n", GetLastError());
@@ -2261,6 +2319,67 @@ static void test_emf_ExtTextOut_on_path(void)
ret = DeleteEnhMetaFile(hMetafile);
ok(ret, "DeleteEnhMetaFile error %d\n", GetLastError());
+
+ /* with outline font */
+ memset(&lf, 0, sizeof(lf));
+ lf.lfCharSet = ANSI_CHARSET;
+ lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
+ lf.lfWeight = FW_DONTCARE;
+ lf.lfHeight = 7;
+ lf.lfQuality = DEFAULT_QUALITY;
+ lstrcpyA(lf.lfFaceName, "Tahoma");
+ hFont = CreateFontIndirectA(&lf);
+ ok(hFont != 0, "CreateFontIndirectA error %d\n", GetLastError());
+ hFont = SelectObject(hdcDisplay, hFont);
+
+ ret = BeginPath(hdcDisplay);
+ ok(ret, "BeginPath error %d\n", GetLastError());
+
+ ret = ExtTextOutA(hdcDisplay, 11, 22, 0, NULL, "Test", 4, dx);
+ ok(ret, "ExtTextOut error %d\n", GetLastError());
+
+ ret = EndPath(hdcDisplay);
+ ok(ret, "EndPath error %d\n", GetLastError());
+
+ ret = GetPath(hdcDisplay, NULL, NULL, 0);
+ ok(ret != 0, "expected != 0\n");
+
+ SelectObject(hdcDisplay, hFont);
+
+ hdcMetafile = CreateEnhMetaFileA(hdcDisplay, NULL, NULL, NULL);
+ ok(hdcMetafile != 0, "CreateEnhMetaFileA error %d\n", GetLastError());
+
+ hFont = SelectObject(hdcMetafile, hFont);
+
+ ret = BeginPath(hdcMetafile);
+ ok(ret, "BeginPath error %d\n", GetLastError());
+
+ ret = ExtTextOutA(hdcMetafile, 11, 22, 0, NULL, "Test", 4, dx);
+ ok(ret, "ExtTextOut error %d\n", GetLastError());
+
+ ret = EndPath(hdcMetafile);
+ ok(ret, "EndPath error %d\n", GetLastError());
+
+ ret = GetPath(hdcMetafile, NULL, NULL, 0);
+todo_wine
+ ok(!ret, "expected 0, got %d\n", ret);
+
+ hFont = SelectObject(hdcMetafile, hFont);
+ DeleteObject(hFont);
+
+ hMetafile = CloseEnhMetaFile(hdcMetafile);
+ ok(hMetafile != 0, "CloseEnhMetaFile error %d\n", GetLastError());
+
+ if (compare_emf_bits(hMetafile, EMF_TEXTOUT_OUTLINE_ON_PATH_BITS, sizeof(EMF_TEXTOUT_OUTLINE_ON_PATH_BITS),
+ "emf_TextOut_on_path", FALSE) != 0)
+ {
+ dump_emf_bits(hMetafile, "emf_TextOut_outline_on_path");
+ dump_emf_records(hMetafile, "emf_TextOut_outline_on_path");
+ }
+
+ ret = DeleteEnhMetaFile(hMetafile);
+ ok(ret, "DeleteEnhMetaFile error %d\n", GetLastError());
+
ret = ReleaseDC(hwnd, hdcDisplay);
ok(ret, "ReleaseDC error %d\n", GetLastError());
DestroyWindow(hwnd);
--
2.7.0

View File

@ -0,0 +1,39 @@
From 69c95a9f1db5c3e9d6958c0a994897bc5a51105d Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Sat, 20 Feb 2016 15:28:36 +0800
Subject: gdi32: ExtTextOut on a path with bitmap font selected shouldn't fail.
This just leads to empty path generated.
---
dlls/gdi32/path.c | 2 +-
dlls/gdi32/tests/metafile.c | 1 -
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/dlls/gdi32/path.c b/dlls/gdi32/path.c
index e09cd0b..8856d49 100644
--- a/dlls/gdi32/path.c
+++ b/dlls/gdi32/path.c
@@ -1525,7 +1525,7 @@ static BOOL pathdrv_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags, const REC
void *outline;
dwSize = GetGlyphOutlineW(dev->hdc, str[idx], ggo_flags, &gm, 0, NULL, &identity);
- if (dwSize == GDI_ERROR) return FALSE;
+ if (dwSize == GDI_ERROR) continue;
/* add outline only if char is printable */
if(dwSize)
diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c
index 9247ac7..e247db9 100644
--- a/dlls/gdi32/tests/metafile.c
+++ b/dlls/gdi32/tests/metafile.c
@@ -2279,7 +2279,6 @@ static void test_emf_ExtTextOut_on_path(void)
ok(ret, "BeginPath error %d\n", GetLastError());
ret = ExtTextOutA(hdcDisplay, 11, 22, 0, NULL, "Test", 4, dx);
-todo_wine
ok(ret, "ExtTextOut error %d\n", GetLastError());
ret = EndPath(hdcDisplay);
--
2.7.0

View File

@ -0,0 +1,415 @@
From 6b6a4c13b1fb589196f6e160289dbaab4fd82d01 Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Sat, 20 Feb 2016 16:09:40 +0800
Subject: gdi32: Add support for paths on a metafile HDC. (v2)
---
dlls/gdi32/enhmfdrv/dc.c | 4 +-
dlls/gdi32/path.c | 186 ++++++++++++++++++++++++++++++++++++++++++--
dlls/gdi32/tests/metafile.c | 4 +-
3 files changed, 185 insertions(+), 9 deletions(-)
diff --git a/dlls/gdi32/enhmfdrv/dc.c b/dlls/gdi32/enhmfdrv/dc.c
index cbf3f5c..a92cf4d 100644
--- a/dlls/gdi32/enhmfdrv/dc.c
+++ b/dlls/gdi32/enhmfdrv/dc.c
@@ -420,12 +420,14 @@ BOOL EMFDRV_AbortPath( PHYSDEV dev )
BOOL EMFDRV_BeginPath( PHYSDEV dev )
{
+ PHYSDEV next = GET_NEXT_PHYSDEV( dev, pBeginPath );
EMRBEGINPATH emr;
emr.emr.iType = EMR_BEGINPATH;
emr.emr.nSize = sizeof(emr);
- return EMFDRV_WriteRecord( dev, &emr.emr );
+ if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
+ return next->funcs->pBeginPath( next );
}
BOOL EMFDRV_CloseFigure( PHYSDEV dev )
diff --git a/dlls/gdi32/path.c b/dlls/gdi32/path.c
index 8856d49..05d74d2 100644
--- a/dlls/gdi32/path.c
+++ b/dlls/gdi32/path.c
@@ -787,13 +787,22 @@ static BOOL pathdrv_AbortPath( PHYSDEV dev )
{
struct path_physdev *physdev = get_path_physdev( dev );
DC *dc = get_dc_ptr( dev->hdc );
+ BOOL ret = TRUE;
+ DWORD obj_type = GetObjectType(dev->hdc);
if (!dc) return FALSE;
+
+ if (obj_type == OBJ_METADC || obj_type == OBJ_ENHMETADC)
+ {
+ PHYSDEV next = GET_NEXT_PHYSDEV( dev, pAbortPath );
+ ret = next->funcs->pAbortPath( next );
+ }
+
free_gdi_path( physdev->path );
pop_dc_driver( dc, &path_driver );
HeapFree( GetProcessHeap(), 0, physdev );
release_dc_ptr( dc );
- return TRUE;
+ return ret;
}
@@ -804,13 +813,22 @@ static BOOL pathdrv_EndPath( PHYSDEV dev )
{
struct path_physdev *physdev = get_path_physdev( dev );
DC *dc = get_dc_ptr( dev->hdc );
+ BOOL ret = TRUE;
+ DWORD obj_type = GetObjectType(dev->hdc);;
if (!dc) return FALSE;
+
+ if (obj_type == OBJ_METADC || obj_type == OBJ_ENHMETADC)
+ {
+ PHYSDEV next = GET_NEXT_PHYSDEV( dev, pEndPath );
+ ret = next->funcs->pEndPath( next );
+ }
+
dc->path = physdev->path;
pop_dc_driver( dc, &path_driver );
HeapFree( GetProcessHeap(), 0, physdev );
release_dc_ptr( dc );
- return TRUE;
+ return ret;
}
@@ -893,6 +911,14 @@ BOOL PATH_RestorePath( DC *dst, DC *src )
static BOOL pathdrv_MoveTo( PHYSDEV dev, INT x, INT y )
{
struct path_physdev *physdev = get_path_physdev( dev );
+ DWORD obj_type = GetObjectType(dev->hdc);
+
+ if (obj_type == OBJ_METADC || obj_type == OBJ_ENHMETADC)
+ {
+ PHYSDEV next = GET_NEXT_PHYSDEV( dev, pMoveTo );
+ if (!next->funcs->pMoveTo( next, x, y )) return FALSE;
+ }
+
physdev->path->newStroke = TRUE;
return TRUE;
}
@@ -905,6 +931,13 @@ static BOOL pathdrv_LineTo( PHYSDEV dev, INT x, INT y )
{
struct path_physdev *physdev = get_path_physdev( dev );
POINT point;
+ DWORD obj_type = GetObjectType(dev->hdc);
+
+ if (obj_type == OBJ_METADC || obj_type == OBJ_ENHMETADC)
+ {
+ PHYSDEV next = GET_NEXT_PHYSDEV( dev, pLineTo );
+ if (!next->funcs->pLineTo( next, x, y )) return FALSE;
+ }
if (!start_new_stroke( physdev )) return FALSE;
point.x = x;
@@ -925,6 +958,14 @@ static BOOL pathdrv_RoundRect( PHYSDEV dev, INT x1, INT y1, INT x2, INT y2, INT
struct path_physdev *physdev = get_path_physdev( dev );
POINT corners[2], pointTemp;
FLOAT_POINT ellCorners[2];
+ DWORD obj_type = GetObjectType(dev->hdc);
+
+ if (obj_type == OBJ_METADC || obj_type == OBJ_ENHMETADC)
+ {
+ PHYSDEV next = GET_NEXT_PHYSDEV( dev, pRoundRect );
+ if (!next->funcs->pRoundRect( next, x1, y1, x2, y2, ell_width, ell_height ))
+ return FALSE;
+ }
PATH_CheckCorners(dev->hdc,corners,x1,y1,x2,y2);
@@ -972,6 +1013,13 @@ static BOOL pathdrv_Rectangle( PHYSDEV dev, INT x1, INT y1, INT x2, INT y2 )
{
struct path_physdev *physdev = get_path_physdev( dev );
POINT corners[2], pointTemp;
+ DWORD obj_type = GetObjectType(dev->hdc);
+
+ if (obj_type == OBJ_METADC || obj_type == OBJ_ENHMETADC)
+ {
+ PHYSDEV next = GET_NEXT_PHYSDEV( dev, pRectangle );
+ if (!next->funcs->pRectangle( next, x1, y1, x2, y2 )) return FALSE;
+ }
PATH_CheckCorners(dev->hdc,corners,x1,y1,x2,y2);
@@ -1147,6 +1195,14 @@ static BOOL pathdrv_AngleArc( PHYSDEV dev, INT x, INT y, DWORD radius, FLOAT eSt
{
INT x1, y1, x2, y2, arcdir;
BOOL ret;
+ DWORD obj_type = GetObjectType(dev->hdc);
+
+ if (obj_type == OBJ_METADC || obj_type == OBJ_ENHMETADC)
+ {
+ PHYSDEV next = GET_NEXT_PHYSDEV( dev, pAngleArc );
+ if (!next->funcs->pAngleArc( next, x, y, radius, eStartAngle, eSweepAngle ))
+ return FALSE;
+ }
x1 = GDI_ROUND( x + cos(eStartAngle*M_PI/180) * radius );
y1 = GDI_ROUND( y - sin(eStartAngle*M_PI/180) * radius );
@@ -1165,6 +1221,15 @@ static BOOL pathdrv_AngleArc( PHYSDEV dev, INT x, INT y, DWORD radius, FLOAT eSt
static BOOL pathdrv_Arc( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend )
{
+ DWORD obj_type = GetObjectType(dev->hdc);
+
+ if (obj_type == OBJ_METADC || obj_type == OBJ_ENHMETADC)
+ {
+ PHYSDEV next = GET_NEXT_PHYSDEV( dev, pArc );
+ if (!next->funcs->pArc( next, left, top, right, bottom, xstart, ystart, xend, yend ))
+ return FALSE;
+ }
+
return PATH_Arc( dev, left, top, right, bottom, xstart, ystart, xend, yend, 0 );
}
@@ -1175,6 +1240,15 @@ static BOOL pathdrv_Arc( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
static BOOL pathdrv_ArcTo( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend )
{
+ DWORD obj_type = GetObjectType(dev->hdc);
+
+ if (obj_type == OBJ_METADC || obj_type == OBJ_ENHMETADC)
+ {
+ PHYSDEV next = GET_NEXT_PHYSDEV( dev, pArcTo );
+ if (!next->funcs->pArcTo( next, left, top, right, bottom, xstart, ystart, xend, yend ))
+ return FALSE;
+ }
+
return PATH_Arc( dev, left, top, right, bottom, xstart, ystart, xend, yend, -1 );
}
@@ -1185,6 +1259,15 @@ static BOOL pathdrv_ArcTo( PHYSDEV dev, INT left, INT top, INT right, INT bottom
static BOOL pathdrv_Chord( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend )
{
+ DWORD obj_type = GetObjectType(dev->hdc);
+
+ if (obj_type == OBJ_METADC || obj_type == OBJ_ENHMETADC)
+ {
+ PHYSDEV next = GET_NEXT_PHYSDEV( dev, pChord );
+ if (!next->funcs->pChord( next, left, top, right, bottom, xstart, ystart, xend, yend ))
+ return FALSE;
+ }
+
return PATH_Arc( dev, left, top, right, bottom, xstart, ystart, xend, yend, 1);
}
@@ -1195,6 +1278,15 @@ static BOOL pathdrv_Chord( PHYSDEV dev, INT left, INT top, INT right, INT bottom
static BOOL pathdrv_Pie( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend )
{
+ DWORD obj_type = GetObjectType(dev->hdc);
+
+ if (obj_type == OBJ_METADC || obj_type == OBJ_ENHMETADC)
+ {
+ PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPie );
+ if (!next->funcs->pPie( next, left, top, right, bottom, xstart, ystart, xend, yend ))
+ return FALSE;
+ }
+
return PATH_Arc( dev, left, top, right, bottom, xstart, ystart, xend, yend, 2 );
}
@@ -1204,6 +1296,15 @@ static BOOL pathdrv_Pie( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
*/
static BOOL pathdrv_Ellipse( PHYSDEV dev, INT x1, INT y1, INT x2, INT y2 )
{
+ DWORD obj_type = GetObjectType(dev->hdc);
+
+ if (obj_type == OBJ_METADC || obj_type == OBJ_ENHMETADC)
+ {
+ PHYSDEV next = GET_NEXT_PHYSDEV( dev, pEllipse );
+ if (!next->funcs->pEllipse( next, x1, y1, x2, y2 ))
+ return FALSE;
+ }
+
return PATH_Arc( dev, x1, y1, x2, y2, x1, (y1+y2)/2, x1, (y1+y2)/2, 0 ) && CloseFigure( dev->hdc );
}
@@ -1214,6 +1315,14 @@ static BOOL pathdrv_Ellipse( PHYSDEV dev, INT x1, INT y1, INT x2, INT y2 )
static BOOL pathdrv_PolyBezierTo( PHYSDEV dev, const POINT *pts, DWORD cbPoints )
{
struct path_physdev *physdev = get_path_physdev( dev );
+ DWORD obj_type = GetObjectType(dev->hdc);
+
+ if (obj_type == OBJ_METADC || obj_type == OBJ_ENHMETADC)
+ {
+ PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolyBezierTo );
+ if (!next->funcs->pPolyBezierTo( next, pts, cbPoints ))
+ return FALSE;
+ }
if (!start_new_stroke( physdev )) return FALSE;
return add_log_points( physdev, pts, cbPoints, PT_BEZIERTO ) != NULL;
@@ -1226,8 +1335,17 @@ static BOOL pathdrv_PolyBezierTo( PHYSDEV dev, const POINT *pts, DWORD cbPoints
static BOOL pathdrv_PolyBezier( PHYSDEV dev, const POINT *pts, DWORD cbPoints )
{
struct path_physdev *physdev = get_path_physdev( dev );
- BYTE *type = add_log_points( physdev, pts, cbPoints, PT_BEZIERTO );
+ BYTE *type;
+ DWORD obj_type = GetObjectType(dev->hdc);
+
+ if (obj_type == OBJ_METADC || obj_type == OBJ_ENHMETADC)
+ {
+ PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolyBezier );
+ if (!next->funcs->pPolyBezier( next, pts, cbPoints ))
+ return FALSE;
+ }
+ type = add_log_points( physdev, pts, cbPoints, PT_BEZIERTO );
if (!type) return FALSE;
type[0] = PT_MOVETO;
return TRUE;
@@ -1242,6 +1360,14 @@ static BOOL pathdrv_PolyDraw( PHYSDEV dev, const POINT *pts, const BYTE *types,
struct path_physdev *physdev = get_path_physdev( dev );
POINT lastmove, orig_pos;
INT i;
+ DWORD obj_type = GetObjectType(dev->hdc);
+
+ if (obj_type == OBJ_METADC || obj_type == OBJ_ENHMETADC)
+ {
+ PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolyDraw );
+ if (!next->funcs->pPolyDraw( next, pts, types, cbPoints ))
+ return FALSE;
+ }
GetCurrentPositionEx( dev->hdc, &orig_pos );
lastmove = orig_pos;
@@ -1300,8 +1426,17 @@ static BOOL pathdrv_PolyDraw( PHYSDEV dev, const POINT *pts, const BYTE *types,
static BOOL pathdrv_Polyline( PHYSDEV dev, const POINT *pts, INT cbPoints )
{
struct path_physdev *physdev = get_path_physdev( dev );
- BYTE *type = add_log_points( physdev, pts, cbPoints, PT_LINETO );
+ BYTE *type;
+ DWORD obj_type = GetObjectType(dev->hdc);
+
+ if (obj_type == OBJ_METADC || obj_type == OBJ_ENHMETADC)
+ {
+ PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolyline );
+ if (!next->funcs->pPolyline( next, pts, cbPoints ))
+ return FALSE;
+ }
+ type = add_log_points( physdev, pts, cbPoints, PT_LINETO );
if (!type) return FALSE;
if (cbPoints) type[0] = PT_MOVETO;
return TRUE;
@@ -1314,6 +1449,14 @@ static BOOL pathdrv_Polyline( PHYSDEV dev, const POINT *pts, INT cbPoints )
static BOOL pathdrv_PolylineTo( PHYSDEV dev, const POINT *pts, INT cbPoints )
{
struct path_physdev *physdev = get_path_physdev( dev );
+ DWORD obj_type = GetObjectType(dev->hdc);
+
+ if (obj_type == OBJ_METADC || obj_type == OBJ_ENHMETADC)
+ {
+ PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolylineTo );
+ if (!next->funcs->pPolylineTo( next, pts, cbPoints ))
+ return FALSE;
+ }
if (!start_new_stroke( physdev )) return FALSE;
return add_log_points( physdev, pts, cbPoints, PT_LINETO ) != NULL;
@@ -1326,8 +1469,17 @@ static BOOL pathdrv_PolylineTo( PHYSDEV dev, const POINT *pts, INT cbPoints )
static BOOL pathdrv_Polygon( PHYSDEV dev, const POINT *pts, INT cbPoints )
{
struct path_physdev *physdev = get_path_physdev( dev );
- BYTE *type = add_log_points( physdev, pts, cbPoints, PT_LINETO );
+ BYTE *type;
+ DWORD obj_type = GetObjectType(dev->hdc);
+
+ if (obj_type == OBJ_METADC || obj_type == OBJ_ENHMETADC)
+ {
+ PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolygon );
+ if (!next->funcs->pPolygon( next, pts, cbPoints ))
+ return FALSE;
+ }
+ type = add_log_points( physdev, pts, cbPoints, PT_LINETO );
if (!type) return FALSE;
if (cbPoints) type[0] = PT_MOVETO;
if (cbPoints > 1) type[cbPoints - 1] = PT_LINETO | PT_CLOSEFIGURE;
@@ -1343,6 +1495,14 @@ static BOOL pathdrv_PolyPolygon( PHYSDEV dev, const POINT* pts, const INT* count
struct path_physdev *physdev = get_path_physdev( dev );
UINT poly;
BYTE *type;
+ DWORD obj_type = GetObjectType(dev->hdc);
+
+ if (obj_type == OBJ_METADC || obj_type == OBJ_ENHMETADC)
+ {
+ PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolyPolygon );
+ if (!next->funcs->pPolyPolygon( next, pts, counts, polygons ))
+ return FALSE;
+ }
for(poly = 0; poly < polygons; poly++) {
type = add_log_points( physdev, pts, counts[poly], PT_LINETO );
@@ -1364,6 +1524,14 @@ static BOOL pathdrv_PolyPolyline( PHYSDEV dev, const POINT* pts, const DWORD* co
struct path_physdev *physdev = get_path_physdev( dev );
UINT poly, count;
BYTE *type;
+ DWORD obj_type = GetObjectType(dev->hdc);
+
+ if (obj_type == OBJ_METADC || obj_type == OBJ_ENHMETADC)
+ {
+ PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolyPolyline );
+ if (!next->funcs->pPolyPolyline( next, pts, counts, polylines ))
+ return FALSE;
+ }
for (poly = count = 0; poly < polylines; poly++) count += counts[poly];
@@ -1513,6 +1681,14 @@ static BOOL pathdrv_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags, const REC
struct path_physdev *physdev = get_path_physdev( dev );
unsigned int idx, ggo_flags = GGO_NATIVE;
POINT offset = {0, 0};
+ DWORD obj_type = GetObjectType(dev->hdc);
+
+ if (obj_type == OBJ_METADC || obj_type == OBJ_ENHMETADC)
+ {
+ PHYSDEV next = GET_NEXT_PHYSDEV( dev, pExtTextOut );
+ if (!next->funcs->pExtTextOut( next, x, y, flags, lprc, str, count, dx ))
+ return FALSE;
+ }
if (!count) return TRUE;
if (flags & ETO_GLYPH_INDEX) ggo_flags |= GGO_GLYPH_INDEX;
diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c
index e247db9..8b487e8 100644
--- a/dlls/gdi32/tests/metafile.c
+++ b/dlls/gdi32/tests/metafile.c
@@ -2300,7 +2300,6 @@ static void test_emf_ExtTextOut_on_path(void)
ok(ret, "EndPath error %d\n", GetLastError());
ret = GetPath(hdcMetafile, NULL, NULL, 0);
-todo_wine
ok(!ret, "expected 0, got %d\n", ret);
hMetafile = CloseEnhMetaFile(hdcMetafile);
@@ -2360,7 +2359,6 @@ todo_wine
ok(ret, "EndPath error %d\n", GetLastError());
ret = GetPath(hdcMetafile, NULL, NULL, 0);
-todo_wine
ok(!ret, "expected 0, got %d\n", ret);
hFont = SelectObject(hdcMetafile, hFont);
@@ -3540,7 +3538,7 @@ static void test_emf_GetPath(void)
EndPath(hdcMetafile);
size = GetPath(hdcMetafile, NULL, NULL, 0);
- todo_wine ok( size == 9, "GetPath returned %d.\n", size);
+ ok( size == 9, "GetPath returned %d.\n", size);
hemf = CloseEnhMetaFile(hdcMetafile);
ok(hemf != 0, "CloseEnhMetaFile error %d\n", GetLastError());
--
2.7.0

View File

@ -3658,9 +3658,13 @@ fi
# | * dlls/gdi32/enhmfdrv/dc.c, dlls/gdi32/path.c, dlls/gdi32/tests/metafile.c
# |
if test "$enable_gdi32_Path_Metafile" -eq 1; then
patch_apply gdi32-Path_Metafile/0001-gdi32-Add-support-for-paths-on-a-metafile-HDC.patch
patch_apply gdi32-Path_Metafile/0001-gdi32-tests-Add-some-additional-tests-for-ExtExtOut-.patch
patch_apply gdi32-Path_Metafile/0002-gdi32-ExtTextOut-on-a-path-with-bitmap-font-selected.patch
patch_apply gdi32-Path_Metafile/0003-gdi32-Add-support-for-paths-on-a-metafile-HDC.-v2.patch
(
echo '+ { "Dmitry Timoshkov", "gdi32: Add support for paths on a metafile HDC.", 1 },';
echo '+ { "Dmitry Timoshkov", "gdi32/tests: Add some additional tests for ExtExtOut on a path for an EMF DC.", 1 },';
echo '+ { "Dmitry Timoshkov", "gdi32: ExtTextOut on a path with bitmap font selected shouldn'\''t fail.", 1 },';
echo '+ { "Dmitry Timoshkov", "gdi32: Add support for paths on a metafile HDC.", 2 },';
) >> "$patchlist"
fi