Home | History | Annotate | Download | only in layout
      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