]>
Commit | Line | Data |
---|---|---|
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 "MorphTables.h" | |
9 | #include "StateTables.h" | |
10 | #include "MorphStateTables.h" | |
11 | #include "SubtableProcessor.h" | |
12 | #include "StateTableProcessor.h" | |
13 | #include "LigatureSubstProc.h" | |
374ca955 | 14 | #include "LEGlyphStorage.h" |
b75a7d8f A |
15 | #include "LESwaps.h" |
16 | ||
17 | U_NAMESPACE_BEGIN | |
18 | ||
19 | #define ExtendedComplement(m) ((le_int32) (~((le_uint32) (m)))) | |
374ca955 | 20 | #define SignBit(m) ((ExtendedComplement(m) >> 1) & (le_int32)(m)) |
b75a7d8f A |
21 | #define SignExtend(v,m) (((v) & SignBit(m))? ((v) | ExtendedComplement(m)): (v)) |
22 | ||
374ca955 | 23 | UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LigatureSubstitutionProcessor) |
b75a7d8f A |
24 | |
25 | LigatureSubstitutionProcessor::LigatureSubstitutionProcessor(const MorphSubtableHeader *morphSubtableHeader) | |
26 | : StateTableProcessor(morphSubtableHeader) | |
27 | { | |
28 | ligatureSubstitutionHeader = (const LigatureSubstitutionHeader *) morphSubtableHeader; | |
29 | ligatureActionTableOffset = SWAPW(ligatureSubstitutionHeader->ligatureActionTableOffset); | |
30 | componentTableOffset = SWAPW(ligatureSubstitutionHeader->componentTableOffset); | |
31 | ligatureTableOffset = SWAPW(ligatureSubstitutionHeader->ligatureTableOffset); | |
32 | ||
33 | entryTable = (const LigatureSubstitutionStateEntry *) ((char *) &stateTableHeader->stHeader + entryTableOffset); | |
34 | } | |
35 | ||
36 | LigatureSubstitutionProcessor::~LigatureSubstitutionProcessor() | |
37 | { | |
38 | } | |
39 | ||
40 | void LigatureSubstitutionProcessor::beginStateTable() | |
41 | { | |
42 | m = -1; | |
43 | } | |
44 | ||
374ca955 | 45 | ByteOffset LigatureSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index) |
b75a7d8f A |
46 | { |
47 | const LigatureSubstitutionStateEntry *entry = &entryTable[index]; | |
48 | ByteOffset newState = SWAPW(entry->newStateOffset); | |
49 | le_int16 flags = SWAPW(entry->flags); | |
50 | ||
51 | if (flags & lsfSetComponent) { | |
52 | if (++m >= nComponents) { | |
53 | m = 0; | |
54 | } | |
55 | ||
56 | componentStack[m] = currGlyph; | |
57 | } | |
58 | ||
59 | ByteOffset actionOffset = flags & lsfActionOffsetMask; | |
60 | ||
61 | if (actionOffset != 0) { | |
62 | const LigatureActionEntry *ap = (const LigatureActionEntry *) ((char *) &ligatureSubstitutionHeader->stHeader + actionOffset); | |
63 | LigatureActionEntry action; | |
64 | le_int32 offset, i = 0; | |
65 | le_int32 stack[nComponents]; | |
66 | le_int16 mm = -1; | |
67 | ||
68 | do { | |
69 | le_uint32 componentGlyph = componentStack[m--]; | |
70 | ||
71 | action = SWAPL(*ap++); | |
72 | ||
73 | if (m < 0) { | |
74 | m = nComponents - 1; | |
75 | } | |
76 | ||
77 | offset = action & lafComponentOffsetMask; | |
78 | if (offset != 0) { | |
79 | const le_int16 *offsetTable = (const le_int16 *)((char *) &ligatureSubstitutionHeader->stHeader + 2 * SignExtend(offset, lafComponentOffsetMask)); | |
80 | ||
374ca955 | 81 | i += SWAPW(offsetTable[LE_GET_GLYPH(glyphStorage[componentGlyph])]); |
b75a7d8f A |
82 | |
83 | if (action & (lafLast | lafStore)) { | |
84 | const TTGlyphID *ligatureOffset = (const TTGlyphID *) ((char *) &ligatureSubstitutionHeader->stHeader + i); | |
85 | TTGlyphID ligatureGlyph = SWAPW(*ligatureOffset); | |
86 | ||
374ca955 | 87 | glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], ligatureGlyph); |
b75a7d8f A |
88 | stack[++mm] = componentGlyph; |
89 | i = 0; | |
90 | } else { | |
374ca955 | 91 | glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], 0xFFFF); |
b75a7d8f A |
92 | } |
93 | } | |
94 | } while (!(action & lafLast)); | |
95 | ||
96 | while (mm >= 0) { | |
97 | if (++m >= nComponents) { | |
98 | m = 0; | |
99 | } | |
100 | ||
101 | componentStack[m] = stack[mm--]; | |
102 | } | |
103 | } | |
104 | ||
105 | if (!(flags & lsfDontAdvance)) { | |
106 | // should handle reverse too! | |
107 | currGlyph += 1; | |
108 | } | |
109 | ||
110 | return newState; | |
111 | } | |
112 | ||
113 | void LigatureSubstitutionProcessor::endStateTable() | |
114 | { | |
115 | } | |
116 | ||
117 | U_NAMESPACE_END |