Aric Stewart : usp10: Apply the GSUB 'rlig' feature for Required ligature substitution.

Alexandre Julliard julliard at winehq.org
Mon May 24 11:30:48 CDT 2010


Module: wine
Branch: master
Commit: 18b310a70373fe3c92195a03de82677a90a3f68d
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=18b310a70373fe3c92195a03de82677a90a3f68d

Author: Aric Stewart <aric at codeweavers.com>
Date:   Fri May 21 15:12:28 2010 -0500

usp10: Apply the GSUB 'rlig' feature for Required ligature substitution.

---

 dlls/usp10/shape.c |   43 +++++++++++++++++++++++++++++++------------
 1 files changed, 31 insertions(+), 12 deletions(-)

diff --git a/dlls/usp10/shape.c b/dlls/usp10/shape.c
index 85fbb64..d7e9811 100644
--- a/dlls/usp10/shape.c
+++ b/dlls/usp10/shape.c
@@ -70,6 +70,8 @@ enum joined_forms {
               (ULONG)_x1         )
 
 #define GSUB_TAG MS_MAKE_TAG('G', 'S', 'U', 'B')
+#define GSUB_E_NOFEATURE -2
+#define GSUB_E_NOGLYPH -1
 
 typedef struct {
     DWORD version;
@@ -348,7 +350,7 @@ static INT GSUB_apply_SingleSubst(const GSUB_LookupTable *look, WORD *glyphs, IN
             }
         }
     }
-    return -1;
+    return GSUB_E_NOGLYPH;
 }
 
 static INT GSUB_apply_LigatureSubst(const GSUB_LookupTable *look, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count)
@@ -413,7 +415,7 @@ static INT GSUB_apply_LigatureSubst(const GSUB_LookupTable *look, WORD *glyphs,
             }
         }
     }
-    return -1;
+    return GSUB_E_NOGLYPH;
 }
 
 static INT GSUB_apply_lookup(const GSUB_LookupList* lookup, INT lookup_index, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count)
@@ -433,13 +435,13 @@ static INT GSUB_apply_lookup(const GSUB_LookupList* lookup, INT lookup_index, WO
         default:
             FIXME("We do not handle SubType %i\n",GET_BE_WORD(look->LookupType));
     }
-    return -1;
+    return GSUB_E_NOGLYPH;
 }
 
 static INT GSUB_apply_feature(const GSUB_Header * header, const GSUB_Feature* feature, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count)
 {
     int i;
-    int out_index = -1;
+    int out_index = GSUB_E_NOGLYPH;
     const GSUB_LookupList *lookup;
 
     lookup = (const GSUB_LookupList*)((const BYTE*)header + GET_BE_WORD(header->LookupList));
@@ -448,10 +450,10 @@ static INT GSUB_apply_feature(const GSUB_Header * header, const GSUB_Feature* fe
     for (i = 0; i < GET_BE_WORD(feature->LookupCount); i++)
     {
         out_index = GSUB_apply_lookup(lookup, GET_BE_WORD(feature->LookupListIndex[i]), glyphs, glyph_index, write_dir, glyph_count);
-        if (out_index != -1)
+        if (out_index != GSUB_E_NOGLYPH)
             break;
     }
-    if (out_index == -1)
+    if (out_index == GSUB_E_NOGLYPH)
         TRACE("lookups found no glyphs\n");
     return out_index;
 }
@@ -508,7 +510,7 @@ static INT apply_GSUB_feature_to_glyph(HDC hdc, SCRIPT_ANALYSIS *psa, void* GSUB
     const GSUB_Feature *feature;
 
     if (!GSUB_Table)
-        return -1;
+        return GSUB_E_NOFEATURE;
 
     header = GSUB_Table;
 
@@ -516,19 +518,19 @@ static INT apply_GSUB_feature_to_glyph(HDC hdc, SCRIPT_ANALYSIS *psa, void* GSUB
     if (!script)
     {
         TRACE("Script not found\n");
-        return -1;
+        return GSUB_E_NOFEATURE;
     }
     language = GSUB_get_lang_table(script, "xxxx"); /* Need to get Lang tag */
     if (!language)
     {
         TRACE("Language not found\n");
-        return -1;
+        return GSUB_E_NOFEATURE;
     }
     feature  =  GSUB_get_feature(header, language, feat);
     if (!feature)
     {
         TRACE("%s feature not found\n",feat);
-        return -1;
+        return GSUB_E_NOFEATURE;
     }
     TRACE("applying feature %s\n",feat);
     return GSUB_apply_feature(header, feature, glyphs, index, write_dir, glyph_count);
@@ -647,9 +649,9 @@ void SHAPE_ShapeArabicGlyphs(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, WC
         {
             INT nextIndex;
             nextIndex = apply_GSUB_feature_to_glyph(hdc, psa, psc->GSUB_Table, pwOutGlyphs, i, dirL, pcGlyphs, contextual_features[context_shape[i]]);
-            if (nextIndex != -1)
+            if (nextIndex > GSUB_E_NOGLYPH)
                 i = nextIndex;
-            shaped = (nextIndex != -1);
+            shaped = (nextIndex > GSUB_E_NOGLYPH);
         }
 
         if (!shaped)
@@ -666,6 +668,23 @@ void SHAPE_ShapeArabicGlyphs(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, WC
         }
     }
 
+    /* Required ligature substitution */
+    if (psc->GSUB_Table)
+    {
+        i = 0;
+        while(i < *pcGlyphs)
+        {
+                INT nextIndex;
+                nextIndex = apply_GSUB_feature_to_glyph(hdc, psa, psc->GSUB_Table, pwOutGlyphs, i, dirL, pcGlyphs, "rlig");
+                if (nextIndex > GSUB_E_NOGLYPH)
+                    i = nextIndex;
+                else if (nextIndex == GSUB_E_NOFEATURE)
+                    break;
+                else
+                    i++;
+        }
+    }
+
     HeapFree(GetProcessHeap(),0,context_shape);
     HeapFree(GetProcessHeap(),0,context_type);
 }




More information about the wine-cvs mailing list