[PATCH v2 5/7] gdi32: Handle zero-width control characters in get_glyph_outline.

Sven Baars sbaars at codeweavers.com
Mon Nov 9 08:07:18 CST 2020


Signed-off-by: Sven Baars <sbaars at codeweavers.com>
---
 dlls/d3dx9_36/tests/core.c |  2 +-
 dlls/gdi32/font.c          | 16 ++++++++++++++++
 dlls/gdi32/tests/font.c    | 16 +++++++++-------
 3 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/dlls/d3dx9_36/tests/core.c b/dlls/d3dx9_36/tests/core.c
index 020f18e622c..14629ce9eb6 100644
--- a/dlls/d3dx9_36/tests/core.c
+++ b/dlls/d3dx9_36/tests/core.c
@@ -807,7 +807,7 @@ static void test_ID3DXFont(IDirect3DDevice9 *device)
     todo_wine ok(height == 0, "Got unexpected height %d.\n", height);
 
     height = ID3DXFont_DrawTextW(font, NULL, L"\t\t\t\t\t\t\t\t\t\ta", -1, &rect, DT_WORDBREAK, 0xff00ff);
-    todo_wine ok(height == 12, "Got unexpected height %d.\n", height);
+    ok(height == 12, "Got unexpected height %d.\n", height);
 
     height = ID3DXFont_DrawTextW(font, NULL, L"\taaaaaaaaaa", -1, &rect, DT_WORDBREAK, 0xff00ff);
     todo_wine ok(height == 24, "Got unexpected height %d.\n", height);
diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c
index 4a6ca1916ac..f0616b6f908 100644
--- a/dlls/gdi32/font.c
+++ b/dlls/gdi32/font.c
@@ -2886,6 +2886,16 @@ static UINT get_glyph_index_linked( struct gdi_font **font, UINT glyph )
     return 0;
 }
 
+static BOOL is_zero_width_control_char( UINT glyph )
+{
+    return glyph == 0x0009 /* \t   */ || glyph == 0x000a /* \n   */ || glyph == 0x000d /* \r   */ ||
+        glyph == 0x001c /* FS   */ || glyph == 0x001d /* GS   */ || glyph == 0x001e /* RS   */ ||
+        glyph == 0x001f /* US   */ || glyph == 0x200b /* ZWSP */ || glyph == 0x200c /* ZWNJ */ ||
+        glyph == 0x200d /* ZWJ  */ || glyph == 0x200e /* LRM  */ || glyph == 0x200f /* RLM  */ ||
+        glyph == 0x202a /* LRE  */ || glyph == 0x202b /* RLE  */ || glyph == 0x202c /* PDF  */ ||
+        glyph == 0x202d /* LRO  */ || glyph == 0x202e /* RLO  */;
+}
+
 static DWORD get_glyph_outline( struct gdi_font *font, UINT glyph, UINT format,
                                 GLYPHMETRICS *gm_ret, ABC *abc_ret, DWORD buflen, void *buf,
                                 const MAT2 *mat )
@@ -2908,6 +2918,12 @@ static DWORD get_glyph_outline( struct gdi_font *font, UINT glyph, UINT format,
     else
     {
         index = get_glyph_index_linked( &font, glyph );
+        if (glyph && !index && is_zero_width_control_char( glyph ))
+        {
+            memset( abc_ret, 0, sizeof(*abc_ret) );
+            return GDI_ERROR;
+        }
+
         if (tategaki)
         {
             UINT orig = index;
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c
index 8985476ed82..5b5efc88743 100644
--- a/dlls/gdi32/tests/font.c
+++ b/dlls/gdi32/tests/font.c
@@ -1505,7 +1505,7 @@ static void test_text_extents(void)
         ok(extents[i-1] <= extents[i],
            "GetTextExtentExPointW generated a non-increasing sequence of partial extents (at position %d)\n",
            i);
-    todo_wine ok(extents[2] == extents[3], "GetTextExtentExPointW doesn't return 0 width for a newline\n");
+    ok(extents[2] == extents[3], "GetTextExtentExPointW doesn't return 0 width for a newline\n");
     ok(extents[len-1] == sz1.cx, "GetTextExtentExPointW extents and size don't match\n");
     ok(0 <= fit1 && fit1 <= len, "GetTextExtentExPointW generated illegal value %d for fit\n", fit1);
     ok(0 < fit1, "GetTextExtentExPointW says we can't even fit one letter in 32767 logical units\n");
@@ -7727,9 +7727,9 @@ static void test_zero_width_control(void)
         ok(result.nGlyphs == 10, "Test %d: unexpected number of glyphs %u.\n", i, result.nGlyphs);
         todo_wine ok(glyphs[5] == glyphs[4], "Test %d: unexpected glyphs %s.\n", i, wine_dbgstr_wn(glyphs, result.nGlyphs));
         if (i < 15)
-            todo_wine ok(pos[6] - pos[5] == 0, "Test %d: unexpected width %d.\n", i, pos[6] - pos[5]);
+            ok(pos[6] - pos[5] == 0, "Test %d: unexpected width %d.\n", i, pos[6] - pos[5]);
         else
-            ok(pos[6] - pos[5] > 0, "Test %d: unexpected width %d.\n", i, pos[6] - pos[5]);
+            todo_wine ok(pos[6] - pos[5] > 0, "Test %d: unexpected width %d.\n", i, pos[6] - pos[5]);
         ok(pos[5] - pos[4] > 0, "Test %d: unexpected width %d.\n", i, pos[5] - pos[4]);
 
         /* They all have zero width in GetTextExtentExPoint */
@@ -7739,8 +7739,8 @@ static void test_zero_width_control(void)
         ret = GetTextExtentExPointW(hdc, zero_width_control + i, 1, 1000, &nfit, &dx, &sz);
         ok(ret, "Test %d: expected TRUE.\n", i);
         ok(nfit == 1, "Test %d: got %d.\n", i, nfit);
-        todo_wine ok(dx == 0, "Test %d: got %d.\n", i, dx);
-        todo_wine ok(sz.cx == 0, "Test %d: got %d.\n", i, sz.cx);
+        ok(dx == 0, "Test %d: got %d.\n", i, dx);
+        ok(sz.cx == 0, "Test %d: got %d.\n", i, sz.cx);
 
         /* They do not all have zero width in GetCharWidth32 */
         len = -1;
@@ -7754,17 +7754,19 @@ static void test_zero_width_control(void)
 
         if (i < 7)
         {
+            todo_wine {
             ok(len > 0, "Test %d: got %d.\n", i, len);
             ok(abc.abcA + abc.abcB + abc.abcC <= len && abc.abcA + abc.abcB + abc.abcC > 0,
                "Test %d: expected %d >= %d > 0.\n", i, len, abc.abcA + abc.abcB + abc.abcC);
             ok(abc.abcB > 0, "Test %d: got %d.\n", i, abc.abcB);
+            }
         }
         else
         {
-            todo_wine ok(len == 0 || broken(i > 11) /* before Win10 */, "Test %d: got %d.\n", i, len);
+            ok(len == 0 || broken(i > 11) /* before Win10 */, "Test %d: got %d.\n", i, len);
             ok(abc.abcA + abc.abcB + abc.abcC == len,
                "Test %d: expected %d == 0.\n", i, abc.abcA + abc.abcB + abc.abcC);
-            ok(abc.abcB > 0, "Test %d: got %d.\n", i, abc.abcB);
+            todo_wine ok(abc.abcB > 0, "Test %d: got %d.\n", i, abc.abcB);
         }
     }
 
-- 
2.25.1




More information about the wine-devel mailing list