]>
Commit | Line | Data |
---|---|---|
51004dcb A |
1 | /* |
2 | * | |
3 | * (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved | |
4 | * | |
5 | */ | |
6 | ||
7 | #include "LETypes.h" | |
8 | #include "MorphTables.h" | |
9 | #include "StateTables.h" | |
10 | #include "MorphStateTables.h" | |
11 | #include "SubtableProcessor2.h" | |
12 | #include "StateTableProcessor2.h" | |
13 | #include "LEGlyphStorage.h" | |
14 | #include "LESwaps.h" | |
15 | #include "LookupTables.h" | |
16 | #include <stdio.h> | |
17 | ||
18 | U_NAMESPACE_BEGIN | |
19 | ||
20 | StateTableProcessor2::StateTableProcessor2() | |
21 | { | |
22 | } | |
23 | ||
24 | StateTableProcessor2::StateTableProcessor2(const MorphSubtableHeader2 *morphSubtableHeader) | |
25 | : SubtableProcessor2(morphSubtableHeader) | |
26 | { | |
27 | stateTableHeader = (const MorphStateTableHeader2 *) morphSubtableHeader; | |
28 | nClasses = SWAPL(stateTableHeader->stHeader.nClasses); | |
29 | classTableOffset = SWAPL(stateTableHeader->stHeader.classTableOffset); | |
30 | stateArrayOffset = SWAPL(stateTableHeader->stHeader.stateArrayOffset); | |
31 | entryTableOffset = SWAPL(stateTableHeader->stHeader.entryTableOffset); | |
32 | ||
33 | classTable = (LookupTable *) ((char *) &stateTableHeader->stHeader + classTableOffset); | |
34 | format = SWAPW(classTable->format); | |
35 | ||
36 | stateArray = (const EntryTableIndex2 *) ((char *) &stateTableHeader->stHeader + stateArrayOffset); | |
37 | } | |
38 | ||
39 | StateTableProcessor2::~StateTableProcessor2() | |
40 | { | |
41 | } | |
42 | ||
43 | void StateTableProcessor2::process(LEGlyphStorage &glyphStorage) | |
44 | { | |
45 | // Start at state 0 | |
46 | // XXX: How do we know when to start at state 1? | |
47 | le_uint16 currentState = 0; | |
48 | le_int32 glyphCount = glyphStorage.getGlyphCount(); | |
49 | ||
50 | le_int32 currGlyph = 0; | |
51 | if ((coverage & scfReverse2) != 0) { // process glyphs in descending order | |
52 | currGlyph = glyphCount - 1; | |
53 | dir = -1; | |
54 | } else { | |
55 | dir = 1; | |
56 | } | |
57 | ||
58 | beginStateTable(); | |
59 | switch (format) { | |
60 | case ltfSimpleArray: { | |
61 | #ifdef TEST_FORMAT | |
62 | SimpleArrayLookupTable *lookupTable0 = (SimpleArrayLookupTable *) classTable; | |
63 | while ((dir == 1 && currGlyph <= glyphCount) || (dir == -1 && currGlyph >= -1)) { | |
64 | LookupValue classCode = classCodeOOB; | |
65 | if (currGlyph == glyphCount || currGlyph == -1) { | |
66 | // XXX: How do we handle EOT vs. EOL? | |
67 | classCode = classCodeEOT; | |
68 | } else { | |
69 | LEGlyphID gid = glyphStorage[currGlyph]; | |
70 | TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid); | |
71 | ||
72 | if (glyphCode == 0xFFFF) { | |
73 | classCode = classCodeDEL; | |
74 | } else { | |
75 | classCode = SWAPW(lookupTable0->valueArray[gid]); | |
76 | } | |
77 | } | |
78 | EntryTableIndex2 entryTableIndex = SWAPW(stateArray[classCode + currentState * nClasses]); | |
79 | currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex); // return a zero-based index instead of a byte offset | |
80 | } | |
81 | #endif | |
82 | break; | |
83 | } | |
84 | case ltfSegmentSingle: { | |
85 | SegmentSingleLookupTable *lookupTable2 = (SegmentSingleLookupTable *) classTable; | |
86 | while ((dir == 1 && currGlyph <= glyphCount) || (dir == -1 && currGlyph >= -1)) { | |
87 | LookupValue classCode = classCodeOOB; | |
88 | if (currGlyph == glyphCount || currGlyph == -1) { | |
89 | // XXX: How do we handle EOT vs. EOL? | |
90 | classCode = classCodeEOT; | |
91 | } else { | |
92 | LEGlyphID gid = glyphStorage[currGlyph]; | |
93 | TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid); | |
94 | ||
95 | if (glyphCode == 0xFFFF) { | |
96 | classCode = classCodeDEL; | |
97 | } else { | |
98 | const LookupSegment *segment = lookupTable2->lookupSegment(lookupTable2->segments, gid); | |
99 | if (segment != NULL) { | |
100 | classCode = SWAPW(segment->value); | |
101 | } | |
102 | } | |
103 | } | |
104 | EntryTableIndex2 entryTableIndex = SWAPW(stateArray[classCode + currentState * nClasses]); | |
105 | currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex); | |
106 | } | |
107 | break; | |
108 | } | |
109 | case ltfSegmentArray: { | |
110 | printf("Lookup Table Format4: specific interpretation needed!\n"); | |
111 | break; | |
112 | } | |
113 | case ltfSingleTable: { | |
114 | SingleTableLookupTable *lookupTable6 = (SingleTableLookupTable *) classTable; | |
115 | while ((dir == 1 && currGlyph <= glyphCount) || (dir == -1 && currGlyph >= -1)) { | |
116 | LookupValue classCode = classCodeOOB; | |
117 | if (currGlyph == glyphCount || currGlyph == -1) { | |
118 | // XXX: How do we handle EOT vs. EOL? | |
119 | classCode = classCodeEOT; | |
120 | } else { | |
121 | LEGlyphID gid = glyphStorage[currGlyph]; | |
122 | TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid); | |
123 | ||
124 | if (glyphCode == 0xFFFF) { | |
125 | classCode = classCodeDEL; | |
126 | } else { | |
127 | const LookupSingle *segment = lookupTable6->lookupSingle(lookupTable6->entries, gid); | |
128 | if (segment != NULL) { | |
129 | classCode = SWAPW(segment->value); | |
130 | } | |
131 | } | |
132 | } | |
133 | EntryTableIndex2 entryTableIndex = SWAPW(stateArray[classCode + currentState * nClasses]); | |
134 | currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex); | |
135 | } | |
136 | break; | |
137 | } | |
138 | case ltfTrimmedArray: { | |
139 | TrimmedArrayLookupTable *lookupTable8 = (TrimmedArrayLookupTable *) classTable; | |
140 | TTGlyphID firstGlyph = SWAPW(lookupTable8->firstGlyph); | |
141 | TTGlyphID lastGlyph = firstGlyph + SWAPW(lookupTable8->glyphCount); | |
142 | ||
143 | while ((dir == 1 && currGlyph <= glyphCount) || (dir == -1 && currGlyph >= -1)) { | |
144 | LookupValue classCode = classCodeOOB; | |
145 | if (currGlyph == glyphCount || currGlyph == -1) { | |
146 | // XXX: How do we handle EOT vs. EOL? | |
147 | classCode = classCodeEOT; | |
148 | } else { | |
149 | TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(glyphStorage[currGlyph]); | |
150 | if (glyphCode == 0xFFFF) { | |
151 | classCode = classCodeDEL; | |
152 | } else if ((glyphCode >= firstGlyph) && (glyphCode < lastGlyph)) { | |
153 | classCode = SWAPW(lookupTable8->valueArray[glyphCode - firstGlyph]); | |
154 | } | |
155 | } | |
156 | EntryTableIndex2 entryTableIndex = SWAPW(stateArray[classCode + currentState * nClasses]); | |
157 | currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex); | |
158 | } | |
159 | break; | |
160 | } | |
161 | default: | |
162 | break; | |
163 | } | |
164 | ||
165 | endStateTable(); | |
166 | } | |
167 | ||
168 | U_NAMESPACE_END |