]> git.saurik.com Git - apple/icu.git/blame - icuSources/layout/PairPositioningSubtables.cpp
ICU-6.2.9.tar.gz
[apple/icu.git] / icuSources / layout / PairPositioningSubtables.cpp
CommitLineData
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
18U_NAMESPACE_BEGIN
19
20le_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
46le_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
93le_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
136const 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
165U_NAMESPACE_END