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