3 * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
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"
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))
23 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LigatureSubstitutionProcessor
)
25 LigatureSubstitutionProcessor::LigatureSubstitutionProcessor(const MorphSubtableHeader
*morphSubtableHeader
)
26 : StateTableProcessor(morphSubtableHeader
)
28 ligatureSubstitutionHeader
= (const LigatureSubstitutionHeader
*) morphSubtableHeader
;
29 ligatureActionTableOffset
= SWAPW(ligatureSubstitutionHeader
->ligatureActionTableOffset
);
30 componentTableOffset
= SWAPW(ligatureSubstitutionHeader
->componentTableOffset
);
31 ligatureTableOffset
= SWAPW(ligatureSubstitutionHeader
->ligatureTableOffset
);
33 entryTable
= (const LigatureSubstitutionStateEntry
*) ((char *) &stateTableHeader
->stHeader
+ entryTableOffset
);
36 LigatureSubstitutionProcessor::~LigatureSubstitutionProcessor()
40 void LigatureSubstitutionProcessor::beginStateTable()
45 ByteOffset
LigatureSubstitutionProcessor::processStateEntry(LEGlyphStorage
&glyphStorage
, le_int32
&currGlyph
, EntryTableIndex index
)
47 const LigatureSubstitutionStateEntry
*entry
= &entryTable
[index
];
48 ByteOffset newState
= SWAPW(entry
->newStateOffset
);
49 le_int16 flags
= SWAPW(entry
->flags
);
51 if (flags
& lsfSetComponent
) {
52 if (++m
>= nComponents
) {
56 componentStack
[m
] = currGlyph
;
59 ByteOffset actionOffset
= flags
& lsfActionOffsetMask
;
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
];
69 le_uint32 componentGlyph
= componentStack
[m
--];
71 action
= SWAPL(*ap
++);
77 offset
= action
& lafComponentOffsetMask
;
79 const le_int16
*offsetTable
= (const le_int16
*)((char *) &ligatureSubstitutionHeader
->stHeader
+ 2 * SignExtend(offset
, lafComponentOffsetMask
));
81 i
+= SWAPW(offsetTable
[LE_GET_GLYPH(glyphStorage
[componentGlyph
])]);
83 if (action
& (lafLast
| lafStore
)) {
84 const TTGlyphID
*ligatureOffset
= (const TTGlyphID
*) ((char *) &ligatureSubstitutionHeader
->stHeader
+ i
);
85 TTGlyphID ligatureGlyph
= SWAPW(*ligatureOffset
);
87 glyphStorage
[componentGlyph
] = LE_SET_GLYPH(glyphStorage
[componentGlyph
], ligatureGlyph
);
88 stack
[++mm
] = componentGlyph
;
91 glyphStorage
[componentGlyph
] = LE_SET_GLYPH(glyphStorage
[componentGlyph
], 0xFFFF);
94 } while (!(action
& lafLast
));
97 if (++m
>= nComponents
) {
101 componentStack
[m
] = stack
[mm
--];
105 if (!(flags
& lsfDontAdvance
)) {
106 // should handle reverse too!
113 void LigatureSubstitutionProcessor::endStateTable()