Update contrib.
3 * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
8 #include "OpenTypeUtilities.h"
9 #include "LEFontInstance.h"
10 #include "OpenTypeTables.h"
13 #include "ScriptAndLanguage.h"
14 #include "GlyphDefinitionTables.h"
15 #include "GlyphIterator.h"
16 #include "LookupProcessor.h"
17 #include "LEGlyphStorage.h"
22 const LETag LookupProcessor::notSelected = 0x00000000;
23 const LETag LookupProcessor::defaultFeature = 0xFFFFFFFF;
25 static const LETag emptyTag = 0x00000000;
28 le_uint32 LookupProcessor::applyLookupTable(const LookupTable *lookupTable,
29 GlyphIterator *glyphIterator, const LEFontInstance *fontInstance,
30 LEErrorCode& success) const
32 if (LE_FAILURE(success)) {
36 le_uint16 lookupType = SWAPW(lookupTable->lookupType);
37 le_uint16 subtableCount = SWAPW(lookupTable->subTableCount);
38 le_int32 startPosition = glyphIterator->getCurrStreamPosition();
41 for (le_uint16 subtable = 0; subtable < subtableCount; subtable += 1) {
42 const LookupSubtable *lookupSubtable = lookupTable->getLookupSubtable(subtable);
44 delta = applySubtable(lookupSubtable, lookupType, glyphIterator,
45 fontInstance, success);
47 if (delta > 0 || LE_FAILURE(success)) {
51 glyphIterator->setCurrStreamPosition(startPosition);
57 le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments,
58 le_bool rightToLeft, const GlyphDefinitionTableHeader *glyphDefinitionTableHeader,
59 const LEFontInstance *fontInstance, LEErrorCode& success) const
61 if (LE_FAILURE(success)) {
65 le_int32 glyphCount = glyphStorage.getGlyphCount();
67 if (lookupSelectArray == NULL) {
71 GlyphIterator glyphIterator(glyphStorage, glyphPositionAdjustments,
72 rightToLeft, 0, 0, glyphDefinitionTableHeader);
73 le_int32 newGlyphCount = glyphCount;
75 for (le_uint16 order = 0; order < lookupOrderCount; order += 1) {
76 le_uint16 lookup = lookupOrderArray[order];
77 LETag selectTag = lookupSelectArray[lookup];
79 if (selectTag != notSelected) {
80 const LookupTable *lookupTable = lookupListTable->getLookupTable(lookup);
81 le_uint16 lookupFlags = SWAPW(lookupTable->lookupFlags);
83 glyphIterator.reset(lookupFlags, selectTag);
85 while (glyphIterator.findFeatureTag()) {
88 while (glyphIterator.next(delta)) {
89 delta = applyLookupTable(lookupTable, &glyphIterator, fontInstance, success);
90 if (LE_FAILURE(success)) {
96 newGlyphCount = glyphIterator.applyInsertions();
100 return newGlyphCount;
103 le_uint32 LookupProcessor::applySingleLookup(le_uint16 lookupTableIndex, GlyphIterator *glyphIterator,
104 const LEFontInstance *fontInstance, LEErrorCode& success) const
106 if (LE_FAILURE(success)) {
110 const LookupTable *lookupTable = lookupListTable->getLookupTable(lookupTableIndex);
111 le_uint16 lookupFlags = SWAPW(lookupTable->lookupFlags);
112 GlyphIterator tempIterator(*glyphIterator, lookupFlags);
113 le_uint32 delta = applyLookupTable(lookupTable, &tempIterator, fontInstance, success);
118 le_int32 LookupProcessor::selectLookups(const FeatureTable *featureTable, LETag featureTag, le_int32 order)
120 le_uint16 lookupCount = featureTable? SWAPW(featureTable->lookupCount) : 0;
121 le_int32 store = order;
123 for (le_uint16 lookup = 0; lookup < lookupCount; lookup += 1) {
124 le_uint16 lookupListIndex = SWAPW(featureTable->lookupListIndexArray[lookup]);
126 if (lookupSelectArray[lookupListIndex] == notSelected) {
127 lookupSelectArray[lookupListIndex] = featureTag;
128 lookupOrderArray[store++] = lookupListIndex;
132 return store - order;
135 LookupProcessor::LookupProcessor(const char *baseAddress,
136 Offset scriptListOffset, Offset featureListOffset, Offset lookupListOffset,
137 LETag scriptTag, LETag languageTag, const LETag *featureOrder)
138 : lookupListTable(NULL), featureListTable(NULL), lookupSelectArray(NULL),
139 requiredFeatureTag(notSelected), lookupOrderArray(NULL), lookupOrderCount(0)
141 const ScriptListTable *scriptListTable = NULL;
142 const LangSysTable *langSysTable = NULL;
143 le_uint16 featureCount = 0;
144 le_uint16 lookupListCount = 0;
145 le_uint16 requiredFeatureIndex;
147 if (scriptListOffset != 0) {
148 scriptListTable = (const ScriptListTable *) (baseAddress + scriptListOffset);
149 langSysTable = scriptListTable->findLanguage(scriptTag, languageTag);
151 if (langSysTable != 0) {
152 featureCount = SWAPW(langSysTable->featureCount);
156 if (featureListOffset != 0) {
157 featureListTable = (const FeatureListTable *) (baseAddress + featureListOffset);
160 if (lookupListOffset != 0) {
161 lookupListTable = (const LookupListTable *) (baseAddress + lookupListOffset);
162 lookupListCount = SWAPW(lookupListTable->lookupCount);
165 if (langSysTable == NULL || featureListTable == NULL || lookupListTable == NULL ||
166 featureCount == 0 || lookupListCount == 0) {
170 requiredFeatureIndex = SWAPW(langSysTable->reqFeatureIndex);
172 lookupSelectArray = LE_NEW_ARRAY(LETag, lookupListCount);
173 if (!lookupSelectArray)
176 for (int i = 0; i < lookupListCount; i += 1) {
177 lookupSelectArray[i] = notSelected;
180 le_int32 count, order = 0;
181 const FeatureTable *featureTable = 0;
184 lookupOrderArray = LE_NEW_ARRAY(le_uint16, lookupListCount);
185 if (!lookupOrderArray)
188 if (requiredFeatureIndex != 0xFFFF) {
189 featureTable = featureListTable->getFeatureTable(requiredFeatureIndex, &featureTag);
190 order += selectLookups(featureTable, defaultFeature, order);
193 if (featureOrder != NULL) {
195 OpenTypeUtilities::sort(lookupOrderArray, order);
198 for (le_int32 tag = 0; featureOrder[tag] != emptyTag; tag += 1) {
199 featureTag = featureOrder[tag];
202 for (le_uint16 feature = 0; feature < featureCount; feature += 1) {
203 le_uint16 featureIndex = SWAPW(langSysTable->featureIndexArray[feature]);
205 featureTable = featureListTable->getFeatureTable(featureIndex, &featureTag);
207 if (featureTag == featureOrder[tag]) {
208 count += selectLookups(featureTable, featureTag, order + count);
213 OpenTypeUtilities::sort(&lookupOrderArray[order], count);
219 for (le_uint16 feature = 0; feature < featureCount; feature += 1) {
220 le_uint16 featureIndex = SWAPW(langSysTable->featureIndexArray[feature]);
222 // don't add the required feature to the list more than once...
223 if (featureIndex == requiredFeatureIndex) {
227 featureTable = featureListTable->getFeatureTable(featureIndex, &featureTag);
228 count = selectLookups(featureTable, featureTag, order);
233 OpenTypeUtilities::sort(lookupOrderArray, order);
237 lookupOrderCount = order;
240 LookupProcessor::LookupProcessor()
242 lookupOrderArray = 0;
243 lookupSelectArray = 0;
246 le_bool LookupProcessor::isBogus()
248 return lookupSelectArray && lookupSelectArray? FALSE : TRUE;
251 LookupProcessor::~LookupProcessor()
253 LE_DELETE_ARRAY(lookupOrderArray);
254 LE_DELETE_ARRAY(lookupSelectArray);