3 * (C) Copyright IBM Corp. 1998-2004 - 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 "GlyphPositionAdjustments.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
, GlyphIterator
*glyphIterator
,
29 const LEFontInstance
*fontInstance
) const
31 le_uint16 lookupType
= SWAPW(lookupTable
->lookupType
);
32 le_uint16 subtableCount
= SWAPW(lookupTable
->subTableCount
);
33 le_int32 startPosition
= glyphIterator
->getCurrStreamPosition();
36 for (le_uint16 subtable
= 0; subtable
< subtableCount
; subtable
+= 1) {
37 const LookupSubtable
*lookupSubtable
= lookupTable
->getLookupSubtable(subtable
);
39 delta
= applySubtable(lookupSubtable
, lookupType
, glyphIterator
, fontInstance
);
45 glyphIterator
->setCurrStreamPosition(startPosition
);
51 le_int32
LookupProcessor::process(LEGlyphStorage
&glyphStorage
, GlyphPositionAdjustment
*glyphPositionAdjustments
,
52 le_bool rightToLeft
, const GlyphDefinitionTableHeader
*glyphDefinitionTableHeader
,
53 const LEFontInstance
*fontInstance
) const
55 le_int32 glyphCount
= glyphStorage
.getGlyphCount();
57 if (lookupSelectArray
== NULL
) {
61 GlyphIterator
glyphIterator(glyphStorage
, glyphPositionAdjustments
,
62 rightToLeft
, 0, 0, glyphDefinitionTableHeader
);
63 le_int32 newGlyphCount
= glyphCount
;
65 for (le_uint16 order
= 0; order
< lookupOrderCount
; order
+= 1) {
66 le_uint16 lookup
= lookupOrderArray
[order
];
67 LETag selectTag
= lookupSelectArray
[lookup
];
69 if (selectTag
!= notSelected
) {
70 const LookupTable
*lookupTable
= lookupListTable
->getLookupTable(lookup
);
71 le_uint16 lookupFlags
= SWAPW(lookupTable
->lookupFlags
);
73 glyphIterator
.reset(lookupFlags
, selectTag
);
75 while (glyphIterator
.findFeatureTag()) {
78 while (glyphIterator
.next(delta
)) {
79 delta
= applyLookupTable(lookupTable
, &glyphIterator
, fontInstance
);
83 newGlyphCount
= glyphIterator
.applyInsertions();
90 le_uint32
LookupProcessor::applySingleLookup(le_uint16 lookupTableIndex
, GlyphIterator
*glyphIterator
,
91 const LEFontInstance
*fontInstance
) const
93 const LookupTable
*lookupTable
= lookupListTable
->getLookupTable(lookupTableIndex
);
94 le_uint16 lookupFlags
= SWAPW(lookupTable
->lookupFlags
);
95 GlyphIterator
tempIterator(*glyphIterator
, lookupFlags
);
96 le_uint32 delta
= applyLookupTable(lookupTable
, &tempIterator
, fontInstance
);
101 le_int32
LookupProcessor::selectLookups(const FeatureTable
*featureTable
, LETag featureTag
, le_int32 order
)
103 le_uint16 lookupCount
= featureTable
? SWAPW(featureTable
->lookupCount
) : 0;
104 le_int32 store
= order
;
106 for (le_uint16 lookup
= 0; lookup
< lookupCount
; lookup
+= 1) {
107 le_uint16 lookupListIndex
= SWAPW(featureTable
->lookupListIndexArray
[lookup
]);
109 if (lookupSelectArray
[lookupListIndex
] == notSelected
) {
110 lookupSelectArray
[lookupListIndex
] = featureTag
;
111 lookupOrderArray
[store
++] = lookupListIndex
;
115 return store
- order
;
118 LookupProcessor::LookupProcessor(const char *baseAddress
,
119 Offset scriptListOffset
, Offset featureListOffset
, Offset lookupListOffset
,
120 LETag scriptTag
, LETag languageTag
, const LETag
*featureOrder
)
121 : lookupListTable(NULL
), featureListTable(NULL
), lookupSelectArray(NULL
),
122 requiredFeatureTag(notSelected
), lookupOrderArray(NULL
), lookupOrderCount(0)
124 const ScriptListTable
*scriptListTable
= NULL
;
125 const LangSysTable
*langSysTable
= NULL
;
126 le_uint16 featureCount
= 0;
127 le_uint16 lookupListCount
= 0;
128 le_uint16 requiredFeatureIndex
;
130 if (scriptListOffset
!= 0) {
131 scriptListTable
= (const ScriptListTable
*) (baseAddress
+ scriptListOffset
);
132 langSysTable
= scriptListTable
->findLanguage(scriptTag
, languageTag
);
134 if (langSysTable
!= 0) {
135 featureCount
= SWAPW(langSysTable
->featureCount
);
139 if (featureListOffset
!= 0) {
140 featureListTable
= (const FeatureListTable
*) (baseAddress
+ featureListOffset
);
143 if (lookupListOffset
!= 0) {
144 lookupListTable
= (const LookupListTable
*) (baseAddress
+ lookupListOffset
);
145 lookupListCount
= SWAPW(lookupListTable
->lookupCount
);
148 if (langSysTable
== NULL
|| featureListTable
== NULL
|| lookupListTable
== NULL
||
149 featureCount
== 0 || lookupListCount
== 0) {
153 requiredFeatureIndex
= SWAPW(langSysTable
->reqFeatureIndex
);
155 lookupSelectArray
= LE_NEW_ARRAY(LETag
, lookupListCount
);
157 for (int i
= 0; i
< lookupListCount
; i
+= 1) {
158 lookupSelectArray
[i
] = notSelected
;
161 le_int32 count
, order
= 0;
162 const FeatureTable
*featureTable
= 0;
165 lookupOrderArray
= LE_NEW_ARRAY(le_uint16
, lookupListCount
);
167 if (requiredFeatureIndex
!= 0xFFFF) {
168 featureTable
= featureListTable
->getFeatureTable(requiredFeatureIndex
, &featureTag
);
169 order
+= selectLookups(featureTable
, defaultFeature
, order
);
172 if (featureOrder
!= NULL
) {
174 OpenTypeUtilities::sort(lookupOrderArray
, order
);
177 for (le_int32 tag
= 0; featureOrder
[tag
] != emptyTag
; tag
+= 1) {
178 featureTag
= featureOrder
[tag
];
181 for (le_uint16 feature
= 0; feature
< featureCount
; feature
+= 1) {
182 le_uint16 featureIndex
= SWAPW(langSysTable
->featureIndexArray
[feature
]);
184 featureTable
= featureListTable
->getFeatureTable(featureIndex
, &featureTag
);
186 if (featureTag
== featureOrder
[tag
]) {
187 count
+= selectLookups(featureTable
, featureTag
, order
+ count
);
192 OpenTypeUtilities::sort(&lookupOrderArray
[order
], count
);
198 for (le_uint16 feature
= 0; feature
< featureCount
; feature
+= 1) {
199 le_uint16 featureIndex
= SWAPW(langSysTable
->featureIndexArray
[feature
]);
201 // don't add the required feature to the list more than once...
202 if (featureIndex
== requiredFeatureIndex
) {
206 featureTable
= featureListTable
->getFeatureTable(featureIndex
, &featureTag
);
207 count
= selectLookups(featureTable
, featureTag
, order
);
212 OpenTypeUtilities::sort(lookupOrderArray
, order
);
216 lookupOrderCount
= order
;
219 LookupProcessor::LookupProcessor()
223 LookupProcessor::~LookupProcessor()
225 LE_DELETE_ARRAY(lookupOrderArray
);
226 LE_DELETE_ARRAY(lookupSelectArray
);