1 /* 2 * 3 * (C) Copyright IBM Corp. 1998-2013 - 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 "ContextualGlyphSubstProc.h" 14 #include "LEGlyphStorage.h" 15 #include "LESwaps.h" 16 17 U_NAMESPACE_BEGIN 18 19 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ContextualGlyphSubstitutionProcessor) 20 21 ContextualGlyphSubstitutionProcessor::ContextualGlyphSubstitutionProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success) 22 : StateTableProcessor(morphSubtableHeader, success), entryTable(), contextualGlyphSubstitutionHeader(morphSubtableHeader, success) 23 { 24 contextualGlyphSubstitutionHeader.orphan(); 25 substitutionTableOffset = SWAPW(contextualGlyphSubstitutionHeader->substitutionTableOffset); 26 27 28 entryTable = LEReferenceToArrayOf<ContextualGlyphSubstitutionStateEntry>(stateTableHeader, success, 29 (const ContextualGlyphSubstitutionStateEntry*)(&stateTableHeader->stHeader), 30 entryTableOffset, LE_UNBOUNDED_ARRAY); 31 int16Table = LEReferenceToArrayOf<le_int16>(stateTableHeader, success, (const le_int16*)(&stateTableHeader->stHeader), 32 0, LE_UNBOUNDED_ARRAY); // rest of the table as le_int16s 33 } 34 35 ContextualGlyphSubstitutionProcessor::~ContextualGlyphSubstitutionProcessor() 36 { 37 } 38 39 void ContextualGlyphSubstitutionProcessor::beginStateTable() 40 { 41 markGlyph = 0; 42 } 43 44 ByteOffset ContextualGlyphSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index) 45 { 46 LEErrorCode success = LE_NO_ERROR; 47 const ContextualGlyphSubstitutionStateEntry *entry = entryTable.getAlias(index, success); 48 ByteOffset newState = SWAPW(entry->newStateOffset); 49 le_int16 flags = SWAPW(entry->flags); 50 WordOffset markOffset = SWAPW(entry->markOffset); 51 WordOffset currOffset = SWAPW(entry->currOffset); 52 53 if (markOffset != 0 && LE_SUCCESS(success)) { 54 LEGlyphID mGlyph = glyphStorage[markGlyph]; 55 TTGlyphID newGlyph = SWAPW(int16Table.getObject(markOffset + LE_GET_GLYPH(mGlyph), success)); // whew. 56 57 glyphStorage[markGlyph] = LE_SET_GLYPH(mGlyph, newGlyph); 58 } 59 60 if (currOffset != 0) { 61 LEGlyphID thisGlyph = glyphStorage[currGlyph]; 62 TTGlyphID newGlyph = SWAPW(int16Table.getObject(currOffset + LE_GET_GLYPH(thisGlyph), success)); // whew. 63 64 glyphStorage[currGlyph] = LE_SET_GLYPH(thisGlyph, newGlyph); 65 } 66 67 if (flags & cgsSetMark) { 68 markGlyph = currGlyph; 69 } 70 71 if (!(flags & cgsDontAdvance)) { 72 // should handle reverse too! 73 currGlyph += 1; 74 } 75 76 return newState; 77 } 78 79 void ContextualGlyphSubstitutionProcessor::endStateTable() 80 { 81 } 82 83 U_NAMESPACE_END 84