Aric Stewart : usp10: Insert dotted circle (U+25CC) for invalid combining sequences in Arabic.
Alexandre Julliard
julliard at winehq.org
Fri Jun 1 13:25:59 CDT 2012
Module: wine
Branch: master
Commit: a2c1bd1ff51aad5c0169e47355cd5d995170d230
URL: http://source.winehq.org/git/wine.git/?a=commit;h=a2c1bd1ff51aad5c0169e47355cd5d995170d230
Author: Aric Stewart <aric at codeweavers.com>
Date: Fri Jun 1 10:22:38 2012 -0500
usp10: Insert dotted circle (U+25CC) for invalid combining sequences in Arabic.
---
dlls/usp10/shape.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 88 insertions(+), 0 deletions(-)
diff --git a/dlls/usp10/shape.c b/dlls/usp10/shape.c
index d582fc7..84953fb 100644
--- a/dlls/usp10/shape.c
+++ b/dlls/usp10/shape.c
@@ -114,6 +114,8 @@ typedef struct tagConsonantComponents
typedef void (*second_reorder_function)(LPWSTR pwChar, IndicSyllable *syllable,WORD* pwGlyphs, IndicSyllable* glyph_index, lexical_function lex);
+typedef int (*combining_lexical_function)(WCHAR c);
+
/* the orders of joined_forms and contextual_features need to line up */
static const char* contextual_features[] =
{
@@ -784,6 +786,45 @@ static inline BOOL get_GSUB_Indic2(SCRIPT_ANALYSIS *psa, ScriptCache *psc)
return(SUCCEEDED(hr));
}
+static void insert_glyph(WORD *pwGlyphs, INT *pcGlyphs, INT cChars, INT write_dir, WORD glyph, INT index, WORD *pwLogClust)
+{
+ int i;
+ for (i = *pcGlyphs; i>=index; i--)
+ pwGlyphs[i+1] = pwGlyphs[i];
+ pwGlyphs[index] = glyph;
+ *pcGlyphs = *pcGlyphs+1;
+ if (write_dir < 0)
+ UpdateClusters(index-3, 1, write_dir, cChars, pwLogClust);
+ else
+ UpdateClusters(index, 1, write_dir, cChars, pwLogClust);
+}
+
+static void mark_invalid_combinations(HDC hdc, const WCHAR* pwcChars, INT cChars, WORD *pwGlyphs, INT *pcGlyphs, INT write_dir, WORD *pwLogClust, combining_lexical_function lex)
+{
+ CHAR *context_type;
+ int i,g;
+ WCHAR invalid = 0x25cc;
+ WORD invalid_glyph;
+
+ context_type = HeapAlloc(GetProcessHeap(),0,cChars);
+
+ /* Mark invalid combinations */
+ for (i = 0; i < cChars; i++)
+ context_type[i] = lex(pwcChars[i]);
+
+ GetGlyphIndicesW(hdc, &invalid, 1, &invalid_glyph, 0);
+ for (i = 1, g=1; i < cChars; i++, g++)
+ {
+ if (context_type[i] != 0 && context_type[i+write_dir]==context_type[i])
+ {
+ insert_glyph(pwGlyphs, pcGlyphs, cChars, write_dir, invalid_glyph, g, pwLogClust);
+ g++;
+ }
+ }
+
+ HeapFree(GetProcessHeap(),0,context_type);
+}
+
static WCHAR neighbour_char(int i, int delta, const WCHAR* chars, INT cchLen)
{
if (i + delta < 0)
@@ -839,6 +880,51 @@ static inline BOOL word_break_causing(WCHAR chr)
return (chr == 0 || chr == 0x20 );
}
+static int combining_lexical_Arabic(WCHAR c)
+{
+ enum {Arab_Norm = 0, Arab_DIAC1, Arab_DIAC2, Arab_DIAC3, Arab_DIAC4, Arab_DIAC5, Arab_DIAC6, Arab_DIAC7, Arab_DIAC8};
+
+ switch(c)
+ {
+ case 0x064B:
+ case 0x064C:
+ case 0x064E:
+ case 0x064F:
+ case 0x0652:
+ case 0x0657:
+ case 0x0658:
+ case 0x06E1: return Arab_DIAC1; break;
+ case 0x064D:
+ case 0x0650:
+ case 0x0656: return Arab_DIAC2; break;
+ case 0x0651: return Arab_DIAC3; break;
+ case 0x0610:
+ case 0x0611:
+ case 0x0612:
+ case 0x0613:
+ case 0x0614:
+ case 0x0659:
+ case 0x06D6:
+ case 0x06DC:
+ case 0x06DF:
+ case 0x06E0:
+ case 0x06E2:
+ case 0x06E4:
+ case 0x06E7:
+ case 0x06E8:
+ case 0x06EB:
+ case 0x06EC: return Arab_DIAC4; break;
+ case 0x06E3:
+ case 0x06EA:
+ case 0x06ED: return Arab_DIAC5; break;
+ case 0x0670: return Arab_DIAC6; break;
+ case 0x0653: return Arab_DIAC7; break;
+ case 0x0655:
+ case 0x0654: return Arab_DIAC8; break;
+ default: return Arab_Norm;
+ }
+}
+
/*
* ContextualShape_Arabic
*/
@@ -929,6 +1015,8 @@ static void ContextualShape_Arabic(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *p
HeapFree(GetProcessHeap(),0,context_shape);
HeapFree(GetProcessHeap(),0,context_type);
+
+ mark_invalid_combinations(hdc, pwcChars, cChars, pwOutGlyphs, pcGlyphs, dirL, pwLogClust, combining_lexical_Arabic);
}
/*
More information about the wine-cvs
mailing list