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 "LigatureSubstProc2.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(LigatureSubstitutionProcessor2
)
25 LigatureSubstitutionProcessor2::LigatureSubstitutionProcessor2(const MorphSubtableHeader2
*morphSubtableHeader
)
26 : StateTableProcessor2(morphSubtableHeader
)
28 ligatureSubstitutionHeader
= (const LigatureSubstitutionHeader2
*) morphSubtableHeader
;
29 ligActionOffset
= SWAPL(ligatureSubstitutionHeader
->ligActionOffset
);
30 componentOffset
= SWAPL(ligatureSubstitutionHeader
->componentOffset
);
31 ligatureOffset
= SWAPL(ligatureSubstitutionHeader
->ligatureOffset
);
33 entryTable
= (const LigatureSubstitutionStateEntry2
*) ((char *) &stateTableHeader
->stHeader
+ entryTableOffset
);
36 LigatureSubstitutionProcessor2::~LigatureSubstitutionProcessor2()
40 void LigatureSubstitutionProcessor2::beginStateTable()
45 le_uint16
LigatureSubstitutionProcessor2::processStateEntry(LEGlyphStorage
&glyphStorage
, le_int32
&currGlyph
, EntryTableIndex2 index
)
47 const LigatureSubstitutionStateEntry2
*entry
= &entryTable
[index
];
48 le_uint16 nextStateIndex
= SWAPW(entry
->nextStateIndex
);
49 le_uint16 flags
= SWAPW(entry
->entryFlags
);
50 le_uint16 ligActionIndex
= SWAPW(entry
->ligActionIndex
);
52 if (flags
& lsfSetComponent
) {
53 if (++m
>= nComponents
) {
56 componentStack
[m
] = currGlyph
;
59 ByteOffset actionOffset
= flags
& lsfPerformAction
;
61 if (actionOffset
!= 0) {
62 const LigatureActionEntry
*ap
= (const LigatureActionEntry
*) ((char *) &ligatureSubstitutionHeader
->stHeader
+ ligActionOffset
) + ligActionIndex
;
63 const TTGlyphID
*ligatureTable
= (const TTGlyphID
*) ((char *) &ligatureSubstitutionHeader
->stHeader
+ ligatureOffset
);
64 LigatureActionEntry action
;
65 le_int32 offset
, i
= 0;
66 le_int32 stack
[nComponents
];
69 const le_uint16
*componentTable
= (const le_uint16
*)((char *) &ligatureSubstitutionHeader
->stHeader
+ componentOffset
);
72 le_uint32 componentGlyph
= componentStack
[m
--]; // pop off
74 action
= SWAPL(*ap
++);
80 offset
= action
& lafComponentOffsetMask
;
83 i
+= SWAPW(componentTable
[LE_GET_GLYPH(glyphStorage
[componentGlyph
]) + (SignExtend(offset
, lafComponentOffsetMask
))]);
85 if (action
& (lafLast
| lafStore
)) {
86 TTGlyphID ligatureGlyph
= SWAPW(ligatureTable
[i
]);
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
)) {
109 return nextStateIndex
;
112 void LigatureSubstitutionProcessor2::endStateTable()