usp10: Fix Contextual Shaping for Languages with RTL write order.
Including Arabic, Syriac, Phags pa, and Mongolian. Signed-off-by: Aric Stewart <aric@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
915acd68de
commit
10e9adfb27
|
@ -1072,6 +1072,8 @@ static void ContextualShape_Arabic(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *p
|
|||
INT *context_shape;
|
||||
INT dirR, dirL;
|
||||
int i;
|
||||
int char_index;
|
||||
int glyph_index;
|
||||
|
||||
if (*pcGlyphs != cChars)
|
||||
{
|
||||
|
@ -1115,8 +1117,12 @@ static void ContextualShape_Arabic(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *p
|
|||
}
|
||||
|
||||
/* Contextual Shaping */
|
||||
i = 0;
|
||||
while(i < *pcGlyphs)
|
||||
if (dirL > 0)
|
||||
char_index = glyph_index = 0;
|
||||
else
|
||||
char_index = glyph_index = cChars-1;
|
||||
|
||||
while(char_index < cChars && char_index >= 0)
|
||||
{
|
||||
BOOL shaped = FALSE;
|
||||
|
||||
|
@ -1124,29 +1130,34 @@ static void ContextualShape_Arabic(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *p
|
|||
{
|
||||
INT nextIndex;
|
||||
INT prevCount = *pcGlyphs;
|
||||
nextIndex = apply_GSUB_feature_to_glyph(hdc, psa, psc, pwOutGlyphs, i, dirL, pcGlyphs, contextual_features[context_shape[i]]);
|
||||
|
||||
/* Apply the contextual feature */
|
||||
nextIndex = apply_GSUB_feature_to_glyph(hdc, psa, psc, pwOutGlyphs, glyph_index, dirL, pcGlyphs, contextual_features[context_shape[char_index]]);
|
||||
|
||||
if (nextIndex > GSUB_E_NOGLYPH)
|
||||
{
|
||||
i = nextIndex;
|
||||
UpdateClusters(nextIndex, *pcGlyphs - prevCount, dirL, cChars, pwLogClust);
|
||||
UpdateClusters(glyph_index, *pcGlyphs - prevCount, dirL, cChars, pwLogClust);
|
||||
char_index += dirL;
|
||||
glyph_index = nextIndex;
|
||||
}
|
||||
shaped = (nextIndex > GSUB_E_NOGLYPH);
|
||||
}
|
||||
|
||||
if (!shaped)
|
||||
{
|
||||
if (context_shape[i] == Xn)
|
||||
if (context_shape[char_index] == Xn)
|
||||
{
|
||||
WORD newGlyph = pwOutGlyphs[i];
|
||||
if (pwcChars[i] >= FIRST_ARABIC_CHAR && pwcChars[i] <= LAST_ARABIC_CHAR)
|
||||
WORD newGlyph = pwOutGlyphs[glyph_index];
|
||||
if (pwcChars[char_index] >= FIRST_ARABIC_CHAR && pwcChars[char_index] <= LAST_ARABIC_CHAR)
|
||||
{
|
||||
/* fall back to presentation form B */
|
||||
WCHAR context_char = wine_shaping_forms[pwcChars[i] - FIRST_ARABIC_CHAR][context_shape[i]];
|
||||
if (context_char != pwcChars[i] && GetGlyphIndicesW(hdc, &context_char, 1, &newGlyph, 0) != GDI_ERROR && newGlyph != 0x0000)
|
||||
pwOutGlyphs[i] = newGlyph;
|
||||
WCHAR context_char = wine_shaping_forms[pwcChars[char_index] - FIRST_ARABIC_CHAR][context_shape[char_index]];
|
||||
if (context_char != pwcChars[char_index] && GetGlyphIndicesW(hdc, &context_char, 1, &newGlyph, 0) != GDI_ERROR && newGlyph != 0x0000)
|
||||
pwOutGlyphs[glyph_index] = newGlyph;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
char_index += dirL;
|
||||
glyph_index += dirL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1293,6 +1304,8 @@ static void ContextualShape_Syriac(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *p
|
|||
INT *context_shape;
|
||||
INT dirR, dirL;
|
||||
int i;
|
||||
int char_index;
|
||||
int glyph_index;
|
||||
|
||||
if (*pcGlyphs != cChars)
|
||||
{
|
||||
|
@ -1355,19 +1368,45 @@ right_join_causing(neighbour_joining_type(i,dirR,context_type,cChars,psa)))
|
|||
}
|
||||
|
||||
/* Contextual Shaping */
|
||||
i = 0;
|
||||
while(i < *pcGlyphs)
|
||||
if (dirL > 0)
|
||||
char_index = glyph_index = 0;
|
||||
else
|
||||
char_index = glyph_index = cChars-1;
|
||||
|
||||
while(char_index < cChars && char_index >= 0)
|
||||
{
|
||||
INT nextIndex;
|
||||
INT nextIndex, offset = 0;
|
||||
INT prevCount = *pcGlyphs;
|
||||
nextIndex = apply_GSUB_feature_to_glyph(hdc, psa, psc, pwOutGlyphs, i, dirL, pcGlyphs, contextual_features[context_shape[i]]);
|
||||
|
||||
/* Apply CCMP first */
|
||||
apply_GSUB_feature_to_glyph(hdc, psa, psc, pwOutGlyphs, glyph_index, dirL, pcGlyphs, "ccmp");
|
||||
|
||||
if (prevCount != *pcGlyphs)
|
||||
{
|
||||
offset = *pcGlyphs - prevCount;
|
||||
if (dirL < 0)
|
||||
glyph_index -= offset * dirL;
|
||||
}
|
||||
|
||||
/* Apply the contextual feature */
|
||||
nextIndex = apply_GSUB_feature_to_glyph(hdc, psa, psc, pwOutGlyphs, glyph_index, dirL, pcGlyphs, contextual_features[context_shape[char_index]]);
|
||||
if (nextIndex > GSUB_E_NOGLYPH)
|
||||
{
|
||||
UpdateClusters(nextIndex, *pcGlyphs - prevCount, dirL, cChars, pwLogClust);
|
||||
i = nextIndex;
|
||||
char_index += dirL;
|
||||
if (!offset)
|
||||
glyph_index = nextIndex;
|
||||
else
|
||||
{
|
||||
offset = *pcGlyphs - prevCount;
|
||||
glyph_index += dirL * (offset + 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
i++;
|
||||
{
|
||||
char_index += dirL;
|
||||
glyph_index += dirL;
|
||||
}
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(),0,context_shape);
|
||||
|
@ -1427,6 +1466,8 @@ static void ContextualShape_Phags_pa(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS
|
|||
INT *context_shape;
|
||||
INT dirR, dirL;
|
||||
int i;
|
||||
int char_index;
|
||||
int glyph_index;
|
||||
|
||||
if (*pcGlyphs != cChars)
|
||||
{
|
||||
|
@ -1475,24 +1516,36 @@ static void ContextualShape_Phags_pa(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS
|
|||
}
|
||||
|
||||
/* Contextual Shaping */
|
||||
i = 0;
|
||||
while(i < *pcGlyphs)
|
||||
if (dirL > 0)
|
||||
char_index = glyph_index = 0;
|
||||
else
|
||||
char_index = glyph_index = cChars-1;
|
||||
|
||||
while(char_index < cChars && char_index >= 0)
|
||||
{
|
||||
if (context_shape[i] >= 0)
|
||||
if (context_shape[char_index] >= 0)
|
||||
{
|
||||
INT nextIndex;
|
||||
INT prevCount = *pcGlyphs;
|
||||
nextIndex = apply_GSUB_feature_to_glyph(hdc, psa, psc, pwOutGlyphs, i, dirL, pcGlyphs, contextual_features[context_shape[i]]);
|
||||
nextIndex = apply_GSUB_feature_to_glyph(hdc, psa, psc, pwOutGlyphs, glyph_index, dirL, pcGlyphs, contextual_features[context_shape[char_index]]);
|
||||
|
||||
if (nextIndex > GSUB_E_NOGLYPH)
|
||||
{
|
||||
UpdateClusters(nextIndex, *pcGlyphs - prevCount, dirL, cChars, pwLogClust);
|
||||
i = nextIndex;
|
||||
glyph_index = nextIndex;
|
||||
char_index += dirL;
|
||||
}
|
||||
else
|
||||
i++;
|
||||
{
|
||||
char_index += dirL;
|
||||
glyph_index += dirL;
|
||||
}
|
||||
}
|
||||
else
|
||||
i++;
|
||||
{
|
||||
char_index += dirL;
|
||||
glyph_index += dirL;
|
||||
}
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(),0,context_shape);
|
||||
|
@ -2769,6 +2822,8 @@ static void ContextualShape_Mongolian(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS
|
|||
INT *context_shape;
|
||||
INT dirL;
|
||||
int i;
|
||||
int char_index;
|
||||
int glyph_index;
|
||||
|
||||
if (*pcGlyphs != cChars)
|
||||
{
|
||||
|
@ -2805,19 +2860,28 @@ static void ContextualShape_Mongolian(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS
|
|||
}
|
||||
|
||||
/* Contextual Shaping */
|
||||
i = 0;
|
||||
while(i < *pcGlyphs)
|
||||
if (dirL > 0)
|
||||
char_index = glyph_index = 0;
|
||||
else
|
||||
char_index = glyph_index = cChars-1;
|
||||
|
||||
while(char_index < cChars && char_index >= 0)
|
||||
{
|
||||
INT nextIndex;
|
||||
INT prevCount = *pcGlyphs;
|
||||
nextIndex = apply_GSUB_feature_to_glyph(hdc, psa, psc, pwOutGlyphs, i, dirL, pcGlyphs, contextual_features[context_shape[i]]);
|
||||
nextIndex = apply_GSUB_feature_to_glyph(hdc, psa, psc, pwOutGlyphs, glyph_index, dirL, pcGlyphs, contextual_features[context_shape[char_index]]);
|
||||
|
||||
if (nextIndex > GSUB_E_NOGLYPH)
|
||||
{
|
||||
UpdateClusters(nextIndex, *pcGlyphs - prevCount, dirL, cChars, pwLogClust);
|
||||
i = nextIndex;
|
||||
glyph_index = nextIndex;
|
||||
char_index += dirL;
|
||||
}
|
||||
else
|
||||
i++;
|
||||
{
|
||||
char_index += dirL;
|
||||
glyph_index += dirL;
|
||||
}
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(),0,context_shape);
|
||||
|
|
Loading…
Reference in New Issue