1 /* 2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.font; 27 28 public final class CCompositeGlyphMapper extends CompositeGlyphMapper { 29 30 private CompositeFont font; 31 private CharToGlyphMapper slotMappers[]; 32 33 public CCompositeGlyphMapper(CompositeFont compFont) { 34 super(compFont); 35 font = compFont; 36 slotMappers = new CharToGlyphMapper[font.numSlots]; 37 missingGlyph = 0; 38 } 39 40 private CharToGlyphMapper getSlotMapper(int slot) { 41 CharToGlyphMapper mapper = slotMappers[slot]; 42 if (mapper == null) { 43 mapper = font.getSlotFont(slot).getMapper(); 44 slotMappers[slot] = mapper; 45 } 46 return mapper; 47 } 48 49 public boolean canDisplay(char ch) { 50 int glyph = charToGlyph(ch); 51 return glyph != missingGlyph; 52 } 53 54 private int convertToGlyph(int unicode) { 55 for (int slot = 0; slot < font.numSlots; slot++) { 56 CharToGlyphMapper mapper = getSlotMapper(slot); 57 int glyphCode = mapper.charToGlyph(unicode); 58 // The CFont Mappers will return a negative code 59 // for fonts that will fill the glyph from fallbacks 60 // - cascading font in OSX-speak. But we need to be 61 // know here that only the codes > 0 are really present. 62 if (glyphCode > 0) { 63 glyphCode = compositeGlyphCode(slot, glyphCode); 64 return glyphCode; 65 } 66 } 67 return missingGlyph; 68 } 69 70 public int getNumGlyphs() { 71 int numGlyphs = 0; 72 for (int slot=0; slot<1 /*font.numSlots*/; slot++) { 73 CharToGlyphMapper mapper = slotMappers[slot]; 74 if (mapper == null) { 75 mapper = font.getSlotFont(slot).getMapper(); 76 slotMappers[slot] = mapper; 77 } 78 numGlyphs += mapper.getNumGlyphs(); 79 } 80 return numGlyphs; 81 } 82 83 public int charToGlyph(int unicode) { 84 return convertToGlyph(unicode); 85 } 86 87 public int charToGlyph(char unicode) { 88 return convertToGlyph(unicode); 89 } 90 91 public boolean charsToGlyphsNS(int count, char[] unicodes, int[] glyphs) { 92 93 for (int i=0; i<count; i++) { 94 int code = unicodes[i]; // char is unsigned. 95 96 if (code >= HI_SURROGATE_START && 97 code <= HI_SURROGATE_END && i < count - 1) { 98 char low = unicodes[i + 1]; 99 100 if (low >= LO_SURROGATE_START && 101 low <= LO_SURROGATE_END) { 102 code = (code - HI_SURROGATE_START) * 103 0x400 + low - LO_SURROGATE_START + 0x10000; 104 glyphs[i + 1] = INVISIBLE_GLYPH_ID; 105 } 106 } 107 108 glyphs[i] = convertToGlyph(code); 109 110 if (code < FontUtilities.MIN_LAYOUT_CHARCODE) { 111 continue; 112 } 113 else if (FontUtilities.isComplexCharCode(code)) { 114 return true; 115 } 116 else if (code >= 0x10000) { 117 i += 1; // Empty glyph slot after surrogate 118 continue; 119 } 120 } 121 122 return false; 123 } 124 125 public void charsToGlyphs(int count, char[] unicodes, int[] glyphs) { 126 for (int i=0; i<count; i++) { 127 int code = unicodes[i]; // char is unsigned. 128 129 if (code >= HI_SURROGATE_START && 130 code <= HI_SURROGATE_END && i < count - 1) { 131 char low = unicodes[i + 1]; 132 133 if (low >= LO_SURROGATE_START && 134 low <= LO_SURROGATE_END) { 135 code = (code - HI_SURROGATE_START) * 136 0x400 + low - LO_SURROGATE_START + 0x10000; 137 138 glyphs[i] = convertToGlyph(code); 139 i += 1; // Empty glyph slot after surrogate 140 glyphs[i] = INVISIBLE_GLYPH_ID; 141 continue; 142 } 143 } 144 145 glyphs[i] = convertToGlyph(code); 146 } 147 } 148 149 public void charsToGlyphs(int count, int[] unicodes, int[] glyphs) { 150 for (int i=0; i<count; i++) { 151 glyphs[i] = convertToGlyph(unicodes[i]); 152 } 153 } 154 155 }