From 9c9513f94a632241ed7be0e9bd724696ed677d3c Mon Sep 17 00:00:00 2001 From: Aric Stewart Date: Mon, 14 Nov 2011 13:16:59 -0700 Subject: [PATCH] usp10: Break with a better understanding on the handling of bidi strengths. --- dlls/usp10/bidi.c | 10 ++++++--- dlls/usp10/usp10.c | 44 ++++++++++++++++++++++++++++++------- dlls/usp10/usp10_internal.h | 3 +++ 3 files changed, 46 insertions(+), 11 deletions(-) diff --git a/dlls/usp10/bidi.c b/dlls/usp10/bidi.c index 9c3942c0512..a2edfa6c730 100644 --- a/dlls/usp10/bidi.c +++ b/dlls/usp10/bidi.c @@ -901,7 +901,7 @@ BOOL BIDI_GetStrengths(LPCWSTR lpString, INT uCount, const SCRIPT_CONTROL *c, case AL: case RLE: case RLO: - lpStrength[i] = 1; + lpStrength[i] = BIDI_STRONG; break; case PDF: case EN: @@ -910,10 +910,14 @@ BOOL BIDI_GetStrengths(LPCWSTR lpString, INT uCount, const SCRIPT_CONTROL *c, case AN: case CS: case BN: - lpStrength[i] = 2; + lpStrength[i] = BIDI_WEAK; break; + case B: + case S: + case WS: + case ON: default: /* Neutrals and NSM */ - lpStrength[i] = 0; + lpStrength[i] = BIDI_NEUTRAL; } } return TRUE; diff --git a/dlls/usp10/usp10.c b/dlls/usp10/usp10.c index 4ac7b8f207b..0496a561ff9 100644 --- a/dlls/usp10/usp10.c +++ b/dlls/usp10/usp10.c @@ -805,6 +805,7 @@ HRESULT WINAPI ScriptItemizeOpenType(const WCHAR *pwcInChars, int cInChars, int WORD *levels = NULL; WORD *strength = NULL; WORD baselevel = 0; + BOOL new_run; TRACE("%s,%d,%d,%p,%p,%p,%p\n", debugstr_wn(pwcInChars, cInChars), cInChars, cMaxItems, psControl, psState, pItems, pcItems); @@ -876,10 +877,13 @@ HRESULT WINAPI ScriptItemizeOpenType(const WCHAR *pwcInChars, int cInChars, int pItems[index].a = scriptInformation[get_char_script(pwcInChars[cnt])].a; pScriptTags[index] = scriptInformation[get_char_script(pwcInChars[cnt])].scriptTag; - if (strength) + if (strength && strength[cnt] == BIDI_STRONG) str = strength[cnt]; + else if (strength) + str = strength[0]; cnt = 0; + if (levels) { pItems[index].a.fRTL = odd(levels[cnt]); @@ -899,9 +903,6 @@ HRESULT WINAPI ScriptItemizeOpenType(const WCHAR *pwcInChars, int cInChars, int for (cnt=1; cnt < cInChars; cnt++) { - if (levels && (levels[cnt] == pItems[index].a.s.uBidiLevel && (!strength || (strength[cnt] == 0 || strength[cnt] == str)))) - continue; - if(pwcInChars[cnt] != Numeric_space && pwcInChars[cnt] != ZWJ && pwcInChars[cnt] != ZWNJ) New_Script = get_char_script(pwcInChars[cnt]); else if (levels) @@ -915,17 +916,44 @@ HRESULT WINAPI ScriptItemizeOpenType(const WCHAR *pwcInChars, int cInChars, int New_Script = get_char_script(pwcInChars[cnt]); } - if ((levels && (levels[cnt] != pItems[index].a.s.uBidiLevel || (strength && (strength[cnt] != str)))) || (New_Script != -1 && New_Script != pItems[index].a.eScript) || New_Script == Script_Control) + new_run = FALSE; + /* merge space strengths*/ + if (strength && strength[cnt] == BIDI_STRONG && str != BIDI_STRONG && New_Script == pItems[index].a.eScript) + str = BIDI_STRONG; + + if (strength && strength[cnt] == BIDI_NEUTRAL && str == BIDI_STRONG && pwcInChars[cnt] != Numeric_space && New_Script == pItems[index].a.eScript) + str = BIDI_NEUTRAL; + + /* changes in level */ + if (levels && (levels[cnt] != pItems[index].a.s.uBidiLevel)) + { + TRACE("Level break(%i/%i)\n",pItems[index].a.s.uBidiLevel,levels[cnt]); + new_run = TRUE; + } + /* changes in strength */ + else if (strength && pwcInChars[cnt] != Numeric_space && str != strength[cnt]) + { + TRACE("Strength break (%i/%i)\n",str,strength[cnt]); + new_run = TRUE; + } + /* changes in script */ + else if ((!levels) && (((pwcInChars[cnt] != Numeric_space) && (New_Script != -1) && (New_Script != pItems[index].a.eScript)) || (New_Script == Script_Control))) + { + TRACE("Script break(%i/%i)\n",pItems[index].a.eScript,New_Script); + new_run = TRUE; + } + + if (new_run) { TRACE("New_Level = %i, New_Strength = %i, New_Script=%d, eScript=%d\n", levels?levels[cnt]:-1, strength?strength[cnt]:str, New_Script, pItems[index].a.eScript); - if (strength && strength[cnt] != 0) - str = strength[cnt]; - index++; if (index+1 > cMaxItems) return E_OUTOFMEMORY; + if (strength) + str = strength[cnt]; + pItems[index].iCharPos = cnt; memset(&pItems[index].a, 0, sizeof(SCRIPT_ANALYSIS)); diff --git a/dlls/usp10/usp10_internal.h b/dlls/usp10/usp10_internal.h index 7a88ac760ef..9f13b40c1aa 100644 --- a/dlls/usp10/usp10_internal.h +++ b/dlls/usp10/usp10_internal.h @@ -122,6 +122,9 @@ typedef int (*lexical_function)(WCHAR c); typedef void (*reorder_function)(LPWSTR pwChar, IndicSyllable *syllable, lexical_function lex); #define odd(x) ((x) & 1) +#define BIDI_STRONG 1 +#define BIDI_WEAK 2 +#define BIDI_NEUTRAL 0 BOOL BIDI_DetermineLevels( LPCWSTR lpString, INT uCount, const SCRIPT_STATE *s, const SCRIPT_CONTROL *c, WORD *lpOutLevels ) DECLSPEC_HIDDEN;