os/textandloc/fontservices/textshaperplugin/IcuSource/layout/LigatureSubstProc.cpp
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/textandloc/fontservices/textshaperplugin/IcuSource/layout/LigatureSubstProc.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,117 @@
1.4 +/*
1.5 + *
1.6 + * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
1.7 + *
1.8 + */
1.9 +
1.10 +#include "LETypes.h"
1.11 +#include "MorphTables.h"
1.12 +#include "StateTables.h"
1.13 +#include "MorphStateTables.h"
1.14 +#include "SubtableProcessor.h"
1.15 +#include "StateTableProcessor.h"
1.16 +#include "LigatureSubstProc.h"
1.17 +#include "LEGlyphStorage.h"
1.18 +#include "LESwaps.h"
1.19 +
1.20 +U_NAMESPACE_BEGIN
1.21 +
1.22 +#define ExtendedComplement(m) ((le_int32) (~((le_uint32) (m))))
1.23 +#define SignBit(m) ((ExtendedComplement(m) >> 1) & (le_int32)(m))
1.24 +#define SignExtend(v,m) (((v) & SignBit(m))? ((v) | ExtendedComplement(m)): (v))
1.25 +
1.26 +UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LigatureSubstitutionProcessor)
1.27 +
1.28 +LigatureSubstitutionProcessor::LigatureSubstitutionProcessor(const MorphSubtableHeader *morphSubtableHeader)
1.29 + : StateTableProcessor(morphSubtableHeader)
1.30 +{
1.31 + ligatureSubstitutionHeader = (const LigatureSubstitutionHeader *) morphSubtableHeader;
1.32 + ligatureActionTableOffset = SWAPW(ligatureSubstitutionHeader->ligatureActionTableOffset);
1.33 + componentTableOffset = SWAPW(ligatureSubstitutionHeader->componentTableOffset);
1.34 + ligatureTableOffset = SWAPW(ligatureSubstitutionHeader->ligatureTableOffset);
1.35 +
1.36 + entryTable = (const LigatureSubstitutionStateEntry *) ((char *) &stateTableHeader->stHeader + entryTableOffset);
1.37 +}
1.38 +
1.39 +LigatureSubstitutionProcessor::~LigatureSubstitutionProcessor()
1.40 +{
1.41 +}
1.42 +
1.43 +void LigatureSubstitutionProcessor::beginStateTable()
1.44 +{
1.45 + m = -1;
1.46 +}
1.47 +
1.48 +ByteOffset LigatureSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index)
1.49 +{
1.50 + const LigatureSubstitutionStateEntry *entry = &entryTable[index];
1.51 + ByteOffset newState = SWAPW(entry->newStateOffset);
1.52 + le_int16 flags = SWAPW(entry->flags);
1.53 +
1.54 + if (flags & lsfSetComponent) {
1.55 + if (++m >= nComponents) {
1.56 + m = 0;
1.57 + }
1.58 +
1.59 + componentStack[m] = currGlyph;
1.60 + }
1.61 +
1.62 + ByteOffset actionOffset = flags & lsfActionOffsetMask;
1.63 +
1.64 + if (actionOffset != 0) {
1.65 + const LigatureActionEntry *ap = (const LigatureActionEntry *) ((char *) &ligatureSubstitutionHeader->stHeader + actionOffset);
1.66 + LigatureActionEntry action;
1.67 + le_int32 offset, i = 0;
1.68 + le_int32 stack[nComponents];
1.69 + le_int16 mm = -1;
1.70 +
1.71 + do {
1.72 + le_uint32 componentGlyph = componentStack[m--];
1.73 +
1.74 + action = SWAPL(*ap++);
1.75 +
1.76 + if (m < 0) {
1.77 + m = nComponents - 1;
1.78 + }
1.79 +
1.80 + offset = action & lafComponentOffsetMask;
1.81 + if (offset != 0) {
1.82 + const le_int16 *offsetTable = (const le_int16 *)((char *) &ligatureSubstitutionHeader->stHeader + 2 * SignExtend(offset, lafComponentOffsetMask));
1.83 +
1.84 + i += SWAPW(offsetTable[LE_GET_GLYPH(glyphStorage[componentGlyph])]);
1.85 +
1.86 + if (action & (lafLast | lafStore)) {
1.87 + const TTGlyphID *ligatureOffset = (const TTGlyphID *) ((char *) &ligatureSubstitutionHeader->stHeader + i);
1.88 + TTGlyphID ligatureGlyph = SWAPW(*ligatureOffset);
1.89 +
1.90 + glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], ligatureGlyph);
1.91 + stack[++mm] = componentGlyph;
1.92 + i = 0;
1.93 + } else {
1.94 + glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], 0xFFFF);
1.95 + }
1.96 + }
1.97 + } while (!(action & lafLast));
1.98 +
1.99 + while (mm >= 0) {
1.100 + if (++m >= nComponents) {
1.101 + m = 0;
1.102 + }
1.103 +
1.104 + componentStack[m] = stack[mm--];
1.105 + }
1.106 + }
1.107 +
1.108 + if (!(flags & lsfDontAdvance)) {
1.109 + // should handle reverse too!
1.110 + currGlyph += 1;
1.111 + }
1.112 +
1.113 + return newState;
1.114 +}
1.115 +
1.116 +void LigatureSubstitutionProcessor::endStateTable()
1.117 +{
1.118 +}
1.119 +
1.120 +U_NAMESPACE_END