]>
Commit | Line | Data |
---|---|---|
b75a7d8f | 1 | /* |
b75a7d8f | 2 | * |
374ca955 | 3 | * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved |
b75a7d8f A |
4 | * |
5 | */ | |
6 | ||
7 | #include "LETypes.h" | |
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" | |
16 | #include "LESwaps.h" | |
17 | ||
18 | U_NAMESPACE_BEGIN | |
19 | ||
20 | le_uint32 PairPositioningSubtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const | |
21 | { | |
22 | switch(SWAPW(subtableFormat)) | |
23 | { | |
24 | case 0: | |
25 | return 0; | |
26 | ||
27 | case 1: | |
28 | { | |
29 | const PairPositioningFormat1Subtable *subtable = (const PairPositioningFormat1Subtable *) this; | |
30 | ||
31 | return subtable->process(glyphIterator, fontInstance); | |
32 | } | |
33 | ||
34 | case 2: | |
35 | { | |
36 | const PairPositioningFormat2Subtable *subtable = (const PairPositioningFormat2Subtable *) this; | |
37 | ||
38 | return subtable->process(glyphIterator, fontInstance); | |
39 | } | |
40 | ||
41 | default: | |
42 | return 0; | |
43 | } | |
44 | } | |
45 | ||
46 | le_uint32 PairPositioningFormat1Subtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const | |
47 | { | |
48 | LEGlyphID firstGlyph = glyphIterator->getCurrGlyphID(); | |
49 | le_int32 coverageIndex = getGlyphCoverage(firstGlyph); | |
50 | GlyphIterator tempIterator(*glyphIterator); | |
51 | ||
52 | if (coverageIndex >= 0 && glyphIterator->next()) { | |
53 | Offset pairSetTableOffset = SWAPW(pairSetTableOffsetArray[coverageIndex]); | |
54 | PairSetTable *pairSetTable = (PairSetTable *) ((char *) this + pairSetTableOffset); | |
374ca955 | 55 | le_uint16 pairValueCount = SWAPW(pairSetTable->pairValueCount); |
b75a7d8f A |
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(); | |
374ca955 A |
60 | const PairValueRecord *pairValueRecord = NULL; |
61 | ||
62 | if (pairValueCount != 0) { | |
63 | pairValueRecord = findPairValueRecord((TTGlyphID) LE_GET_GLYPH(secondGlyph), pairSetTable->pairValueRecordArray, pairValueCount, recordSize); | |
64 | } | |
b75a7d8f A |
65 | |
66 | if (pairValueRecord == NULL) { | |
67 | return 0; | |
68 | } | |
69 | ||
70 | if (valueFormat1 != 0) { | |
71 | GlyphPositionAdjustment adjustment; | |
72 | ||
73 | tempIterator.getCurrGlyphPositionAdjustment(adjustment); | |
74 | pairValueRecord->valueRecord1.adjustPosition(SWAPW(valueFormat1), (char *) this, adjustment, fontInstance); | |
75 | tempIterator.setCurrGlyphPositionAdjustment(&adjustment); | |
76 | } | |
77 | ||
78 | if (valueFormat2 != 0) { | |
79 | const ValueRecord *valueRecord2 = (const ValueRecord *) ((char *) &pairValueRecord->valueRecord1 + valueRecord1Size); | |
80 | GlyphPositionAdjustment adjustment; | |
81 | ||
82 | glyphIterator->getCurrGlyphPositionAdjustment(adjustment); | |
83 | valueRecord2->adjustPosition(SWAPW(valueFormat2), (char *) this, adjustment, fontInstance); | |
84 | glyphIterator->setCurrGlyphPositionAdjustment(&adjustment); | |
85 | } | |
86 | ||
87 | return 2; | |
88 | } | |
89 | ||
90 | return 0; | |
91 | } | |
92 | ||
93 | le_uint32 PairPositioningFormat2Subtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const | |
94 | { | |
95 | LEGlyphID firstGlyph = glyphIterator->getCurrGlyphID(); | |
96 | le_int32 coverageIndex = getGlyphCoverage(firstGlyph); | |
97 | GlyphIterator tempIterator(*glyphIterator); | |
98 | ||
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)); | |
111 | ||
112 | ||
113 | if (valueFormat1 != 0) { | |
114 | GlyphPositionAdjustment adjustment; | |
115 | ||
116 | tempIterator.getCurrGlyphPositionAdjustment(adjustment); | |
117 | class2Record->valueRecord1.adjustPosition(SWAPW(valueFormat1), (char *) this, adjustment, fontInstance); | |
118 | tempIterator.setCurrGlyphPositionAdjustment(&adjustment); | |
119 | } | |
120 | ||
121 | if (valueFormat2 != 0) { | |
122 | const ValueRecord *valueRecord2 = (const ValueRecord *) ((char *) &class2Record->valueRecord1 + valueRecord1Size); | |
123 | GlyphPositionAdjustment adjustment; | |
124 | ||
125 | glyphIterator->getCurrGlyphPositionAdjustment(adjustment); | |
126 | valueRecord2->adjustPosition(SWAPW(valueFormat2), (const char *) this, adjustment, fontInstance); | |
127 | glyphIterator->setCurrGlyphPositionAdjustment(&adjustment); | |
128 | } | |
129 | ||
130 | return 2; | |
131 | } | |
132 | ||
133 | return 0; | |
134 | } | |
135 | ||
136 | const PairValueRecord *PairPositioningFormat1Subtable::findPairValueRecord(TTGlyphID glyphID, const PairValueRecord *records, le_uint16 recordCount, le_uint16 recordSize) const | |
137 | { | |
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); | |
144 | ||
145 | if (SWAPW(trial->secondGlyph) <= glyphID) { | |
146 | record = trial; | |
147 | } | |
148 | ||
149 | while (probe > recordSize) { | |
150 | probe >>= 1; | |
151 | trial = (const PairValueRecord *) ((char *) record + probe); | |
152 | ||
153 | if (SWAPW(trial->secondGlyph) <= glyphID) { | |
154 | record = trial; | |
155 | } | |
156 | } | |
157 | ||
158 | if (SWAPW(record->secondGlyph) == glyphID) { | |
159 | return record; | |
160 | } | |
161 | ||
162 | return NULL; | |
163 | } | |
164 | ||
165 | U_NAMESPACE_END |