Aric Stewart : usp10: Implement Contextual Positioning Subtable: Format 2.

Alexandre Julliard julliard at winehq.org
Wed Jan 25 13:18:53 CST 2017


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

Author: Aric Stewart <aric at codeweavers.com>
Date:   Wed Jan 25 07:16:29 2017 -0600

usp10: Implement Contextual Positioning Subtable: Format 2.

Used by the font Noto Nastaliq Urdu.

Signed-off-by: Aric Stewart <aric at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/usp10/opentype.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 128 insertions(+)

diff --git a/dlls/usp10/opentype.c b/dlls/usp10/opentype.c
index 29ec503..90df479 100644
--- a/dlls/usp10/opentype.c
+++ b/dlls/usp10/opentype.c
@@ -511,6 +511,29 @@ typedef struct {
 
 typedef struct {
     WORD PosFormat;
+    WORD Coverage;
+    WORD ClassDef;
+    WORD PosClassSetCnt;
+    WORD PosClassSet[1];
+} GPOS_ContextPosFormat2;
+
+typedef struct {
+    WORD PosClassRuleCnt;
+    WORD PosClassRule[1];
+} GPOS_PosClassSet;
+
+typedef struct {
+    WORD GlyphCount;
+    WORD PosCount;
+    WORD Class[1];
+} GPOS_PosClassRule_1;
+
+typedef struct {
+    GPOS_PosLookupRecord PosLookupRecord[1];
+} GPOS_PosClassRule_2;
+
+typedef struct {
+    WORD PosFormat;
     WORD BacktrackGlyphCount;
     WORD Coverage[1];
 } GPOS_ChainContextPosFormat3_1;
@@ -1869,6 +1892,109 @@ static BOOL GPOS_apply_MarkToMark(const OT_LookupTable *look, const SCRIPT_ANALY
     return rc;
 }
 
+static INT GPOS_apply_ContextPos(ScriptCache *psc, LPOUTLINETEXTMETRICW lpotm, LPLOGFONTW lplogfont, const SCRIPT_ANALYSIS *analysis, INT* piAdvance,
+                                      const OT_LookupList *lookup, const OT_LookupTable *look, const WORD *glyphs, INT glyph_index,
+                                      INT glyph_count, INT ppem, GOFFSET *pGoffset)
+{
+    int j;
+    int write_dir = (analysis->fRTL && !analysis->fLogicalOrder) ? -1 : 1;
+
+    TRACE("Contextual Positioning Subtable\n");
+
+    for (j = 0; j < GET_BE_WORD(look->SubTableCount); j++)
+    {
+        const GPOS_ContextPosFormat2 *cpf2 = (GPOS_ContextPosFormat2*)GPOS_get_subtable(look, j);
+
+        if (GET_BE_WORD(cpf2->PosFormat) == 1)
+        {
+            static int once;
+            if (!once++)
+                FIXME("  TODO: subtype 1\n");
+            continue;
+        }
+        else if (GET_BE_WORD(cpf2->PosFormat) == 2)
+        {
+            WORD offset = GET_BE_WORD(cpf2->Coverage);
+            int index;
+
+            TRACE("Contextual Positioning Subtable: Format 2\n");
+
+            index = GSUB_is_glyph_covered((const BYTE*)cpf2+offset, glyphs[glyph_index]);
+            TRACE("Coverage index %i\n",index);
+            if (index != -1)
+            {
+                int k, count, class;
+                const GPOS_PosClassSet *pcs;
+                const void *glyph_class_table = NULL;
+
+                offset = GET_BE_WORD(cpf2->ClassDef);
+                glyph_class_table = (const BYTE *)cpf2 + offset;
+
+                class = OT_get_glyph_class(glyph_class_table,glyphs[glyph_index]);
+
+                offset = GET_BE_WORD(cpf2->PosClassSet[class]);
+                if (offset == 0)
+                {
+                    TRACE("No class rule table for class %i\n",class);
+                    continue;
+                }
+                pcs = (const GPOS_PosClassSet*)((const BYTE*)cpf2+offset);
+                count = GET_BE_WORD(pcs->PosClassRuleCnt);
+                TRACE("PosClassSet has %i members\n",count);
+                for (k = 0; k < count; k++)
+                {
+                    const GPOS_PosClassRule_1 *pr;
+                    const GPOS_PosClassRule_2 *pr_2;
+                    int g_count, l;
+
+                    offset = GET_BE_WORD(pcs->PosClassRule[k]);
+                    pr = (const GPOS_PosClassRule_1*)((const BYTE*)pcs+offset);
+                    g_count = GET_BE_WORD(pr->GlyphCount);
+                    TRACE("PosClassRule has %i glyphs classes\n",g_count);
+                    for (l = 0; l < g_count-1; l++)
+                    {
+                        int g_class = OT_get_glyph_class(glyph_class_table, glyphs[glyph_index + (write_dir * (l+1))]);
+                        if (g_class != GET_BE_WORD(pr->Class[l])) break;
+                    }
+
+                    if (l < g_count-1)
+                    {
+                        TRACE("Rule does not match\n");
+                        continue;
+                    }
+
+                    TRACE("Rule matches\n");
+                    pr_2 = (const GPOS_PosClassRule_2*)((const BYTE*)pr+
+                        FIELD_OFFSET(GPOS_PosClassRule_1, Class[g_count-1]));
+
+                    for (l = 0; l < GET_BE_WORD(pr->PosCount); l++)
+                    {
+                        int lookupIndex = GET_BE_WORD(pr_2->PosLookupRecord[l].LookupListIndex);
+                        int SequenceIndex = GET_BE_WORD(pr_2->PosLookupRecord[l].SequenceIndex) * write_dir;
+
+                        TRACE("Position: %i -> %i %i\n",l, SequenceIndex, lookupIndex);
+                        GPOS_apply_lookup(psc, lpotm, lplogfont, analysis, piAdvance, lookup, lookupIndex, glyphs, glyph_index + SequenceIndex, glyph_count, pGoffset);
+                    }
+                    return glyph_index + 1;
+                }
+            }
+
+            TRACE("Not covered\n");
+            continue;
+        }
+        else if (GET_BE_WORD(cpf2->PosFormat) == 3)
+        {
+            static int once;
+            if (!once++)
+                FIXME("  TODO: subtype 3\n");
+            continue;
+        }
+        else
+            FIXME("Unhandled Contextual Positioning Format %i\n",GET_BE_WORD(cpf2->PosFormat));
+    }
+    return glyph_index + 1;
+}
+
 static INT GPOS_apply_ChainContextPos(ScriptCache *psc, LPOUTLINETEXTMETRICW lpotm, LPLOGFONTW lplogfont, const SCRIPT_ANALYSIS *analysis, INT* piAdvance,
                                       const OT_LookupList *lookup, const OT_LookupTable *look, const WORD *glyphs, INT glyph_index,
                                       INT glyph_count, INT ppem, GOFFSET *pGoffset)
@@ -2117,6 +2243,8 @@ static INT GPOS_apply_lookup(ScriptCache *psc, LPOUTLINETEXTMETRICW lpotm, LPLOG
             }
             break;
         }
+        case 7:
+            return GPOS_apply_ContextPos(psc, lpotm, lplogfont, analysis, piAdvance, lookup, look, glyphs, glyph_index, glyph_count, ppem, pGoffset);
         case 8:
         {
             return GPOS_apply_ChainContextPos(psc, lpotm, lplogfont, analysis, piAdvance, lookup, look, glyphs, glyph_index, glyph_count, ppem, pGoffset);




More information about the wine-cvs mailing list