[PATCH] gdi32: Limit GetGlyphOutlineW(uChar) to a WORD.

Arkadiusz Hiler ahiler at codeweavers.com
Mon Sep 21 09:24:54 CDT 2020


Turns out GetGlyphOutlineW() is using only two bytes for the character, which
is common for GDI font API.

This limits us to chars in the range 0x0000 - 0xffff.

Fixes eden* PLUS+MOSAIC.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45400
Signed-off-by: Arkadiusz Hiler <ahiler at codeweavers.com>
---
 dlls/gdi32/font.c                       |   2 +
 dlls/gdi32/tests/Makefile.in            |   1 +
 dlls/gdi32/tests/font.c                 |  54 ++++++++++++++++
 dlls/gdi32/tests/resource.rc            |   3 +
 dlls/gdi32/tests/wine_glyphoutlines.sfd |  79 ++++++++++++++++++++++++
 dlls/gdi32/tests/wine_glyphoutlines.ttf | Bin 0 -> 1748 bytes
 6 files changed, 139 insertions(+)
 create mode 100644 dlls/gdi32/tests/wine_glyphoutlines.sfd
 create mode 100644 dlls/gdi32/tests/wine_glyphoutlines.ttf

diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c
index e099bec5e81..0fa1722d621 100644
--- a/dlls/gdi32/font.c
+++ b/dlls/gdi32/font.c
@@ -2905,6 +2905,8 @@ DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
     dc = get_dc_ptr(hdc);
     if(!dc) return GDI_ERROR;
 
+    uChar &= 0xFFFF;
+
     dev = GET_DC_PHYSDEV( dc, pGetGlyphOutline );
     ret = dev->funcs->pGetGlyphOutline( dev, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
     release_dc_ptr( dc );
diff --git a/dlls/gdi32/tests/Makefile.in b/dlls/gdi32/tests/Makefile.in
index 8b722cfe5d2..acb2051c9f9 100644
--- a/dlls/gdi32/tests/Makefile.in
+++ b/dlls/gdi32/tests/Makefile.in
@@ -20,6 +20,7 @@ C_SRCS = \
 
 FONT_SRCS = \
 	vertical.sfd \
+	wine_glyphoutlines.sfd \
 	wine_longname.sfd \
 	wine_test.sfd \
 	wine_ttfnames.sfd \
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c
index f5c8d4dac3b..f272a10f098 100644
--- a/dlls/gdi32/tests/font.c
+++ b/dlls/gdi32/tests/font.c
@@ -6131,6 +6131,59 @@ static void check_vertical_metrics(const char *face)
     ReleaseDC(NULL, hdc);
 }
 
