3 * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
8 #include "LEFontInstance.h"
9 #include "OpenTypeTables.h"
10 #include "GlyphPositioningTables.h"
11 #include "PairPositioningSubtables.h"
12 #include "ValueRecords.h"
13 #include "GlyphIterator.h"
14 #include "GlyphPositionAdjustments.h"
15 #include "OpenTypeUtilities.h"
20 le_uint32
PairPositioningSubtable::process(GlyphIterator
*glyphIterator
, const LEFontInstance
*fontInstance
) const
22 switch(SWAPW(subtableFormat
))
29 const PairPositioningFormat1Subtable
*subtable
= (const PairPositioningFormat1Subtable
*) this;
31 return subtable
->process(glyphIterator
, fontInstance
);
36 const PairPositioningFormat2Subtable
*subtable
= (const PairPositioningFormat2Subtable
*) this;
38 return subtable
->process(glyphIterator
, fontInstance
);
46 le_uint32
PairPositioningFormat1Subtable::process(GlyphIterator
*glyphIterator
, const LEFontInstance
*fontInstance
) const
48 LEGlyphID firstGlyph
= glyphIterator
->getCurrGlyphID();
49 le_int32 coverageIndex
= getGlyphCoverage(firstGlyph
);
50 GlyphIterator
tempIterator(*glyphIterator
);
52 if (coverageIndex
>= 0 && glyphIterator
->next()) {
53 Offset pairSetTableOffset
= SWAPW(pairSetTableOffsetArray
[coverageIndex
]);
54 PairSetTable
*pairSetTable
= (PairSetTable
*) ((char *) this + pairSetTableOffset
);
55 le_uint16 pairValueCount
= SWAPW(pairSetTable
->pairValueCount
);
56 le_int16 valueRecord1Size
= ValueRecord::getSize(SWAPW(valueFormat1
));
57 le_int16 valueRecord2Size
= ValueRecord::getSize(SWAPW(valueFormat2
));
58 le_int16 recordSize
= sizeof(PairValueRecord
) - sizeof(ValueRecord
) + valueRecord1Size
+ valueRecord2Size
;
59 LEGlyphID secondGlyph
= glyphIterator
->getCurrGlyphID();
60 const PairValueRecord
*pairValueRecord
= NULL
;
62 if (pairValueCount
!= 0) {
63 pairValueRecord
= findPairValueRecord((TTGlyphID
) LE_GET_GLYPH(secondGlyph
), pairSetTable
->pairValueRecordArray
, pairValueCount
, recordSize
);
66 if (pairValueRecord
== NULL
) {
70 if (valueFormat1
!= 0) {
71 GlyphPositionAdjustment adjustment
;
73 tempIterator
.getCurrGlyphPositionAdjustment(adjustment
);
74 pairValueRecord
->valueRecord1
.adjustPosition(SWAPW(valueFormat1
), (char *) this, adjustment
, fontInstance
);
75 tempIterator
.setCurrGlyphPositionAdjustment(&adjustment
);
78 if (valueFormat2
!= 0) {
79 const ValueRecord
*valueRecord2
= (const ValueRecord
*) ((char *) &pairValueRecord
->valueRecord1
+ valueRecord1Size
);
80 GlyphPositionAdjustment adjustment
;
82 glyphIterator
->getCurrGlyphPositionAdjustment(adjustment
);
83 valueRecord2
->adjustPosition(SWAPW(valueFormat2
), (char *) this, adjustment
, fontInstance
);
84 glyphIterator
->setCurrGlyphPositionAdjustment(&adjustment
);
93 le_uint32
PairPositioningFormat2Subtable::process(GlyphIterator
*glyphIterator
, const LEFontInstance
*fontInstance
) const
95 LEGlyphID firstGlyph
= glyphIterator
->getCurrGlyphID();
96 le_int32 coverageIndex
= getGlyphCoverage(firstGlyph
);
97 GlyphIterator
tempIterator(*glyphIterator
);
99 if (coverageIndex
>= 0 && glyphIterator
->next()) {
100 LEGlyphID secondGlyph
= glyphIterator
->getCurrGlyphID();
101 const ClassDefinitionTable
*classDef1
= (const ClassDefinitionTable
*) ((char *) this + SWAPW(classDef1Offset
));
102 const ClassDefinitionTable
*classDef2
= (const ClassDefinitionTable
*) ((char *) this + SWAPW(classDef2Offset
));
103 le_int32 class1
= classDef1
->getGlyphClass(firstGlyph
);
104 le_int32 class2
= classDef2
->getGlyphClass(secondGlyph
);
105 le_int16 valueRecord1Size
= ValueRecord::getSize(SWAPW(valueFormat1
));
106 le_int16 valueRecord2Size
= ValueRecord::getSize(SWAPW(valueFormat2
));
107 le_int16 class2RecordSize
= valueRecord1Size
+ valueRecord2Size
;
108 le_int16 class1RecordSize
= class2RecordSize
* SWAPW(class2Count
);
109 const Class1Record
*class1Record
= (const Class1Record
*) ((char *) class1RecordArray
+ (class1RecordSize
* class1
));
110 const Class2Record
*class2Record
= (const Class2Record
*) ((char *) class1Record
->class2RecordArray
+ (class2RecordSize
* class2
));
113 if (valueFormat1
!= 0) {
114 GlyphPositionAdjustment adjustment
;
116 tempIterator
.getCurrGlyphPositionAdjustment(adjustment
);
117 class2Record
->valueRecord1
.adjustPosition(SWAPW(valueFormat1
), (char *) this, adjustment
, fontInstance
);
118 tempIterator
.setCurrGlyphPositionAdjustment(&adjustment
);
121 if (valueFormat2
!= 0) {
122 const ValueRecord
*valueRecord2
= (const ValueRecord
*) ((char *) &class2Record
->valueRecord1
+ valueRecord1Size
);
123 GlyphPositionAdjustment adjustment
;
125 glyphIterator
->getCurrGlyphPositionAdjustment(adjustment
);
126 valueRecord2
->adjustPosition(SWAPW(valueFormat2
), (const char *) this, adjustment
, fontInstance
);
127 glyphIterator
->setCurrGlyphPositionAdjustment(&adjustment
);
136 const PairValueRecord
*PairPositioningFormat1Subtable::findPairValueRecord(TTGlyphID glyphID
, const PairValueRecord
*records
, le_uint16 recordCount
, le_uint16 recordSize
) const
138 le_uint8 bit
= OpenTypeUtilities::highBit(recordCount
);
139 le_uint16 power
= 1 << bit
;
140 le_uint16 extra
= (recordCount
- power
) * recordSize
;
141 le_uint16 probe
= power
* recordSize
;
142 const PairValueRecord
*record
= records
;
143 const PairValueRecord
*trial
= (const PairValueRecord
*) ((char *) record
+ extra
);
145 if (SWAPW(trial
->secondGlyph
) <= glyphID
) {
149 while (probe
> recordSize
) {
151 trial
= (const PairValueRecord
*) ((char *) record
+ probe
);
153 if (SWAPW(trial
->secondGlyph
) <= glyphID
) {
158 if (SWAPW(record
->secondGlyph
) == glyphID
) {