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 import java.nio.ByteBuffer; 29 import java.util.Locale; 30 31 public class TrueTypeGlyphMapper extends CharToGlyphMapper { 32 33 static final char REVERSE_SOLIDUS = 0x005c; // the backslash char. 34 static final char JA_YEN = 0x00a5; 35 static final char JA_FULLWIDTH_TILDE_CHAR = 0xff5e; 36 static final char JA_WAVE_DASH_CHAR = 0x301c; 37 38 /* if running on Solaris and default Locale is ja_JP then 39 * we map need to remap reverse solidus (backslash) to Yen as 40 * apparently expected there. 41 */ 42 static final boolean isJAlocale = Locale.JAPAN.equals(Locale.getDefault()); 43 private final boolean needsJAremapping; 44 private boolean remapJAWaveDash; 45 46 TrueTypeFont font; 47 CMap cmap; 48 int numGlyphs; 49 50 public TrueTypeGlyphMapper(TrueTypeFont font) { 51 this.font = font; 52 try { 53 cmap = CMap.initialize(font); 54 } catch (Exception e) { 55 cmap = null; 56 } 57 if (cmap == null) { 58 handleBadCMAP(); 59 } 60 missingGlyph = 0; /* standard for TrueType fonts */ 61 ByteBuffer buffer = font.getTableBuffer(TrueTypeFont.maxpTag); 62 if (buffer != null && buffer.capacity() >= 6) { 63 numGlyphs = buffer.getChar(4); // offset 4 bytes in MAXP table. 64 } else { 65 handleBadCMAP(); 66 } 67 if (FontUtilities.isSolaris && isJAlocale && font.supportsJA()) { 68 needsJAremapping = true; 69 if (FontUtilities.isSolaris8 && 70 getGlyphFromCMAP(JA_WAVE_DASH_CHAR) == missingGlyph) { 71 remapJAWaveDash = true; 72 } 73 } else { 74 needsJAremapping = false; 75 } 76 } 77 78 public int getNumGlyphs() { 79 return numGlyphs; 80 } 81 82 private char getGlyphFromCMAP(int charCode) { 83 try { 84 char glyphCode = cmap.getGlyph(charCode); 85 if (glyphCode < numGlyphs || 86 glyphCode >= FileFontStrike.INVISIBLE_GLYPHS) { 87 return glyphCode; 88 } else { 89 if (FontUtilities.isLogging()) { 90 FontUtilities.getLogger().warning 91 (font + " out of range glyph id=" + 92 Integer.toHexString((int)glyphCode) + 96 } 97 } catch(Exception e) { 98 handleBadCMAP(); 99 return (char) missingGlyph; 100 } 101 } 102 103 private void handleBadCMAP() { 104 if (FontUtilities.isLogging()) { 105 FontUtilities.getLogger().severe("Null Cmap for " + font + 106 "substituting for this font"); 107 } 108 SunFontManager.getInstance().deRegisterBadFont(font); 109 /* The next line is not really a solution, but might 110 * reduce the exceptions until references to this font2D 111 * are gone. 112 */ 113 cmap = CMap.theNullCmap; 114 } 115 116 @SuppressWarnings("fallthrough") 117 private final char remapJAChar(char unicode) { 118 switch (unicode) { 119 case REVERSE_SOLIDUS: 120 return JA_YEN; 121 /* This is a workaround for bug 4533422. 122 * Japanese wave dash missing from Solaris JA TrueType fonts. 123 */ 124 case JA_WAVE_DASH_CHAR: 125 if (remapJAWaveDash) { 126 return JA_FULLWIDTH_TILDE_CHAR; 127 } 128 default: return unicode; 129 } 130 } 131 @SuppressWarnings("fallthrough") 132 private final int remapJAIntChar(int unicode) { 133 switch (unicode) { 134 case REVERSE_SOLIDUS: 135 return JA_YEN; 136 /* This is a workaround for bug 4533422. 137 * Japanese wave dash missing from Solaris JA TrueType fonts. 138 */ 139 case JA_WAVE_DASH_CHAR: 140 if (remapJAWaveDash) { 141 return JA_FULLWIDTH_TILDE_CHAR; 142 } 143 default: return unicode; 144 } 145 } 146 147 public int charToGlyph(char unicode) { 148 if (needsJAremapping) { 149 unicode = remapJAChar(unicode); 150 } 151 int glyph = getGlyphFromCMAP(unicode); 152 if (font.checkUseNatives() && glyph < font.glyphToCharMap.length) { 153 font.glyphToCharMap[glyph] = unicode; 154 } 155 return glyph; 156 } 157 158 public int charToGlyph(int unicode) { 159 if (needsJAremapping) { 160 unicode = remapJAIntChar(unicode); 161 } 162 int glyph = getGlyphFromCMAP(unicode); 163 if (font.checkUseNatives() && glyph < font.glyphToCharMap.length) { 164 font.glyphToCharMap[glyph] = (char)unicode; | 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 import java.nio.ByteBuffer; 29 import java.util.Locale; 30 31 public class TrueTypeGlyphMapper extends CharToGlyphMapper { 32 33 static final char REVERSE_SOLIDUS = 0x005c; // the backslash char. 34 static final char JA_YEN = 0x00a5; 35 36 /* if running on Solaris and default Locale is ja_JP then 37 * we map need to remap reverse solidus (backslash) to Yen as 38 * apparently expected there. 39 */ 40 static final boolean isJAlocale = Locale.JAPAN.equals(Locale.getDefault()); 41 private final boolean needsJAremapping; 42 43 TrueTypeFont font; 44 CMap cmap; 45 int numGlyphs; 46 47 public TrueTypeGlyphMapper(TrueTypeFont font) { 48 this.font = font; 49 try { 50 cmap = CMap.initialize(font); 51 } catch (Exception e) { 52 cmap = null; 53 } 54 if (cmap == null) { 55 handleBadCMAP(); 56 } 57 missingGlyph = 0; /* standard for TrueType fonts */ 58 ByteBuffer buffer = font.getTableBuffer(TrueTypeFont.maxpTag); 59 if (buffer != null && buffer.capacity() >= 6) { 60 numGlyphs = buffer.getChar(4); // offset 4 bytes in MAXP table. 61 } else { 62 handleBadCMAP(); 63 } 64 if (FontUtilities.isSolaris && isJAlocale && font.supportsJA()) { 65 needsJAremapping = true; 66 } else { 67 needsJAremapping = false; 68 } 69 } 70 71 public int getNumGlyphs() { 72 return numGlyphs; 73 } 74 75 private char getGlyphFromCMAP(int charCode) { 76 try { 77 char glyphCode = cmap.getGlyph(charCode); 78 if (glyphCode < numGlyphs || 79 glyphCode >= FileFontStrike.INVISIBLE_GLYPHS) { 80 return glyphCode; 81 } else { 82 if (FontUtilities.isLogging()) { 83 FontUtilities.getLogger().warning 84 (font + " out of range glyph id=" + 85 Integer.toHexString((int)glyphCode) + 89 } 90 } catch(Exception e) { 91 handleBadCMAP(); 92 return (char) missingGlyph; 93 } 94 } 95 96 private void handleBadCMAP() { 97 if (FontUtilities.isLogging()) { 98 FontUtilities.getLogger().severe("Null Cmap for " + font + 99 "substituting for this font"); 100 } 101 SunFontManager.getInstance().deRegisterBadFont(font); 102 /* The next line is not really a solution, but might 103 * reduce the exceptions until references to this font2D 104 * are gone. 105 */ 106 cmap = CMap.theNullCmap; 107 } 108 109 private final char remapJAChar(char unicode) { 110 return (unicode == REVERSE_SOLIDUS) ? JA_YEN : unicode; 111 } 112 113 private final int remapJAIntChar(int unicode) { 114 return (unicode == REVERSE_SOLIDUS) ? JA_YEN : unicode; 115 } 116 117 public int charToGlyph(char unicode) { 118 if (needsJAremapping) { 119 unicode = remapJAChar(unicode); 120 } 121 int glyph = getGlyphFromCMAP(unicode); 122 if (font.checkUseNatives() && glyph < font.glyphToCharMap.length) { 123 font.glyphToCharMap[glyph] = unicode; 124 } 125 return glyph; 126 } 127 128 public int charToGlyph(int unicode) { 129 if (needsJAremapping) { 130 unicode = remapJAIntChar(unicode); 131 } 132 int glyph = getGlyphFromCMAP(unicode); 133 if (font.checkUseNatives() && glyph < font.glyphToCharMap.length) { 134 font.glyphToCharMap[glyph] = (char)unicode; |