]> git.saurik.com Git - apple/icu.git/blame - icuSources/layout/MorphTables2.cpp
ICU-59180.0.1.tar.gz
[apple/icu.git] / icuSources / layout / MorphTables2.cpp
CommitLineData
51004dcb 1/*
2ca993e8 2 * (C) Copyright IBM Corp. and others 1998 - 2015 - All Rights Reserved
51004dcb
A
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
18U_NAMESPACE_BEGIN
19
57a6839d
A
20void MorphTableHeader2::process(const LEReferenceTo<MorphTableHeader2> &base, LEGlyphStorage &glyphStorage,
21 le_int32 typoFlags, LEErrorCode &success) const
51004dcb 22{
57a6839d
A
23 if(LE_FAILURE(success)) return;
24
25 le_uint32 chainCount = SWAPL(this->nChains);
26 LEReferenceTo<ChainHeader2> chainHeader(base, success, &chains[0]);
27 /* chainHeader and subtableHeader are implemented as a moving pointer rather than an array dereference
28 * to (slightly) reduce code churn. However, must be careful to preincrement them the 2nd time through.
29 * We don't want to increment them at the end of the loop, as that would attempt to dereference
30 * out of range memory.
31 */
32 le_uint32 chain;
33
34 for (chain = 0; LE_SUCCESS(success) && (chain < chainCount); chain++) {
35 if (chain>0) {
36 le_uint32 chainLength = SWAPL(chainHeader->chainLength);
37 chainHeader.addOffset(chainLength, success); // Don't increment the first time
38 }
51004dcb 39 FeatureFlags flag = SWAPL(chainHeader->defaultFlags);
51004dcb
A
40 le_uint32 nFeatureEntries = SWAPL(chainHeader->nFeatureEntries);
41 le_uint32 nSubtables = SWAPL(chainHeader->nSubtables);
57a6839d
A
42 LEReferenceTo<MorphSubtableHeader2> subtableHeader(chainHeader,
43 success, (const MorphSubtableHeader2 *)&chainHeader->featureTable[nFeatureEntries]);
51004dcb 44 le_uint32 subtable;
57a6839d 45 if(LE_FAILURE(success)) break; // malformed table
51004dcb
A
46
47 if (typoFlags != 0) {
48 le_uint32 featureEntry;
57a6839d
A
49 LEReferenceToArrayOf<FeatureTableEntry> featureTableRef(chainHeader, success, &chainHeader->featureTable[0], nFeatureEntries);
50 if(LE_FAILURE(success)) break;
51004dcb
A
51 // Feature subtables
52 for (featureEntry = 0; featureEntry < nFeatureEntries; featureEntry++) {
57a6839d 53 const FeatureTableEntry &featureTableEntry = featureTableRef(featureEntry, success);
51004dcb
A
54 le_int16 featureType = SWAPW(featureTableEntry.featureType);
55 le_int16 featureSetting = SWAPW(featureTableEntry.featureSetting);
56 le_uint32 enableFlags = SWAPL(featureTableEntry.enableFlags);
57 le_uint32 disableFlags = SWAPL(featureTableEntry.disableFlags);
58 switch (featureType) {
59 case ligaturesType:
60 if ((typoFlags & LE_Ligatures_FEATURE_ENUM ) && (featureSetting ^ 0x1)){
61 flag &= disableFlags;
62 flag |= enableFlags;
63 } else {
64 if (((typoFlags & LE_RLIG_FEATURE_FLAG) && featureSetting == requiredLigaturesOnSelector) ||
65 ((typoFlags & LE_CLIG_FEATURE_FLAG) && featureSetting == contextualLigaturesOnSelector) ||
66 ((typoFlags & LE_HLIG_FEATURE_FLAG) && featureSetting == historicalLigaturesOnSelector) ||
67 ((typoFlags & LE_LIGA_FEATURE_FLAG) && featureSetting == commonLigaturesOnSelector)) {
68 flag &= disableFlags;
69 flag |= enableFlags;
70 }
71 }
72 break;
73 case letterCaseType:
74 if ((typoFlags & LE_SMCP_FEATURE_FLAG) && featureSetting == smallCapsSelector) {
75 flag &= disableFlags;
76 flag |= enableFlags;
77 }
78 break;
79 case verticalSubstitutionType:
80 break;
81 case linguisticRearrangementType:
82 break;
83 case numberSpacingType:
84 break;
85 case smartSwashType:
86 if ((typoFlags & LE_SWSH_FEATURE_FLAG) && (featureSetting ^ 0x1)){
87 flag &= disableFlags;
88 flag |= enableFlags;
89 }
90 break;
91 case diacriticsType:
92 break;
93 case verticalPositionType:
94 break;
95 case fractionsType:
96 if (((typoFlags & LE_FRAC_FEATURE_FLAG) && featureSetting == diagonalFractionsSelector) ||
97 ((typoFlags & LE_AFRC_FEATURE_FLAG) && featureSetting == verticalFractionsSelector)) {
98 flag &= disableFlags;
99 flag |= enableFlags;
100 } else {
101 flag &= disableFlags;
102 }
103 break;
104 case typographicExtrasType:
105 if ((typoFlags & LE_ZERO_FEATURE_FLAG) && featureSetting == slashedZeroOnSelector) {
106 flag &= disableFlags;
107 flag |= enableFlags;
108 }
109 break;
110 case mathematicalExtrasType:
111 break;
112 case ornamentSetsType:
113 break;
114 case characterAlternativesType:
115 break;
116 case designComplexityType:
117 if (((typoFlags & LE_SS01_FEATURE_FLAG) && featureSetting == designLevel1Selector) ||
118 ((typoFlags & LE_SS02_FEATURE_FLAG) && featureSetting == designLevel2Selector) ||
119 ((typoFlags & LE_SS03_FEATURE_FLAG) && featureSetting == designLevel3Selector) ||
120 ((typoFlags & LE_SS04_FEATURE_FLAG) && featureSetting == designLevel4Selector) ||
121 ((typoFlags & LE_SS05_FEATURE_FLAG) && featureSetting == designLevel5Selector) ||
122 ((typoFlags & LE_SS06_FEATURE_FLAG) && featureSetting == designLevel6Selector) ||
123 ((typoFlags & LE_SS07_FEATURE_FLAG) && featureSetting == designLevel7Selector)) {
124
125 flag &= disableFlags;
126 flag |= enableFlags;
127 }
128 break;
129 case styleOptionsType:
130 break;
131 case characterShapeType:
132 break;
133 case numberCaseType:
134 break;
135 case textSpacingType:
136 break;
137 case transliterationType:
138 break;
139 case annotationType:
140 if ((typoFlags & LE_NALT_FEATURE_FLAG) && featureSetting == circleAnnotationSelector) {
141 flag &= disableFlags;
142 flag |= enableFlags;
143 }
144 break;
145 case kanaSpacingType:
146 break;
147 case ideographicSpacingType:
148 break;
149 case rubyKanaType:
150 if ((typoFlags & LE_RUBY_FEATURE_FLAG) && featureSetting == rubyKanaOnSelector) {
151 flag &= disableFlags;
152 flag |= enableFlags;
153 }
154 break;
155 case cjkRomanSpacingType:
156 break;
157 default:
158 break;
159 }
160 }
161 }
162
57a6839d
A
163 for (subtable = 0; LE_SUCCESS(success) && subtable < nSubtables; subtable++) {
164 if(subtable>0) {
165 le_uint32 length = SWAPL(subtableHeader->length);
166 subtableHeader.addOffset(length, success); // Don't addOffset for the last entry.
2ca993e8 167 if (LE_FAILURE(success)) break;
57a6839d 168 }
51004dcb
A
169 le_uint32 coverage = SWAPL(subtableHeader->coverage);
170 FeatureFlags subtableFeatures = SWAPL(subtableHeader->subtableFeatures);
171 // should check coverage more carefully...
172 if (((coverage & scfIgnoreVt2) || !(coverage & scfVertical2)) && (subtableFeatures & flag) != 0) {
57a6839d 173 subtableHeader->process(subtableHeader, glyphStorage, success);
51004dcb 174 }
51004dcb 175 }
51004dcb
A
176 }
177}
178
57a6839d 179void MorphSubtableHeader2::process(const LEReferenceTo<MorphSubtableHeader2> &base, LEGlyphStorage &glyphStorage, LEErrorCode &success) const
51004dcb
A
180{
181 SubtableProcessor2 *processor = NULL;
182
2ca993e8
A
183 if (LE_FAILURE(success)) return;
184
51004dcb
A
185 switch (SWAPL(coverage) & scfTypeMask2)
186 {
187 case mstIndicRearrangement:
57a6839d 188 processor = new IndicRearrangementProcessor2(base, success);
51004dcb
A
189 break;
190
191 case mstContextualGlyphSubstitution:
57a6839d 192 processor = new ContextualGlyphSubstitutionProcessor2(base, success);
51004dcb
A
193 break;
194
195 case mstLigatureSubstitution:
57a6839d 196 processor = new LigatureSubstitutionProcessor2(base, success);
51004dcb
A
197 break;
198
199 case mstReservedUnused:
200 break;
201
202 case mstNonContextualGlyphSubstitution:
57a6839d 203 processor = NonContextualGlyphSubstitutionProcessor2::createInstance(base, success);
51004dcb
A
204 break;
205
206
207 case mstContextualGlyphInsertion:
57a6839d 208 processor = new ContextualGlyphInsertionProcessor2(base, success);
51004dcb
A
209 break;
210
211 default:
57a6839d
A
212 return;
213 break; /*NOTREACHED*/
51004dcb
A
214 }
215
216 if (processor != NULL) {
57a6839d 217 processor->process(glyphStorage, success);
51004dcb 218 delete processor;
57a6839d
A
219 } else {
220 if(LE_SUCCESS(success)) {
221 success = LE_MEMORY_ALLOCATION_ERROR; // because ptr is null and we didn't break out.
222 }
51004dcb
A
223 }
224}
225
226U_NAMESPACE_END