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-2004 - All Rights Reserved 29 * 30 */ 31 32#include "LETypes.h" 33#include "OpenTypeTables.h" 34#include "OpenTypeUtilities.h" 35#include "CoverageTables.h" 36#include "LESwaps.h" 37 38U_NAMESPACE_BEGIN 39 40le_int32 CoverageTable::getGlyphCoverage(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const 41{ 42 if(LE_FAILURE(success)) return -1; 43 44 switch(SWAPW(coverageFormat)) 45 { 46 case 0: 47 return -1; 48 49 case 1: 50 { 51 LEReferenceTo<CoverageFormat1Table> f1Table(base, success); 52 53 return f1Table->getGlyphCoverage(f1Table, glyphID, success); 54 } 55 56 case 2: 57 { 58 LEReferenceTo<CoverageFormat2Table> f2Table(base, success); 59 60 return f2Table->getGlyphCoverage(f2Table, glyphID, success); 61 } 62 63 default: 64 return -1; 65 } 66} 67 68le_int32 CoverageFormat1Table::getGlyphCoverage(LEReferenceTo<CoverageFormat1Table> &base, LEGlyphID glyphID, LEErrorCode &success) const 69{ 70 if(LE_FAILURE(success)) return -1; 71 72 TTGlyphID ttGlyphID = (TTGlyphID) LE_GET_GLYPH(glyphID); 73 le_uint16 count = SWAPW(glyphCount); 74 le_uint8 bit = OpenTypeUtilities::highBit(count); 75 le_uint16 power = 1 << bit; 76 le_uint16 extra = count - power; 77 le_uint16 probe = power; 78 le_uint16 index = 0; 79 80 if (count == 0) { 81 return -1; 82 } 83 84 LEReferenceToArrayOf<TTGlyphID>(base, success, glyphArray, count); 85 if(LE_FAILURE(success)) return -1; // range checks array 86 87 88 if (SWAPW(glyphArray[extra]) <= ttGlyphID) { 89 index = extra; 90 } 91 92 while (probe > (1 << 0)) { 93 probe >>= 1; 94 95 if (SWAPW(glyphArray[index + probe]) <= ttGlyphID) { 96 index += probe; 97 } 98 } 99 100 if (SWAPW(glyphArray[index]) == ttGlyphID) { 101 return index; 102 } 103 104 return -1; 105} 106 107le_int32 CoverageFormat2Table::getGlyphCoverage(LEReferenceTo<CoverageFormat2Table> &base, LEGlyphID glyphID, LEErrorCode &success) const 108{ 109 if(LE_FAILURE(success)) return -1; 110 111 TTGlyphID ttGlyphID = (TTGlyphID) LE_GET_GLYPH(glyphID); 112 le_uint16 count = SWAPW(rangeCount); 113 114 LEReferenceToArrayOf<GlyphRangeRecord> rangeRecordArrayRef(base, success, rangeRecordArray, count); 115 le_int32 rangeIndex = 116 OpenTypeUtilities::getGlyphRangeIndex(ttGlyphID, rangeRecordArrayRef, success); 117 118 if (rangeIndex < 0 || LE_FAILURE(success)) { // could fail if array out of bounds 119 return -1; 120 } 121 122 TTGlyphID firstInRange = SWAPW(rangeRecordArray[rangeIndex].firstGlyph); 123 le_uint16 startCoverageIndex = SWAPW(rangeRecordArray[rangeIndex].rangeValue); 124 125 return startCoverageIndex + (ttGlyphID - firstInRange); 126} 127 128U_NAMESPACE_END 129