1 /* 2 * 3 * (C) Copyright IBM Corp. and others 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 "SubtableProcessor2.h" 12 #include "StateTableProcessor2.h" 13 #include "ContextualGlyphSubstProc2.h" 14 #include "LEGlyphStorage.h" 15 #include "LESwaps.h" 16 #include <stdio.h> 17 18 U_NAMESPACE_BEGIN 19 20 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ContextualGlyphSubstitutionProcessor2) 21 22 ContextualGlyphSubstitutionProcessor2::ContextualGlyphSubstitutionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader) 23 : StateTableProcessor2(morphSubtableHeader) 24 { 25 contextualGlyphHeader = (const ContextualGlyphHeader2 *) morphSubtableHeader; 26 le_uint32 perGlyphTableOffset = SWAPL(contextualGlyphHeader->perGlyphTableOffset); 27 perGlyphTable = ((le_uint32 *) ((char *)&stateTableHeader->stHeader + perGlyphTableOffset)); 28 entryTable = (const ContextualGlyphStateEntry2 *) ((char *) &stateTableHeader->stHeader + entryTableOffset); 29 } 30 31 ContextualGlyphSubstitutionProcessor2::~ContextualGlyphSubstitutionProcessor2() 32 { 33 } 34 35 void ContextualGlyphSubstitutionProcessor2::beginStateTable() 36 { 37 markGlyph = 0; 38 } 39 40 le_uint16 ContextualGlyphSubstitutionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index) 41 { 42 const ContextualGlyphStateEntry2 *entry = &entryTable[index]; 43 le_uint16 newState = SWAPW(entry->newStateIndex); 44 le_uint16 flags = SWAPW(entry->flags); 45 le_int16 markIndex = SWAPW(entry->markIndex); 46 le_int16 currIndex = SWAPW(entry->currIndex); 47 48 if (markIndex != -1) { 49 le_uint32 offset = SWAPL(perGlyphTable[markIndex]); 50 LEGlyphID mGlyph = glyphStorage[markGlyph]; 51 TTGlyphID newGlyph = lookup(offset, mGlyph); 52 glyphStorage[markGlyph] = LE_SET_GLYPH(mGlyph, newGlyph); 53 } 54 55 if (currIndex != -1) { 56 le_uint32 offset = SWAPL(perGlyphTable[currIndex]); 57 LEGlyphID thisGlyph = glyphStorage[currGlyph]; 58 TTGlyphID newGlyph = lookup(offset, thisGlyph); 59 glyphStorage[currGlyph] = LE_SET_GLYPH(thisGlyph, newGlyph); 60 } 61 62 if (flags & cgsSetMark) { 63 markGlyph = currGlyph; 64 } 65 66 if (!(flags & cgsDontAdvance)) { 67 currGlyph += dir; 68 } 69 70 return newState; 71 } 72 73 TTGlyphID ContextualGlyphSubstitutionProcessor2::lookup(le_uint32 offset, LEGlyphID gid) 74 { 75 LookupTable *lookupTable = ((LookupTable *) ((char *)perGlyphTable + offset)); 76 le_int16 format = SWAPW(lookupTable->format); 77 TTGlyphID newGlyph = 0xFFFF; 78 79 switch (format) { 80 case ltfSimpleArray: { 81 #ifdef TEST_FORMAT 82 // Disabled pending for design review 83 SimpleArrayLookupTable *lookupTable0 = (SimpleArrayLookupTable *) lookupTable; 84 TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid); 85 newGlyph = SWAPW(lookupTable0->valueArray[glyphCode]); 86 #endif 87 break; 88 } 89 case ltfSegmentSingle: { 90 #ifdef TEST_FORMAT 91 // Disabled pending for design review 92 SegmentSingleLookupTable *lookupTable2 = (SegmentSingleLookupTable *) lookupTable; 93 const LookupSegment *segment = lookupTable2->lookupSegment(lookupTable2->segments, gid); 94 if (segment != NULL) { 95 newGlyph = SWAPW(segment->value); 96 } 97 #endif 98 break; 99 } 100 case ltfSegmentArray: { 101 printf("Context Lookup Table Format4: specific interpretation needed!\n"); 102 break; 103 } 104 case ltfSingleTable: 105 { 106 #ifdef TEST_FORMAT 107 // Disabled pending for design review 108 SingleTableLookupTable *lookupTable6 = (SingleTableLookupTable *) lookupTable; 109 const LookupSingle *segment = lookupTable6->lookupSingle(lookupTable6->entries, gid); 110 if (segment != NULL) { 111 newGlyph = SWAPW(segment->value); 112 } 113 #endif 114 break; 115 } 116 case ltfTrimmedArray: { 117 TrimmedArrayLookupTable *lookupTable8 = (TrimmedArrayLookupTable *) lookupTable; 118 TTGlyphID firstGlyph = SWAPW(lookupTable8->firstGlyph); 119 TTGlyphID lastGlyph = firstGlyph + SWAPW(lookupTable8->glyphCount); 120 TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid); 121 if ((glyphCode >= firstGlyph) && (glyphCode < lastGlyph)) { 122 newGlyph = SWAPW(lookupTable8->valueArray[glyphCode - firstGlyph]); 123 } 124 } 125 default: 126 break; 127 } 128 return newGlyph; 129 } 130 131 void ContextualGlyphSubstitutionProcessor2::endStateTable() 132 { 133 } 134 135 U_NAMESPACE_END 136