Module: wine Branch: master Commit: 4377cc62f849dbee52ddea1ba3e556ca6bba4938 URL: http://source.winehq.org/git/wine.git/?a=commit;h=4377cc62f849dbee52ddea1ba3...
Author: Aric Stewart aric@codeweavers.com Date: Thu May 6 08:28:57 2010 -0500
usp10: Implement mirroring for bidi support.
---
dlls/usp10/tests/usp10.c | 24 ++++++++++++++++++++++++ dlls/usp10/usp10.c | 39 ++++++++++++++++++++++++++++++++------- 2 files changed, 56 insertions(+), 7 deletions(-)
diff --git a/dlls/usp10/tests/usp10.c b/dlls/usp10/tests/usp10.c index f76f95c..2d7641d 100644 --- a/dlls/usp10/tests/usp10.c +++ b/dlls/usp10/tests/usp10.c @@ -582,12 +582,15 @@ static void test_ScriptGetCMap(HDC hdc, unsigned short pwOutGlyphs[256]) SCRIPT_CACHE psc = NULL; int cInChars; int cChars; + unsigned short pwOutGlyphs2[256]; unsigned short pwOutGlyphs3[256]; DWORD dwFlags; int cnt;
static const WCHAR TestItem1[] = {'T', 'e', 's', 't', 'a', 0}; static const WCHAR TestItem2[] = {0x202B, 'i', 'n', 0x202C,0}; + static const WCHAR TestItem3[] = {'a','b','c','d','(','<','{','[',0x2039,0}; + static const WCHAR TestItem3b[] = {'a','b','c','d',')','>','}',']',0x203A,0};
/* Check to make sure that SCRIPT_CACHE gets allocated ok */ dwFlags = 0; @@ -640,6 +643,27 @@ static void test_ScriptGetCMap(HDC hdc, unsigned short pwOutGlyphs[256]) ok(pwOutGlyphs3[0] == 0, "Glyph 0 should be default glyph\n"); ok(pwOutGlyphs3[3] == 0, "Glyph 0 should be default glyph\n");
+ + cInChars = cChars = 9; + hr = ScriptGetCMap(hdc, &psc, TestItem3b, cInChars, dwFlags, pwOutGlyphs2); + ok (hr == S_OK, "ScriptGetCMap should return S_OK not (%08x)\n", hr); + ok (psc != NULL, "psc should not be null and have SCRIPT_CACHE buffer address\n"); + + cInChars = cChars = 9; + dwFlags = SGCM_RTL; + hr = ScriptGetCMap(hdc, &psc, TestItem3, cInChars, dwFlags, pwOutGlyphs3); + ok (hr == S_OK, "ScriptGetCMap should return S_OK not (%08x)\n", hr); + ok (psc != NULL, "psc should not be null and have SCRIPT_CACHE buffer address\n"); + ok(pwOutGlyphs3[0] == pwOutGlyphs2[0], "glyph incorrectly altered\n"); + ok(pwOutGlyphs3[1] == pwOutGlyphs2[1], "glyph incorreclty altered\n"); + ok(pwOutGlyphs3[2] == pwOutGlyphs2[2], "glyph incorreclty altered\n"); + ok(pwOutGlyphs3[3] == pwOutGlyphs2[3], "glyph incorreclty altered\n"); + ok(pwOutGlyphs3[4] == pwOutGlyphs2[4], "glyph not mirrored correctly\n"); + ok(pwOutGlyphs3[5] == pwOutGlyphs2[5], "glyph not mirrored correctly\n"); + ok(pwOutGlyphs3[6] == pwOutGlyphs2[6], "glyph not mirrored correctly\n"); + ok(pwOutGlyphs3[7] == pwOutGlyphs2[7], "glyph not mirrored correctly\n"); + ok(pwOutGlyphs3[8] == pwOutGlyphs2[8], "glyph not mirrored correctly\n"); + hr = ScriptFreeCache( &psc); ok (!psc, "psc is not null after ScriptFreeCache\n"); } diff --git a/dlls/usp10/usp10.c b/dlls/usp10/usp10.c index 3a7fcd1..43a3b5e 100644 --- a/dlls/usp10/usp10.c +++ b/dlls/usp10/usp10.c @@ -271,6 +271,12 @@ static HRESULT init_script_cache(const HDC hdc, SCRIPT_CACHE *psc) return S_OK; }
+static WCHAR mirror_char( WCHAR ch ) +{ + extern const WCHAR wine_mirror_map[]; + return ch + wine_mirror_map[wine_mirror_map[ch >> 8] + (ch & 0xff)]; +} + /*********************************************************************** * DllMain * @@ -1392,13 +1398,18 @@ HRESULT WINAPI ScriptShape(HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcChars, for (i = 0; i < cChars; i++) { int idx = i; + WCHAR chInput; if (rtl) idx = cChars - 1 - i; - if (!(pwOutGlyphs[i] = get_cache_glyph(psc, pwcChars[idx]))) + if (psa->fRTL) + chInput = mirror_char(pwcChars[idx]); + else + chInput = pwcChars[idx]; + if (!(pwOutGlyphs[i] = get_cache_glyph(psc, chInput))) { WORD glyph; if (!hdc) return E_PENDING; - if (GetGlyphIndicesW(hdc, &pwcChars[idx], 1, &glyph, 0) == GDI_ERROR) return S_FALSE; - pwOutGlyphs[i] = set_cache_glyph(psc, pwcChars[idx], glyph); + if (GetGlyphIndicesW(hdc, &chInput, 1, &glyph, 0) == GDI_ERROR) return S_FALSE; + pwOutGlyphs[i] = set_cache_glyph(psc, chInput, glyph); } } } @@ -1408,6 +1419,7 @@ HRESULT WINAPI ScriptShape(HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcChars, for (i = 0; i < cChars; i++) { int idx = i; + /* No mirroring done here */ if (rtl) idx = cChars - 1 - i; pwOutGlyphs[i] = pwcChars[idx]; } @@ -1534,24 +1546,37 @@ HRESULT WINAPI ScriptGetCMap(HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcInChars { for (i = 0; i < cChars; i++) { - if (!(pwOutGlyphs[i] = get_cache_glyph(psc, pwcInChars[i]))) + WCHAR inChar; + if (dwFlags == SGCM_RTL) + inChar = mirror_char(pwcInChars[i]); + else + inChar = pwcInChars[i]; + if (!(pwOutGlyphs[i] = get_cache_glyph(psc, inChar))) { WORD glyph; if (!hdc) return E_PENDING; - if (GetGlyphIndicesW(hdc, &pwcInChars[i], 1, &glyph, GGI_MARK_NONEXISTING_GLYPHS) == GDI_ERROR) return S_FALSE; + if (GetGlyphIndicesW(hdc, &inChar, 1, &glyph, GGI_MARK_NONEXISTING_GLYPHS) == GDI_ERROR) return S_FALSE; if (glyph == 0xffff) { hr = S_FALSE; glyph = 0x0; } - pwOutGlyphs[i] = set_cache_glyph(psc, pwcInChars[i], glyph); + pwOutGlyphs[i] = set_cache_glyph(psc, inChar, glyph); } } } else { TRACE("no glyph translation\n"); - for (i = 0; i < cChars; i++) pwOutGlyphs[i] = pwcInChars[i]; + for (i = 0; i < cChars; i++) + { + WCHAR inChar; + if (dwFlags == SGCM_RTL) + inChar = mirror_char(pwcInChars[i]); + else + inChar = pwcInChars[i]; + pwOutGlyphs[i] = inChar; + } } return hr; }