/* * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Sun designates this * particular file as subject to the "Classpath" exception as provided * by Sun in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ package sun.font; /* * This isn't a critical performance case, so don't do any * char->glyph map caching for Type1 fonts. The ones that are used * in composites will be cached there. */ public final class Type1GlyphMapper extends CharToGlyphMapper { Type1Font font; FontScaler scaler; public Type1GlyphMapper(Type1Font font) { this.font = font; initMapper(); } private void initMapper() { scaler = font.getScaler(); try { missingGlyph = scaler.getMissingGlyphCode(); } catch (FontScalerException fe) { scaler = FontScaler.getNullScaler(); try { missingGlyph = scaler.getMissingGlyphCode(); } catch (FontScalerException e) { //should not happen missingGlyph = 0; } } } public int getNumGlyphs() { try { return scaler.getNumGlyphs(); } catch (FontScalerException e) { scaler = FontScaler.getNullScaler(); return getNumGlyphs(); } } public int getMissingGlyphCode() { return missingGlyph; } public boolean canDisplay(char ch) { try { return scaler.getGlyphCode(ch) != missingGlyph; } catch(FontScalerException e) { scaler = FontScaler.getNullScaler(); return canDisplay(ch); } } public int charToGlyph(char ch) { try { return scaler.getGlyphCode(ch); } catch (FontScalerException e) { scaler = FontScaler.getNullScaler(); return charToGlyph(ch); } } public int charToGlyph(int ch) { if (ch < 0 || ch > 0xffff) { return missingGlyph; } else { try { return scaler.getGlyphCode((char)ch); } catch (FontScalerException e) { scaler = FontScaler.getNullScaler(); return charToGlyph(ch); } } } public void charsToGlyphs(int count, char[] unicodes, int[] glyphs) { /* The conversion into surrogates is misleading. * The Type1 glyph mapper only accepts 16 bit unsigned shorts. * If its > not in the range it can use assign the missing glyph. */ for (int i=0; i= HI_SURROGATE_START && code <= HI_SURROGATE_END && i < count - 1) { char low = unicodes[i + 1]; if (low >= LO_SURROGATE_START && low <= LO_SURROGATE_END) { code = (code - HI_SURROGATE_START) * 0x400 + low - LO_SURROGATE_START + 0x10000; glyphs[i + 1] = 0xFFFF; // invisible glyph } } glyphs[i] = charToGlyph(code); if (code >= 0x10000) { i += 1; // Empty glyph slot after surrogate } } } public void charsToGlyphs(int count, int[] unicodes, int[] glyphs) { /* I believe this code path is never exercised. Its there mainly * for surrogates and/or the opentype engine which aren't likely * to be an issue for Type1 fonts. So no need to optimise it. */ for (int i=0; i= HI_SURROGATE_START && code <= HI_SURROGATE_END && i < count - 1) { char low = unicodes[i + 1]; if (low >= LO_SURROGATE_START && low <= LO_SURROGATE_END) { code = (code - HI_SURROGATE_START) * 0x400 + low - LO_SURROGATE_START + 0x10000; glyphs[i + 1] = INVISIBLE_GLYPH_ID; } } glyphs[i] = charToGlyph(code); if (code < FontUtilities.MIN_LAYOUT_CHARCODE) { continue; } else if (FontUtilities.isComplexCharCode(code)) { return true; } else if (code >= 0x10000) { i += 1; // Empty glyph slot after surrogate continue; } } return false; } }