Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/usp10/tests/usp10.c | 62 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 56 insertions(+), 6 deletions(-)
diff --git a/dlls/usp10/tests/usp10.c b/dlls/usp10/tests/usp10.c index 8c4b125bae..e907c8c40a 100644 --- a/dlls/usp10/tests/usp10.c +++ b/dlls/usp10/tests/usp10.c @@ -3403,26 +3403,76 @@ static void test_ScriptGetGlyphABCWidth(HDC hdc) { HRESULT hr; SCRIPT_CACHE sc = NULL; - ABC abc; + HFONT hfont, prev_hfont; + TEXTMETRICA tm; + ABC abc, abc2; + LOGFONTA lf; + WORD glyph; + INT width; + DWORD ret;
- hr = ScriptGetGlyphABCWidth(NULL, NULL, 'a', NULL); + glyph = 0; + ret = GetGlyphIndicesA(hdc, "a", 1, &glyph, 0); + ok(ret == 1, "Failed to get glyph index.\n"); + ok(glyph != 0, "Unexpected glyph index.\n"); + + hr = ScriptGetGlyphABCWidth(NULL, NULL, glyph, NULL); ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", hr);
- hr = ScriptGetGlyphABCWidth(NULL, &sc, 'a', NULL); + hr = ScriptGetGlyphABCWidth(NULL, &sc, glyph, NULL); ok(broken(hr == E_PENDING) || hr == E_INVALIDARG, /* WIN7 */ "expected E_INVALIDARG, got 0x%08x\n", hr);
- hr = ScriptGetGlyphABCWidth(NULL, &sc, 'a', &abc); + hr = ScriptGetGlyphABCWidth(NULL, &sc, glyph, &abc); ok(hr == E_PENDING, "expected E_PENDING, got 0x%08x\n", hr);
if (0) { /* crashes on WinXP */ - hr = ScriptGetGlyphABCWidth(hdc, &sc, 'a', NULL); + hr = ScriptGetGlyphABCWidth(hdc, &sc, glyph, NULL); ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", hr); }
- hr = ScriptGetGlyphABCWidth(hdc, &sc, 'a', &abc); + hr = ScriptGetGlyphABCWidth(hdc, &sc, glyph, &abc); ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr); + ok(abc.abcB != 0, "Unexpected width.\n"); + + ret = GetCharABCWidthsI(hdc, glyph, 1, NULL, &abc2); + ok(ret, "Failed to get char width.\n"); + ok(!memcmp(&abc, &abc2, sizeof(abc)), "Unexpected width.\n"); + + ScriptFreeCache(&sc); + + /* Bitmap font */ + memset(&lf, 0, sizeof(lf)); + strcpy(lf.lfFaceName, "System"); + lf.lfHeight = 20; + + hfont = CreateFontIndirectA(&lf); + prev_hfont = SelectObject(hdc, hfont); + + ret = GetTextMetricsA(hdc, &tm); + ok(ret, "Failed to get text metrics.\n"); + ok(!(tm.tmPitchAndFamily & TMPF_TRUETYPE), "Unexpected TrueType font.\n"); + ok(tm.tmPitchAndFamily & TMPF_FIXED_PITCH, "Unexpected fixed pitch font.\n"); + + glyph = 0; + ret = GetGlyphIndicesA(hdc, "i", 1, &glyph, 0); + ok(ret == 1, "Failed to get glyph index.\n"); + ok(glyph != 0, "Unexpected glyph index.\n"); + + sc = NULL; + hr = ScriptGetGlyphABCWidth(hdc, &sc, glyph, &abc); + ok(hr == S_OK, "Failed to get glyph width, hr %#x.\n", hr); + ok(abc.abcB != 0, "Unexpected width.\n"); + + ret = GetCharWidthI(hdc, glyph, 1, NULL, &width); + ok(ret, "Failed to get char width.\n"); + abc2.abcA = abc2.abcC = 0; + abc2.abcB = width; + ok(!memcmp(&abc, &abc2, sizeof(abc)), "Unexpected width.\n"); + + SelectObject(hdc, prev_hfont); + DeleteObject(hfont);
ScriptFreeCache(&sc); }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/usp10/usp10.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/usp10/usp10.c b/dlls/usp10/usp10.c index 032d0745b0..c42b57dc5b 100644 --- a/dlls/usp10/usp10.c +++ b/dlls/usp10/usp10.c @@ -3715,7 +3715,7 @@ HRESULT WINAPI ScriptGetGlyphABCWidth(HDC hdc, SCRIPT_CACHE *psc, WORD glyph, AB else { INT width; - if (!GetCharWidth32W(hdc, glyph, glyph, &width)) return S_FALSE; + if (!GetCharWidthI(hdc, glyph, 1, NULL, &width)) return S_FALSE; abc->abcB = width; abc->abcA = abc->abcC = 0; }
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=44410 Signed-off-by: Nikolay Sivov nsivov@codeweavers.com ---
Fixes regression with corrupted cache data.
dlls/usp10/usp10.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-)
diff --git a/dlls/usp10/usp10.c b/dlls/usp10/usp10.c index c42b57dc5b..a05de9838f 100644 --- a/dlls/usp10/usp10.c +++ b/dlls/usp10/usp10.c @@ -3416,35 +3416,41 @@ HRESULT WINAPI ScriptPlaceOpenType( HDC hdc, SCRIPT_CACHE *psc, SCRIPT_ANALYSIS if (pABC) memset(pABC, 0, sizeof(ABC)); for (i = 0; i < cGlyphs; i++) { + WORD glyph; ABC abc; + + /* FIXME: set to more reasonable values */ + pGoffset[i].du = pGoffset[i].dv = 0; + if (pGlyphProps[i].sva.fZeroWidth) { abc.abcA = abc.abcB = abc.abcC = 0; + if (piAdvance) piAdvance[i] = 0; + continue; + } + + if (psa->fNoGlyphIndex) + { + if (FAILED(hr = ScriptGetCMap(hdc, psc, &pwGlyphs[i], 1, 0, &glyph))) return hr; } - else if (!get_cache_glyph_widths(psc, pwGlyphs[i], &abc)) + else + glyph = pwGlyphs[i]; + + if (!get_cache_glyph_widths(psc, glyph, &abc)) { - BOOL ret; if (!hdc) return E_PENDING; if (get_cache_pitch_family(psc) & TMPF_TRUETYPE) { - if (psa->fNoGlyphIndex) - ret = GetCharABCWidthsW(hdc, pwGlyphs[i], pwGlyphs[i], &abc); - else - ret = GetCharABCWidthsI(hdc, 0, 1, (WORD *)&pwGlyphs[i], &abc); - if (!ret) return S_FALSE; + if (!GetCharABCWidthsI(hdc, glyph, 1, NULL, &abc)) return S_FALSE; } else { INT width; - if (psa->fNoGlyphIndex) - ret = GetCharWidth32W(hdc, pwGlyphs[i], pwGlyphs[i], &width); - else - ret = GetCharWidthI(hdc, 0, 1, (WORD *)&pwGlyphs[i], &width); - if (!ret) return S_FALSE; + if (!GetCharWidthI(hdc, glyph, 1, NULL, &width)) return S_FALSE; abc.abcB = width; abc.abcA = abc.abcC = 0; } - set_cache_glyph_widths(psc, pwGlyphs[i], &abc); + set_cache_glyph_widths(psc, glyph, &abc); } if (pABC) { @@ -3452,8 +3458,6 @@ HRESULT WINAPI ScriptPlaceOpenType( HDC hdc, SCRIPT_CACHE *psc, SCRIPT_ANALYSIS pABC->abcB += abc.abcB; pABC->abcC += abc.abcC; } - /* FIXME: set to more reasonable values */ - pGoffset[i].du = pGoffset[i].dv = 0; if (piAdvance) piAdvance[i] = abc.abcA + abc.abcB + abc.abcC; }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/usp10/usp10.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/usp10/usp10.c b/dlls/usp10/usp10.c index a05de9838f..abc2605919 100644 --- a/dlls/usp10/usp10.c +++ b/dlls/usp10/usp10.c @@ -3712,7 +3712,7 @@ HRESULT WINAPI ScriptGetGlyphABCWidth(HDC hdc, SCRIPT_CACHE *psc, WORD glyph, AB if (!get_cache_glyph_widths(psc, glyph, abc)) { if (!hdc) return E_PENDING; - if ((get_cache_pitch_family(psc) & TMPF_TRUETYPE)) + if (get_cache_pitch_family(psc) & TMPF_TRUETYPE) { if (!GetCharABCWidthsI(hdc, 0, 1, &glyph, abc)) return S_FALSE; }