]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/layout/MultipleSubstSubtables.cpp
ICU-62141.0.1.tar.gz
[apple/icu.git] / icuSources / layout / MultipleSubstSubtables.cpp
index 65b0c6104358e248ea823207c90c75e85de543fe..4fdc0a4dc72d9f6cdb35cef74e42eab44069a314 100644 (file)
@@ -1,7 +1,6 @@
 /*
- * %W% %E%
  *
- * (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1998-2015 - All Rights Reserved
  *
  */
 
 
 U_NAMESPACE_BEGIN
 
-le_uint32 MultipleSubstitutionSubtable::process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter) const
+le_uint32 MultipleSubstitutionSubtable::process(const LETableReference &base, GlyphIterator *glyphIterator, LEErrorCode& success, const LEGlyphFilter *filter) const
 {
+    if (LE_FAILURE(success)) {
+        return 0;
+    }
+
     LEGlyphID glyph = glyphIterator->getCurrGlyphID();
-    le_int32 coverageIndex = getGlyphCoverage(glyph);
+
+    // If there's a filter, we only want to do the
+    // substitution if the *input* glyphs doesn't
+    // exist.
+    //
+    // FIXME: is this always the right thing to do?
+    // FIXME: should this only be done for a non-zero
+    //        glyphCount?
+    if (filter != NULL && filter->accept(glyph)) {
+        return 0;
+    }
+
+    le_int32 coverageIndex = getGlyphCoverage(base, glyph, success);
     le_uint16 seqCount = SWAPW(sequenceCount);
+    LEReferenceToArrayOf<Offset>
+        sequenceTableOffsetArrayRef(base, success, sequenceTableOffsetArray, seqCount);
 
+    if (LE_FAILURE(success)) {
+        return 0;
+    }
     if (coverageIndex >= 0 && coverageIndex < seqCount) {
         Offset sequenceTableOffset = SWAPW(sequenceTableOffsetArray[coverageIndex]);
         const SequenceTable *sequenceTable = (const SequenceTable *) ((char *) this + sequenceTableOffset);
@@ -29,17 +49,47 @@ le_uint32 MultipleSubstitutionSubtable::process(GlyphIterator *glyphIterator, co
         if (glyphCount == 0) {
             glyphIterator->setCurrGlyphID(0xFFFF);
             return 1;
-        } else if (glyphCount >= 1) {
+        } else if (glyphCount == 1) {
             TTGlyphID substitute = SWAPW(sequenceTable->substituteArray[0]);
 
-            if (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, substitute))) {
-                glyphIterator->setCurrGlyphID(substitute);
+            if (filter != NULL && ! filter->accept(LE_SET_GLYPH(glyph, substitute))) {
+                return 0;
             }
 
+            glyphIterator->setCurrGlyphID(substitute);
             return 1;
         } else {
-            // Can't do this 'till there's a way to
-            // grow the glyph array...
+            // If there's a filter, make sure all of the output glyphs
+            // exist.
+            if (filter != NULL) {
+                for (le_int32 i = 0; i < glyphCount; i += 1) {
+                    TTGlyphID substitute = SWAPW(sequenceTable->substituteArray[i]);
+
+                    if (! filter->accept(substitute)) {
+                        return 0;
+                    }
+                }
+            }
+
+            LEGlyphID *newGlyphs = glyphIterator->insertGlyphs(glyphCount, success);
+            if (LE_FAILURE(success)) { 
+                return 0;
+            }
+
+            le_int32 insert = 0, direction = 1;
+
+            if (glyphIterator->isRightToLeft()) {
+                insert = glyphCount - 1;
+                direction = -1;
+            }
+
+            for (le_int32 i = 0; i < glyphCount; i += 1) {
+                TTGlyphID substitute = SWAPW(sequenceTable->substituteArray[i]);
+
+                newGlyphs[insert] = LE_SET_GLYPH(glyph, substitute);
+                insert += direction;
+            }
+
             return 1;
         }
     }