os/textandloc/fontservices/textshaperplugin/IcuSource/layout/MultipleSubstSubtables.cpp
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/textandloc/fontservices/textshaperplugin/IcuSource/layout/MultipleSubstSubtables.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,96 @@
1.4 +/*
1.5 + *
1.6 + * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
1.7 + *
1.8 + */
1.9 +
1.10 +#include "LETypes.h"
1.11 +#include "LEGlyphFilter.h"
1.12 +#include "OpenTypeTables.h"
1.13 +#include "GlyphSubstitutionTables.h"
1.14 +#include "MultipleSubstSubtables.h"
1.15 +#include "GlyphIterator.h"
1.16 +#include "LESwaps.h"
1.17 +
1.18 +U_NAMESPACE_BEGIN
1.19 +
1.20 +le_uint32 MultipleSubstitutionSubtable::process(GlyphIterator *glyphIterator, LEErrorCode& success,
1.21 + const LEGlyphFilter *filter) const
1.22 +{
1.23 + if (LE_FAILURE(success)) {
1.24 + return 0;
1.25 + }
1.26 +
1.27 + LEGlyphID glyph = glyphIterator->getCurrGlyphID();
1.28 +
1.29 + // If there's a filter, we only want to do the
1.30 + // substitution if the *input* glyphs doesn't
1.31 + // exist.
1.32 + //
1.33 + // FIXME: is this always the right thing to do?
1.34 + // FIXME: should this only be done for a non-zero
1.35 + // glyphCount?
1.36 + if (filter != NULL && filter->accept(glyph)) {
1.37 + return 0;
1.38 + }
1.39 +
1.40 + le_int32 coverageIndex = getGlyphCoverage(glyph);
1.41 + le_uint16 seqCount = SWAPW(sequenceCount);
1.42 +
1.43 + if (coverageIndex >= 0 && coverageIndex < seqCount) {
1.44 + Offset sequenceTableOffset = SWAPW(sequenceTableOffsetArray[coverageIndex]);
1.45 + const SequenceTable *sequenceTable = (const SequenceTable *) ((char *) this + sequenceTableOffset);
1.46 + le_uint16 glyphCount = SWAPW(sequenceTable->glyphCount);
1.47 +
1.48 + if (glyphCount == 0) {
1.49 + glyphIterator->setCurrGlyphID(0xFFFF);
1.50 + return 1;
1.51 + } else if (glyphCount == 1) {
1.52 + TTGlyphID substitute = SWAPW(sequenceTable->substituteArray[0]);
1.53 +
1.54 + if (filter != NULL && ! filter->accept(LE_SET_GLYPH(glyph, substitute))) {
1.55 + return 0;
1.56 + }
1.57 +
1.58 + glyphIterator->setCurrGlyphID(substitute);
1.59 + return 1;
1.60 + } else {
1.61 + // If there's a filter, make sure all of the output glyphs
1.62 + // exist.
1.63 + if (filter != NULL) {
1.64 + for (le_int32 i = 0; i < glyphCount; i += 1) {
1.65 + TTGlyphID substitute = SWAPW(sequenceTable->substituteArray[i]);
1.66 +
1.67 + if (! filter->accept(substitute)) {
1.68 + return 0;
1.69 + }
1.70 + }
1.71 + }
1.72 +
1.73 + LEGlyphID *newGlyphs = glyphIterator->insertGlyphs(glyphCount, success);
1.74 + if (LE_FAILURE(success)) {
1.75 + return 0;
1.76 + }
1.77 +
1.78 + le_int32 insert = 0, direction = 1;
1.79 +
1.80 + if (glyphIterator->isRightToLeft()) {
1.81 + insert = glyphCount - 1;
1.82 + direction = -1;
1.83 + }
1.84 +
1.85 + for (le_int32 i = 0; i < glyphCount; i += 1) {
1.86 + TTGlyphID substitute = SWAPW(sequenceTable->substituteArray[i]);
1.87 +
1.88 + newGlyphs[insert] = LE_SET_GLYPH(glyph, substitute);
1.89 + insert += direction;
1.90 + }
1.91 +
1.92 + return 1;
1.93 + }
1.94 + }
1.95 +
1.96 + return 0;
1.97 +}
1.98 +
1.99 +U_NAMESPACE_END