os/textandloc/fontservices/textshaperplugin/IcuSource/layout/LigatureSubstProc.cpp
changeset 0 bde4ae8d615e
     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