From: Sven Baars Subject: [PATCH v2 5/7] gdi32: Handle zero-width control characters in get_glyph_outline. Message-Id: <20201109140720.472712-6-sbaars@codeweavers.com> Date: Mon, 9 Nov 2020 15:07:18 +0100 In-Reply-To: <20201109140720.472712-1-sbaars@codeweavers.com> References: <20201109140720.472712-1-sbaars@codeweavers.com> Signed-off-by: Sven Baars --- 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