]> git.saurik.com Git - apple/icu.git/blob - icuSources/layout/LookupProcessor.cpp
ICU-3.13.tar.gz
[apple/icu.git] / icuSources / layout / LookupProcessor.cpp
1 /*
2 * %W% %E%
3 *
4 * (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
5 *
6 */
7
8 #include "LETypes.h"
9 #include "OpenTypeUtilities.h"
10 #include "LEFontInstance.h"
11 #include "OpenTypeTables.h"
12 #include "Features.h"
13 #include "Lookups.h"
14 #include "ScriptAndLanguage.h"
15 #include "GlyphDefinitionTables.h"
16 #include "GlyphPositionAdjustments.h"
17 #include "LookupProcessor.h"
18 #include "LESwaps.h"
19
20 U_NAMESPACE_BEGIN
21
22 const LETag LookupProcessor::notSelected = 0x00000000;
23 const LETag LookupProcessor::defaultFeature = 0xFFFFFFFF;
24
25 const LETag emptyTag = 0x00000000;
26
27
28 le_uint32 LookupProcessor::applyLookupTable(const LookupTable *lookupTable, GlyphIterator *glyphIterator,
29 const LEFontInstance *fontInstance) const
30 {
31 le_uint16 lookupType = SWAPW(lookupTable->lookupType);
32 le_uint16 subtableCount = SWAPW(lookupTable->subTableCount);
33 le_int32 startPosition = glyphIterator->getCurrStreamPosition();
34 le_uint32 delta;
35
36 for (le_uint16 subtable = 0; subtable < subtableCount; subtable += 1) {
37 const LookupSubtable *lookupSubtable = lookupTable->getLookupSubtable(subtable);
38
39 delta = applySubtable(lookupSubtable, lookupType, glyphIterator, fontInstance);
40
41 if (delta > 0) {
42 return 1;
43 }
44
45 glyphIterator->setCurrStreamPosition(startPosition);
46 }
47
48 return 1;
49 }
50
51 void LookupProcessor::process(LEGlyphID *glyphs, GlyphPositionAdjustment *glyphPositionAdjustments, const LETag **glyphTags, le_int32 glyphCount,
52 le_bool rightToLeft, const GlyphDefinitionTableHeader *glyphDefinitionTableHeader,
53 const LEFontInstance *fontInstance) const
54 {
55 if (lookupSelectArray == NULL) {
56 return;
57 }
58
59 for (le_uint16 order = 0; order < lookupOrderCount; order += 1) {
60 le_uint16 lookup = lookupOrderArray[order];
61 LETag selectTag = lookupSelectArray[lookup];
62
63 if (selectTag != notSelected) {
64 const LookupTable *lookupTable = lookupListTable->getLookupTable(lookup);
65 le_uint16 lookupFlags = SWAPW(lookupTable->lookupFlags);
66 GlyphIterator glyphIterator(glyphs, glyphPositionAdjustments, glyphCount,
67 rightToLeft, lookupFlags, selectTag, glyphTags,
68 glyphDefinitionTableHeader);
69
70 while (glyphIterator.findFeatureTag()) {
71 le_uint32 delta = 1;
72
73 while (glyphIterator.next(delta)) {
74 delta = applyLookupTable(lookupTable, &glyphIterator, fontInstance);
75 }
76 }
77 }
78 }
79 }
80
81 le_uint32 LookupProcessor::applySingleLookup(le_uint16 lookupTableIndex, GlyphIterator *glyphIterator,
82 const LEFontInstance *fontInstance) const
83 {
84 const LookupTable *lookupTable = lookupListTable->getLookupTable(lookupTableIndex);
85 le_uint16 lookupFlags = SWAPW(lookupTable->lookupFlags);
86 GlyphIterator tempIterator(*glyphIterator, lookupFlags);
87 le_uint32 delta = applyLookupTable(lookupTable, &tempIterator, fontInstance);
88
89 return delta;
90 }
91
92 le_int32 LookupProcessor::selectLookups(const FeatureTable *featureTable, LETag featureTag, le_int32 order)
93 {
94 le_uint16 lookupCount = featureTable? SWAPW(featureTable->lookupCount) : 0;
95
96 for (le_uint16 lookup = 0; lookup < lookupCount; lookup += 1) {
97 le_uint16 lookupListIndex = SWAPW(featureTable->lookupListIndexArray[lookup]);
98
99 lookupSelectArray[lookupListIndex] = featureTag;
100 lookupOrderArray[order + lookup] = lookupListIndex;
101 }
102
103 return lookupCount;
104 }
105
106 LookupProcessor::LookupProcessor(const char *baseAddress,
107 Offset scriptListOffset, Offset featureListOffset, Offset lookupListOffset,
108 LETag scriptTag, LETag languageTag, const LETag *featureOrder)
109 : lookupListTable(NULL), featureListTable(NULL), lookupSelectArray(NULL),
110 requiredFeatureTag(notSelected), lookupOrderArray(NULL), lookupOrderCount(0)
111 {
112 const ScriptListTable *scriptListTable = NULL;
113 const LangSysTable *langSysTable = NULL;
114 le_uint16 featureCount = 0;
115 le_uint16 lookupListCount = 0;
116 le_uint16 requiredFeatureIndex;
117
118 if (scriptListOffset != 0) {
119 scriptListTable = (const ScriptListTable *) (baseAddress + scriptListOffset);
120 langSysTable = scriptListTable->findLanguage(scriptTag, languageTag);
121
122 if (langSysTable != 0) {
123 featureCount = SWAPW(langSysTable->featureCount);
124 }
125 }
126
127 if (featureListOffset != 0) {
128 featureListTable = (const FeatureListTable *) (baseAddress + featureListOffset);
129 }
130
131 if (lookupListOffset != 0) {
132 lookupListTable = (const LookupListTable *) (baseAddress + lookupListOffset);
133 lookupListCount = SWAPW(lookupListTable->lookupCount);
134 }
135
136 if (langSysTable == NULL || featureListTable == NULL || lookupListTable == NULL ||
137 featureCount == 0 || lookupListCount == 0) {
138 return;
139 }
140
141 requiredFeatureIndex = SWAPW(langSysTable->reqFeatureIndex);
142
143 lookupSelectArray = LE_NEW_ARRAY(LETag, lookupListCount);
144
145 for (int i = 0; i < lookupListCount; i += 1) {
146 lookupSelectArray[i] = notSelected;
147 }
148
149 le_int32 count, order = 0;
150 const FeatureTable *featureTable = 0;
151 LETag featureTag;
152
153 lookupOrderArray = LE_NEW_ARRAY(le_uint16, lookupListCount);
154
155 if (requiredFeatureIndex != 0xFFFF) {
156 featureTable = featureListTable->getFeatureTable(requiredFeatureIndex, &featureTag);
157 order += selectLookups(featureTable, defaultFeature, order);
158 }
159
160 if (featureOrder != NULL) {
161 if (order > 1) {
162 OpenTypeUtilities::sort(lookupOrderArray, order);
163 }
164
165 for (le_int32 tag = 0; featureOrder[tag] != emptyTag; tag += 1) {
166 featureTag = featureOrder[tag];
167 count = 0;
168
169 for (le_uint16 feature = 0; feature < featureCount; feature += 1) {
170 le_uint16 featureIndex = SWAPW(langSysTable->featureIndexArray[feature]);
171
172 featureTable = featureListTable->getFeatureTable(featureIndex, &featureTag);
173
174 if (featureTag == featureOrder[tag]) {
175 count += selectLookups(featureTable, featureTag, order + count);
176 }
177 }
178
179 if (count > 1) {
180 OpenTypeUtilities::sort(&lookupOrderArray[order], count);
181 }
182
183 order += count;
184 }
185 } else {
186 for (le_uint16 feature = 0; feature < featureCount; feature += 1) {
187 le_uint16 featureIndex = SWAPW(langSysTable->featureIndexArray[feature]);
188
189 featureTable = featureListTable->getFeatureTable(featureIndex, &featureTag);
190 count = selectLookups(featureTable, featureTag, order);
191 order += count;
192 }
193
194 if (order > 1) {
195 OpenTypeUtilities::sort(lookupOrderArray, order);
196 }
197 }
198
199 lookupOrderCount = order;
200 }
201
202 LookupProcessor::LookupProcessor()
203 {
204 }
205
206 LookupProcessor::~LookupProcessor()
207 {
208 LE_DELETE_ARRAY(lookupOrderArray);
209 LE_DELETE_ARRAY(lookupSelectArray);
210 };
211
212 U_NAMESPACE_END