]>
Commit | Line | Data |
---|---|---|
b75a7d8f A |
1 | /* |
2 | * @(#)PairPositioningSubtables.cpp 1.7 00/03/15 | |
3 | * | |
4 | * (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved | |
5 | * | |
6 | */ | |
7 | ||
8 | #include "LETypes.h" | |
9 | #include "LEFontInstance.h" | |
10 | #include "OpenTypeTables.h" | |
11 | #include "GlyphPositioningTables.h" | |
12 | #include "PairPositioningSubtables.h" | |
13 | #include "ValueRecords.h" | |
14 | #include "GlyphIterator.h" | |
15 | #include "GlyphPositionAdjustments.h" | |
16 | #include "OpenTypeUtilities.h" | |
17 | #include "LESwaps.h" | |
18 | ||
19 | U_NAMESPACE_BEGIN | |
20 | ||
21 | le_uint32 PairPositioningSubtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const | |
22 | { | |
23 | switch(SWAPW(subtableFormat)) | |
24 | { | |
25 | case 0: | |
26 | return 0; | |
27 | ||
28 | case 1: | |
29 | { | |
30 | const PairPositioningFormat1Subtable *subtable = (const PairPositioningFormat1Subtable *) this; | |
31 | ||
32 | return subtable->process(glyphIterator, fontInstance); | |
33 | } | |
34 | ||
35 | case 2: | |
36 | { | |
37 | const PairPositioningFormat2Subtable *subtable = (const PairPositioningFormat2Subtable *) this; | |
38 | ||
39 | return subtable->process(glyphIterator, fontInstance); | |
40 | } | |
41 | ||
42 | default: | |
43 | return 0; | |
44 | } | |
45 | } | |
46 | ||
47 | le_uint32 PairPositioningFormat1Subtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const | |
48 | { | |
49 | LEGlyphID firstGlyph = glyphIterator->getCurrGlyphID(); | |
50 | le_int32 coverageIndex = getGlyphCoverage(firstGlyph); | |
51 | GlyphIterator tempIterator(*glyphIterator); | |
52 | ||
53 | if (coverageIndex >= 0 && glyphIterator->next()) { | |
54 | Offset pairSetTableOffset = SWAPW(pairSetTableOffsetArray[coverageIndex]); | |
55 | PairSetTable *pairSetTable = (PairSetTable *) ((char *) this + pairSetTableOffset); | |
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 = | |
61 | findPairValueRecord((TTGlyphID) LE_GET_GLYPH(secondGlyph), pairSetTable->pairValueRecordArray, SWAPW(pairSetTable->pairValueCount), recordSize); | |
62 | ||
63 | if (pairValueRecord == NULL) { | |
64 | return 0; | |
65 | } | |
66 | ||
67 | if (valueFormat1 != 0) { | |
68 | GlyphPositionAdjustment adjustment; | |
69 | ||
70 | tempIterator.getCurrGlyphPositionAdjustment(adjustment); | |
71 | pairValueRecord->valueRecord1.adjustPosition(SWAPW(valueFormat1), (char *) this, adjustment, fontInstance); | |
72 | tempIterator.setCurrGlyphPositionAdjustment(&adjustment); | |
73 | } | |
74 | ||
75 | if (valueFormat2 != 0) { | |
76 | const ValueRecord *valueRecord2 = (const ValueRecord *) ((char *) &pairValueRecord->valueRecord1 + valueRecord1Size); | |
77 | GlyphPositionAdjustment adjustment; | |
78 | ||
79 | glyphIterator->getCurrGlyphPositionAdjustment(adjustment); | |
80 | valueRecord2->adjustPosition(SWAPW(valueFormat2), (char *) this, adjustment, fontInstance); | |
81 | glyphIterator->setCurrGlyphPositionAdjustment(&adjustment); | |
82 | } | |
83 | ||
84 | return 2; | |
85 | } | |
86 | ||
87 | return 0; | |
88 | } | |
89 | ||
90 | le_uint32 PairPositioningFormat2Subtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const | |
91 | { | |
92 | LEGlyphID firstGlyph = glyphIterator->getCurrGlyphID(); | |
93 | le_int32 coverageIndex = getGlyphCoverage(firstGlyph); | |
94 | GlyphIterator tempIterator(*glyphIterator); | |
95 | ||
96 | if (coverageIndex >= 0 && glyphIterator->next()) { | |
97 | LEGlyphID secondGlyph = glyphIterator->getCurrGlyphID(); | |
98 | const ClassDefinitionTable *classDef1 = (const ClassDefinitionTable *) ((char *) this + SWAPW(classDef1Offset)); | |
99 | const ClassDefinitionTable *classDef2 = (const ClassDefinitionTable *) ((char *) this + SWAPW(classDef2Offset)); | |
100 | le_int32 class1 = classDef1->getGlyphClass(firstGlyph); | |
101 | le_int32 class2 = classDef2->getGlyphClass(secondGlyph); | |
102 | le_int16 valueRecord1Size = ValueRecord::getSize(SWAPW(valueFormat1)); | |
103 | le_int16 valueRecord2Size = ValueRecord::getSize(SWAPW(valueFormat2)); | |
104 | le_int16 class2RecordSize = valueRecord1Size + valueRecord2Size; | |
105 | le_int16 class1RecordSize = class2RecordSize * SWAPW(class2Count); | |
106 | const Class1Record *class1Record = (const Class1Record *) ((char *) class1RecordArray + (class1RecordSize * class1)); | |
107 | const Class2Record *class2Record = (const Class2Record *) ((char *) class1Record->class2RecordArray + (class2RecordSize * class2)); | |
108 | ||
109 | ||
110 | if (valueFormat1 != 0) { | |
111 | GlyphPositionAdjustment adjustment; | |
112 | ||
113 | tempIterator.getCurrGlyphPositionAdjustment(adjustment); | |
114 | class2Record->valueRecord1.adjustPosition(SWAPW(valueFormat1), (char *) this, adjustment, fontInstance); | |
115 | tempIterator.setCurrGlyphPositionAdjustment(&adjustment); | |
116 | } | |
117 | ||
118 | if (valueFormat2 != 0) { | |
119 | const ValueRecord *valueRecord2 = (const ValueRecord *) ((char *) &class2Record->valueRecord1 + valueRecord1Size); | |
120 | GlyphPositionAdjustment adjustment; | |
121 | ||
122 | glyphIterator->getCurrGlyphPositionAdjustment(adjustment); | |
123 | valueRecord2->adjustPosition(SWAPW(valueFormat2), (const char *) this, adjustment, fontInstance); | |
124 | glyphIterator->setCurrGlyphPositionAdjustment(&adjustment); | |
125 | } | |
126 | ||
127 | return 2; | |
128 | } | |
129 | ||
130 | return 0; | |
131 | } | |
132 | ||
133 | const PairValueRecord *PairPositioningFormat1Subtable::findPairValueRecord(TTGlyphID glyphID, const PairValueRecord *records, le_uint16 recordCount, le_uint16 recordSize) const | |
134 | { | |
135 | le_uint8 bit = OpenTypeUtilities::highBit(recordCount); | |
136 | le_uint16 power = 1 << bit; | |
137 | le_uint16 extra = (recordCount - power) * recordSize; | |
138 | le_uint16 probe = power * recordSize; | |
139 | const PairValueRecord *record = records; | |
140 | const PairValueRecord *trial = (const PairValueRecord *) ((char *) record + extra); | |
141 | ||
142 | if (SWAPW(trial->secondGlyph) <= glyphID) { | |
143 | record = trial; | |
144 | } | |
145 | ||
146 | while (probe > recordSize) { | |
147 | probe >>= 1; | |
148 | trial = (const PairValueRecord *) ((char *) record + probe); | |
149 | ||
150 | if (SWAPW(trial->secondGlyph) <= glyphID) { | |
151 | record = trial; | |
152 | } | |
153 | } | |
154 | ||
155 | if (SWAPW(record->secondGlyph) == glyphID) { | |
156 | return record; | |
157 | } | |
158 | ||
159 | return NULL; | |
160 | } | |
161 | ||
162 | U_NAMESPACE_END |