Signed-off-by: Sven Baars sbaars@codeweavers.com --- ../dlls/gdi32/tests/font.c:1361:19: warning: ‘code’ may be used uninitialized in this function [-Wmaybe-uninitialized] 1361 | ret = GetCharABCWidthsA(hdc, code, code, abc); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dlls/gdi32/tests/font.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c index 4c8b1cbb91b..d3ec971dce0 100644 --- a/dlls/gdi32/tests/font.c +++ b/dlls/gdi32/tests/font.c @@ -1330,17 +1330,16 @@ static void test_GetCharABCWidths(void)
memset(&lf, 0, sizeof(lf)); lf.lfHeight = 20; - switch(i) + if (i == 1) { - case 1: strcpy(lf.lfFaceName, "Tahoma"); code = 'a'; - break; - case 2: + } + else + { strcpy(lf.lfFaceName, "Times New Roman"); lf.lfItalic = TRUE; code = 'f'; - break; } if (!is_truetype_font_installed(lf.lfFaceName)) {
Signed-off-by: Sven Baars sbaars@codeweavers.com --- dlls/gdi32/tests/font.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c index d3ec971dce0..2592db2cc06 100644 --- a/dlls/gdi32/tests/font.c +++ b/dlls/gdi32/tests/font.c @@ -1505,17 +1505,33 @@ 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[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"); + GetTextExtentExPointW(hdc, wt, len, extents[2], &fit2, NULL, &sz2); ok(sz1.cx == sz2.cx && sz1.cy == sz2.cy, "GetTextExtentExPointW returned different sizes for the same string\n"); ok(fit2 == 3, "GetTextExtentExPointW extents isn't consistent with fit\n"); + + extents2[2] = -1; + GetTextExtentExPointW(hdc, wt, len, extents[2], &fit2, extents2, &sz2); + ok(sz1.cx == sz2.cx && sz1.cy == sz2.cy, "GetTextExtentExPointW returned different sizes for the same string\n"); + ok(fit2 == 3, "GetTextExtentExPointW extents isn't consistent with fit\n"); + ok(extents2[2] == extents[2], "GetTextExtentExPointW last extent isn't set\n"); + GetTextExtentExPointW(hdc, wt, len, extents[2]-1, &fit2, NULL, &sz2); ok(fit2 == 2, "GetTextExtentExPointW extents isn't consistent with fit\n"); + + extents2[1] = -1; + GetTextExtentExPointW(hdc, wt, len, extents[2]-1, &fit2, extents2, &sz2); + ok(fit2 == 2, "GetTextExtentExPointW extents isn't consistent with fit\n"); + ok(extents2[1] == extents[1], "GetTextExtentExPointW extent isn't set\n"); + GetTextExtentExPointW(hdc, wt, 2, 0, NULL, extents + 2, &sz2); ok(extents[0] == extents[2] && extents[1] == extents[3], "GetTextExtentExPointW with lpnFit == NULL returns incorrect results\n"); + GetTextExtentExPointW(hdc, wt, 2, 0, NULL, NULL, &sz1); ok(sz1.cx == sz2.cx && sz1.cy == sz2.cy, "GetTextExtentExPointW with lpnFit and alpDx both NULL returns incorrect results\n");
Signed-off-by: Sven Baars sbaars@codeweavers.com --- dlls/gdi32/font.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c index 6ad03df176b..4a6ca1916ac 100644 --- a/dlls/gdi32/font.c +++ b/dlls/gdi32/font.c @@ -4897,6 +4897,11 @@ BOOL WINAPI GetTextExtentExPointI( HDC hdc, const WORD *indices, INT count, INT unsigned int dx = abs( INTERNAL_XDSTOWS( dc, pos[i] )) + (i + 1) * dc->charExtra; if (nfit && dx > (unsigned int)max_ext) break; if (dxs) dxs[i] = dx; + if (nfit && dx == (unsigned int)max_ext) + { + i++; + break; + } } if (nfit) *nfit = i; } @@ -5033,7 +5038,12 @@ BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count, INT max_ext, { unsigned int dx = abs( INTERNAL_XDSTOWS( dc, pos[i] )) + (i + 1) * dc->charExtra; if (nfit && dx > (unsigned int)max_ext) break; - if (dxs) dxs[i] = dx; + if (dxs) dxs[i] = dx; + if (nfit && dx == (unsigned int)max_ext) + { + i++; + break; + } } if (nfit) *nfit = i; }
Signed-off-by: Sven Baars sbaars@codeweavers.com --- dlls/gdi32/tests/font.c | 128 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+)
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c index 2592db2cc06..1068395a54e 100644 --- a/dlls/gdi32/tests/font.c +++ b/dlls/gdi32/tests/font.c @@ -7666,6 +7666,133 @@ done: ReleaseDC(0, hdc); }
+static void test_zero_width_control(void) +{ + int len, dx, nfit, pos[20]; + DWORD size, charcount; + GCP_RESULTSW result; + WCHAR space_glyph; + WCHAR glyphs[20]; + unsigned int i; + LOGFONTA lf; + HFONT hfont; + BOOL ret; + SIZE sz; + HDC hdc; + ABC abc; + + static const WCHAR nul[] = {0}; + static const WCHAR space[] = {' '}; + static const WCHAR zero_width_control[] = { + 0x0009, /* \t */ + 0x000a, /* \n */ + 0x000d, /* \r */ + 0x001c, /* FS */ + 0x001d, /* GS */ + 0x001e, /* RS */ + 0x001f, /* US */ + 0x200b, /* ZWSP */ + 0x200c, /* ZWNJ */ + 0x200d, /* ZWJ */ + 0x200e, /* LRM */ + 0x200f, /* RLM */ + 0x202a, /* LRE */ + 0x202c, /* PDF */ + 0x202d, /* LRO */ + 0x202b, /* RLE */ + 0x202e, /* RLO */ + }; + + memset(&lf, 0, sizeof(lf)); + strcpy(lf.lfFaceName, "Tahoma"); + lf.lfHeight = 20; + + hfont = CreateFontIndirectA(&lf); + hdc = GetDC(NULL); + hfont = SelectObject(hdc, hfont); + + memset(&result, 0, sizeof(result)); + result.lStructSize = sizeof(result); + result.lpCaretPos = pos; + result.lpGlyphs = glyphs; + + for (i = 0; i < ARRAY_SIZE(zero_width_control); ++i) + { + WCHAR test[] = {'W', 'i', 'n', 'e', ' ', zero_width_control[i], 'T', 'e', 's', 't', 0}; + + /* Some control characters are treated as space */ + result.nGlyphs = 20; + size = GetCharacterPlacementW(hdc, test, 10, 0, &result, 0); + ok(size, "Test %d: GetCharacterPlacementA failed.\n", i); + 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]); + else + 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 */ + nfit = -1; + dx = -1; + sz.cx = -1; + 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); + + /* They do not all have zero width in GetCharWidth32 */ + len = -1; + ret = GetCharWidth32W(hdc, zero_width_control[i], zero_width_control[i], &len); + ok(ret, "Test %d: expected TRUE.\n", i); + if (i < 7) + ok(len > 0, "Test %d: got %d.\n", i, len); + else + todo_wine ok(len == 0, "Test %d: got %d.\n", i, len); + + /* Because ABC does not have zero width */ + memset(&abc, 0, sizeof(abc)); + ret = GetCharABCWidthsW(hdc, zero_width_control[i], zero_width_control[i], &abc); + ok(ret, "Test %d: expected TRUE.\n", i); + if (i != 2) + ok(abc.abcA + abc.abcB + abc.abcC == len, "Test %d: expected %d, got %d.\n", i, len, abc.abcA + abc.abcB + abc.abcC); + else + todo_wine ok(abc.abcA + abc.abcB + abc.abcC != len, "Test %d: expected %d, got %d.\n", i, len, abc.abcA + abc.abcB + abc.abcC); + ok(abc.abcB > 0, "Test %d: got %d.\n", i, abc.abcB); + } + + /* The NUL character does not have zero width */ + nfit = -1; + dx = -1; + sz.cx = -1; + ret = GetTextExtentExPointW(hdc, nul, 1, 1000, &nfit, &dx, &sz); + ok(ret, "Expected TRUE.\n"); + ok(nfit == 1, "Got %d.\n", nfit); + ok(dx > 0, "Got %d.\n", dx); + ok(sz.cx > 0, "Got %d.\n", sz.cx); + + memset(&abc, 0, sizeof(abc)); + ret = GetCharABCWidthsW(hdc, 0, 0, &abc); + ok(ret, "Expected TRUE.\n"); + todo_wine ok(abc.abcA == 0, "Got %d.\n", abc.abcA); + ok(abc.abcB > 0, "Got %d.\n", abc.abcB); + ok(abc.abcC > 0, "Got %d.\n", abc.abcC); + + /* Test that characters that are treated as spaces by GetCharacterPlacement */ + /* are not treated like spaces by GetGlyphIndices. */ + charcount = GetGlyphIndicesW(hdc, space, 1, &space_glyph, 0); + ok(charcount == 1, "Wrong character count %d.\n", charcount); + + charcount = GetGlyphIndicesW(hdc, zero_width_control, ARRAY_SIZE(zero_width_control), glyphs, 0); + ok(charcount == ARRAY_SIZE(zero_width_control), "Wrong character count %d.\n", charcount); + for (i = 0; i < ARRAY_SIZE(zero_width_control); ++i) + ok(glyphs[i] != space_glyph, "Test %d: glyph is a space: %04x\n", i, glyphs[i]); + + DeleteObject(hfont); + ReleaseDC(NULL, hdc); +} + START_TEST(font) { static const char *test_names[] = @@ -7752,6 +7879,7 @@ START_TEST(font) test_ttf_names(); test_lang_names(); test_char_width(); + test_zero_width_control();
/* These tests should be last test until RemoveFontResource * is properly implemented.
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=81590
Your paranoid android.
=== w2008s64 (32 bit report) ===
gdi32: font.c:7759: Test failed: Test 0: expected 16, got 8. font.c:7759: Test failed: Test 1: expected 16, got 4. font.c:7759: Test failed: Test 3: expected 16, got 8. font.c:7759: Test failed: Test 4: expected 16, got 8. font.c:7759: Test failed: Test 5: expected 16, got 8. font.c:7759: Test failed: Test 6: expected 16, got 8. font.c:7752: Test failed: Test 12: got 8. font.c:7752: Test failed: Test 13: got 8. font.c:7752: Test failed: Test 14: got 8. font.c:7752: Test failed: Test 15: got 8. font.c:7752: Test failed: Test 16: got 8.
=== w8 (32 bit report) ===
gdi32: font.c:7759: Test failed: Test 0: expected 16, got 8. font.c:7759: Test failed: Test 1: expected 16, got 4. font.c:7759: Test failed: Test 3: expected 16, got 8. font.c:7759: Test failed: Test 4: expected 16, got 8. font.c:7759: Test failed: Test 5: expected 16, got 8. font.c:7759: Test failed: Test 6: expected 16, got 8. font.c:7752: Test failed: Test 12: got 8. font.c:7752: Test failed: Test 13: got 8. font.c:7752: Test failed: Test 14: got 8. font.c:7752: Test failed: Test 15: got 8. font.c:7752: Test failed: Test 16: got 8.
=== w8adm (32 bit report) ===
gdi32: font.c:7759: Test failed: Test 0: expected 16, got 8. font.c:7759: Test failed: Test 1: expected 16, got 4. font.c:7759: Test failed: Test 3: expected 16, got 8. font.c:7759: Test failed: Test 4: expected 16, got 8. font.c:7759: Test failed: Test 5: expected 16, got 8. font.c:7759: Test failed: Test 6: expected 16, got 8. font.c:7752: Test failed: Test 12: got 8. font.c:7752: Test failed: Test 13: got 8. font.c:7752: Test failed: Test 14: got 8. font.c:7752: Test failed: Test 15: got 8. font.c:7752: Test failed: Test 16: got 8.
=== w10pro64_ar (32 bit report) ===
gdi32: font.c:7759: Test failed: Test 3: expected 16, got 8. font.c:7759: Test failed: Test 4: expected 16, got 8. font.c:7759: Test failed: Test 5: expected 16, got 8. font.c:7759: Test failed: Test 6: expected 16, got 8. font.c:7780: Test failed: Got 0.
=== w10pro64_he (32 bit report) ===
gdi32: font.c:7761: Test failed: Test 2: expected 6, got 6. font.c:7780: Test failed: Got 0.
=== w10pro64_ja (32 bit report) ===
gdi32: font.c:7759: Test failed: Test 3: expected 16, got 8. font.c:7759: Test failed: Test 4: expected 16, got 8. font.c:7759: Test failed: Test 5: expected 16, got 8. font.c:7759: Test failed: Test 6: expected 16, got 8. font.c:7780: Test failed: Got 0.
=== w10pro64_zh_CN (32 bit report) ===
gdi32: font.c:7761: Test failed: Test 2: expected 8, got 8. font.c:7780: Test failed: Got 0.
=== w2008s64 (64 bit report) ===
gdi32: font.c:7759: Test failed: Test 0: expected 16, got 8. font.c:7759: Test failed: Test 1: expected 16, got 4. font.c:7759: Test failed: Test 3: expected 16, got 8. font.c:7759: Test failed: Test 4: expected 16, got 8. font.c:7759: Test failed: Test 5: expected 16, got 8. font.c:7759: Test failed: Test 6: expected 16, got 8. font.c:7752: Test failed: Test 12: got 8. font.c:7752: Test failed: Test 13: got 8. font.c:7752: Test failed: Test 14: got 8. font.c:7752: Test failed: Test 15: got 8. font.c:7752: Test failed: Test 16: got 8.
=== w864 (64 bit report) ===
gdi32: font.c:7759: Test failed: Test 0: expected 16, got 8. font.c:7759: Test failed: Test 1: expected 16, got 4. font.c:7759: Test failed: Test 3: expected 16, got 8. font.c:7759: Test failed: Test 4: expected 16, got 8. font.c:7759: Test failed: Test 5: expected 16, got 8. font.c:7759: Test failed: Test 6: expected 16, got 8. font.c:7752: Test failed: Test 12: got 8. font.c:7752: Test failed: Test 13: got 8. font.c:7752: Test failed: Test 14: got 8. font.c:7752: Test failed: Test 15: got 8. font.c:7752: Test failed: Test 16: got 8.
=== w10pro64_ar (64 bit report) ===
gdi32: font.c:7759: Test failed: Test 3: expected 16, got 8. font.c:7759: Test failed: Test 4: expected 16, got 8. font.c:7759: Test failed: Test 5: expected 16, got 8. font.c:7759: Test failed: Test 6: expected 16, got 8. font.c:7780: Test failed: Got 0.
=== w10pro64_he (64 bit report) ===
gdi32: font.c:7761: Test failed: Test 2: expected 6, got 6. font.c:7780: Test failed: Got 0.
=== w10pro64_ja (64 bit report) ===
gdi32: font.c:7759: Test failed: Test 3: expected 16, got 8. font.c:7759: Test failed: Test 4: expected 16, got 8. font.c:7759: Test failed: Test 5: expected 16, got 8. font.c:7759: Test failed: Test 6: expected 16, got 8. font.c:7780: Test failed: Got 0.
=== w10pro64_zh_CN (64 bit report) ===
gdi32: font.c:7761: Test failed: Test 2: expected 8, got 8. font.c:7780: Test failed: Got 0.
Signed-off-by: Sven Baars sbaars@codeweavers.com --- dlls/d3dx9_36/tests/core.c | 2 +- dlls/gdi32/font.c | 16 ++++++++++++++++ dlls/gdi32/tests/font.c | 16 ++++++++-------- 3 files changed, 25 insertions(+), 9 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 1068395a54e..39e3de441e0 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,17 +7739,17 @@ 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; ret = GetCharWidth32W(hdc, zero_width_control[i], zero_width_control[i], &len); ok(ret, "Test %d: expected TRUE.\n", i); if (i < 7) - ok(len > 0, "Test %d: got %d.\n", i, len); + todo_wine ok(len > 0, "Test %d: got %d.\n", i, len); else - todo_wine ok(len == 0, "Test %d: got %d.\n", i, len); + ok(len == 0, "Test %d: got %d.\n", i, len);
/* Because ABC does not have zero width */ memset(&abc, 0, sizeof(abc)); @@ -7759,7 +7759,7 @@ static void test_zero_width_control(void) ok(abc.abcA + abc.abcB + abc.abcC == len, "Test %d: expected %d, got %d.\n", i, len, abc.abcA + abc.abcB + abc.abcC); else todo_wine ok(abc.abcA + abc.abcB + abc.abcC != len, "Test %d: expected %d, got %d.\n", i, len, 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); }
/* The NUL character does not have zero width */
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=81591
Your paranoid android.
=== w2008s64 (32 bit report) ===
gdi32: font.c:7759: Test failed: Test 0: expected 16, got 8. font.c:7759: Test failed: Test 1: expected 16, got 4. font.c:7759: Test failed: Test 3: expected 16, got 8. font.c:7759: Test failed: Test 4: expected 16, got 8. font.c:7759: Test failed: Test 5: expected 16, got 8. font.c:7759: Test failed: Test 6: expected 16, got 8. font.c:7752: Test failed: Test 12: got 8. font.c:7752: Test failed: Test 13: got 8. font.c:7752: Test failed: Test 14: got 8. font.c:7752: Test failed: Test 15: got 8. font.c:7752: Test failed: Test 16: got 8.
=== w8 (32 bit report) ===
gdi32: font.c:7759: Test failed: Test 0: expected 16, got 8. font.c:7759: Test failed: Test 1: expected 16, got 4. font.c:7759: Test failed: Test 3: expected 16, got 8. font.c:7759: Test failed: Test 4: expected 16, got 8. font.c:7759: Test failed: Test 5: expected 16, got 8. font.c:7759: Test failed: Test 6: expected 16, got 8. font.c:7752: Test failed: Test 12: got 8. font.c:7752: Test failed: Test 13: got 8. font.c:7752: Test failed: Test 14: got 8. font.c:7752: Test failed: Test 15: got 8. font.c:7752: Test failed: Test 16: got 8.
=== w8adm (32 bit report) ===
gdi32: font.c:7759: Test failed: Test 0: expected 16, got 8. font.c:7759: Test failed: Test 1: expected 16, got 4. font.c:7759: Test failed: Test 3: expected 16, got 8. font.c:7759: Test failed: Test 4: expected 16, got 8. font.c:7759: Test failed: Test 5: expected 16, got 8. font.c:7759: Test failed: Test 6: expected 16, got 8. font.c:7752: Test failed: Test 12: got 8. font.c:7752: Test failed: Test 13: got 8. font.c:7752: Test failed: Test 14: got 8. font.c:7752: Test failed: Test 15: got 8. font.c:7752: Test failed: Test 16: got 8.
=== w10pro64_ar (32 bit report) ===
gdi32: font.c:7759: Test failed: Test 3: expected 16, got 8. font.c:7759: Test failed: Test 4: expected 16, got 8. font.c:7759: Test failed: Test 5: expected 16, got 8. font.c:7759: Test failed: Test 6: expected 16, got 8. font.c:7780: Test failed: Got 0.
=== w10pro64_he (32 bit report) ===
gdi32: font.c:7761: Test failed: Test 2: expected 6, got 6. font.c:7780: Test failed: Got 0.
=== w10pro64_ja (32 bit report) ===
gdi32: font.c:7759: Test failed: Test 3: expected 16, got 8. font.c:7759: Test failed: Test 4: expected 16, got 8. font.c:7759: Test failed: Test 5: expected 16, got 8. font.c:7759: Test failed: Test 6: expected 16, got 8. font.c:7780: Test failed: Got 0.
=== w10pro64_zh_CN (32 bit report) ===
gdi32: font.c:7761: Test failed: Test 2: expected 8, got 8. font.c:7780: Test failed: Got 0.
=== w2008s64 (64 bit report) ===
gdi32: font.c:7759: Test failed: Test 0: expected 16, got 8. font.c:7759: Test failed: Test 1: expected 16, got 4. font.c:7759: Test failed: Test 3: expected 16, got 8. font.c:7759: Test failed: Test 4: expected 16, got 8. font.c:7759: Test failed: Test 5: expected 16, got 8. font.c:7759: Test failed: Test 6: expected 16, got 8. font.c:7752: Test failed: Test 12: got 8. font.c:7752: Test failed: Test 13: got 8. font.c:7752: Test failed: Test 14: got 8. font.c:7752: Test failed: Test 15: got 8. font.c:7752: Test failed: Test 16: got 8.
=== w864 (64 bit report) ===
gdi32: font.c:7759: Test failed: Test 0: expected 16, got 8. font.c:7759: Test failed: Test 1: expected 16, got 4. font.c:7759: Test failed: Test 3: expected 16, got 8. font.c:7759: Test failed: Test 4: expected 16, got 8. font.c:7759: Test failed: Test 5: expected 16, got 8. font.c:7759: Test failed: Test 6: expected 16, got 8. font.c:7752: Test failed: Test 12: got 8. font.c:7752: Test failed: Test 13: got 8. font.c:7752: Test failed: Test 14: got 8. font.c:7752: Test failed: Test 15: got 8. font.c:7752: Test failed: Test 16: got 8.
=== w10pro64_ar (64 bit report) ===
gdi32: font.c:7759: Test failed: Test 3: expected 16, got 8. font.c:7759: Test failed: Test 4: expected 16, got 8. font.c:7759: Test failed: Test 5: expected 16, got 8. font.c:7759: Test failed: Test 6: expected 16, got 8. font.c:7780: Test failed: Got 0.
=== w10pro64_he (64 bit report) ===
gdi32: font.c:7761: Test failed: Test 2: expected 6, got 6. font.c:7780: Test failed: Got 0.
=== w10pro64_ja (64 bit report) ===
gdi32: font.c:7759: Test failed: Test 3: expected 16, got 8. font.c:7759: Test failed: Test 4: expected 16, got 8. font.c:7759: Test failed: Test 5: expected 16, got 8. font.c:7759: Test failed: Test 6: expected 16, got 8. font.c:7780: Test failed: Got 0.
=== w10pro64_zh_CN (64 bit report) ===
gdi32: font.c:7761: Test failed: Test 2: expected 8, got 8. font.c:7780: Test failed: Got 0.
Similar to the tests already present for usp10.
Signed-off-by: Sven Baars sbaars@codeweavers.com --- dlls/gdi32/tests/font.c | 441 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 440 insertions(+), 1 deletion(-)
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c index 39e3de441e0..62eaab8639c 100644 --- a/dlls/gdi32/tests/font.c +++ b/dlls/gdi32/tests/font.c @@ -4895,12 +4895,307 @@ static void test_GetTextMetrics2(const char *fontname, int font_height) ok(ratio >= 90 && ratio <= 110, "expected width/height ratio 90-110, got %d\n", ratio); }
+struct enum_font_range_param { + BYTE range; + LOGFONTA lf; +}; + +static int CALLBACK enum_font_range_proc(const LOGFONTA *lf, const TEXTMETRICA *tm, DWORD type, LPARAM param) +{ + NEWTEXTMETRICEXA *ntme = (NEWTEXTMETRICEXA *)tm; + struct enum_font_range_param *efrp = (struct enum_font_range_param *)param; + int idx = 0; + DWORD i; + DWORD mask = 0; + + if (type != TRUETYPE_FONTTYPE) + return 1; + + i = efrp->range; + while (i >= sizeof(DWORD)*8) + { + idx++; + i -= (sizeof(DWORD)*8); + } + if (idx > 3) + return 0; + + mask = 1 << i; + + if (ntme->ntmFontSig.fsUsb[idx] & mask) + { + memcpy(&(efrp->lf), lf, sizeof(LOGFONTA)); + return 0; + } + return 1; +} + +static int _find_font_for_range(HDC hdc, const CHAR *recommended, BYTE range, const WCHAR check, HFONT *hfont, HFONT *hfont_orig) +{ + int rc = 0; + struct enum_font_range_param param; + + param.range = range; + memset(¶m.lf, 0, sizeof(LOGFONTA)); + *hfont = NULL; + + if (recommended) + { + lstrcpyA(param.lf.lfFaceName, recommended); + if (!EnumFontFamiliesExA(hdc, ¶m.lf, enum_font_range_proc, (LPARAM)¶m, 0)) + { + *hfont = CreateFontIndirectA(¶m.lf); + if (*hfont) + { + winetest_trace("Using font %s.\n", param.lf.lfFaceName); + rc = 1; + } + } + if (!rc) + winetest_skip("Font %s is not available.\n", recommended); + } + + if (!*hfont) + { + memset(¶m.lf, 0, sizeof(LOGFONTA)); + param.lf.lfCharSet = DEFAULT_CHARSET; + + if (!EnumFontFamiliesExA(hdc, ¶m.lf, enum_font_range_proc, (LPARAM)¶m, 0) && param.lf.lfFaceName[0]) + { + *hfont = CreateFontIndirectA(¶m.lf); + if (*hfont) + winetest_trace("Trying font %s: failures will only be warnings.\n",param.lf.lfFaceName); + } + } + + if (*hfont) + { + WORD glyph = 0; + + *hfont_orig = SelectObject(hdc, *hfont); + if (GetGlyphIndicesW(hdc, &check, 1, &glyph, 0) == GDI_ERROR || glyph == 0) + { + winetest_trace("Font fails to contain required glyphs.\n"); + SelectObject(hdc, *hfont_orig); + DeleteObject(*hfont); + *hfont = NULL; + rc = 0; + } + else if (!rc) + rc = -1; + } + else + winetest_trace("Failed to find usable font.\n"); + + return rc; +} + +#define find_font_for_range(a, b, c, d, e, f) \ + (winetest_set_location(__FILE__, __LINE__), 0) ? 0 : \ + _find_font_for_range(a, b, c, d, e, f) + +struct expected_character_placement +{ + int order; + int dx; + int reorder; +}; + +static inline void _test_character_placement_ok(int valid, HDC hdc, const WCHAR *string, unsigned int str_len, const struct expected_character_placement *expected, unsigned int expected_len) +{ + GCP_RESULTSW result; + unsigned int i, max_glyphs = 1.5 * str_len; + DWORD size; + int dx; + + memset(&result, 0, sizeof(result)); + result.lStructSize = sizeof(result); + result.lpCaretPos = heap_alloc(max_glyphs * sizeof(*result.lpCaretPos)); + result.lpGlyphs = heap_alloc(max_glyphs * sizeof(*result.lpGlyphs)); + result.lpOrder = heap_alloc(max_glyphs * sizeof(*result.lpOrder)); + result.lpDx = heap_alloc(max_glyphs * sizeof(*result.lpDx)); + result.nGlyphs = max_glyphs; + + memset(result.lpOrder, -1, max_glyphs * sizeof(*result.lpOrder)); + memset(result.lpDx, -1, max_glyphs * sizeof(*result.lpDx)); + + size = GetCharacterPlacementW(hdc, string, str_len, 0, &result, 0); + winetest_ok(size, "GetCharacterPlacementW failed.\n"); + if (valid > 0) + winetest_ok(result.nGlyphs == expected_len, "Expected %d, got %d.\n", expected_len, result.nGlyphs); + else if (result.nGlyphs != expected_len) + winetest_trace("Expected %d, got %d.\n", expected_len, result.nGlyphs); + for (i = 0; i < result.nGlyphs; ++i) + { + if (valid > 0) + todo_wine_if(expected[i].order != i) + winetest_ok(result.lpOrder[i] == expected[i].order, "Character %d, expected order %d, got %d.\n", + i, expected[i].order, result.lpOrder[i]); + else if (result.lpOrder[i] != expected[i].reorder) + winetest_trace("Character %d, expected order %d, got %d.\n", i, expected[i].reorder, result.lpOrder[i]); + if (expected[i].dx) + { + GetCharWidthI(hdc, result.lpGlyphs[result.lpOrder[i]], 1, NULL, &dx); + if (valid > 0) + winetest_ok(result.lpDx[result.lpOrder[i]] == dx, "Character %d, expected dx %d, got %d.\n", + i, dx, result.lpDx[result.lpOrder[i]]); + else if (result.lpDx[result.lpOrder[i]] != dx) + winetest_trace("Character %d, expected dx %d, got %d.\n", + i, dx, result.lpDx[result.lpOrder[i]]); + } + } + + if (expected[0].reorder >= 0) + { + memset(result.lpOrder, -1, max_glyphs * sizeof(*result.lpOrder)); + memset(result.lpDx, -1, max_glyphs * sizeof(*result.lpDx)); + + size = GetCharacterPlacementW(hdc, string, str_len, 0, &result, GCP_REORDER); + winetest_ok(size, "GetCharacterPlacementW failed with GCP_REORDER.\n"); + if (valid > 0) + winetest_ok(result.nGlyphs == expected_len, "Expected %d with GCP_REORDER, got %d.\n", expected_len, result.nGlyphs); + else if (result.nGlyphs != expected_len) + winetest_trace("Expected %d with GCP_REORDER, got %d.\n", expected_len, result.nGlyphs); + for (i = 0; i < result.nGlyphs; ++i) + { + if (valid > 0) + todo_wine_if(expected[i].order != i) + winetest_ok(result.lpOrder[i] == expected[i].reorder, "Character %d, expected GCP_REORDER order %d, got %d.\n", + i, expected[i].reorder, result.lpOrder[i]); + else if (result.lpOrder[i] != expected[i].reorder) + winetest_trace("Character %d, expected GCP_REORDER order %d, got %d.\n", i, expected[i].reorder, result.lpOrder[i]); + if (expected[i].dx) + { + GetCharWidthI(hdc, result.lpGlyphs[result.lpOrder[i]], 1, NULL, &dx); + if (valid > 0) + winetest_ok(result.lpDx[result.lpOrder[i]] == dx, "Character %d, expected GCP_REORDER dx %d, got %d.\n", + i, dx, result.lpDx[result.lpOrder[i]]); + else if (result.lpDx[result.lpOrder[i]] != dx) + winetest_trace("Character %d, expected GCP_REORDER dx %d, got %d.\n", + i, dx, result.lpDx[result.lpOrder[i]]); + } + } + } + + heap_free(result.lpCaretPos); + heap_free(result.lpGlyphs); + heap_free(result.lpOrder); + heap_free(result.lpDx); +} + +#define test_character_placement_ok(a, b, c, d, e, f) \ + (winetest_set_location(__FILE__, __LINE__), 0) ? 0 : \ + _test_character_placement_ok(a, b, c, d, e, f) + static void test_GetCharacterPlacement(void) { + static const WCHAR test1[] = {'w', 'i', 'n', 'e'}; + static const struct expected_character_placement t1_expected[] = + {{0,1,0},{1,1,1},{2,1,2},{3,1,3}}; + + static const WCHAR test2[] = {0x202B, 'i', 'n', 0x202C}; + static const struct expected_character_placement t2_expected[] = + {{0,0,0},{1,1,1},{2,1,2},{3,0,3}}; + + static const WCHAR test3[] = {'t', 't', 'f', 'f', 'f', 'i',}; + static const struct expected_character_placement t3_expected[] = + {{0,1,0},{0,1,0},{0,1,0},{1,1,1},{1,1,1},{1,1,1}}; + + /* Hebrew */ + static const WCHAR test_hebrew[] = + {0x05e9, 0x05dc, 0x05d5, 0x05dd}; + static const struct expected_character_placement hebrew_expected[] = + {{0,1,3},{1,1,2},{2,1,1},{3,1,0}}; + + /* Arabic */ + static const WCHAR test_arabic[] = + {0x0633, 0x0644, 0x0627, 0x0645}; + static const struct expected_character_placement arabic_expected[] = + {{0,1,2},{1,1,1},{2,1,1},{3,1,0}}; + + /* Thai */ + static const WCHAR test_thai[] = + {0x0e2a, 0x0e04, 0x0e23, 0x0e34, 0x0e1b, 0x0e15, 0x0e4c, 0x0e44, 0x0e17, 0x0e22}; + static const struct expected_character_placement thai_expected[] = + {{0,1,0},{1,1,1},{2,1,2},{3,1,3},{4,1,4},{5,1,5},{6,1,6},{7,1,7},{8,1,8},{9,1,9}}; + + /* Thaana */ + static const WCHAR test_thaana[] = + {0x078a, 0x07ae, 0x0792, 0x07b0, 0x0020, 0x0796, 0x07aa, 0x0789, 0x07b0, 0x0795, 0x07ac, 0x0791, 0x07b0}; + static const struct expected_character_placement thaana_expected[] = + {{0,1,12},{1,1,11},{2,0,10},{3,1,9},{4,1,8},{5,1,7},{6,1,6},{7,1,5},{8,1,4},{9,1,3},{10,1,2},{11,0,1},{12,1,0}}; + + /* Phags-pa */ + static const WCHAR test_phagspa[] = + {0xa84f, 0xa861, 0xa843, 0x0020, 0xa863, 0xa861, 0xa859, 0x0020, 0xa850, 0xa85c, 0xa85e}; + static const struct expected_character_placement phagspa_expected[] = + {{0,1,-1},{1,1,-1},{2,1,-1},{3,1,-1},{4,1,-1},{5,1,-1},{6,1,-1},{7,1,-1},{8,1,-1},{9,1,-1},{10,1,-1}}; + + /* Lao */ + static const WCHAR test_lao[] = + {0x0ead, 0x0eb1, 0x0e81, 0x0eaa, 0x0ead, 0x0e99, 0x0ea5, 0x0eb2, 0x0ea7}; + static const struct expected_character_placement lao_expected[] = + {{0,1,0},{1,1,1},{2,1,2},{3,1,3},{4,1,4},{5,1,5},{6,1,6},{7,1,7},{8,1,8}}; + + /* Tibetan */ + static const WCHAR test_tibetan[] = + {0x0f04, 0x0f05, 0x0f0e, 0x0020, 0x0f51, 0x0f7c, 0x0f53, 0x0f0b, 0x0f5a, 0x0f53, 0x0f0b, 0x0f51, 0x0f44, 0x0f0b, 0x0f54, 0x0f7c, 0x0f0d}; + static const struct expected_character_placement tibetan_expected[] = + {{0,1,-1},{1,1,-1},{2,1,-1},{3,1,-1},{4,1,-1},{5,1,-1},{6,1,-1},{7,1,-1},{8,1,-1},{9,1,-1},{10,1,-1},{11,1,-1},{12,1,-1},{13,1,-1},{14,1,-1},{15,1,-1},{16,1,-1}}; + + /* Devanagari */ + static const WCHAR test_devanagari[] = + {0x0926, 0x0947, 0x0935, 0x0928, 0x093e, 0x0917, 0x0930, 0x0940}; + static const struct expected_character_placement devanagari_expected[] = + {{0,1,-1},{1,1,-1},{2,1,-1},{3,1,-1},{4,1,-1},{5,1,-1},{6,1,-1},{7,1,-1}}; + + /* Bengali */ + static const WCHAR test_bengali[] = + {0x09ac, 0x09be, 0x0982, 0x09b2, 0x09be}; + static const struct expected_character_placement bengali_expected[] = + {{0,1,-1},{1,1,-1},{2,1,-1},{3,1,-1},{4,1,-1}}; + + /* Gurmukhi */ + static const WCHAR test_gurmukhi[] = + {0x0a17, 0x0a41, 0x0a30, 0x0a2e, 0x0a41, 0x0a16, 0x0a40}; + static const struct expected_character_placement gurmukhi_expected[] = + {{0,1,-1},{1,1,-1},{2,1,-1},{3,1,-1},{4,1,-1},{5,1,-1},{6,1,-1}}; + + /* Gujarati */ + static const WCHAR test_gujarati[] = + {0x0a97, 0x0ac1, 0x0a9c, 0x0ab0, 0x0abe, 0x0aa4, 0x0ac0}; + static const struct expected_character_placement gujarati_expected[] = + {{0,1,-1},{1,1,-1},{2,1,-1},{3,1,-1},{4,1,-1},{5,1,-1},{6,1,-1}}; + + /* Oriya */ + static const WCHAR test_oriya[] = + {0x0b13, 0x0b21, 0x0b3c, 0x0b3f, 0x0b06}; + static const struct expected_character_placement oriya_expected[] = + {{0,1,0},{1,1,1},{2,1,2},{2,1,2},{3,1,3}}; + + /* Tamil */ + static const WCHAR test_tamil[] = + {0x0ba4, 0x0bae, 0x0bbf, 0x0bb4, 0x0bcd}; + static const struct expected_character_placement tamil_expected[] = + {{0,1,0},{1,1,1},{2,1,2},{3,1,3},{3,1,3}}; + + /* Malayalam */ + static const WCHAR test_malayalam[] = + {0x0d2e, 0x0d32, 0x0d2f, 0x0d3e, 0x0d33, 0x0d02}; + static const struct expected_character_placement malayalam_expected[] = + {{0,1,-1},{1,1,-1},{2,1,-1},{3,1,-1},{4,1,-1},{5,1,-1}}; + + /* Kannada */ + static const WCHAR test_kannada[] = + {0x0c95, 0x0ca8, 0x0ccd, 0x0ca8, 0x0ca1}; + static const struct expected_character_placement kannada_expected[] = + {{0,1,0},{1,1,1},{2,1,2},{2,1,2},{3,1,3}}; + + HFONT hfont, hfont_orig; GCP_RESULTSA result; DWORD size, size2; WCHAR glyphs[20]; - int pos[20]; + int test_valid, pos[20]; HDC hdc;
hdc = CreateCompatibleDC(0); @@ -4947,6 +5242,150 @@ static void test_GetCharacterPlacement(void) ok(glyphs[0] == 'W', "Unexpected first glyph %s\n", wine_dbgstr_wn(glyphs, 1)); todo_wine ok(pos[0] == 0, "Unexpected caret position %d\n", pos[0]);
+ test_valid = find_font_for_range(hdc, "Tahoma", 0, test1[0], &hfont, &hfont_orig); + if (hfont != NULL) + { + test_character_placement_ok(test_valid, hdc, test1, 4, t1_expected, ARRAY_SIZE(t1_expected)); + SelectObject(hdc, hfont_orig); + DeleteObject(hfont); + } + + test_valid = find_font_for_range(hdc, "Tahoma", 0, test2[0], &hfont, &hfont_orig); + if (hfont != NULL) + { + test_character_placement_ok(test_valid, hdc, test2, 4, t2_expected, ARRAY_SIZE(t2_expected)); + SelectObject(hdc, hfont_orig); + DeleteObject(hfont); + } + + test_valid = find_font_for_range(hdc, "Calibri", 0, test3[0], &hfont, &hfont_orig); + if (hfont != NULL) + { + test_character_placement_ok(test_valid, hdc, test3, 6, t3_expected, ARRAY_SIZE(t3_expected)); + SelectObject(hdc, hfont_orig); + DeleteObject(hfont); + } + + test_valid = find_font_for_range(hdc, "Microsoft Sans Serif", 11, test_hebrew[0], &hfont, &hfont_orig); + if (hfont != NULL) + { + test_character_placement_ok(test_valid, hdc, test_hebrew, 4, hebrew_expected, ARRAY_SIZE(hebrew_expected)); + SelectObject(hdc, hfont_orig); + DeleteObject(hfont); + } + + test_valid = find_font_for_range(hdc, "Microsoft Sans Serif", 13, test_arabic[0], &hfont, &hfont_orig); + if (hfont != NULL) + { + test_character_placement_ok(test_valid, hdc, test_arabic, 4, arabic_expected, ARRAY_SIZE(arabic_expected)); + SelectObject(hdc, hfont_orig); + DeleteObject(hfont); + } + + test_valid = find_font_for_range(hdc, "Microsoft Sans Serif", 24, test_thai[0], &hfont, &hfont_orig); + if (hfont != NULL) + { + test_character_placement_ok(test_valid, hdc, test_thai, 10, thai_expected, ARRAY_SIZE(thai_expected)); + SelectObject(hdc, hfont_orig); + DeleteObject(hfont); + } + + test_valid = find_font_for_range(hdc, "MV Boli", 72, test_thaana[0], &hfont, &hfont_orig); + if (hfont != NULL) + { + test_character_placement_ok(test_valid, hdc, test_thaana, 13, thaana_expected, ARRAY_SIZE(thaana_expected)); + SelectObject(hdc, hfont_orig); + DeleteObject(hfont); + } + + test_valid = find_font_for_range(hdc, "Microsoft PhagsPa", 53, test_phagspa[0], &hfont, &hfont_orig); + if (hfont != NULL) + { + test_character_placement_ok(test_valid, hdc, test_phagspa, 11, phagspa_expected, ARRAY_SIZE(phagspa_expected)); + SelectObject(hdc, hfont_orig); + DeleteObject(hfont); + } + + test_valid = find_font_for_range(hdc, "DokChampa", 25, test_lao[0], &hfont, &hfont_orig); + if (hfont != NULL) + { + test_character_placement_ok(test_valid, hdc, test_lao, 9, lao_expected, ARRAY_SIZE(lao_expected)); + SelectObject(hdc, hfont_orig); + DeleteObject(hfont); + } + + test_valid = find_font_for_range(hdc, "Microsoft Himalaya", 70, test_tibetan[0], &hfont, &hfont_orig); + if (hfont != NULL) + { + test_character_placement_ok(test_valid, hdc, test_tibetan, 17, tibetan_expected, ARRAY_SIZE(tibetan_expected)); + SelectObject(hdc, hfont_orig); + DeleteObject(hfont); + } + + test_valid = find_font_for_range(hdc, "Mangal", 15, test_devanagari[0], &hfont, &hfont_orig); + if (hfont != NULL) + { + test_character_placement_ok(test_valid, hdc, test_devanagari, 8, devanagari_expected, ARRAY_SIZE(devanagari_expected)); + SelectObject(hdc, hfont_orig); + DeleteObject(hfont); + } + + test_valid = find_font_for_range(hdc, "Vrinda", 16, test_bengali[0], &hfont, &hfont_orig); + if (hfont != NULL) + { + test_character_placement_ok(test_valid, hdc, test_bengali, 5, bengali_expected, ARRAY_SIZE(bengali_expected)); + SelectObject(hdc, hfont_orig); + DeleteObject(hfont); + } + + test_valid = find_font_for_range(hdc, "Raavi", 17, test_gurmukhi[0], &hfont, &hfont_orig); + if (hfont != NULL) + { + test_character_placement_ok(test_valid, hdc, test_gurmukhi, 7, gurmukhi_expected, ARRAY_SIZE(gurmukhi_expected)); + SelectObject(hdc, hfont_orig); + DeleteObject(hfont); + } + + test_valid = find_font_for_range(hdc, "Shruti", 18, test_gujarati[0], &hfont, &hfont_orig); + if (hfont != NULL) + { + test_character_placement_ok(test_valid, hdc, test_gujarati, 7, gujarati_expected, ARRAY_SIZE(gujarati_expected)); + SelectObject(hdc, hfont_orig); + DeleteObject(hfont); + } + + test_valid = find_font_for_range(hdc, "Kalinga", 19, test_oriya[0], &hfont, &hfont_orig); + if (hfont != NULL) + { + test_character_placement_ok(test_valid, hdc, test_oriya, 5, oriya_expected, ARRAY_SIZE(oriya_expected)); + SelectObject(hdc, hfont_orig); + DeleteObject(hfont); + } + + test_valid = find_font_for_range(hdc, "Latha", 20, test_tamil[0], &hfont, &hfont_orig); + if (hfont != NULL) + { + test_character_placement_ok(test_valid, hdc, test_tamil, 5, tamil_expected, ARRAY_SIZE(tamil_expected)); + SelectObject(hdc, hfont_orig); + DeleteObject(hfont); + } + + test_valid = find_font_for_range(hdc, "Kartika", 23, test_malayalam[0], &hfont, &hfont_orig); + if (hfont != NULL) + { + test_character_placement_ok(test_valid, hdc, test_malayalam, 6, malayalam_expected, ARRAY_SIZE(malayalam_expected)); + SelectObject(hdc, hfont_orig); + DeleteObject(hfont); + } + + test_valid = find_font_for_range(hdc, "Tunga", 22, test_kannada[0], &hfont, &hfont_orig); + if (hfont != NULL) + { + test_character_placement_ok(test_valid, hdc, test_kannada, 5, kannada_expected, ARRAY_SIZE(kannada_expected)); + SelectObject(hdc, hfont_orig); + DeleteObject(hfont); + } + DeleteDC(hdc); }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=81592
Your paranoid android.
=== w2008s64 (32 bit report) ===
gdi32: font.c:5280: Test failed: Character 2, expected order 2, got 1. font.c:5280: Test failed: Character 3, expected order 3, got 2. font.c:8198: Test failed: Test 0: expected 16, got 8. font.c:8198: Test failed: Test 1: expected 16, got 4. font.c:8198: Test failed: Test 3: expected 16, got 8. font.c:8198: Test failed: Test 4: expected 16, got 8. font.c:8198: Test failed: Test 5: expected 16, got 8. font.c:8198: Test failed: Test 6: expected 16, got 8. font.c:8191: Test failed: Test 12: got 8. font.c:8191: Test failed: Test 13: got 8. font.c:8191: Test failed: Test 14: got 8. font.c:8191: Test failed: Test 15: got 8. font.c:8191: Test failed: Test 16: got 8.
=== w8 (32 bit report) ===
gdi32: font.c:8198: Test failed: Test 0: expected 16, got 8. font.c:8198: Test failed: Test 1: expected 16, got 4. font.c:8198: Test failed: Test 3: expected 16, got 8. font.c:8198: Test failed: Test 4: expected 16, got 8. font.c:8198: Test failed: Test 5: expected 16, got 8. font.c:8198: Test failed: Test 6: expected 16, got 8. font.c:8191: Test failed: Test 12: got 8. font.c:8191: Test failed: Test 13: got 8. font.c:8191: Test failed: Test 14: got 8. font.c:8191: Test failed: Test 15: got 8. font.c:8191: Test failed: Test 16: got 8.
=== w8adm (32 bit report) ===
gdi32: font.c:8198: Test failed: Test 0: expected 16, got 8. font.c:8198: Test failed: Test 1: expected 16, got 4. font.c:8198: Test failed: Test 3: expected 16, got 8. font.c:8198: Test failed: Test 4: expected 16, got 8. font.c:8198: Test failed: Test 5: expected 16, got 8. font.c:8198: Test failed: Test 6: expected 16, got 8. font.c:8191: Test failed: Test 12: got 8. font.c:8191: Test failed: Test 13: got 8. font.c:8191: Test failed: Test 14: got 8. font.c:8191: Test failed: Test 15: got 8. font.c:8191: Test failed: Test 16: got 8.
=== w10pro64_ar (32 bit report) ===
gdi32: font.c:8198: Test failed: Test 3: expected 16, got 8. font.c:8198: Test failed: Test 4: expected 16, got 8. font.c:8198: Test failed: Test 5: expected 16, got 8. font.c:8198: Test failed: Test 6: expected 16, got 8. font.c:8219: Test failed: Got 0.
=== w10pro64_he (32 bit report) ===
gdi32: font.c:8200: Test failed: Test 2: expected 6, got 6. font.c:8219: Test failed: Got 0.
=== w10pro64_ja (32 bit report) ===
gdi32: font.c:8198: Test failed: Test 3: expected 16, got 8. font.c:8198: Test failed: Test 4: expected 16, got 8. font.c:8198: Test failed: Test 5: expected 16, got 8. font.c:8198: Test failed: Test 6: expected 16, got 8. font.c:8219: Test failed: Got 0.
=== w10pro64_zh_CN (32 bit report) ===
gdi32: font.c:8200: Test failed: Test 2: expected 8, got 8. font.c:8219: Test failed: Got 0.
=== w2008s64 (64 bit report) ===
gdi32: font.c:5280: Test failed: Character 2, expected order 2, got 1. font.c:5280: Test failed: Character 3, expected order 3, got 2. font.c:8198: Test failed: Test 0: expected 16, got 8. font.c:8198: Test failed: Test 1: expected 16, got 4. font.c:8198: Test failed: Test 3: expected 16, got 8. font.c:8198: Test failed: Test 4: expected 16, got 8. font.c:8198: Test failed: Test 5: expected 16, got 8. font.c:8198: Test failed: Test 6: expected 16, got 8. font.c:8191: Test failed: Test 12: got 8. font.c:8191: Test failed: Test 13: got 8. font.c:8191: Test failed: Test 14: got 8. font.c:8191: Test failed: Test 15: got 8. font.c:8191: Test failed: Test 16: got 8.
=== w864 (64 bit report) ===
gdi32: font.c:8198: Test failed: Test 0: expected 16, got 8. font.c:8198: Test failed: Test 1: expected 16, got 4. font.c:8198: Test failed: Test 3: expected 16, got 8. font.c:8198: Test failed: Test 4: expected 16, got 8. font.c:8198: Test failed: Test 5: expected 16, got 8. font.c:8198: Test failed: Test 6: expected 16, got 8. font.c:8191: Test failed: Test 12: got 8. font.c:8191: Test failed: Test 13: got 8. font.c:8191: Test failed: Test 14: got 8. font.c:8191: Test failed: Test 15: got 8. font.c:8191: Test failed: Test 16: got 8.
=== w10pro64_ar (64 bit report) ===
gdi32: font.c:8198: Test failed: Test 3: expected 16, got 8. font.c:8198: Test failed: Test 4: expected 16, got 8. font.c:8198: Test failed: Test 5: expected 16, got 8. font.c:8198: Test failed: Test 6: expected 16, got 8. font.c:8219: Test failed: Got 0.
=== w10pro64_he (64 bit report) ===
gdi32: font.c:8200: Test failed: Test 2: expected 6, got 6. font.c:8219: Test failed: Got 0.
=== w10pro64_ja (64 bit report) ===
gdi32: font.c:8198: Test failed: Test 3: expected 16, got 8. font.c:8198: Test failed: Test 4: expected 16, got 8. font.c:8198: Test failed: Test 5: expected 16, got 8. font.c:8198: Test failed: Test 6: expected 16, got 8. font.c:8219: Test failed: Got 0.
=== w10pro64_zh_CN (64 bit report) ===
gdi32: font.c:8200: Test failed: Test 2: expected 8, got 8. font.c:8219: Test failed: Got 0.
Signed-off-by: Sven Baars sbaars@codeweavers.com --- An implementation that also returns the correct lpOrder would require an implementation of SCRIPT_STATE.fGcpClusters. But this implementation already seems to be less broken than the previous one.
dlls/gdi32/font.c | 218 +++++++++++++++++++++++++++++----------- dlls/gdi32/tests/font.c | 8 +- 2 files changed, 167 insertions(+), 59 deletions(-)
diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c index f0616b6f908..4f4e485220b 100644 --- a/dlls/gdi32/font.c +++ b/dlls/gdi32/font.c @@ -31,6 +31,7 @@ #include "winnls.h" #include "winternl.h" #include "winreg.h" +#include "usp10.h" #include "gdi_private.h" #include "resource.h" #include "wine/exception.h" @@ -4046,6 +4047,89 @@ static void FONT_NewTextMetricExWToA(const NEWTEXTMETRICEXW *ptmW, NEWTEXTMETRIC memcpy(&ptmA->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE)); }
+/* Compute glyph positions using Uniscribe */ +static BOOL get_glyph_positions( HDC hdc, const WCHAR *string, int str_len, WORD *glyphs_in, + int *advance_in, unsigned int *max_num_glyphs ) +{ + unsigned int i, glyph_pos = 0, max_num_items = *max_num_glyphs + 1; + int num_items = 0, num_glyphs, num_chars; + WORD *glyphs = NULL, *log_clust = NULL; + SCRIPT_VISATTR *psva = NULL; + SCRIPT_ITEM *items = NULL; + GOFFSET *goffset = NULL; + SCRIPT_CACHE sc = NULL; + int *advance = NULL; + BOOL ret = FALSE; + HRESULT res; + + items = heap_alloc( sizeof(*items) * (max_num_items + 1) ); + if (!items) + goto cleanup; + + res = ScriptItemize( string, str_len, max_num_items, NULL, NULL, items, &num_items ); + if (res) + WARN( "ScriptItemize failed with %x.\n", res ); + + if (glyphs_in) + glyphs = glyphs_in; + else + glyphs = heap_alloc( *max_num_glyphs * sizeof(*glyphs) ); + if (!glyphs) + goto cleanup; + + if (advance_in) + advance = advance_in; + else + advance = heap_alloc( *max_num_glyphs * sizeof(*advance) ); + if (!advance) + goto cleanup; + + log_clust = heap_alloc( str_len * sizeof(*log_clust) ); + if (!log_clust) + goto cleanup; + + goffset = heap_alloc( *max_num_glyphs * sizeof(*goffset) ); + if (!goffset) + goto cleanup; + + psva = heap_alloc( *max_num_glyphs * sizeof(*psva) ); + if (!psva) + goto cleanup; + + for (i = 0; i < num_items; ++i) + { + num_glyphs = *max_num_glyphs - glyph_pos; + num_chars = items[i+1].iCharPos - items[i].iCharPos; + + res = ScriptShape( hdc, &sc, string + items[i].iCharPos, num_chars, num_glyphs, + &items[i].a, glyphs + glyph_pos, log_clust + glyph_pos, psva, &num_glyphs ); + if (res) + WARN( "ScriptShape failed with %x.\n", res ); + + res = ScriptPlace( hdc, &sc, glyphs + glyph_pos, num_glyphs, psva, &items[i].a, + advance + glyph_pos, goffset, NULL ); + if (res) + WARN( "ScriptPlace failed with %x.\n", res ); + + glyph_pos += num_glyphs; + } + + *max_num_glyphs = glyph_pos; + ret = TRUE; + +cleanup: + heap_free( items ); + if (!glyphs_in) + heap_free( glyphs ); + if (!advance_in) + heap_free( advance ); + heap_free( log_clust ); + heap_free( goffset ); + heap_free( psva ); + + return ret; +} + /* compute positions for text rendering, in device coords */ static BOOL get_char_positions( DC *dc, const WCHAR *str, INT count, INT *dx, SIZE *size ) { @@ -7252,32 +7336,32 @@ GetCharacterPlacementW( DWORD dwFlags /* [in] Flags specifying how to process the string */ ) { - DWORD ret=0; + int *kern = NULL, *advance = NULL, kern_total = 0; + unsigned int i, nSet, pos = 0; + DWORD ret = 0; SIZE size; - UINT i, nSet; - int *kern = NULL, kern_total = 0;
- TRACE("%s, %d, %d, 0x%08x\n", - debugstr_wn(lpString, uCount), uCount, nMaxExtent, dwFlags); + TRACE( "%s, %d, %d, 0x%08x\n", + debugstr_wn( lpString, uCount ), uCount, nMaxExtent, dwFlags );
if (!uCount) return 0;
if (!lpResults) - return GetTextExtentPoint32W(hdc, lpString, uCount, &size) ? MAKELONG(size.cx, size.cy) : 0; + return GetTextExtentPoint32W( hdc, lpString, uCount, &size ) ? MAKELONG( size.cx, size.cy ) : 0;
- TRACE("lStructSize=%d, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p\n" - "lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n", - lpResults->lStructSize, lpResults->lpOutString, lpResults->lpOrder, - lpResults->lpDx, lpResults->lpCaretPos, lpResults->lpClass, - lpResults->lpGlyphs, lpResults->nGlyphs, lpResults->nMaxFit); + TRACE( "lStructSize=%d, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p\n" + "lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n", + lpResults->lStructSize, lpResults->lpOutString, lpResults->lpOrder, + lpResults->lpDx, lpResults->lpCaretPos, lpResults->lpClass, + lpResults->lpGlyphs, lpResults->nGlyphs, lpResults->nMaxFit );
if (dwFlags & ~(GCP_REORDER | GCP_USEKERNING)) - FIXME("flags 0x%08x ignored\n", dwFlags); + FIXME( "flags 0x%08x ignored\n", dwFlags ); if (lpResults->lpClass) - FIXME("classes not implemented\n"); + FIXME( "classes not implemented\n" ); if (lpResults->lpCaretPos && (dwFlags & GCP_REORDER)) - FIXME("Caret positions for complex scripts not implemented\n"); + FIXME( "Caret positions for complex scripts not implemented\n" );
nSet = (UINT)uCount; if (nSet > lpResults->nGlyphs) @@ -7286,72 +7370,94 @@ GetCharacterPlacementW( /* return number of initialized fields */ lpResults->nGlyphs = nSet;
- if (!(dwFlags & GCP_REORDER)) + if (dwFlags & GCP_USEKERNING) { - /* Treat the case where no special handling was requested in a fastpath way */ - /* copy will do if the GCP_REORDER flag is not set */ - if (lpResults->lpOutString) - memcpy( lpResults->lpOutString, lpString, nSet * sizeof(WCHAR)); - - if (lpResults->lpOrder) + kern = kern_string( hdc, lpString, nSet, &kern_total ); + if (!kern) { - for (i = 0; i < nSet; i++) - lpResults->lpOrder[i] = i; + SetLastError( ERROR_NOT_ENOUGH_MEMORY ); + return 0; } } - else - { - BIDI_Reorder(NULL, lpString, uCount, dwFlags, WINE_GCPW_FORCE_LTR, lpResults->lpOutString, - nSet, lpResults->lpOrder, NULL, NULL ); - }
- if (dwFlags & GCP_USEKERNING) + if (!(dwFlags & GCP_REORDER)) { - kern = kern_string(hdc, lpString, nSet, &kern_total); - if (!kern) + if (lpResults->lpDx) + advance = lpResults->lpDx; + else if (lpResults->lpCaretPos) + advance = heap_alloc( lpResults->nGlyphs * sizeof(*advance) ); + + if (!get_glyph_positions( hdc, lpString, nSet, lpResults->lpGlyphs, advance, &lpResults->nGlyphs )) { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); + if (!lpResults->lpDx) + heap_free( advance ); return 0; } - }
- /* FIXME: Will use the placement chars */ - if (lpResults->lpDx) - { - int c; - for (i = 0; i < nSet; i++) + if (lpResults->lpOutString) + memcpy( lpResults->lpOutString, lpString, nSet * sizeof(WCHAR) ); + + if (lpResults->lpCaretPos) { - if (GetCharWidth32W(hdc, lpString[i], lpString[i], &c)) + for (i = 0; i < lpResults->nGlyphs; i++) { - lpResults->lpDx[i] = c; + + lpResults->lpCaretPos[i] = pos; + pos += advance[i]; + if (dwFlags & GCP_USEKERNING) - lpResults->lpDx[i] += kern[i]; + pos += kern[i]; } } - }
- if (lpResults->lpCaretPos && !(dwFlags & GCP_REORDER)) + if (lpResults->lpOrder) + { + if (lpResults->lpGlyphs) + for(i = 0; i < lpResults->nGlyphs; i++) + lpResults->lpOrder[i] = i; + else + for(i = 0; i < nSet; i++) + lpResults->lpOrder[i] = i; + } + + if (!lpResults->lpDx) + heap_free( advance ); + } + else { - int pos = 0; + BIDI_Reorder( NULL, lpString, uCount, dwFlags, WINE_GCPW_FORCE_LTR, lpResults->lpOutString, + nSet, lpResults->lpOrder, NULL, NULL );
- lpResults->lpCaretPos[0] = 0; - for (i = 0; i < nSet - 1; i++) + if (lpResults->lpDx) { - if (dwFlags & GCP_USEKERNING) - pos += kern[i]; - - if (GetTextExtentPoint32W(hdc, &lpString[i], 1, &size)) - lpResults->lpCaretPos[i + 1] = (pos += size.cx); + int c; + for (i = 0; i < nSet; i++) + { + if (GetCharWidth32W( hdc, lpString[i], lpString[i], &c )) + lpResults->lpDx[i] = c; + } } + + if(lpResults->lpGlyphs) + GetGlyphIndicesW( hdc, lpString, nSet, lpResults->lpGlyphs, 0 ); + }
- if (lpResults->lpGlyphs) - GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0); + if (lpResults->lpDx && (dwFlags & GCP_USEKERNING)) + { + if (lpResults->nGlyphs != nSet) + FIXME( "Kerning not supported with the number of glyphs unequal to the number of input characters\n" ); + else + { + for (i = 0; i < lpResults->nGlyphs; i++) + lpResults->lpDx[i] += kern[i]; + } + }
- if (GetTextExtentPoint32W(hdc, lpString, uCount, &size)) - ret = MAKELONG(size.cx + kern_total, size.cy); + if (GetTextExtentPoint32W( hdc, lpString, uCount, &size )) + ret = MAKELONG( size.cx + kern_total, size.cy );
- heap_free(kern); + heap_free( kern );
return ret; } diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c index 62eaab8639c..ea2ae4c523f 100644 --- a/dlls/gdi32/tests/font.c +++ b/dlls/gdi32/tests/font.c @@ -5022,7 +5022,8 @@ static inline void _test_character_placement_ok(int valid, HDC hdc, const WCHAR size = GetCharacterPlacementW(hdc, string, str_len, 0, &result, 0); winetest_ok(size, "GetCharacterPlacementW failed.\n"); if (valid > 0) - winetest_ok(result.nGlyphs == expected_len, "Expected %d, got %d.\n", expected_len, result.nGlyphs); + todo_wine_if(expected[expected_len - 1].order != expected_len - 1) + winetest_ok(result.nGlyphs == expected_len, "Expected %d, got %d.\n", expected_len, result.nGlyphs); else if (result.nGlyphs != expected_len) winetest_trace("Expected %d, got %d.\n", expected_len, result.nGlyphs); for (i = 0; i < result.nGlyphs; ++i) @@ -5053,7 +5054,8 @@ static inline void _test_character_placement_ok(int valid, HDC hdc, const WCHAR size = GetCharacterPlacementW(hdc, string, str_len, 0, &result, GCP_REORDER); winetest_ok(size, "GetCharacterPlacementW failed with GCP_REORDER.\n"); if (valid > 0) - winetest_ok(result.nGlyphs == expected_len, "Expected %d with GCP_REORDER, got %d.\n", expected_len, result.nGlyphs); + todo_wine_if(expected[expected_len - 1].order != expected_len - 1) + winetest_ok(result.nGlyphs == expected_len, "Expected %d with GCP_REORDER, got %d.\n", expected_len, result.nGlyphs); else if (result.nGlyphs != expected_len) winetest_trace("Expected %d with GCP_REORDER, got %d.\n", expected_len, result.nGlyphs); for (i = 0; i < result.nGlyphs; ++i) @@ -8164,7 +8166,7 @@ static void test_zero_width_control(void) size = GetCharacterPlacementW(hdc, test, 10, 0, &result, 0); ok(size, "Test %d: GetCharacterPlacementA failed.\n", i); 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)); + ok(glyphs[5] == glyphs[4], "Test %d: unexpected glyphs %s.\n", i, wine_dbgstr_wn(glyphs, result.nGlyphs)); if (i < 15) ok(pos[6] - pos[5] == 0, "Test %d: unexpected width %d.\n", i, pos[6] - pos[5]); else
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=81593
Your paranoid android.
=== w2008s64 (32 bit report) ===
gdi32: font.c:5282: Test failed: Character 2, expected order 2, got 1. font.c:5282: Test failed: Character 3, expected order 3, got 2. font.c:8200: Test failed: Test 0: expected 16, got 8. font.c:8200: Test failed: Test 1: expected 16, got 4. font.c:8200: Test failed: Test 3: expected 16, got 8. font.c:8200: Test failed: Test 4: expected 16, got 8. font.c:8200: Test failed: Test 5: expected 16, got 8. font.c:8200: Test failed: Test 6: expected 16, got 8. font.c:8193: Test failed: Test 12: got 8. font.c:8193: Test failed: Test 13: got 8. font.c:8193: Test failed: Test 14: got 8. font.c:8193: Test failed: Test 15: got 8. font.c:8193: Test failed: Test 16: got 8.
=== w8 (32 bit report) ===
gdi32: font.c:8200: Test failed: Test 0: expected 16, got 8. font.c:8200: Test failed: Test 1: expected 16, got 4. font.c:8200: Test failed: Test 3: expected 16, got 8. font.c:8200: Test failed: Test 4: expected 16, got 8. font.c:8200: Test failed: Test 5: expected 16, got 8. font.c:8200: Test failed: Test 6: expected 16, got 8. font.c:8193: Test failed: Test 12: got 8. font.c:8193: Test failed: Test 13: got 8. font.c:8193: Test failed: Test 14: got 8. font.c:8193: Test failed: Test 15: got 8. font.c:8193: Test failed: Test 16: got 8.
=== w8adm (32 bit report) ===
gdi32: font.c:8200: Test failed: Test 0: expected 16, got 8. font.c:8200: Test failed: Test 1: expected 16, got 4. font.c:8200: Test failed: Test 3: expected 16, got 8. font.c:8200: Test failed: Test 4: expected 16, got 8. font.c:8200: Test failed: Test 5: expected 16, got 8. font.c:8200: Test failed: Test 6: expected 16, got 8. font.c:8193: Test failed: Test 12: got 8. font.c:8193: Test failed: Test 13: got 8. font.c:8193: Test failed: Test 14: got 8. font.c:8193: Test failed: Test 15: got 8. font.c:8193: Test failed: Test 16: got 8.
=== w10pro64_ar (32 bit report) ===
gdi32: font.c:8200: Test failed: Test 3: expected 16, got 8. font.c:8200: Test failed: Test 4: expected 16, got 8. font.c:8200: Test failed: Test 5: expected 16, got 8. font.c:8200: Test failed: Test 6: expected 16, got 8. font.c:8221: Test failed: Got 0.
=== w10pro64_he (32 bit report) ===
gdi32: font.c:8202: Test failed: Test 2: expected 6, got 6. font.c:8221: Test failed: Got 0.
=== w10pro64_ja (32 bit report) ===
gdi32: font.c:8200: Test failed: Test 3: expected 16, got 8. font.c:8200: Test failed: Test 4: expected 16, got 8. font.c:8200: Test failed: Test 5: expected 16, got 8. font.c:8200: Test failed: Test 6: expected 16, got 8. font.c:8221: Test failed: Got 0.
=== w10pro64_zh_CN (32 bit report) ===
gdi32: font.c:8202: Test failed: Test 2: expected 8, got 8. font.c:8221: Test failed: Got 0.
=== w2008s64 (64 bit report) ===
gdi32: font.c:5282: Test failed: Character 2, expected order 2, got 1. font.c:5282: Test failed: Character 3, expected order 3, got 2. font.c:8200: Test failed: Test 0: expected 16, got 8. font.c:8200: Test failed: Test 1: expected 16, got 4. font.c:8200: Test failed: Test 3: expected 16, got 8. font.c:8200: Test failed: Test 4: expected 16, got 8. font.c:8200: Test failed: Test 5: expected 16, got 8. font.c:8200: Test failed: Test 6: expected 16, got 8. font.c:8193: Test failed: Test 12: got 8. font.c:8193: Test failed: Test 13: got 8. font.c:8193: Test failed: Test 14: got 8. font.c:8193: Test failed: Test 15: got 8. font.c:8193: Test failed: Test 16: got 8.
=== w864 (64 bit report) ===
gdi32: font.c:8200: Test failed: Test 0: expected 16, got 8. font.c:8200: Test failed: Test 1: expected 16, got 4. font.c:8200: Test failed: Test 3: expected 16, got 8. font.c:8200: Test failed: Test 4: expected 16, got 8. font.c:8200: Test failed: Test 5: expected 16, got 8. font.c:8200: Test failed: Test 6: expected 16, got 8. font.c:8193: Test failed: Test 12: got 8. font.c:8193: Test failed: Test 13: got 8. font.c:8193: Test failed: Test 14: got 8. font.c:8193: Test failed: Test 15: got 8. font.c:8193: Test failed: Test 16: got 8.
=== w10pro64_ar (64 bit report) ===
gdi32: font.c:8200: Test failed: Test 3: expected 16, got 8. font.c:8200: Test failed: Test 4: expected 16, got 8. font.c:8200: Test failed: Test 5: expected 16, got 8. font.c:8200: Test failed: Test 6: expected 16, got 8. font.c:8221: Test failed: Got 0.
=== w10pro64_he (64 bit report) ===
gdi32: font.c:8202: Test failed: Test 2: expected 6, got 6. font.c:8221: Test failed: Got 0.
=== w10pro64_ja (64 bit report) ===
gdi32: font.c:8200: Test failed: Test 3: expected 16, got 8. font.c:8200: Test failed: Test 4: expected 16, got 8. font.c:8200: Test failed: Test 5: expected 16, got 8. font.c:8200: Test failed: Test 6: expected 16, got 8. font.c:8221: Test failed: Got 0.
=== w10pro64_zh_CN (64 bit report) ===
gdi32: font.c:8202: Test failed: Test 2: expected 8, got 8. font.c:8221: Test failed: Got 0.