diff --git a/patches/gdi32-Path_Metafile/0001-gdi32-Add-support-for-paths-on-a-metafile-HDC.patch b/patches/gdi32-Path_Metafile/0001-gdi32-Add-support-for-paths-on-a-metafile-HDC.patch deleted file mode 100644 index b895b864..00000000 --- a/patches/gdi32-Path_Metafile/0001-gdi32-Add-support-for-paths-on-a-metafile-HDC.patch +++ /dev/null @@ -1,91 +0,0 @@ -From 58997b0ea80c550b399bddb5d2a1629ec8c5c6b5 Mon Sep 17 00:00:00 2001 -From: Dmitry Timoshkov -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 - diff --git a/patches/gdi32-Path_Metafile/0001-gdi32-tests-Add-some-additional-tests-for-ExtExtOut-.patch b/patches/gdi32-Path_Metafile/0001-gdi32-tests-Add-some-additional-tests-for-ExtExtOut-.patch new file mode 100644 index 00000000..04f4c0aa --- /dev/null +++ b/patches/gdi32-Path_Metafile/0001-gdi32-tests-Add-some-additional-tests-for-ExtExtOut-.patch @@ -0,0 +1,171 @@ +From e9e959a5ad7964f0f7546d0306b46342f46be4bd Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +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 + diff --git a/patches/gdi32-Path_Metafile/0002-gdi32-ExtTextOut-on-a-path-with-bitmap-font-selected.patch b/patches/gdi32-Path_Metafile/0002-gdi32-ExtTextOut-on-a-path-with-bitmap-font-selected.patch new file mode 100644 index 00000000..990bea8e --- /dev/null +++ b/patches/gdi32-Path_Metafile/0002-gdi32-ExtTextOut-on-a-path-with-bitmap-font-selected.patch @@ -0,0 +1,39 @@ +From 69c95a9f1db5c3e9d6958c0a994897bc5a51105d Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +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 + diff --git a/patches/gdi32-Path_Metafile/0003-gdi32-Add-support-for-paths-on-a-metafile-HDC.-v2.patch b/patches/gdi32-Path_Metafile/0003-gdi32-Add-support-for-paths-on-a-metafile-HDC.-v2.patch new file mode 100644 index 00000000..5068b01d --- /dev/null +++ b/patches/gdi32-Path_Metafile/0003-gdi32-Add-support-for-paths-on-a-metafile-HDC.-v2.patch @@ -0,0 +1,415 @@ +From 6b6a4c13b1fb589196f6e160289dbaab4fd82d01 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +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 + diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 69fc43b2..6947e6b4 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -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