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