]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/layout/LookupProcessor.cpp
ICU-511.32.tar.gz
[apple/icu.git] / icuSources / layout / LookupProcessor.cpp
index 107fd496480a220f70a39f5cb07669ffccd1d923..03986bafbf6f75c70e01ece7e73a3611293637b8 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *
- * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
+ * (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
  *
  */
 
@@ -8,7 +8,7 @@
 #include "OpenTypeUtilities.h"
 #include "LEFontInstance.h"
 #include "OpenTypeTables.h"
-#include "Features.h"
+#include "ICUFeatures.h"
 #include "Lookups.h"
 #include "ScriptAndLanguage.h"
 #include "GlyphDefinitionTables.h"
 U_NAMESPACE_BEGIN
 
 le_uint32 LookupProcessor::applyLookupTable(const LookupTable *lookupTable, GlyphIterator *glyphIterator,
-                                         const LEFontInstance *fontInstance) const
+                                         const LEFontInstance *fontInstance, LEErrorCode& success) const
 {
+    if (LE_FAILURE(success)) {
+        return 0;
+    }
+
     le_uint16 lookupType = SWAPW(lookupTable->lookupType);
     le_uint16 subtableCount = SWAPW(lookupTable->subTableCount);
     le_int32 startPosition = glyphIterator->getCurrStreamPosition();
@@ -30,9 +34,9 @@ le_uint32 LookupProcessor::applyLookupTable(const LookupTable *lookupTable, Glyp
     for (le_uint16 subtable = 0; subtable < subtableCount; subtable += 1) {
         const LookupSubtable *lookupSubtable = lookupTable->getLookupSubtable(subtable);
 
-        delta = applySubtable(lookupSubtable, lookupType, glyphIterator, fontInstance);
+        delta = applySubtable(lookupSubtable, lookupType, glyphIterator, fontInstance, success);
 
-        if (delta > 0) {
+        if (delta > 0 && LE_FAILURE(success)) {
             return 1;
         }
 
@@ -44,8 +48,12 @@ le_uint32 LookupProcessor::applyLookupTable(const LookupTable *lookupTable, Glyp
 
 le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments,
                               le_bool rightToLeft, const GlyphDefinitionTableHeader *glyphDefinitionTableHeader,
-                              const LEFontInstance *fontInstance) const
+                              const LEFontInstance *fontInstance, LEErrorCode& success) const
 {
+    if (LE_FAILURE(success)) {
+        return 0;
+    }    
+       
     le_int32 glyphCount = glyphStorage.getGlyphCount();
 
     if (lookupSelectArray == NULL) {
@@ -62,15 +70,17 @@ le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdj
 
         if (selectMask != 0) {
             const LookupTable *lookupTable = lookupListTable->getLookupTable(lookup);
+            if (!lookupTable) {
+                continue;
+            }
             le_uint16 lookupFlags = SWAPW(lookupTable->lookupFlags);
             
             glyphIterator.reset(lookupFlags, selectMask);
 
             while (glyphIterator.findFeatureTag()) {
-                le_uint32 delta = 1;
-
-                while (glyphIterator.next(delta)) {
-                    delta = applyLookupTable(lookupTable, &glyphIterator, fontInstance);
+                applyLookupTable(lookupTable, &glyphIterator, fontInstance, success);
+                if (LE_FAILURE(success)) { 
+                    return 0;
                 }
             }
 
@@ -82,12 +92,20 @@ le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdj
 }
 
 le_uint32 LookupProcessor::applySingleLookup(le_uint16 lookupTableIndex, GlyphIterator *glyphIterator,
-                                          const LEFontInstance *fontInstance) const
+                                          const LEFontInstance *fontInstance, LEErrorCode& success) const
 {
+    if (LE_FAILURE(success)) {
+        return 0;
+    }    
+
     const LookupTable *lookupTable = lookupListTable->getLookupTable(lookupTableIndex);
+    if (lookupTable == NULL) {
+        success = LE_INTERNAL_ERROR;
+        return 0;
+    }
     le_uint16 lookupFlags = SWAPW(lookupTable->lookupFlags);
     GlyphIterator tempIterator(*glyphIterator, lookupFlags);
-    le_uint32 delta = applyLookupTable(lookupTable, &tempIterator, fontInstance);
+    le_uint32 delta = applyLookupTable(lookupTable, &tempIterator, fontInstance, success);
 
     return delta;
 }
@@ -99,6 +117,9 @@ le_int32 LookupProcessor::selectLookups(const FeatureTable *featureTable, Featur
 
     for (le_uint16 lookup = 0; lookup < lookupCount; lookup += 1) {
         le_uint16 lookupListIndex = SWAPW(featureTable->lookupListIndexArray[lookup]);
+       if (lookupListIndex >= lookupSelectCount) {
+           continue;
+        }
 
         lookupSelectArray[lookupListIndex] |= featureMask;
         lookupOrderArray[store++] = lookupListIndex;
@@ -109,8 +130,9 @@ le_int32 LookupProcessor::selectLookups(const FeatureTable *featureTable, Featur
 
 LookupProcessor::LookupProcessor(const char *baseAddress,
         Offset scriptListOffset, Offset featureListOffset, Offset lookupListOffset,
-        LETag scriptTag, LETag languageTag, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool orderFeatures)
-    : lookupListTable(NULL), featureListTable(NULL), lookupSelectArray(NULL),
+        LETag scriptTag, LETag languageTag, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool orderFeatures, 
+        LEErrorCode& success)
+    : lookupListTable(NULL), featureListTable(NULL), lookupSelectArray(NULL), lookupSelectCount(0),
       lookupOrderArray(NULL), lookupOrderCount(0)
 {
     const ScriptListTable *scriptListTable = NULL;
@@ -119,6 +141,10 @@ LookupProcessor::LookupProcessor(const char *baseAddress,
     le_uint16 lookupListCount = 0;
     le_uint16 requiredFeatureIndex;
 
+    if (LE_FAILURE(success)) {
+        return;
+    } 
+
     if (scriptListOffset != 0) {
         scriptListTable = (const ScriptListTable *) (baseAddress + scriptListOffset);
         langSysTable = scriptListTable->findLanguage(scriptTag, languageTag);
@@ -145,10 +171,15 @@ LookupProcessor::LookupProcessor(const char *baseAddress,
     requiredFeatureIndex = SWAPW(langSysTable->reqFeatureIndex);
 
     lookupSelectArray = LE_NEW_ARRAY(FeatureMask, lookupListCount);
+    if (lookupSelectArray == NULL) {
+        success = LE_MEMORY_ALLOCATION_ERROR;
+        return;
+    }
 
     for (int i = 0; i < lookupListCount; i += 1) {
         lookupSelectArray[i] = 0;
     }
+    lookupSelectCount = lookupListCount;
 
     le_int32 count, order = 0;
     le_int32 featureReferences = 0;
@@ -166,15 +197,27 @@ LookupProcessor::LookupProcessor(const char *baseAddress,
         le_uint16 featureIndex = SWAPW(langSysTable->featureIndexArray[feature]);
 
         featureTable = featureListTable->getFeatureTable(featureIndex, &featureTag);
+        if (!featureTable) {
+             continue;
+        }
         featureReferences += SWAPW(featureTable->lookupCount);
     }
 
+    if (!featureTable) {
+        success = LE_INTERNAL_ERROR;
+        return;
+    }
+
     if (requiredFeatureIndex != 0xFFFF) {
         requiredFeatureTable = featureListTable->getFeatureTable(requiredFeatureIndex, &requiredFeatureTag);
         featureReferences += SWAPW(featureTable->lookupCount);
     }
 
     lookupOrderArray = LE_NEW_ARRAY(le_uint16, featureReferences);
+    if (lookupOrderArray == NULL) {
+        success = LE_MEMORY_ALLOCATION_ERROR;
+        return;
+    }
 
     for (le_int32 f = 0; f < featureMapCount; f += 1) {
         FeatureMap fm = featureMap[f];
@@ -264,6 +307,8 @@ LookupProcessor::LookupProcessor(const char *baseAddress,
 
 LookupProcessor::LookupProcessor()
 {
+       lookupOrderArray = NULL;
+       lookupSelectArray = NULL;
 }
 
 LookupProcessor::~LookupProcessor()