jdk/src/share/native/sun/font/layout/MorphTables2.cpp
changeset 16891 91e99bed64ae
parent 16889 3df90f344221
equal deleted inserted replaced
16890:36b30720a997 16891:91e99bed64ae
    40 #include "LEGlyphStorage.h"
    40 #include "LEGlyphStorage.h"
    41 #include "LESwaps.h"
    41 #include "LESwaps.h"
    42 
    42 
    43 U_NAMESPACE_BEGIN
    43 U_NAMESPACE_BEGIN
    44 
    44 
    45 void MorphTableHeader2::process(LEGlyphStorage &glyphStorage, le_int32 typoFlags) const
    45 void MorphTableHeader2::process(const LEReferenceTo<MorphTableHeader2> &base, LEGlyphStorage &glyphStorage,
       
    46                                 le_int32 typoFlags, LEErrorCode &success) const
    46 {
    47 {
    47     const ChainHeader2 *chainHeader = chains;
    48   if(LE_FAILURE(success)) return;
    48     le_uint32 chainCount = SWAPL(this->nChains);
    49 
    49     le_uint32 chain;
    50   le_uint32 chainCount = SWAPL(this->nChains);
    50 
    51   LEReferenceTo<ChainHeader2> chainHeader(base, success, &chains[0]);
    51     for (chain = 0; chain < chainCount; chain++) {
    52   /* chainHeader and subtableHeader are implemented as a moving pointer rather than an array dereference
       
    53    * to (slightly) reduce code churn. However, must be careful to preincrement them the 2nd time through.
       
    54    * We don't want to increment them at the end of the loop, as that would attempt to dereference
       
    55    * out of range memory.
       
    56    */
       
    57   le_uint32 chain;
       
    58 
       
    59   for (chain = 0; LE_SUCCESS(success) && (chain < chainCount); chain++) {
       
    60         if (chain>0) {
       
    61           le_uint32 chainLength = SWAPL(chainHeader->chainLength);
       
    62           chainHeader.addOffset(chainLength, success); // Don't increment the first time
       
    63         }
    52         FeatureFlags flag = SWAPL(chainHeader->defaultFlags);
    64         FeatureFlags flag = SWAPL(chainHeader->defaultFlags);
    53         le_uint32 chainLength = SWAPL(chainHeader->chainLength);
       
    54         le_uint32 nFeatureEntries = SWAPL(chainHeader->nFeatureEntries);
    65         le_uint32 nFeatureEntries = SWAPL(chainHeader->nFeatureEntries);
    55         le_uint32 nSubtables = SWAPL(chainHeader->nSubtables);
    66         le_uint32 nSubtables = SWAPL(chainHeader->nSubtables);
    56         const MorphSubtableHeader2 *subtableHeader =
    67         LEReferenceTo<MorphSubtableHeader2> subtableHeader(chainHeader,
    57             (const MorphSubtableHeader2 *)&chainHeader->featureTable[nFeatureEntries];
    68               success, (const MorphSubtableHeader2 *)&chainHeader->featureTable[nFeatureEntries]);
    58         le_uint32 subtable;
    69         le_uint32 subtable;
       
    70         if(LE_FAILURE(success)) break; // malformed table
    59 
    71 
    60         if (typoFlags != 0) {
    72         if (typoFlags != 0) {
    61            le_uint32 featureEntry;
    73            le_uint32 featureEntry;
    62 
    74            LEReferenceToArrayOf<FeatureTableEntry> featureTableRef(chainHeader, success, &chainHeader->featureTable[0], nFeatureEntries);
       
    75            if(LE_FAILURE(success)) break;
    63             // Feature subtables
    76             // Feature subtables
    64             for (featureEntry = 0; featureEntry < nFeatureEntries; featureEntry++) {
    77             for (featureEntry = 0; featureEntry < nFeatureEntries; featureEntry++) {
    65                 FeatureTableEntry featureTableEntry = chains->featureTable[featureEntry];
    78                 const FeatureTableEntry &featureTableEntry = featureTableRef(featureEntry, success);
    66                 le_int16 featureType = SWAPW(featureTableEntry.featureType);
    79                 le_int16 featureType = SWAPW(featureTableEntry.featureType);
    67                 le_int16 featureSetting = SWAPW(featureTableEntry.featureSetting);
    80                 le_int16 featureSetting = SWAPW(featureTableEntry.featureSetting);
    68                 le_uint32 enableFlags = SWAPL(featureTableEntry.enableFlags);
    81                 le_uint32 enableFlags = SWAPL(featureTableEntry.enableFlags);
    69                 le_uint32 disableFlags = SWAPL(featureTableEntry.disableFlags);
    82                 le_uint32 disableFlags = SWAPL(featureTableEntry.disableFlags);
    70                 switch (featureType) {
    83                 switch (featureType) {
   170                         break;
   183                         break;
   171                 }
   184                 }
   172             }
   185             }
   173         }
   186         }
   174 
   187 
   175         for (subtable = 0; subtable < nSubtables; subtable++) {
   188         for (subtable = 0;  LE_SUCCESS(success) && subtable < nSubtables; subtable++) {
   176             le_uint32 length = SWAPL(subtableHeader->length);
   189             if(subtable>0)  {
       
   190               le_uint32 length = SWAPL(subtableHeader->length);
       
   191               subtableHeader.addOffset(length, success); // Don't addOffset for the last entry.
       
   192             }
   177             le_uint32 coverage = SWAPL(subtableHeader->coverage);
   193             le_uint32 coverage = SWAPL(subtableHeader->coverage);
   178             FeatureFlags subtableFeatures = SWAPL(subtableHeader->subtableFeatures);
   194             FeatureFlags subtableFeatures = SWAPL(subtableHeader->subtableFeatures);
   179             // should check coverage more carefully...
   195             // should check coverage more carefully...
   180             if (((coverage & scfIgnoreVt2) || !(coverage & scfVertical2)) && (subtableFeatures & flag) != 0) {
   196             if (((coverage & scfIgnoreVt2) || !(coverage & scfVertical2)) && (subtableFeatures & flag) != 0) {
   181                 subtableHeader->process(glyphStorage);
   197               subtableHeader->process(subtableHeader, glyphStorage, success);
   182             }
   198             }
   183             subtableHeader = (const MorphSubtableHeader2 *) ((char *)subtableHeader + length);
       
   184         }
   199         }
   185         chainHeader = (const ChainHeader2 *)((char *)chainHeader + chainLength);
       
   186     }
   200     }
   187 }
   201 }
   188 
   202 
   189 void MorphSubtableHeader2::process(LEGlyphStorage &glyphStorage) const
   203 void MorphSubtableHeader2::process(const LEReferenceTo<MorphSubtableHeader2> &base, LEGlyphStorage &glyphStorage, LEErrorCode &success) const
   190 {
   204 {
   191     SubtableProcessor2 *processor = NULL;
   205     SubtableProcessor2 *processor = NULL;
   192 
   206 
   193     switch (SWAPL(coverage) & scfTypeMask2)
   207     switch (SWAPL(coverage) & scfTypeMask2)
   194     {
   208     {
   195     case mstIndicRearrangement:
   209     case mstIndicRearrangement:
   196         processor = new IndicRearrangementProcessor2(this);
   210         processor = new IndicRearrangementProcessor2(base, success);
   197         break;
   211         break;
   198 
   212 
   199     case mstContextualGlyphSubstitution:
   213     case mstContextualGlyphSubstitution:
   200         processor = new ContextualGlyphSubstitutionProcessor2(this);
   214         processor = new ContextualGlyphSubstitutionProcessor2(base, success);
   201         break;
   215         break;
   202 
   216 
   203     case mstLigatureSubstitution:
   217     case mstLigatureSubstitution:
   204         processor = new LigatureSubstitutionProcessor2(this);
   218         processor = new LigatureSubstitutionProcessor2(base, success);
   205         break;
   219         break;
   206 
   220 
   207     case mstReservedUnused:
   221     case mstReservedUnused:
   208         break;
   222         break;
   209 
   223 
   210     case mstNonContextualGlyphSubstitution:
   224     case mstNonContextualGlyphSubstitution:
   211         processor = NonContextualGlyphSubstitutionProcessor2::createInstance(this);
   225         processor = NonContextualGlyphSubstitutionProcessor2::createInstance(base, success);
   212         break;
   226         break;
   213 
   227 
   214 
   228 
   215     case mstContextualGlyphInsertion:
   229     case mstContextualGlyphInsertion:
   216         processor = new ContextualGlyphInsertionProcessor2(this);
   230         processor = new ContextualGlyphInsertionProcessor2(base, success);
   217         break;
   231         break;
   218 
   232 
   219     default:
   233     default:
   220         break;
   234         return;
       
   235         break; /*NOTREACHED*/
   221     }
   236     }
   222 
   237 
   223     if (processor != NULL) {
   238     if (processor != NULL) {
   224         processor->process(glyphStorage);
   239       processor->process(glyphStorage, success);
   225         delete processor;
   240         delete processor;
       
   241     } else {
       
   242       if(LE_SUCCESS(success)) {
       
   243         success = LE_MEMORY_ALLOCATION_ERROR; // because ptr is null and we didn't break out.
       
   244       }
   226     }
   245     }
   227 }
   246 }
   228 
   247 
   229 U_NAMESPACE_END
   248 U_NAMESPACE_END