< prev index next >

src/java.desktop/share/classes/sun/font/TrueTypeGlyphMapper.java

Print this page




  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;


< prev index next >