41 |
41 |
42 U_NAMESPACE_BEGIN |
42 U_NAMESPACE_BEGIN |
43 |
43 |
44 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ContextualGlyphSubstitutionProcessor2) |
44 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ContextualGlyphSubstitutionProcessor2) |
45 |
45 |
46 ContextualGlyphSubstitutionProcessor2::ContextualGlyphSubstitutionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader) |
46 ContextualGlyphSubstitutionProcessor2::ContextualGlyphSubstitutionProcessor2( |
47 : StateTableProcessor2(morphSubtableHeader) |
47 const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success) |
|
48 : StateTableProcessor2(morphSubtableHeader, success), contextualGlyphHeader(morphSubtableHeader, success) |
48 { |
49 { |
49 contextualGlyphHeader = (const ContextualGlyphHeader2 *) morphSubtableHeader; |
50 if(LE_FAILURE(success)) return; |
50 le_uint32 perGlyphTableOffset = SWAPL(contextualGlyphHeader->perGlyphTableOffset); |
51 le_uint32 perGlyphTableOffset = SWAPL(contextualGlyphHeader->perGlyphTableOffset); |
51 perGlyphTable = ((le_uint32 *) ((char *)&stateTableHeader->stHeader + perGlyphTableOffset)); |
52 perGlyphTable = LEReferenceToArrayOf<le_uint32> (stHeader, success, perGlyphTableOffset, LE_UNBOUNDED_ARRAY); |
52 entryTable = (const ContextualGlyphStateEntry2 *) ((char *) &stateTableHeader->stHeader + entryTableOffset); |
53 entryTable = LEReferenceToArrayOf<ContextualGlyphStateEntry2>(stHeader, success, entryTableOffset, LE_UNBOUNDED_ARRAY); |
53 } |
54 } |
54 |
55 |
55 ContextualGlyphSubstitutionProcessor2::~ContextualGlyphSubstitutionProcessor2() |
56 ContextualGlyphSubstitutionProcessor2::~ContextualGlyphSubstitutionProcessor2() |
56 { |
57 { |
57 } |
58 } |
59 void ContextualGlyphSubstitutionProcessor2::beginStateTable() |
60 void ContextualGlyphSubstitutionProcessor2::beginStateTable() |
60 { |
61 { |
61 markGlyph = 0; |
62 markGlyph = 0; |
62 } |
63 } |
63 |
64 |
64 le_uint16 ContextualGlyphSubstitutionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index) |
65 le_uint16 ContextualGlyphSubstitutionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, |
|
66 EntryTableIndex2 index, LEErrorCode &success) |
65 { |
67 { |
66 const ContextualGlyphStateEntry2 *entry = &entryTable[index]; |
68 if(LE_FAILURE(success)) return 0; |
|
69 const ContextualGlyphStateEntry2 *entry = entryTable.getAlias(index, success); |
|
70 if(LE_FAILURE(success)) return 0; |
67 le_uint16 newState = SWAPW(entry->newStateIndex); |
71 le_uint16 newState = SWAPW(entry->newStateIndex); |
68 le_uint16 flags = SWAPW(entry->flags); |
72 le_uint16 flags = SWAPW(entry->flags); |
69 le_int16 markIndex = SWAPW(entry->markIndex); |
73 le_int16 markIndex = SWAPW(entry->markIndex); |
70 le_int16 currIndex = SWAPW(entry->currIndex); |
74 le_int16 currIndex = SWAPW(entry->currIndex); |
71 |
75 |
72 if (markIndex != -1) { |
76 if (markIndex != -1) { |
73 le_uint32 offset = SWAPL(perGlyphTable[markIndex]); |
77 le_uint32 offset = SWAPL(perGlyphTable(markIndex, success)); |
74 LEGlyphID mGlyph = glyphStorage[markGlyph]; |
78 LEGlyphID mGlyph = glyphStorage[markGlyph]; |
75 TTGlyphID newGlyph = lookup(offset, mGlyph); |
79 TTGlyphID newGlyph = lookup(offset, mGlyph, success); |
76 glyphStorage[markGlyph] = LE_SET_GLYPH(mGlyph, newGlyph); |
80 glyphStorage[markGlyph] = LE_SET_GLYPH(mGlyph, newGlyph); |
77 } |
81 } |
78 |
82 |
79 if (currIndex != -1) { |
83 if (currIndex != -1) { |
80 le_uint32 offset = SWAPL(perGlyphTable[currIndex]); |
84 le_uint32 offset = SWAPL(perGlyphTable(currIndex, success)); |
81 LEGlyphID thisGlyph = glyphStorage[currGlyph]; |
85 LEGlyphID thisGlyph = glyphStorage[currGlyph]; |
82 TTGlyphID newGlyph = lookup(offset, thisGlyph); |
86 TTGlyphID newGlyph = lookup(offset, thisGlyph, success); |
83 glyphStorage[currGlyph] = LE_SET_GLYPH(thisGlyph, newGlyph); |
87 glyphStorage[currGlyph] = LE_SET_GLYPH(thisGlyph, newGlyph); |
84 } |
88 } |
85 |
89 |
86 if (flags & cgsSetMark) { |
90 if (flags & cgsSetMark) { |
87 markGlyph = currGlyph; |
91 markGlyph = currGlyph; |
92 } |
96 } |
93 |
97 |
94 return newState; |
98 return newState; |
95 } |
99 } |
96 |
100 |
97 TTGlyphID ContextualGlyphSubstitutionProcessor2::lookup(le_uint32 offset, LEGlyphID gid) |
101 TTGlyphID ContextualGlyphSubstitutionProcessor2::lookup(le_uint32 offset, LEGlyphID gid, LEErrorCode &success) |
98 { |
102 { |
99 LookupTable *lookupTable = ((LookupTable *) ((char *)perGlyphTable + offset)); |
103 TTGlyphID newGlyph = 0xFFFF; |
|
104 if(LE_FAILURE(success)) return newGlyph; |
|
105 LEReferenceTo<LookupTable> lookupTable(perGlyphTable, success, offset); |
|
106 if(LE_FAILURE(success)) return newGlyph; |
100 le_int16 format = SWAPW(lookupTable->format); |
107 le_int16 format = SWAPW(lookupTable->format); |
101 TTGlyphID newGlyph = 0xFFFF; |
|
102 |
108 |
103 switch (format) { |
109 switch (format) { |
104 case ltfSimpleArray: { |
110 case ltfSimpleArray: { |
105 #ifdef TEST_FORMAT |
111 #ifdef TEST_FORMAT |
106 // Disabled pending for design review |
112 // Disabled pending for design review |
107 SimpleArrayLookupTable *lookupTable0 = (SimpleArrayLookupTable *) lookupTable; |
113 LEReferenceTo<SimpleArrayLookupTable> lookupTable0(lookupTable, success); |
|
114 LEReferenceToArrayOf<LookupValue> valueArray(lookupTable0, success, &lookupTable0->valueArray[0], LE_UNBOUNDED_ARRAY); |
|
115 if(LE_FAILURE(success)) return newGlyph; |
108 TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid); |
116 TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid); |
109 newGlyph = SWAPW(lookupTable0->valueArray[glyphCode]); |
117 newGlyph = SWAPW(lookupTable0->valueArray(glyphCode, success)); |
110 #endif |
118 #endif |
111 break; |
119 break; |
112 } |
120 } |
113 case ltfSegmentSingle: { |
121 case ltfSegmentSingle: { |
114 #ifdef TEST_FORMAT |
122 #ifdef TEST_FORMAT |
115 // Disabled pending for design review |
123 // Disabled pending for design review |
116 SegmentSingleLookupTable *lookupTable2 = (SegmentSingleLookupTable *) lookupTable; |
124 LEReferenceTo<SegmentSingleLookupTable> lookupTable2 = (SegmentSingleLookupTable *) lookupTable; |
117 const LookupSegment *segment = lookupTable2->lookupSegment(lookupTable2->segments, gid); |
125 const LookupSegment *segment = lookupTable2->lookupSegment(lookupTable2->segments, gid); |
118 if (segment != NULL) { |
126 if (segment != NULL) { |
119 newGlyph = SWAPW(segment->value); |
127 newGlyph = SWAPW(segment->value); |
120 } |
128 } |
121 #endif |
129 #endif |
127 } |
135 } |
128 case ltfSingleTable: |
136 case ltfSingleTable: |
129 { |
137 { |
130 #ifdef TEST_FORMAT |
138 #ifdef TEST_FORMAT |
131 // Disabled pending for design review |
139 // Disabled pending for design review |
132 SingleTableLookupTable *lookupTable6 = (SingleTableLookupTable *) lookupTable; |
140 LEReferenceTo<SingleTableLookupTable> lookupTable6 = (SingleTableLookupTable *) lookupTable; |
133 const LookupSingle *segment = lookupTable6->lookupSingle(lookupTable6->entries, gid); |
141 const LEReferenceTo<LookupSingle> segment = lookupTable6->lookupSingle(lookupTable6->entries, gid); |
134 if (segment != NULL) { |
142 if (segment != NULL) { |
135 newGlyph = SWAPW(segment->value); |
143 newGlyph = SWAPW(segment->value); |
136 } |
144 } |
137 #endif |
145 #endif |
138 break; |
146 break; |
139 } |
147 } |
140 case ltfTrimmedArray: { |
148 case ltfTrimmedArray: { |
141 TrimmedArrayLookupTable *lookupTable8 = (TrimmedArrayLookupTable *) lookupTable; |
149 LEReferenceTo<TrimmedArrayLookupTable> lookupTable8(lookupTable, success); |
|
150 if (LE_FAILURE(success)) return newGlyph; |
142 TTGlyphID firstGlyph = SWAPW(lookupTable8->firstGlyph); |
151 TTGlyphID firstGlyph = SWAPW(lookupTable8->firstGlyph); |
143 TTGlyphID lastGlyph = firstGlyph + SWAPW(lookupTable8->glyphCount); |
152 TTGlyphID glyphCount = SWAPW(lookupTable8->glyphCount); |
|
153 TTGlyphID lastGlyph = firstGlyph + glyphCount; |
144 TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid); |
154 TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid); |
145 if ((glyphCode >= firstGlyph) && (glyphCode < lastGlyph)) { |
155 if ((glyphCode >= firstGlyph) && (glyphCode < lastGlyph)) { |
146 newGlyph = SWAPW(lookupTable8->valueArray[glyphCode - firstGlyph]); |
156 LEReferenceToArrayOf<LookupValue> valueArray(lookupTable8, success, &lookupTable8->valueArray[0], glyphCount); |
|
157 newGlyph = SWAPW(valueArray(glyphCode - firstGlyph, success)); |
147 } |
158 } |
148 } |
159 } |
149 default: |
160 default: |
150 break; |
161 break; |
151 } |
162 } |