+static void test_GetGlyphOutlineW_character_limited_to_a_word(void)
+{
+    char ttf_name[MAX_PATH];
+    HFONT hfont, hfont_old;
+    LOGFONTA lf;
+    HDC hdc;
+    DWORD num, ret;
+    GLYPHMETRICS gm1, gm2;
+
+    if (!write_ttf_file("wine_glyphoutlines.ttf", ttf_name))
+    {
+        skip("Failed to create ttf file for testing\n");
+        return;
+    }
+
+    num = pAddFontResourceExA(ttf_name, FR_PRIVATE, 0);
+    ok(num == 1, "AddFontResourceExA should add 1 fonts from vertical.ttf\n");
+
+    hdc = CreateCompatibleDC(0);
+    memset(&lf, 0, sizeof(lf));
+    lf.lfHeight = 72;
+    lstrcpyA(lf.lfFaceName, "WineTestGlyphOutlines");
+
+    hfont = CreateFontIndirectA(&lf);
+    ok(hfont != 0, "CreateFontIndirectA error %u\n", GetLastError());
+    hfont_old = SelectObject(hdc, hfont);
+
+    /* the font has two glyph with different metrics - .notdef and 0x10000 */
+
+    ret = GetGlyphOutlineW(hdc, 'A', GGO_METRICS, &gm1, 0, NULL, &mat);
+    ok(ret != GDI_ERROR, "GetGlyphOutlineW failed with %d, lest error %d\n", ret, GetLastError());
+
+    ret = GetGlyphOutlineW(hdc, 0x10000, GGO_METRICS, &gm2, 0, NULL, &mat);
+    ok(ret != GDI_ERROR, "GetGlyphOutlineW failed with %d, lest error %d\n", ret, GetLastError());
+
+    /* we shouldn't be able to use 0x10000 and isntead get the .notdef */
+    ok(gm1.gmBlackBoxX == gm2.gmBlackBoxX, "gmBlackBoxX differs, %d should equal %d\n", gm1.gmBlackBoxX, gm2.gmBlackBoxX);
+    ok(gm1.gmBlackBoxY == gm2.gmBlackBoxY, "gmBlackBoxY differs, %d should equal %d\n", gm1.gmBlackBoxY, gm2.gmBlackBoxY);
+    ok(gm1.gmptGlyphOrigin.x == gm2.gmptGlyphOrigin.x, "gmptGlyphOrigin.x differs, %d should equal %d\n", gm1.gmptGlyphOrigin.x, gm2.gmptGlyphOrigin.x);
+    ok(gm1.gmptGlyphOrigin.y == gm2.gmptGlyphOrigin.y, "gmptGlyphOrigin.y difference, %d should equal %d\n", gm1.gmptGlyphOrigin.y, gm2.gmptGlyphOrigin.y);
+    ok(gm1.gmCellIncX == gm2.gmCellIncX, "gmCellIncX differs, %d should equal %d\n", gm1.gmCellIncX, gm2.gmCellIncX);
+    ok(gm1.gmCellIncY == gm2.gmCellIncY, "gmCellIncY differs, %d should equal %d\n", gm1.gmCellIncY, gm2.gmCellIncY);
+
+    SelectObject(hdc, hfont_old);
+    DeleteObject(hfont);
+
+    DeleteDC(hdc);
+
+    ret = pRemoveFontResourceExA(ttf_name, FR_PRIVATE, 0);
+    ok(ret, "RemoveFontResourceEx() error %d\n", GetLastError());
+    DeleteFileA(ttf_name);
+}
+
 static void test_vertical_font(void)
 {
     char ttf_name[MAX_PATH];
@@ -7396,6 +7449,7 @@ START_TEST(font)
     test_RealizationInfo();
     test_GetTextFace();
     test_GetGlyphOutline();
+    test_GetGlyphOutlineW_character_limited_to_a_word();
     test_GetTextMetrics2("Tahoma", -11);
     test_GetTextMetrics2("Tahoma", -55);
     test_GetTextMetrics2("Tahoma", -110);
diff --git a/dlls/gdi32/tests/resource.rc b/dlls/gdi32/tests/resource.rc
index b5a6107a987..c47f4bb87f9 100644
--- a/dlls/gdi32/tests/resource.rc
+++ b/dlls/gdi32/tests/resource.rc
@@ -37,3 +37,6 @@ wine_ttfnames.ttf RCDATA wine_ttfnames.ttf
 
 /* @makedep: wine_ttfnames_bold.ttf */
 wine_ttfnames_bold.ttf RCDATA wine_ttfnames_bold.ttf
+
+/* @makedep: wine_glyphoutlines.ttf */
+wine_glyphoutlines.ttf RCDATA wine_glyphoutlines.ttf
diff --git a/dlls/gdi32/tests/wine_glyphoutlines.sfd b/dlls/gdi32/tests/wine_glyphoutlines.sfd
new file mode 100644
index 00000000000..20bd8427b84
--- /dev/null
+++ b/dlls/gdi32/tests/wine_glyphoutlines.sfd
@@ -0,0 +1,79 @@
+SplineFontDB: 3.2
+FontName: WineTestGlyphOutlines
+FullName: WineTestGlyphOutlines
+FamilyName: wine_glyphoutlines
+Weight: Regular
+Copyright: Copyright (c) 2020, Arkadiusz Hiler
+UComments: "2020-9-21: Created with FontForge (http://fontforge.org)"
+Version: 001.000
+ItalicAngle: 0
+UnderlinePosition: -100
+UnderlineWidth: 50
+Ascent: 800
+Descent: 200
+InvalidEm: 0
+LayerCount: 2
+Layer: 0 0 "Back" 1
+Layer: 1 0 "Fore" 0
+XUID: [1021 1016 2035354264 8878123]
+OS2Version: 0
+OS2_WeightWidthSlopeOnly: 0
+OS2_UseTypoMetrics: 1
+CreationTime: 1600686238
+ModificationTime: 1600688343
+OS2TypoAscent: 0
+OS2TypoAOffset: 1
+OS2TypoDescent: 0
+OS2TypoDOffset: 1
+OS2TypoLinegap: 0
+OS2WinAscent: 0
+OS2WinAOffset: 1
+OS2WinDescent: 0
+OS2WinDOffset: 1
+HheadAscent: 0
+HheadAOffset: 1
+HheadDescent: 0
+HheadDOffset: 1
+OS2Vendor: 'PfEd'
+DEI: 91125
+Encoding: UnicodeFull
+Compacted: 1
+UnicodeInterp: none
+NameList: AGL For New Fonts
+DisplaySize: -48
+AntiAlias: 1
+FitToEm: 0
+WinInfo: 0 25 20
+BeginChars: 1114112 2
+
+StartChar: u10000
+Encoding: 65536 65536 0
+Width: 2000
+Flags: HW
+LayerCount: 2
+Fore
+SplineSet
+847 687 m 25
+ 205 129 l 1053
+70 753 m 25
+ 934 75 l 1049
+1847 687 m 25
+ 1205 129 l 1053
+1070 753 m 25
+ 1934 75 l 1049
+EndSplineSet
+EndChar
+
+StartChar: .notdef
+Encoding: 0 0 1
+Width: 120
+Flags: HWO
+LayerCount: 2
+Fore
+SplineSet
+66 714 m 29
+ 64 92 l 1053
+EndSplineSet
+EndChar
+EndChars
+EndSplineFont
diff --git a/dlls/gdi32/tests/wine_glyphoutlines.ttf b/dlls/gdi32/tests/wine_glyphoutlines.ttf
new file mode 100644
index 0000000000000000000000000000000000000000..2b72ddaf559bfcbbda82e2073767eb978792fa1f
GIT binary patch
literal 1748
zcmds1O>YxN7=C7U?R-IsfL1*~G?W}5Bw_7CL at 0*@5+^F4M354QB8A0XY>SO|Yp>NL
z2k5CpRh!aCRQv#XE#iR4f%c3zAta=>^uUo5C=wha^UUrTLQAFg+IKac=Y8h=nh(Da
z0Jh>QSeVS^rcSPYck?!oUL(6}Y-BWt{b;9tgL>D*>4VwNC-cjII7|I}e%=kS+y0IE
zeU7D~TMHWvMnd`;*ISGJ;>B|>J{bk9N$OK2&n<Md{`w>FpBw`v677GqD*EoE-d&oH
z7TT`kYw9}xHb2O_7{JH$AEDkp?=FP+3>{oQL|s+fdGE!}#|OB66Oe0RP>bB>1HUu>
zEY~y8d*kT-zSJ at I!I4+!u%3~@la;})WFDTz5RSL3$aU(ikea2?hs<%zv^>;m%Ss$c
z!=~6VW7EfuDeWm at ZpfI}cDJ~O6eE2j?~(g9nZ;9N1g#}fJSQWXXo{M=I9kARgJP-1
zA<W42#vLx|y);EpTfmT3#Yxup5II8T(r1re4qep=;}en9-o2c8m*j0I&Nja|D({RE
z|0Y?sXdV0FUtQ{E(H4mnbBT0Q;jHc6wSBv|Il})DZ-M at L;<FjTERM<t`jmE9N2PqQ
zu}a?N9VIVK at E%fV0osJsCM{u2Y+Sx-owt67CwXh*kqkFxWFeW8)9S>}=G1|`7&lm8
zJ5~*rjCjXji*Ia?!8Se=R}4;Jo49Lmn*2-sGVC^{(C;U~0^RTpmgvM!23xp*UktX<
zBTgHff)dvaPLscnV+asp5ml5?L<tcT-%_5PL?H_&9=*iFw73Kp1=`h7!xFi1Vjmt?
za4ZNHtL0)TQv34zRo2Nmy=u66$t{%YwIwxP_B|SXN&5=z=a|W7&XD;6MvJH=D>WLG
zE8ZNNQCJG<kxzx(DLNHt=(7OEIpr1WzDtm!dxh?LuF}Gbi|%LH3WqtSP1q@})Mz*M
zChf#u(kAv<wxK=@ax}M&Tu_N}LAB_qY`>!pt7%p=<<+7wUEzeOkbE}NH`u55jsK7p
z?~MkWVZBvWT#omrxF3g=>3!)>(ZH+L%0WdrPNv^+95VlYtN)bLbOZLUEZ^7PMRzFy
sDP+2yVNPyTi(n^`@hjDR=pzoTS^ACfU-Y)e2x2_>qUY0i-qh1y19@)s4*&oF

literal 0
HcmV?d00001

-- 
2.28.0




More information about the wine-devel mailing list