Home | History | Annotate | Download | only in layout
      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 
     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 
     36 LigatureSubstitutionProcessor::~LigatureSubstitutionProcessor()
     37 {
     38 }
     39 
     40 void LigatureSubstitutionProcessor::beginStateTable()
     41 {
     42     m = -1;
     43 }
     44 
     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 
    113 void LigatureSubstitutionProcessor::endStateTable()
    114 {
    115 }
    116 
    117 U_NAMESPACE_END
    118