1/* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. Oracle designates this 7 * particular file as subject to the "Classpath" exception as provided 8 * by Oracle in the LICENSE file that accompanied this code. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 * 24 */ 25 26/* 27 * 28 * (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved 29 * 30 */ 31 32#include "LETypes.h" 33#include "LEGlyphFilter.h" 34#include "OpenTypeTables.h" 35#include "GlyphSubstitutionTables.h" 36#include "MultipleSubstSubtables.h" 37#include "GlyphIterator.h" 38#include "LESwaps.h" 39 40U_NAMESPACE_BEGIN 41 42le_uint32 MultipleSubstitutionSubtable::process(const LETableReference &base, GlyphIterator *glyphIterator, LEErrorCode& success, const LEGlyphFilter *filter) const 43{ 44 if (LE_FAILURE(success)) { 45 return 0; 46 } 47 48 LEGlyphID glyph = glyphIterator->getCurrGlyphID(); 49 50 // If there's a filter, we only want to do the 51 // substitution if the *input* glyphs doesn't 52 // exist. 53 // 54 // FIXME: is this always the right thing to do? 55 // FIXME: should this only be done for a non-zero 56 // glyphCount? 57 if (filter != NULL && filter->accept(glyph, success)) { 58 return 0; 59 } 60 if(LE_FAILURE(success)) return 0; 61 62 le_int32 coverageIndex = getGlyphCoverage(base, glyph, success); 63 le_uint16 seqCount = SWAPW(sequenceCount); 64 LEReferenceToArrayOf<Offset> 65 sequenceTableOffsetArrayRef(base, success, sequenceTableOffsetArray, seqCount); 66 67 if (LE_FAILURE(success)) { 68 return 0; 69 } 70 71 if (coverageIndex >= 0 && coverageIndex < seqCount) { 72 Offset sequenceTableOffset = SWAPW(sequenceTableOffsetArray[coverageIndex]); 73 LEReferenceTo<SequenceTable> sequenceTable(base, success, sequenceTableOffset); 74 if (LE_FAILURE(success)) { 75 return 0; 76 } 77 le_uint16 glyphCount = SWAPW(sequenceTable->glyphCount); 78 LEReferenceToArrayOf<Offset> 79 substituteArrayRef(base, success, sequenceTable->substituteArray, glyphCount); 80 81 if (glyphCount == 0) { 82 glyphIterator->setCurrGlyphID(0xFFFF); 83 return 1; 84 } else if (glyphCount == 1) { 85 TTGlyphID substitute = SWAPW(sequenceTable->substituteArray[0]); 86 87 if (filter != NULL && ! filter->accept(LE_SET_GLYPH(glyph, substitute), success)) { 88 return 0; 89 } 90 91 glyphIterator->setCurrGlyphID(substitute); 92 return 1; 93 } else { 94 // If there's a filter, make sure all of the output glyphs 95 // exist. 96 if (filter != NULL) { 97 for (le_int32 i = 0; i < glyphCount; i += 1) { 98 TTGlyphID substitute = SWAPW(sequenceTable->substituteArray[i]); 99 100 if (! filter->accept(substitute, success)) { 101 return 0; 102 } 103 } 104 } 105 106 LEGlyphID *newGlyphs = glyphIterator->insertGlyphs(glyphCount, success); 107 if (LE_FAILURE(success)) { 108 return 0; 109 } 110 111 le_int32 insert = 0, direction = 1; 112 113 if (glyphIterator->isRightToLeft()) { 114 insert = glyphCount - 1; 115 direction = -1; 116 } 117 118 for (le_int32 i = 0; i < glyphCount; i += 1) { 119 TTGlyphID substitute = SWAPW(sequenceTable->substituteArray[i]); 120 121 newGlyphs[insert] = LE_SET_GLYPH(glyph, substitute); 122 insert += direction; 123 } 124 125 return 1; 126 } 127 } 128 129 return 0; 130} 131 132U_NAMESPACE_END 133