fontservices/textshaperplugin/IcuSource/layout/LigatureSubstProc.cpp
changeset 0 1fb32624e06b
equal deleted inserted replaced
-1:000000000000 0:1fb32624e06b
       
     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