Commit 4377cc62 authored by Aric Stewart's avatar Aric Stewart Committed by Alexandre Julliard

usp10: Implement mirroring for bidi support.

parent 6f3f505f
...@@ -582,12 +582,15 @@ static void test_ScriptGetCMap(HDC hdc, unsigned short pwOutGlyphs[256]) ...@@ -582,12 +582,15 @@ static void test_ScriptGetCMap(HDC hdc, unsigned short pwOutGlyphs[256])
SCRIPT_CACHE psc = NULL; SCRIPT_CACHE psc = NULL;
int cInChars; int cInChars;
int cChars; int cChars;
unsigned short pwOutGlyphs2[256];
unsigned short pwOutGlyphs3[256]; unsigned short pwOutGlyphs3[256];
DWORD dwFlags; DWORD dwFlags;
int cnt; int cnt;
static const WCHAR TestItem1[] = {'T', 'e', 's', 't', 'a', 0}; static const WCHAR TestItem1[] = {'T', 'e', 's', 't', 'a', 0};
static const WCHAR TestItem2[] = {0x202B, 'i', 'n', 0x202C,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 */ /* Check to make sure that SCRIPT_CACHE gets allocated ok */
dwFlags = 0; dwFlags = 0;
...@@ -640,6 +643,27 @@ static void test_ScriptGetCMap(HDC hdc, unsigned short pwOutGlyphs[256]) ...@@ -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[0] == 0, "Glyph 0 should be default glyph\n");
ok(pwOutGlyphs3[3] == 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); hr = ScriptFreeCache( &psc);
ok (!psc, "psc is not null after ScriptFreeCache\n"); ok (!psc, "psc is not null after ScriptFreeCache\n");
} }
......
...@@ -271,6 +271,12 @@ static HRESULT init_script_cache(const HDC hdc, SCRIPT_CACHE *psc) ...@@ -271,6 +271,12 @@ static HRESULT init_script_cache(const HDC hdc, SCRIPT_CACHE *psc)
return S_OK; 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 * DllMain
* *
...@@ -1392,13 +1398,18 @@ HRESULT WINAPI ScriptShape(HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcChars, ...@@ -1392,13 +1398,18 @@ HRESULT WINAPI ScriptShape(HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcChars,
for (i = 0; i < cChars; i++) for (i = 0; i < cChars; i++)
{ {
int idx = i; int idx = i;
WCHAR chInput;
if (rtl) idx = cChars - 1 - i; 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; WORD glyph;
if (!hdc) return E_PENDING; if (!hdc) return E_PENDING;
if (GetGlyphIndicesW(hdc, &pwcChars[idx], 1, &glyph, 0) == GDI_ERROR) return S_FALSE; if (GetGlyphIndicesW(hdc, &chInput, 1, &glyph, 0) == GDI_ERROR) return S_FALSE;
pwOutGlyphs[i] = set_cache_glyph(psc, pwcChars[idx], glyph); pwOutGlyphs[i] = set_cache_glyph(psc, chInput, glyph);
} }
} }
} }
...@@ -1408,6 +1419,7 @@ HRESULT WINAPI ScriptShape(HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcChars, ...@@ -1408,6 +1419,7 @@ HRESULT WINAPI ScriptShape(HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcChars,
for (i = 0; i < cChars; i++) for (i = 0; i < cChars; i++)
{ {
int idx = i; int idx = i;
/* No mirroring done here */
if (rtl) idx = cChars - 1 - i; if (rtl) idx = cChars - 1 - i;
pwOutGlyphs[i] = pwcChars[idx]; pwOutGlyphs[i] = pwcChars[idx];
} }
...@@ -1534,24 +1546,37 @@ HRESULT WINAPI ScriptGetCMap(HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcInChars ...@@ -1534,24 +1546,37 @@ HRESULT WINAPI ScriptGetCMap(HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcInChars
{ {
for (i = 0; i < cChars; i++) 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; WORD glyph;
if (!hdc) return E_PENDING; 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) if (glyph == 0xffff)
{ {
hr = S_FALSE; hr = S_FALSE;
glyph = 0x0; glyph = 0x0;
} }
pwOutGlyphs[i] = set_cache_glyph(psc, pwcInChars[i], glyph); pwOutGlyphs[i] = set_cache_glyph(psc, inChar, glyph);
} }
} }
} }
else else
{ {
TRACE("no glyph translation\n"); 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; return hr;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment