3 * (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
8 #include "MorphTables.h"
9 #include "StateTables.h"
10 #include "MorphStateTables.h"
11 #include "SubtableProcessor2.h"
12 #include "StateTableProcessor2.h"
13 #include "LEGlyphStorage.h"
15 #include "LookupTables.h"
20 StateTableProcessor2::StateTableProcessor2()
24 StateTableProcessor2::StateTableProcessor2(const MorphSubtableHeader2
*morphSubtableHeader
)
25 : SubtableProcessor2(morphSubtableHeader
)
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
);
33 classTable
= (LookupTable
*) ((char *) &stateTableHeader
->stHeader
+ classTableOffset
);
34 format
= SWAPW(classTable
->format
);
36 stateArray
= (const EntryTableIndex2
*) ((char *) &stateTableHeader
->stHeader
+ stateArrayOffset
);
39 StateTableProcessor2::~StateTableProcessor2()
43 void StateTableProcessor2::process(LEGlyphStorage
&glyphStorage
)
46 // XXX: How do we know when to start at state 1?
47 le_uint16 currentState
= 0;
48 le_int32 glyphCount
= glyphStorage
.getGlyphCount();
50 le_int32 currGlyph
= 0;
51 if ((coverage
& scfReverse2
) != 0) { // process glyphs in descending order
52 currGlyph
= glyphCount
- 1;
60 case ltfSimpleArray
: {
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
;
69 LEGlyphID gid
= glyphStorage
[currGlyph
];
70 TTGlyphID glyphCode
= (TTGlyphID
) LE_GET_GLYPH(gid
);
72 if (glyphCode
== 0xFFFF) {
73 classCode
= classCodeDEL
;
75 classCode
= SWAPW(lookupTable0
->valueArray
[gid
]);
78 EntryTableIndex2 entryTableIndex
= SWAPW(stateArray
[classCode
+ currentState
* nClasses
]);
79 currentState
= processStateEntry(glyphStorage
, currGlyph
, entryTableIndex
); // return a zero-based index instead of a byte offset
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
;
92 LEGlyphID gid
= glyphStorage
[currGlyph
];
93 TTGlyphID glyphCode
= (TTGlyphID
) LE_GET_GLYPH(gid
);
95 if (glyphCode
== 0xFFFF) {
96 classCode
= classCodeDEL
;
98 const LookupSegment
*segment
= lookupTable2
->lookupSegment(lookupTable2
->segments
, gid
);
99 if (segment
!= NULL
) {
100 classCode
= SWAPW(segment
->value
);
104 EntryTableIndex2 entryTableIndex
= SWAPW(stateArray
[classCode
+ currentState
* nClasses
]);
105 currentState
= processStateEntry(glyphStorage
, currGlyph
, entryTableIndex
);
109 case ltfSegmentArray
: {
110 printf("Lookup Table Format4: specific interpretation needed!\n");
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
;
121 LEGlyphID gid
= glyphStorage
[currGlyph
];
122 TTGlyphID glyphCode
= (TTGlyphID
) LE_GET_GLYPH(gid
);
124 if (glyphCode
== 0xFFFF) {
125 classCode
= classCodeDEL
;
127 const LookupSingle
*segment
= lookupTable6
->lookupSingle(lookupTable6
->entries
, gid
);
128 if (segment
!= NULL
) {
129 classCode
= SWAPW(segment
->value
);
133 EntryTableIndex2 entryTableIndex
= SWAPW(stateArray
[classCode
+ currentState
* nClasses
]);
134 currentState
= processStateEntry(glyphStorage
, currGlyph
, entryTableIndex
);
138 case ltfTrimmedArray
: {
139 TrimmedArrayLookupTable
*lookupTable8
= (TrimmedArrayLookupTable
*) classTable
;
140 TTGlyphID firstGlyph
= SWAPW(lookupTable8
->firstGlyph
);
141 TTGlyphID lastGlyph
= firstGlyph
+ SWAPW(lookupTable8
->glyphCount
);
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
;
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
]);
156 EntryTableIndex2 entryTableIndex
= SWAPW(stateArray
[classCode
+ currentState
* nClasses
]);
157 currentState
= processStateEntry(glyphStorage
, currGlyph
, entryTableIndex
);