]> git.saurik.com Git - apple/icu.git/blame - icuSources/layout/PairPositioningSubtables.cpp
ICU-3.13.tar.gz
[apple/icu.git] / icuSources / layout / PairPositioningSubtables.cpp
CommitLineData
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
19U_NAMESPACE_BEGIN
20
21le_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
47le_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
90le_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
133const 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
162U_NAMESPACE_END