os/textandloc/fontservices/textshaperplugin/IcuSource/layout/MultipleSubstSubtables.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 /*
     2  *
     3  * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
     4  *
     5  */
     6 
     7 #include "LETypes.h"
     8 #include "LEGlyphFilter.h"
     9 #include "OpenTypeTables.h"
    10 #include "GlyphSubstitutionTables.h"
    11 #include "MultipleSubstSubtables.h"
    12 #include "GlyphIterator.h"
    13 #include "LESwaps.h"
    14 
    15 U_NAMESPACE_BEGIN
    16 
    17 le_uint32 MultipleSubstitutionSubtable::process(GlyphIterator *glyphIterator, LEErrorCode& success,
    18     const LEGlyphFilter *filter) const
    19 {
    20     if (LE_FAILURE(success)) {
    21         return 0;
    22     }
    23 
    24     LEGlyphID glyph = glyphIterator->getCurrGlyphID();
    25 
    26     // If there's a filter, we only want to do the
    27     // substitution if the *input* glyphs doesn't
    28     // exist.
    29     //
    30     // FIXME: is this always the right thing to do?
    31     // FIXME: should this only be done for a non-zero
    32     //        glyphCount?
    33     if (filter != NULL && filter->accept(glyph)) {
    34         return 0;
    35     }
    36 
    37     le_int32 coverageIndex = getGlyphCoverage(glyph);
    38     le_uint16 seqCount = SWAPW(sequenceCount);
    39 
    40     if (coverageIndex >= 0 && coverageIndex < seqCount) {
    41         Offset sequenceTableOffset = SWAPW(sequenceTableOffsetArray[coverageIndex]);
    42         const SequenceTable *sequenceTable = (const SequenceTable *) ((char *) this + sequenceTableOffset);
    43         le_uint16 glyphCount = SWAPW(sequenceTable->glyphCount);
    44 
    45         if (glyphCount == 0) {
    46             glyphIterator->setCurrGlyphID(0xFFFF);
    47             return 1;
    48         } else if (glyphCount == 1) {
    49             TTGlyphID substitute = SWAPW(sequenceTable->substituteArray[0]);
    50 
    51             if (filter != NULL && ! filter->accept(LE_SET_GLYPH(glyph, substitute))) {
    52                 return 0;
    53             }
    54 
    55             glyphIterator->setCurrGlyphID(substitute);
    56             return 1;
    57         } else {
    58             // If there's a filter, make sure all of the output glyphs
    59             // exist.
    60             if (filter != NULL) {
    61                 for (le_int32 i = 0; i < glyphCount; i += 1) {
    62                     TTGlyphID substitute = SWAPW(sequenceTable->substituteArray[i]);
    63 
    64                     if (! filter->accept(substitute)) {
    65                         return 0;
    66                     }
    67                 }
    68             }
    69 
    70             LEGlyphID *newGlyphs = glyphIterator->insertGlyphs(glyphCount, success);
    71             if (LE_FAILURE(success)) {
    72                 return 0;
    73             }
    74 
    75             le_int32 insert = 0, direction = 1;
    76 
    77             if (glyphIterator->isRightToLeft()) {
    78                 insert = glyphCount - 1;
    79                 direction = -1;
    80             }
    81 
    82             for (le_int32 i = 0; i < glyphCount; i += 1) {
    83                 TTGlyphID substitute = SWAPW(sequenceTable->substituteArray[i]);
    84 
    85                 newGlyphs[insert] = LE_SET_GLYPH(glyph, substitute);
    86                 insert += direction;
    87             }
    88 
    89             return 1;
    90         }
    91     }
    92 
    93     return 0;
    94 }
    95 
    96 U_NAMESPACE_END