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