Home | History | Annotate | Download | only in layout
      1 /*
      2  * (C) Copyright IBM Corp. and others 1998 - 2013 - All Rights Reserved
      3  *
      4  */
      5 
      6 #include "LETypes.h"
      7 #include "LayoutTables.h"
      8 #include "MorphTables.h"
      9 #include "SubtableProcessor2.h"
     10 #include "IndicRearrangementProcessor2.h"
     11 #include "ContextualGlyphSubstProc2.h"
     12 #include "LigatureSubstProc2.h"
     13 #include "NonContextualGlyphSubstProc2.h"
     14 #include "ContextualGlyphInsertionProc2.h"
     15 #include "LEGlyphStorage.h"
     16 #include "LESwaps.h"
     17 
     18 U_NAMESPACE_BEGIN
     19 
     20 void MorphTableHeader2::process(LEGlyphStorage &glyphStorage, le_int32 typoFlags) const
     21 {
     22     const ChainHeader2 *chainHeader = chains;
     23     le_uint32 chainCount = SWAPL(this->nChains);
     24 	le_uint32 chain;
     25 
     26     for (chain = 0; chain < chainCount; chain++) {
     27         FeatureFlags flag = SWAPL(chainHeader->defaultFlags);
     28         le_uint32 chainLength = SWAPL(chainHeader->chainLength);
     29         le_uint32 nFeatureEntries = SWAPL(chainHeader->nFeatureEntries);
     30         le_uint32 nSubtables = SWAPL(chainHeader->nSubtables);
     31         const MorphSubtableHeader2 *subtableHeader =
     32             (const MorphSubtableHeader2 *)&chainHeader->featureTable[nFeatureEntries];
     33         le_uint32 subtable;
     34 
     35         if (typoFlags != 0) {
     36            le_uint32 featureEntry;
     37 
     38             // Feature subtables
     39             for (featureEntry = 0; featureEntry < nFeatureEntries; featureEntry++) {
     40                 FeatureTableEntry featureTableEntry = chains->featureTable[featureEntry];
     41                 le_int16 featureType = SWAPW(featureTableEntry.featureType);
     42                 le_int16 featureSetting = SWAPW(featureTableEntry.featureSetting);
     43                 le_uint32 enableFlags = SWAPL(featureTableEntry.enableFlags);
     44                 le_uint32 disableFlags = SWAPL(featureTableEntry.disableFlags);
     45                 switch (featureType) {
     46                     case ligaturesType:
     47                         if ((typoFlags & LE_Ligatures_FEATURE_ENUM ) && (featureSetting ^ 0x1)){
     48                             flag &= disableFlags;
     49                             flag |= enableFlags;
     50                         } else {
     51                             if (((typoFlags & LE_RLIG_FEATURE_FLAG) && featureSetting == requiredLigaturesOnSelector) ||
     52                                 ((typoFlags & LE_CLIG_FEATURE_FLAG) && featureSetting == contextualLigaturesOnSelector) ||
     53                                 ((typoFlags & LE_HLIG_FEATURE_FLAG) && featureSetting == historicalLigaturesOnSelector) ||
     54                                 ((typoFlags & LE_LIGA_FEATURE_FLAG) && featureSetting == commonLigaturesOnSelector)) {
     55                                 flag &= disableFlags;
     56                                 flag |= enableFlags;
     57                             }
     58                         }
     59                         break;
     60                     case letterCaseType:
     61                         if ((typoFlags & LE_SMCP_FEATURE_FLAG) && featureSetting == smallCapsSelector) {
     62                             flag &= disableFlags;
     63                             flag |= enableFlags;
     64                         }
     65                         break;
     66                     case verticalSubstitutionType:
     67                         break;
     68                     case linguisticRearrangementType:
     69                         break;
     70                     case numberSpacingType:
     71                         break;
     72                     case smartSwashType:
     73                         if ((typoFlags & LE_SWSH_FEATURE_FLAG) && (featureSetting ^ 0x1)){
     74                             flag &= disableFlags;
     75                             flag |= enableFlags;
     76                         }
     77                         break;
     78                     case diacriticsType:
     79                         break;
     80                     case verticalPositionType:
     81                         break;
     82                     case fractionsType:
     83                         if (((typoFlags & LE_FRAC_FEATURE_FLAG) && featureSetting == diagonalFractionsSelector) ||
     84                             ((typoFlags & LE_AFRC_FEATURE_FLAG) && featureSetting == verticalFractionsSelector)) {
     85                             flag &= disableFlags;
     86                             flag |= enableFlags;
     87                         } else {
     88                             flag &= disableFlags;
     89                         }
     90                         break;
     91                     case typographicExtrasType:
     92                         if ((typoFlags & LE_ZERO_FEATURE_FLAG) && featureSetting == slashedZeroOnSelector) {
     93                             flag &= disableFlags;
     94                             flag |= enableFlags;
     95                         }
     96                         break;
     97                     case mathematicalExtrasType:
     98                         break;
     99                     case ornamentSetsType:
    100                         break;
    101                     case characterAlternativesType:
    102                         break;
    103                     case designComplexityType:
    104                         if (((typoFlags & LE_SS01_FEATURE_FLAG) && featureSetting == designLevel1Selector) ||
    105                             ((typoFlags & LE_SS02_FEATURE_FLAG) && featureSetting == designLevel2Selector) ||
    106                             ((typoFlags & LE_SS03_FEATURE_FLAG) && featureSetting == designLevel3Selector) ||
    107                             ((typoFlags & LE_SS04_FEATURE_FLAG) && featureSetting == designLevel4Selector) ||
    108                             ((typoFlags & LE_SS05_FEATURE_FLAG) && featureSetting == designLevel5Selector) ||
    109                             ((typoFlags & LE_SS06_FEATURE_FLAG) && featureSetting == designLevel6Selector) ||
    110                             ((typoFlags & LE_SS07_FEATURE_FLAG) && featureSetting == designLevel7Selector)) {
    111 
    112                             flag &= disableFlags;
    113                             flag |= enableFlags;
    114                         }
    115                         break;
    116                     case styleOptionsType:
    117                         break;
    118                     case characterShapeType:
    119                         break;
    120                     case numberCaseType:
    121                         break;
    122                     case textSpacingType:
    123                         break;
    124                     case transliterationType:
    125                         break;
    126                     case annotationType:
    127                         if ((typoFlags & LE_NALT_FEATURE_FLAG) && featureSetting == circleAnnotationSelector) {
    128                             flag &= disableFlags;
    129                             flag |= enableFlags;
    130                         }
    131                         break;
    132                     case kanaSpacingType:
    133                         break;
    134                     case ideographicSpacingType:
    135                         break;
    136                     case rubyKanaType:
    137                         if ((typoFlags & LE_RUBY_FEATURE_FLAG) && featureSetting == rubyKanaOnSelector) {
    138                             flag &= disableFlags;
    139                             flag |= enableFlags;
    140                         }
    141                         break;
    142                     case cjkRomanSpacingType:
    143                         break;
    144                     default:
    145                         break;
    146                 }
    147             }
    148         }
    149 
    150         for (subtable = 0; subtable < nSubtables; subtable++) {
    151             le_uint32 length = SWAPL(subtableHeader->length);
    152             le_uint32 coverage = SWAPL(subtableHeader->coverage);
    153             FeatureFlags subtableFeatures = SWAPL(subtableHeader->subtableFeatures);
    154             // should check coverage more carefully...
    155             if (((coverage & scfIgnoreVt2) || !(coverage & scfVertical2)) && (subtableFeatures & flag) != 0) {
    156                 subtableHeader->process(glyphStorage);
    157             }
    158             subtableHeader = (const MorphSubtableHeader2 *) ((char *)subtableHeader + length);
    159         }
    160         chainHeader = (const ChainHeader2 *)((char *)chainHeader + chainLength);
    161     }
    162 }
    163 
    164 void MorphSubtableHeader2::process(LEGlyphStorage &glyphStorage) const
    165 {
    166     SubtableProcessor2 *processor = NULL;
    167 
    168     switch (SWAPL(coverage) & scfTypeMask2)
    169     {
    170     case mstIndicRearrangement:
    171         processor = new IndicRearrangementProcessor2(this);
    172         break;
    173 
    174     case mstContextualGlyphSubstitution:
    175         processor = new ContextualGlyphSubstitutionProcessor2(this);
    176         break;
    177 
    178     case mstLigatureSubstitution:
    179         processor = new LigatureSubstitutionProcessor2(this);
    180         break;
    181 
    182     case mstReservedUnused:
    183         break;
    184 
    185     case mstNonContextualGlyphSubstitution:
    186         processor = NonContextualGlyphSubstitutionProcessor2::createInstance(this);
    187         break;
    188 
    189 
    190     case mstContextualGlyphInsertion:
    191         processor = new ContextualGlyphInsertionProcessor2(this);
    192         break;
    193 
    194     default:
    195         break;
    196     }
    197 
    198     if (processor != NULL) {
    199         processor->process(glyphStorage);
    200         delete processor;
    201     }
    202 }
    203 
    204 U_NAMESPACE_END
    205