• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
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"
14 #include "LEGlyphStorage.h"
15 #include "LESwaps.h"
16 
17 U_NAMESPACE_BEGIN
18 
19 #define ExtendedComplement(m) ((le_int32) (~((le_uint32) (m))))
20 #define SignBit(m) ((ExtendedComplement(m) >> 1) & (le_int32)(m))
21 #define SignExtend(v,m) (((v) & SignBit(m))? ((v) | ExtendedComplement(m)): (v))
22 
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LigatureSubstitutionProcessor)23 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LigatureSubstitutionProcessor)
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 
~LigatureSubstitutionProcessor()36 LigatureSubstitutionProcessor::~LigatureSubstitutionProcessor()
37 {
38 }
39 
beginStateTable()40 void LigatureSubstitutionProcessor::beginStateTable()
41 {
42     m = -1;
43 }
44 
processStateEntry(LEGlyphStorage & glyphStorage,le_int32 & currGlyph,EntryTableIndex index)45 ByteOffset LigatureSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index)
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 
81                 i += SWAPW(offsetTable[LE_GET_GLYPH(glyphStorage[componentGlyph])]);
82 
83                 if (action & (lafLast | lafStore))  {
84                     const TTGlyphID *ligatureOffset = (const TTGlyphID *) ((char *) &ligatureSubstitutionHeader->stHeader + i);
85                     TTGlyphID ligatureGlyph = SWAPW(*ligatureOffset);
86 
87                     glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], ligatureGlyph);
88                     stack[++mm] = componentGlyph;
89                     i = 0;
90                 } else {
91                     glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], 0xFFFF);
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 
endStateTable()113 void LigatureSubstitutionProcessor::endStateTable()
114 {
115 }
116 
117 U_NAMESPACE_END
118