Commit 10e9adfb authored by Aric Stewart's avatar Aric Stewart Committed by Alexandre Julliard

usp10: Fix Contextual Shaping for Languages with RTL write order.

Including Arabic, Syriac, Phags pa, and Mongolian. Signed-off-by: 's avatarAric Stewart <aric@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent 915acd68
......@@ -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);
......
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