annotate src/share/native/sun/font/layout/StateTableProcessor2.cpp @ 5725:6784c9903db7

8004986: Better handling of glyph table 8004987: Improve font layout 8004994: Improve checking of glyph table Reviewed-by: bae, mschoene, jgodinez Contributed-by: steven.loomis@oracle.com
author prr
date Mon, 25 Feb 2013 09:52:53 -0800
parents 8a95f38503fe
children 245c2dce7225
rev   line source
prr@5645 1 /*
prr@5645 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
prr@5645 3 *
prr@5645 4 * This code is free software; you can redistribute it and/or modify it
prr@5645 5 * under the terms of the GNU General Public License version 2 only, as
prr@5645 6 * published by the Free Software Foundation. Oracle designates this
prr@5645 7 * particular file as subject to the "Classpath" exception as provided
prr@5645 8 * by Oracle in the LICENSE file that accompanied this code.
prr@5645 9 *
prr@5645 10 * This code is distributed in the hope that it will be useful, but WITHOUT
prr@5645 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
prr@5645 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
prr@5645 13 * version 2 for more details (a copy is included in the LICENSE file that
prr@5645 14 * accompanied this code).
prr@5645 15 *
prr@5645 16 * You should have received a copy of the GNU General Public License version
prr@5645 17 * 2 along with this work; if not, write to the Free Software Foundation,
prr@5645 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
prr@5645 19 *
prr@5645 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
prr@5645 21 * or visit www.oracle.com if you need additional information or have any
prr@5645 22 * questions.
prr@5645 23 *
prr@5645 24 */
prr@5645 25
prr@5645 26 /*
prr@5645 27 *
prr@5645 28 * (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
prr@5645 29 *
prr@5645 30 */
prr@5645 31
prr@5645 32 #include "LETypes.h"
prr@5645 33 #include "MorphTables.h"
prr@5645 34 #include "StateTables.h"
prr@5645 35 #include "MorphStateTables.h"
prr@5645 36 #include "SubtableProcessor2.h"
prr@5645 37 #include "StateTableProcessor2.h"
prr@5645 38 #include "LEGlyphStorage.h"
prr@5645 39 #include "LESwaps.h"
prr@5645 40 #include "LookupTables.h"
prr@5645 41
prr@5645 42 U_NAMESPACE_BEGIN
prr@5645 43
prr@5645 44 StateTableProcessor2::StateTableProcessor2()
prr@5645 45 {
prr@5645 46 }
prr@5645 47
prr@5645 48 StateTableProcessor2::StateTableProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
prr@5645 49 : SubtableProcessor2(morphSubtableHeader)
prr@5645 50 {
prr@5645 51 stateTableHeader = (const MorphStateTableHeader2 *) morphSubtableHeader;
prr@5645 52 nClasses = SWAPL(stateTableHeader->stHeader.nClasses);
prr@5645 53 classTableOffset = SWAPL(stateTableHeader->stHeader.classTableOffset);
prr@5645 54 stateArrayOffset = SWAPL(stateTableHeader->stHeader.stateArrayOffset);
prr@5645 55 entryTableOffset = SWAPL(stateTableHeader->stHeader.entryTableOffset);
prr@5645 56
prr@5645 57 classTable = (LookupTable *) ((char *) &stateTableHeader->stHeader + classTableOffset);
prr@5645 58 format = SWAPW(classTable->format);
prr@5645 59
prr@5645 60 stateArray = (const EntryTableIndex2 *) ((char *) &stateTableHeader->stHeader + stateArrayOffset);
prr@5645 61 }
prr@5645 62
prr@5645 63 StateTableProcessor2::~StateTableProcessor2()
prr@5645 64 {
prr@5645 65 }
prr@5645 66
prr@5645 67 void StateTableProcessor2::process(LEGlyphStorage &glyphStorage)
prr@5645 68 {
prr@5645 69 // Start at state 0
prr@5645 70 // XXX: How do we know when to start at state 1?
prr@5645 71 le_uint16 currentState = 0;
prr@5645 72 le_int32 glyphCount = glyphStorage.getGlyphCount();
prr@5645 73
prr@5725 74 LE_STATE_PATIENCE_INIT();
prr@5725 75
prr@5645 76 le_int32 currGlyph = 0;
prr@5645 77 if ((coverage & scfReverse2) != 0) { // process glyphs in descending order
prr@5645 78 currGlyph = glyphCount - 1;
prr@5645 79 dir = -1;
prr@5645 80 } else {
prr@5645 81 dir = 1;
prr@5645 82 }
prr@5645 83
prr@5645 84 beginStateTable();
prr@5645 85 switch (format) {
prr@5645 86 case ltfSimpleArray: {
prr@5645 87 #ifdef TEST_FORMAT
prr@5645 88 SimpleArrayLookupTable *lookupTable0 = (SimpleArrayLookupTable *) classTable;
prr@5645 89 while ((dir == 1 && currGlyph <= glyphCount) || (dir == -1 && currGlyph >= -1)) {
prr@5725 90 if(LE_STATE_PATIENCE_DECR()) {
prr@5725 91 LE_DEBUG_BAD_FONT("patience exceeded - state table not moving")
prr@5725 92 break; // patience exceeded.
prr@5725 93 }
prr@5645 94 LookupValue classCode = classCodeOOB;
prr@5645 95 if (currGlyph == glyphCount || currGlyph == -1) {
prr@5645 96 // XXX: How do we handle EOT vs. EOL?
prr@5645 97 classCode = classCodeEOT;
prr@5645 98 } else {
prr@5645 99 LEGlyphID gid = glyphStorage[currGlyph];
prr@5645 100 TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid);
prr@5645 101
prr@5645 102 if (glyphCode == 0xFFFF) {
prr@5645 103 classCode = classCodeDEL;
prr@5645 104 } else {
prr@5645 105 classCode = SWAPW(lookupTable0->valueArray[gid]);
prr@5645 106 }
prr@5645 107 }
prr@5645 108 EntryTableIndex2 entryTableIndex = SWAPW(stateArray[classCode + currentState * nClasses]);
prr@5725 109 LE_STATE_PATIENCE_CURR(le_int32, currGlyph);
prr@5645 110 currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex); // return a zero-based index instead of a byte offset
prr@5725 111 LE_STATE_PATIENCE_INCR(currGlyph);
prr@5645 112 }
prr@5645 113 #endif
prr@5645 114 break;
prr@5645 115 }
prr@5645 116 case ltfSegmentSingle: {
prr@5645 117 SegmentSingleLookupTable *lookupTable2 = (SegmentSingleLookupTable *) classTable;
prr@5645 118 while ((dir == 1 && currGlyph <= glyphCount) || (dir == -1 && currGlyph >= -1)) {
prr@5725 119 if(LE_STATE_PATIENCE_DECR()) {
prr@5725 120 LE_DEBUG_BAD_FONT("patience exceeded - state table not moving")
prr@5725 121 break; // patience exceeded.
prr@5725 122 }
prr@5645 123 LookupValue classCode = classCodeOOB;
prr@5645 124 if (currGlyph == glyphCount || currGlyph == -1) {
prr@5645 125 // XXX: How do we handle EOT vs. EOL?
prr@5645 126 classCode = classCodeEOT;
prr@5645 127 } else {
prr@5645 128 LEGlyphID gid = glyphStorage[currGlyph];
prr@5645 129 TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid);
prr@5645 130
prr@5645 131 if (glyphCode == 0xFFFF) {
prr@5645 132 classCode = classCodeDEL;
prr@5645 133 } else {
prr@5645 134 const LookupSegment *segment = lookupTable2->lookupSegment(lookupTable2->segments, gid);
prr@5645 135 if (segment != NULL) {
prr@5645 136 classCode = SWAPW(segment->value);
prr@5645 137 }
prr@5645 138 }
prr@5645 139 }
prr@5645 140 EntryTableIndex2 entryTableIndex = SWAPW(stateArray[classCode + currentState * nClasses]);
prr@5725 141 LE_STATE_PATIENCE_CURR(le_int32, currGlyph);
prr@5645 142 currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex);
prr@5725 143 LE_STATE_PATIENCE_INCR(currGlyph);
prr@5645 144 }
prr@5645 145 break;
prr@5645 146 }
prr@5645 147 case ltfSegmentArray: {
prr@5725 148 //printf("Lookup Table Format4: specific interpretation needed!\n");
prr@5645 149 break;
prr@5645 150 }
prr@5645 151 case ltfSingleTable: {
prr@5645 152 SingleTableLookupTable *lookupTable6 = (SingleTableLookupTable *) classTable;
prr@5645 153 while ((dir == 1 && currGlyph <= glyphCount) || (dir == -1 && currGlyph >= -1)) {
prr@5725 154 if(LE_STATE_PATIENCE_DECR()) {
prr@5725 155 LE_DEBUG_BAD_FONT("patience exceeded - state table not moving")
prr@5725 156 break; // patience exceeded.
prr@5725 157 }
prr@5645 158 LookupValue classCode = classCodeOOB;
prr@5645 159 if (currGlyph == glyphCount || currGlyph == -1) {
prr@5645 160 // XXX: How do we handle EOT vs. EOL?
prr@5645 161 classCode = classCodeEOT;
prr@5725 162 } else if(currGlyph > glyphCount) {
prr@5725 163 // note if > glyphCount, we've run off the end (bad font)
prr@5725 164 currGlyph = glyphCount;
prr@5725 165 classCode = classCodeEOT;
prr@5645 166 } else {
prr@5645 167 LEGlyphID gid = glyphStorage[currGlyph];
prr@5645 168 TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid);
prr@5645 169
prr@5645 170 if (glyphCode == 0xFFFF) {
prr@5645 171 classCode = classCodeDEL;
prr@5645 172 } else {
prr@5645 173 const LookupSingle *segment = lookupTable6->lookupSingle(lookupTable6->entries, gid);
prr@5645 174 if (segment != NULL) {
prr@5645 175 classCode = SWAPW(segment->value);
prr@5645 176 }
prr@5645 177 }
prr@5645 178 }
prr@5645 179 EntryTableIndex2 entryTableIndex = SWAPW(stateArray[classCode + currentState * nClasses]);
prr@5725 180 LE_STATE_PATIENCE_CURR(le_int32, currGlyph);
prr@5645 181 currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex);
prr@5725 182 LE_STATE_PATIENCE_INCR(currGlyph);
prr@5645 183 }
prr@5645 184 break;
prr@5645 185 }
prr@5645 186 case ltfTrimmedArray: {
prr@5645 187 TrimmedArrayLookupTable *lookupTable8 = (TrimmedArrayLookupTable *) classTable;
prr@5645 188 TTGlyphID firstGlyph = SWAPW(lookupTable8->firstGlyph);
prr@5645 189 TTGlyphID lastGlyph = firstGlyph + SWAPW(lookupTable8->glyphCount);
prr@5645 190
prr@5645 191 while ((dir == 1 && currGlyph <= glyphCount) || (dir == -1 && currGlyph >= -1)) {
prr@5725 192 if(LE_STATE_PATIENCE_DECR()) {
prr@5725 193 LE_DEBUG_BAD_FONT("patience exceeded - state table not moving")
prr@5725 194 break; // patience exceeded.
prr@5725 195 }
prr@5725 196
prr@5645 197 LookupValue classCode = classCodeOOB;
prr@5645 198 if (currGlyph == glyphCount || currGlyph == -1) {
prr@5645 199 // XXX: How do we handle EOT vs. EOL?
prr@5645 200 classCode = classCodeEOT;
prr@5645 201 } else {
prr@5645 202 TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(glyphStorage[currGlyph]);
prr@5645 203 if (glyphCode == 0xFFFF) {
prr@5645 204 classCode = classCodeDEL;
prr@5645 205 } else if ((glyphCode >= firstGlyph) && (glyphCode < lastGlyph)) {
prr@5645 206 classCode = SWAPW(lookupTable8->valueArray[glyphCode - firstGlyph]);
prr@5645 207 }
prr@5645 208 }
prr@5645 209 EntryTableIndex2 entryTableIndex = SWAPW(stateArray[classCode + currentState * nClasses]);
prr@5725 210 LE_STATE_PATIENCE_CURR(le_int32, currGlyph);
prr@5645 211 currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex);
prr@5725 212 LE_STATE_PATIENCE_INCR(currGlyph);
prr@5645 213 }
prr@5645 214 break;
prr@5645 215 }
prr@5645 216 default:
prr@5645 217 break;
prr@5645 218 }
prr@5645 219
prr@5645 220 endStateTable();
prr@5645 221 }
prr@5645 222
prr@5645 223 U_NAMESPACE_END