jdk/src/share/native/sun/font/layout/LookupProcessor.cpp
changeset 16891 91e99bed64ae
parent 16890 36b30720a997
child 18219 d4cd832b9802
equal deleted inserted replaced
16890:36b30720a997 16891:91e99bed64ae
    42 #include "LEGlyphStorage.h"
    42 #include "LEGlyphStorage.h"
    43 #include "LESwaps.h"
    43 #include "LESwaps.h"
    44 
    44 
    45 U_NAMESPACE_BEGIN
    45 U_NAMESPACE_BEGIN
    46 
    46 
    47 le_uint32 LookupProcessor::applyLookupTable(const LookupTable *lookupTable, GlyphIterator *glyphIterator,
    47 le_uint32 LookupProcessor::applyLookupTable(const LEReferenceTo<LookupTable> &lookupTable, GlyphIterator *glyphIterator,
    48                                          const LEFontInstance *fontInstance, LEErrorCode& success) const
    48                                          const LEFontInstance *fontInstance, LEErrorCode& success) const
    49 {
    49 {
    50     if (LE_FAILURE(success)) {
    50     if (LE_FAILURE(success)) {
    51         return 0;
    51         return 0;
    52     }
    52     }
    55     le_uint16 subtableCount = SWAPW(lookupTable->subTableCount);
    55     le_uint16 subtableCount = SWAPW(lookupTable->subTableCount);
    56     le_int32 startPosition = glyphIterator->getCurrStreamPosition();
    56     le_int32 startPosition = glyphIterator->getCurrStreamPosition();
    57     le_uint32 delta;
    57     le_uint32 delta;
    58 
    58 
    59     for (le_uint16 subtable = 0; subtable < subtableCount; subtable += 1) {
    59     for (le_uint16 subtable = 0; subtable < subtableCount; subtable += 1) {
    60         const LookupSubtable *lookupSubtable = lookupTable->getLookupSubtable(subtable);
    60       LEReferenceTo<LookupSubtable> lookupSubtable = lookupTable->getLookupSubtable(lookupTable, subtable, success);
    61 
    61 
    62         delta = applySubtable(lookupSubtable, lookupType, glyphIterator, fontInstance, success);
    62         delta = applySubtable(lookupSubtable, lookupType, glyphIterator, fontInstance, success);
    63 
    63 
    64         if (delta > 0 && LE_FAILURE(success)) {
    64         if (delta > 0 && LE_FAILURE(success)) {
    65             return 1;
    65             return 1;
    70 
    70 
    71     return 1;
    71     return 1;
    72 }
    72 }
    73 
    73 
    74 le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments,
    74 le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments,
    75                               le_bool rightToLeft, const GlyphDefinitionTableHeader *glyphDefinitionTableHeader,
    75                                   le_bool rightToLeft, const LEReferenceTo<GlyphDefinitionTableHeader> &glyphDefinitionTableHeader,
    76                               const LEFontInstance *fontInstance, LEErrorCode& success) const
    76                               const LEFontInstance *fontInstance, LEErrorCode& success) const
    77 {
    77 {
    78     if (LE_FAILURE(success)) {
    78     if (LE_FAILURE(success)) {
    79         return 0;
    79         return 0;
    80     }
    80     }
    87 
    87 
    88     GlyphIterator glyphIterator(glyphStorage, glyphPositionAdjustments,
    88     GlyphIterator glyphIterator(glyphStorage, glyphPositionAdjustments,
    89                                 rightToLeft, 0, 0, glyphDefinitionTableHeader);
    89                                 rightToLeft, 0, 0, glyphDefinitionTableHeader);
    90     le_int32 newGlyphCount = glyphCount;
    90     le_int32 newGlyphCount = glyphCount;
    91 
    91 
    92     for (le_uint16 order = 0; order < lookupOrderCount; order += 1) {
    92     for (le_uint16 order = 0; order < lookupOrderCount && LE_SUCCESS(success); order += 1) {
    93         le_uint16 lookup = lookupOrderArray[order];
    93         le_uint16 lookup = lookupOrderArray[order];
    94         FeatureMask selectMask = lookupSelectArray[lookup];
    94         FeatureMask selectMask = lookupSelectArray[lookup];
    95 
    95 
    96         if (selectMask != 0) {
    96         if (selectMask != 0) {
    97             const LookupTable *lookupTable = lookupListTable->getLookupTable(lookup);
    97           const LEReferenceTo<LookupTable> lookupTable = lookupListTable->getLookupTable(lookupListTable, lookup, success);
    98             if (!lookupTable) {
    98           if (!lookupTable.isValid() ||LE_FAILURE(success) ) {
    99                 continue;
    99                 continue;
   100             }
   100             }
   101             le_uint16 lookupFlags = SWAPW(lookupTable->lookupFlags);
   101             le_uint16 lookupFlags = SWAPW(lookupTable->lookupFlags);
   102 
   102 
   103             glyphIterator.reset(lookupFlags, selectMask);
   103             glyphIterator.reset(lookupFlags, selectMask);
   104 
   104 
   105             while (glyphIterator.findFeatureTag()) {
   105             while (glyphIterator.findFeatureTag()) {
   106                 applyLookupTable(lookupTable, &glyphIterator, fontInstance, success);
   106               applyLookupTable(lookupTable, &glyphIterator, fontInstance, success); // TODO
   107                 if (LE_FAILURE(success)) {
   107                 if (LE_FAILURE(success)) {
   108                     return 0;
   108                     return 0;
   109                 }
   109                 }
   110             }
   110             }
   111 
   111 
   121 {
   121 {
   122     if (LE_FAILURE(success)) {
   122     if (LE_FAILURE(success)) {
   123         return 0;
   123         return 0;
   124     }
   124     }
   125 
   125 
   126     const LookupTable *lookupTable = lookupListTable->getLookupTable(lookupTableIndex);
   126     const LEReferenceTo<LookupTable> lookupTable = lookupListTable->getLookupTable(lookupListTable, lookupTableIndex, success);
   127     if (lookupTable == NULL) {
   127     if (!lookupTable.isValid()) {
   128         success = LE_INTERNAL_ERROR;
   128         success = LE_INTERNAL_ERROR;
   129         return 0;
   129         return 0;
   130     }
   130     }
   131     le_uint16 lookupFlags = SWAPW(lookupTable->lookupFlags);
   131     le_uint16 lookupFlags = SWAPW(lookupTable->lookupFlags);
   132     GlyphIterator tempIterator(*glyphIterator, lookupFlags);
   132     GlyphIterator tempIterator(*glyphIterator, lookupFlags);
   133     le_uint32 delta = applyLookupTable(lookupTable, &tempIterator, fontInstance, success);
   133     le_uint32 delta = applyLookupTable(lookupTable, &tempIterator, fontInstance, success);
   134 
   134 
   135     return delta;
   135     return delta;
   136 }
   136 }
   137 
   137 
   138 le_int32 LookupProcessor::selectLookups(const FeatureTable *featureTable, FeatureMask featureMask, le_int32 order)
   138 le_int32 LookupProcessor::selectLookups(const LEReferenceTo<FeatureTable> &featureTable, FeatureMask featureMask, le_int32 order, LEErrorCode &success)
   139 {
   139 {
   140     le_uint16 lookupCount = featureTable? SWAPW(featureTable->lookupCount) : 0;
   140   le_uint16 lookupCount = featureTable.isValid()? SWAPW(featureTable->lookupCount) : 0;
   141     le_int32  store = order;
   141     le_int32  store = order;
   142 
   142 
   143     for (le_uint16 lookup = 0; lookup < lookupCount; lookup += 1) {
   143     LEReferenceToArrayOf<le_uint16> lookupListIndexArray(featureTable, success, featureTable->lookupListIndexArray, lookupCount);
   144         le_uint16 lookupListIndex = SWAPW(featureTable->lookupListIndexArray[lookup]);
   144 
   145         if (lookupListIndex >= lookupSelectCount) {
   145     for (le_uint16 lookup = 0; LE_SUCCESS(success) && lookup < lookupCount; lookup += 1) {
   146             continue;
   146       le_uint16 lookupListIndex = SWAPW(lookupListIndexArray.getObject(lookup,success));
   147         }
   147       if (lookupListIndex >= lookupSelectCount) {
   148 
   148         continue;
   149         lookupSelectArray[lookupListIndex] |= featureMask;
   149       }
   150         lookupOrderArray[store++] = lookupListIndex;
   150 
       
   151       lookupSelectArray[lookupListIndex] |= featureMask;
       
   152       lookupOrderArray[store++] = lookupListIndex;
   151     }
   153     }
   152 
   154 
   153     return store - order;
   155     return store - order;
   154 }
   156 }
   155 
   157 
   156 LookupProcessor::LookupProcessor(const char *baseAddress,
   158 LookupProcessor::LookupProcessor(const LETableReference &baseAddress,
   157         Offset scriptListOffset, Offset featureListOffset, Offset lookupListOffset,
   159         Offset scriptListOffset, Offset featureListOffset, Offset lookupListOffset,
   158         LETag scriptTag, LETag languageTag, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool orderFeatures,
   160         LETag scriptTag, LETag languageTag, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool orderFeatures,
   159         LEErrorCode& success)
   161         LEErrorCode& success)
   160     : lookupListTable(NULL), featureListTable(NULL), lookupSelectArray(NULL), lookupSelectCount(0),
   162     : lookupListTable(), featureListTable(), lookupSelectArray(NULL), lookupSelectCount(0),
   161       lookupOrderArray(NULL), lookupOrderCount(0)
   163       lookupOrderArray(NULL), lookupOrderCount(0), fReference(baseAddress)
   162 {
   164 {
   163     const ScriptListTable *scriptListTable = NULL;
   165   LEReferenceTo<ScriptListTable> scriptListTable;
   164     const LangSysTable *langSysTable = NULL;
   166   LEReferenceTo<LangSysTable> langSysTable;
   165     le_uint16 featureCount = 0;
   167     le_uint16 featureCount = 0;
   166     le_uint16 lookupListCount = 0;
   168     le_uint16 lookupListCount = 0;
   167     le_uint16 requiredFeatureIndex;
   169     le_uint16 requiredFeatureIndex;
   168 
   170 
   169     if (LE_FAILURE(success)) {
   171     if (LE_FAILURE(success)) {
   170         return;
   172         return;
   171     }
   173     }
   172 
   174 
   173     if (scriptListOffset != 0) {
   175     if (scriptListOffset != 0) {
   174         scriptListTable = (const ScriptListTable *) (baseAddress + scriptListOffset);
   176       scriptListTable = LEReferenceTo<ScriptListTable>(baseAddress, success, scriptListOffset);
   175         langSysTable = scriptListTable->findLanguage(scriptTag, languageTag);
   177       langSysTable = scriptListTable->findLanguage(scriptListTable, scriptTag, languageTag, success);
   176 
   178 
   177         if (langSysTable != 0) {
   179       if (langSysTable.isValid() && LE_SUCCESS(success)) {
   178             featureCount = SWAPW(langSysTable->featureCount);
   180         featureCount = SWAPW(langSysTable->featureCount);
   179         }
   181       }
   180     }
   182     }
   181 
   183 
   182     if (featureListOffset != 0) {
   184     if (featureListOffset != 0) {
   183         featureListTable = (const FeatureListTable *) (baseAddress + featureListOffset);
   185       featureListTable = LEReferenceTo<FeatureListTable>(baseAddress, success, featureListOffset);
   184     }
   186     }
   185 
   187 
   186     if (lookupListOffset != 0) {
   188     if (lookupListOffset != 0) {
   187         lookupListTable = (const LookupListTable *) (baseAddress + lookupListOffset);
   189       lookupListTable = LEReferenceTo<LookupListTable>(baseAddress,success, lookupListOffset);
       
   190       if(LE_SUCCESS(success) && lookupListTable.isValid()) {
   188         lookupListCount = SWAPW(lookupListTable->lookupCount);
   191         lookupListCount = SWAPW(lookupListTable->lookupCount);
   189     }
   192       }
   190 
   193     }
   191     if (langSysTable == NULL || featureListTable == NULL || lookupListTable == NULL ||
   194 
       
   195     if (langSysTable.isEmpty() || featureListTable.isEmpty() || lookupListTable.isEmpty() ||
   192         featureCount == 0 || lookupListCount == 0) {
   196         featureCount == 0 || lookupListCount == 0) {
   193         return;
   197         return;
   194     }
   198     }
   195 
   199 
   196     requiredFeatureIndex = SWAPW(langSysTable->reqFeatureIndex);
   200     if(langSysTable.isValid()) {
       
   201       requiredFeatureIndex = SWAPW(langSysTable->reqFeatureIndex);
       
   202     }
   197 
   203 
   198     lookupSelectArray = LE_NEW_ARRAY(FeatureMask, lookupListCount);
   204     lookupSelectArray = LE_NEW_ARRAY(FeatureMask, lookupListCount);
   199     if (lookupSelectArray == NULL) {
   205     if (lookupSelectArray == NULL) {
   200         success = LE_MEMORY_ALLOCATION_ERROR;
   206         success = LE_MEMORY_ALLOCATION_ERROR;
   201         return;
   207         return;
   207 
   213 
   208     lookupSelectCount = lookupListCount;
   214     lookupSelectCount = lookupListCount;
   209 
   215 
   210     le_int32 count, order = 0;
   216     le_int32 count, order = 0;
   211     le_uint32 featureReferences = 0;
   217     le_uint32 featureReferences = 0;
   212     const FeatureTable *featureTable = NULL;
   218     LEReferenceTo<FeatureTable> featureTable;
   213     LETag featureTag;
   219     LETag featureTag;
   214 
   220 
   215     const FeatureTable *requiredFeatureTable = NULL;
   221     LEReferenceTo<FeatureTable> requiredFeatureTable;
   216     LETag requiredFeatureTag = 0x00000000U;
   222     LETag requiredFeatureTag = 0x00000000U;
   217 
   223 
   218     // Count the total number of lookups referenced by all features. This will
   224     // Count the total number of lookups referenced by all features. This will
   219     // be the maximum number of entries in the lookupOrderArray. We can't use
   225     // be the maximum number of entries in the lookupOrderArray. We can't use
   220     // lookupListCount because some lookups might be referenced by more than
   226     // lookupListCount because some lookups might be referenced by more than
   221     // one feature.
   227     // one feature.
   222     for (le_uint32 feature = 0; feature < featureCount; feature += 1) {
   228     if(featureListTable.isValid() && LE_SUCCESS(success)) {
   223         le_uint16 featureIndex = SWAPW(langSysTable->featureIndexArray[feature]);
   229       LEReferenceToArrayOf<le_uint16> featureIndexArray(langSysTable, success, langSysTable->featureIndexArray, featureCount);
   224 
   230 
   225         featureTable = featureListTable->getFeatureTable(featureIndex, &featureTag);
   231       for (le_uint32 feature = 0; LE_SUCCESS(success)&&(feature < featureCount); feature += 1) {
   226         if (!featureTable) {
   232         le_uint16 featureIndex = SWAPW(featureIndexArray.getObject(feature, success));
   227              continue;
   233 
       
   234         featureTable = featureListTable->getFeatureTable(featureListTable, featureIndex,  &featureTag, success);
       
   235         if (!featureTable.isValid() || LE_FAILURE(success)) {
       
   236           continue;
   228         }
   237         }
   229         featureReferences += SWAPW(featureTable->lookupCount);
   238         featureReferences += SWAPW(featureTable->lookupCount);
   230     }
   239       }
   231 
   240     }
   232     if (!featureTable) {
   241 
       
   242     if (!featureTable.isValid() || LE_FAILURE(success)) {
   233         success = LE_INTERNAL_ERROR;
   243         success = LE_INTERNAL_ERROR;
   234         return;
   244         return;
   235     }
   245     }
   236 
   246 
   237     if (requiredFeatureIndex != 0xFFFF) {
   247     if (requiredFeatureIndex != 0xFFFF) {
   238         requiredFeatureTable = featureListTable->getFeatureTable(requiredFeatureIndex, &requiredFeatureTag);
   248       requiredFeatureTable = featureListTable->getFeatureTable(featureListTable, requiredFeatureIndex, &requiredFeatureTag, success);
   239         featureReferences += SWAPW(featureTable->lookupCount);
   249       featureReferences += SWAPW(featureTable->lookupCount);
   240     }
   250     }
   241 
   251 
   242     lookupOrderArray = LE_NEW_ARRAY(le_uint16, featureReferences);
   252     lookupOrderArray = LE_NEW_ARRAY(le_uint16, featureReferences);
   243     if (lookupOrderArray == NULL) {
   253     if (lookupOrderArray == NULL) {
   244         success = LE_MEMORY_ALLOCATION_ERROR;
   254         success = LE_MEMORY_ALLOCATION_ERROR;
   249         FeatureMap fm = featureMap[f];
   259         FeatureMap fm = featureMap[f];
   250         count = 0;
   260         count = 0;
   251 
   261 
   252         // If this is the required feature, add its lookups
   262         // If this is the required feature, add its lookups
   253         if (requiredFeatureTag == fm.tag) {
   263         if (requiredFeatureTag == fm.tag) {
   254             count += selectLookups(requiredFeatureTable, fm.mask, order);
   264           count += selectLookups(requiredFeatureTable, fm.mask, order, success);
   255         }
   265         }
   256 
   266 
   257         if (orderFeatures) {
   267         if (orderFeatures) {
   258             // If we added lookups from the required feature, sort them
   268             // If we added lookups from the required feature, sort them
   259             if (count > 1) {
   269             if (count > 1) {
   260                 OpenTypeUtilities::sort(lookupOrderArray, order);
   270                 OpenTypeUtilities::sort(lookupOrderArray, order);
   261             }
   271             }
   262 
   272 
   263             for (le_uint16 feature = 0; feature < featureCount; feature += 1) {
   273             for (le_uint16 feature = 0; feature < featureCount; feature += 1) {
   264                 le_uint16 featureIndex = SWAPW(langSysTable->featureIndexArray[feature]);
   274               LEReferenceToArrayOf<le_uint16> featureIndexArray(langSysTable, success, langSysTable->featureIndexArray, featureCount);
       
   275               le_uint16 featureIndex = SWAPW(featureIndexArray.getObject(feature,success));
   265 
   276 
   266                 // don't add the required feature to the list more than once...
   277                 // don't add the required feature to the list more than once...
   267                 // TODO: Do we need this check? (Spec. says required feature won't be in feature list...)
   278                 // TODO: Do we need this check? (Spec. says required feature won't be in feature list...)
   268                 if (featureIndex == requiredFeatureIndex) {
   279                 if (featureIndex == requiredFeatureIndex) {
   269                     continue;
   280                     continue;
   270                 }
   281                 }
   271 
   282 
   272                 featureTable = featureListTable->getFeatureTable(featureIndex, &featureTag);
   283                 featureTable = featureListTable->getFeatureTable(featureListTable, featureIndex, &featureTag, success);
   273 
   284 
   274                 if (featureTag == fm.tag) {
   285                 if (featureTag == fm.tag) {
   275                     count += selectLookups(featureTable, fm.mask, order + count);
   286                   count += selectLookups(featureTable, fm.mask, order + count, success);
   276                 }
   287                 }
   277             }
   288             }
   278 
   289 
   279             if (count > 1) {
   290             if (count > 1) {
   280                 OpenTypeUtilities::sort(&lookupOrderArray[order], count);
   291                 OpenTypeUtilities::sort(&lookupOrderArray[order], count);
   281             }
   292             }
   282 
   293 
   283             order += count;
   294             order += count;
   284         } else {
   295         } else if(langSysTable.isValid()) {
   285             for (le_uint16 feature = 0; feature < featureCount; feature += 1) {
   296           LEReferenceToArrayOf<le_uint16> featureIndexArray(langSysTable, success, langSysTable->featureIndexArray, featureCount);
   286                 le_uint16 featureIndex = SWAPW(langSysTable->featureIndexArray[feature]);
   297           for (le_uint16 feature = 0; LE_SUCCESS(success)&& (feature < featureCount); feature += 1) {
       
   298             le_uint16 featureIndex = SWAPW(featureIndexArray.getObject(feature,success));
   287 
   299 
   288                 // don't add the required feature to the list more than once...
   300                 // don't add the required feature to the list more than once...
   289                 // NOTE: This check is commented out because the spec. says that
   301                 // NOTE: This check is commented out because the spec. says that
   290                 // the required feature won't be in the feature list, and because
   302                 // the required feature won't be in the feature list, and because
   291                 // any duplicate entries will be removed below.
   303                 // any duplicate entries will be removed below.
   293                 if (featureIndex == requiredFeatureIndex) {
   305                 if (featureIndex == requiredFeatureIndex) {
   294                     continue;
   306                     continue;
   295                 }
   307                 }
   296 #endif
   308 #endif
   297 
   309 
   298                 featureTable = featureListTable->getFeatureTable(featureIndex, &featureTag);
   310                 featureTable = featureListTable->getFeatureTable(featureListTable, featureIndex, &featureTag, success);
   299 
   311 
   300                 if (featureTag == fm.tag) {
   312                 if (featureTag == fm.tag) {
   301                     order += selectLookups(featureTable, fm.mask, order);
   313                   order += selectLookups(featureTable, fm.mask, order, success);
   302                 }
   314                 }
   303             }
   315             }
   304         }
   316         }
   305     }
   317     }
   306 
   318