]> git.saurik.com Git - apple/icu.git/blob - icuSources/layout/MorphTables2.cpp
ICU-511.32.tar.gz
[apple/icu.git] / icuSources / layout / MorphTables2.cpp
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