• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
process(LEGlyphStorage & glyphStorage,le_int32 typoFlags) const20 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 
process(LEGlyphStorage & glyphStorage) const164 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