} /* System.out.println("fontIndex=" + fontIndex + ", styleIndex=" + styleIndex + ", fbIndex=" + i + ",fbS=" + fallbackScripts[i] + ", id=" + id); */ fallbackFontNameIDs.add(id); nameIDs[index++] = id; } if (index < nameIDs.length) { short[] newNameIDs = new short[index]; System.arraycopy(nameIDs, 0, newNameIDs, 0, index); nameIDs = newNameIDs; } compFontNameIDs[fontIndex][styleIndex] = nameIDs; } } } private short remapLocaleMap(int fontIndex, int styleIndex, short scriptID, short fontID) { String scriptName = getString(table_scriptIDs[scriptID]); String value = (String)localeMap.get(scriptName); if (value == null) { String fontName = fontNames[fontIndex]; String styleName = styleNames[styleIndex]; value = (String)localeMap.get(fontName + "." + styleName + "." + scriptName); } if (value == null) { return fontID; } for (int i = 0; i < table_componentFontNameIDs.length; i++) { String name = getString(table_componentFontNameIDs[i]); if (value.equalsIgnoreCase(name)) { fontID = (short)i; break; } } return fontID; } public static boolean hasMonoToPropMap() { return table_proportionals != null && table_proportionals.length != 0; } private short remapProportional(int fontIndex, short id) { if (preferPropFonts && table_proportionals.length != 0 && fontIndex != 2 && //"monospaced" fontIndex != 4) { //"dialoginput" int i = 0; while (i < table_proportionals.length) { if (table_proportionals[i] == id) { return table_proportionals[i + 1]; } i += 2; } } return id; } ///////////////////////////////////////////////////////////////////// // Methods for handling font and style names // ///////////////////////////////////////////////////////////////////// protected static final int NUM_FONTS = 5; protected static final int NUM_STYLES = 4; protected static final String[] fontNames = {"serif", "sansserif", "monospaced", "dialog", "dialoginput"}; protected static final String[] publicFontNames = {Font.SERIF, Font.SANS_SERIF, Font.MONOSPACED, Font.DIALOG, Font.DIALOG_INPUT}; protected static final String[] styleNames = {"plain", "bold", "italic", "bolditalic"}; /** * Checks whether the given font family name is a valid logical font name. * The check is case insensitive. */ public static boolean isLogicalFontFamilyName(String fontName) { return isLogicalFontFamilyNameLC(fontName.toLowerCase(Locale.ENGLISH)); } /** * Checks whether the given font family name is a valid logical font name. * The check is case sensitive. */ public static boolean isLogicalFontFamilyNameLC(String fontName) { for (int i = 0; i < fontNames.length; i++) { if (fontName.equals(fontNames[i])) { return true; } } return false; } /** * Checks whether the given style name is a valid logical font style name. */ private static boolean isLogicalFontStyleName(String styleName) { for (int i = 0; i < styleNames.length; i++) { if (styleName.equals(styleNames[i])) { return true; } } return false; } /** * Checks whether the given font face name is a valid logical font name. * The check is case insensitive. */ public static boolean isLogicalFontFaceName(String fontName) { return isLogicalFontFaceNameLC(fontName.toLowerCase(Locale.ENGLISH)); } /** * Checks whether the given font face name is a valid logical font name. * The check is case sensitive. */ public static boolean isLogicalFontFaceNameLC(String fontName) { int period = fontName.indexOf('.'); if (period >= 0) { String familyName = fontName.substring(0, period); String styleName = fontName.substring(period + 1); return isLogicalFontFamilyName(familyName) && isLogicalFontStyleName(styleName); } else { return isLogicalFontFamilyName(fontName); } } protected static int getFontIndex(String fontName) { return getArrayIndex(fontNames, fontName); } protected static int getStyleIndex(String styleName) { return getArrayIndex(styleNames, styleName); } private static int getArrayIndex(String[] names, String name) { for (int i = 0; i < names.length; i++) { if (name.equals(names[i])) { return i; } } assert false; return 0; } protected static int getStyleIndex(int style) { switch (style) { case Font.PLAIN: return 0; case Font.BOLD: return 1; case Font.ITALIC: return 2; case Font.BOLD | Font.ITALIC: return 3; default: return 0; } } protected static String getFontName(int fontIndex) { return fontNames[fontIndex]; } protected static String getStyleName(int styleIndex) { return styleNames[styleIndex]; } /** * Returns the font face name for the given logical font * family name and style. * The style argument is interpreted as in java.awt.Font.Font. */ public static String getLogicalFontFaceName(String familyName, int style) { assert isLogicalFontFamilyName(familyName); return familyName.toLowerCase(Locale.ENGLISH) + "." + getStyleString(style); } /** * Returns the string typically used in properties files * for the given style. * The style argument is interpreted as in java.awt.Font.Font. */ public static String getStyleString(int style) { return getStyleName(getStyleIndex(style)); } /** * Returns a fallback name for the given font name. For a few known * font names, matching logical font names are returned. For all * other font names, defaultFallback is returned. * defaultFallback differs between AWT and 2D. */ public abstract String getFallbackFamilyName(String fontName, String defaultFallback); /** * Returns the 1.1 equivalent for some old 1.0 font family names for * which we need to maintain compatibility in some configurations. * Returns null for other font names. */ protected String getCompatibilityFamilyName(String fontName) { fontName = fontName.toLowerCase(Locale.ENGLISH); if (fontName.equals("timesroman")) { return "serif"; } else if (fontName.equals("helvetica")) { return "sansserif"; } else if (fontName.equals("courier")) { return "monospaced"; } return null; } protected static String[] installedFallbackFontFiles = null; /** * Maps a file name given in the font configuration file * to a format appropriate for the platform. */ protected String mapFileName(String fileName) { return fileName; } ////////////////////////////////////////////////////////////////////// // reordering // ////////////////////////////////////////////////////////////////////// /* Mappings from file encoding to font config name for font supporting * the corresponding language. This is filled in by initReorderMap() */ protected HashMap reorderMap = null; /* Platform-specific mappings */ protected abstract void initReorderMap(); /* Move item at index "src" to "dst", shuffling all values in * between down */ private void shuffle(String[] seq, int src, int dst) { if (dst >= src) { return; } String tmp = seq[src]; for (int i=src; i>dst; i--) { seq[i] = seq[i-1]; } seq[dst] = tmp; } /* Called to determine if there's a re-order sequence for this locale/ * encoding. If there's none then the caller can "bail" and avoid * unnecessary work */ public static boolean willReorderForStartupLocale() { return getReorderSequence() != null; } private static Object getReorderSequence() { if (fontConfig.reorderMap == null) { fontConfig.initReorderMap(); } HashMap reorderMap = fontConfig.reorderMap; /* Find the most specific mapping */ String language = startupLocale.getLanguage(); String country = startupLocale.getCountry(); Object val = reorderMap.get(encoding + "." + language + "." + country); if (val == null) { val = reorderMap.get(encoding + "." + language); } if (val == null) { val = reorderMap.get(encoding); } return val; } /* This method reorders the sequence such that the matches for the * file encoding are moved ahead of other elements. * If an encoding uses more than one font, they are all moved up. */ private void reorderSequenceForLocale(String[] seq) { Object val = getReorderSequence(); if (val instanceof String) { for (int i=0; i< seq.length; i++) { if (seq[i].equals(val)) { shuffle(seq, i, 0); return; } } } else if (val instanceof String[]) { String[] fontLangs = (String[])val; for (int l=0; l<fontLangs.length;l++) { for (int i=0; i<seq.length;i++) { if (seq[i].equals(fontLangs[l])) { shuffle(seq, i, l); } } } } } private static Vector splitSequence(String sequence) { //String.split would be more convenient, but incurs big performance penalty Vector parts = new Vector(); int start = 0; int end; while ((end = sequence.indexOf(',', start)) >= 0) { parts.add(sequence.substring(start, end)); start = end + 1; } if (sequence.length() > start) { parts.add(sequence.substring(start, sequence.length())); } return parts; } protected String[] split(String sequence) { Vector v = splitSequence(sequence); return (String[])v.toArray(new String[0]); } //////////////////////////////////////////////////////////////////////// // Methods for extracting information from the fontconfig data for AWT// //////////////////////////////////////////////////////////////////////// private Hashtable charsetRegistry = new Hashtable(5); /** * Returns FontDescriptors describing the physical fonts used for the * given logical font name and style. The font name is interpreted * in a case insensitive way. * The style argument is interpreted as in java.awt.Font.Font. */ public FontDescriptor[] getFontDescriptors(String fontName, int style) { assert isLogicalFontFamilyName(fontName); fontName = fontName.toLowerCase(Locale.ENGLISH); int fontIndex = getFontIndex(fontName); int styleIndex = getStyleIndex(style); return getFontDescriptors(fontIndex, styleIndex); } private FontDescriptor[][][] fontDescriptors = new FontDescriptor[NUM_FONTS][NUM_STYLES][]; private FontDescriptor[] getFontDescriptors(int fontIndex, int styleIndex) { FontDescriptor[] descriptors = fontDescriptors[fontIndex][styleIndex]; if (descriptors == null) { descriptors = buildFontDescriptors(fontIndex, styleIndex); fontDescriptors[fontIndex][styleIndex] = descriptors; } return descriptors; } private FontDescriptor[] buildFontDescriptors(int fontIndex, int styleIndex) { String fontName = fontNames[fontIndex]; String styleName = styleNames[styleIndex]; short[] scriptIDs = getCoreScripts(fontIndex); short[] nameIDs = compFontNameIDs[fontIndex][styleIndex]; String[] sequence = new String[scriptIDs.length]; String[] names = new String[scriptIDs.length]; for (int i = 0; i < sequence.length; i++) { names[i] = getComponentFontName(nameIDs[i]); sequence[i] = getScriptName(scriptIDs[i]); if (alphabeticSuffix != null && "alphabetic".equals(sequence[i])) { sequence[i] = sequence[i] + "/" + alphabeticSuffix; } } int[][] fontExclusionRanges = compExclusions[fontIndex]; FontDescriptor[] descriptors = new FontDescriptor[names.length]; for (int i = 0; i < names.length; i++) { String awtFontName; String encoding; awtFontName = makeAWTFontName(names[i], sequence[i]); // look up character encoding encoding = getEncoding(names[i], sequence[i]); if (encoding == null) { encoding = "default"; } CharsetEncoder enc = getFontCharsetEncoder(encoding.trim(), awtFontName); // we already have the exclusion ranges int[] exclusionRanges = fontExclusionRanges[i]; // create descriptor descriptors[i] = new FontDescriptor(awtFontName, enc, exclusionRanges); } return descriptors; } /** * Returns the AWT font name for the given platform font name and * character subset. */ protected String makeAWTFontName(String platformFontName, String characterSubsetName) { return platformFontName; } /** * Returns the java.io name of the platform character encoding for the * given AWT font name and character subset. May return "default" * to indicate that getDefaultFontCharset should be called to obtain * a charset encoder. */ protected abstract String getEncoding(String awtFontName, String characterSubsetName); private CharsetEncoder getFontCharsetEncoder(final String charsetName, String fontName) { Charset fc = null; if (charsetName.equals("default")) { fc = (Charset) charsetRegistry.get(fontName); } else { fc = (Charset) charsetRegistry.get(charsetName); } if (fc != null) { return fc.newEncoder(); } if (!charsetName.startsWith("sun.awt.") && !charsetName.equals("default")) { fc = Charset.forName(charsetName); } else { Class fcc = (Class) AccessController.doPrivileged(new PrivilegedAction() { public Object run() { try { return Class.forName(charsetName, true, Thread.currentThread().getContextClassLoader()); } catch (ClassNotFoundException e) { } return null; } }); if (fcc != null) { try { fc = (Charset) fcc.newInstance(); } catch (Exception e) { } } } if (fc == null) { fc = getDefaultFontCharset(fontName); } if (charsetName.equals("default")){ charsetRegistry.put(fontName, fc); } else { charsetRegistry.put(charsetName, fc); } return fc.newEncoder(); } protected abstract Charset getDefaultFontCharset( String fontName); /* This retrieves the platform font directories (path) calculated * by setAWTFontPathSequence(String[]). The default implementation * returns null, its expected that X11 platforms may return * non-null. */ public HashSet<String> getAWTFontPathSet() { return null; } //////////////////////////////////////////////////////////////////////// // methods for extracting information from the fontconfig data for 2D // //////////////////////////////////////////////////////////////////////// /** * Returns an array of composite font descriptors for all logical font * faces. * If the font configuration file doesn't specify Lucida Sans Regular * or the given fallback font as component fonts, they are added here. */ public CompositeFontDescriptor[] get2DCompositeFontInfo() { CompositeFontDescriptor[] result = new CompositeFontDescriptor[NUM_FONTS * NUM_STYLES]; String defaultFontFile = fontManager.getDefaultFontFile(); String defaultFontFaceName = fontManager.getDefaultFontFaceName(); for (int fontIndex = 0; fontIndex < NUM_FONTS; fontIndex++) { String fontName = publicFontNames[fontIndex]; // determine exclusion ranges for font // AWT uses separate exclusion range array per component font. // 2D packs all range boundaries into one array. // Both use separate entries for lower and upper boundary. int[][] exclusions = compExclusions[fontIndex]; int numExclusionRanges = 0; for (int i = 0; i < exclusions.length; i++) { numExclusionRanges += exclusions[i].length; }Lines 501–1000 of 2272. Previous lines Load more
} /* System.out.println("fontIndex=" + fontIndex + ", styleIndex=" + styleIndex + ", fbIndex=" + i + ",fbS=" + fallbackScripts[i] + ", id=" + id); */ fallbackFontNameIDs.add(id); nameIDs[index++] = id; } if (index < nameIDs.length) { short[] newNameIDs = new short[index]; System.arraycopy(nameIDs, 0, newNameIDs, 0, index); nameIDs = newNameIDs; } compFontNameIDs[fontIndex][styleIndex] = nameIDs; } } } private short remapLocaleMap(int fontIndex, int styleIndex, short scriptID, short fontID) { String scriptName = getString(table_scriptIDs[scriptID]); String value = (String)localeMap.get(scriptName); if (value == null) { String fontName = fontNames[fontIndex]; String styleName = styleNames[styleIndex]; value = (String)localeMap.get(fontName + "." + styleName + "." + scriptName); } if (value == null) { return fontID; } for (int i = 0; i < table_componentFontNameIDs.length; i++) { String name = getString(table_componentFontNameIDs[i]); if (value.equalsIgnoreCase(name)) { fontID = (short)i; break; } } return fontID; } public static boolean hasMonoToPropMap() { return table_proportionals != null && table_proportionals.length != 0; } private short remapProportional(int fontIndex, short id) { if (preferPropFonts && table_proportionals.length != 0 && fontIndex != 2 && //"monospaced" fontIndex != 4) { //"dialoginput" int i = 0; while (i < table_proportionals.length) { if (table_proportionals[i] == id) { return table_proportionals[i + 1]; } i += 2; } } return id; } ///////////////////////////////////////////////////////////////////// // Methods for handling font and style names // ///////////////////////////////////////////////////////////////////// protected static final int NUM_FONTS = 5; protected static final int NUM_STYLES = 4; protected static final String[] fontNames = {"serif", "sansserif", "monospaced", "dialog", "dialoginput"}; protected static final String[] publicFontNames = {Font.SERIF, Font.SANS_SERIF, Font.MONOSPACED, Font.DIALOG, Font.DIALOG_INPUT}; protected static final String[] styleNames = {"plain", "bold", "italic", "bolditalic"}; /** * Checks whether the given font family name is a valid logical font name. * The check is case insensitive. */ public static boolean isLogicalFontFamilyName(String fontName) { return isLogicalFontFamilyNameLC(fontName.toLowerCase(Locale.ENGLISH)); } /** * Checks whether the given font family name is a valid logical font name. * The check is case sensitive. */ public static boolean isLogicalFontFamilyNameLC(String fontName) { for (int i = 0; i < fontNames.length; i++) { if (fontName.equals(fontNames[i])) { return true; } } return false; } /** * Checks whether the given style name is a valid logical font style name. */ private static boolean isLogicalFontStyleName(String styleName) { for (int i = 0; i < styleNames.length; i++) { if (styleName.equals(styleNames[i])) { return true; } } return false; } /** * Checks whether the given font face name is a valid logical font name. * The check is case insensitive. */ public static boolean isLogicalFontFaceName(String fontName) { return isLogicalFontFaceNameLC(fontName.toLowerCase(Locale.ENGLISH)); } /** * Checks whether the given font face name is a valid logical font name. * The check is case sensitive. */ public static boolean isLogicalFontFaceNameLC(String fontName) { int period = fontName.indexOf('.'); if (period >= 0) { String familyName = fontName.substring(0, period); String styleName = fontName.substring(period + 1); return isLogicalFontFamilyName(familyName) && isLogicalFontStyleName(styleName); } else { return isLogicalFontFamilyName(fontName); } } protected static int getFontIndex(String fontName) { return getArrayIndex(fontNames, fontName); } protected static int getStyleIndex(String styleName) { return getArrayIndex(styleNames, styleName); } private static int getArrayIndex(String[] names, String name) { for (int i = 0; i < names.length; i++) { if (name.equals(names[i])) { return i; } } assert false; return 0; } protected static int getStyleIndex(int style) { switch (style) { case Font.PLAIN: return 0; case Font.BOLD: return 1; case Font.ITALIC: return 2; case Font.BOLD | Font.ITALIC: return 3; default: return 0; } } protected static String getFontName(int fontIndex) { return fontNames[fontIndex]; } protected static String getStyleName(int styleIndex) { return styleNames[styleIndex]; } /** * Returns the font face name for the given logical font * family name and style. * The style argument is interpreted as in java.awt.Font.Font. */ public static String getLogicalFontFaceName(String familyName, int style) { assert isLogicalFontFamilyName(familyName); return familyName.toLowerCase(Locale.ENGLISH) + "." + getStyleString(style); } /** * Returns the string typically used in properties files * for the given style. * The style argument is interpreted as in java.awt.Font.Font. */ public static String getStyleString(int style) { return getStyleName(getStyleIndex(style)); } /** * Returns a fallback name for the given font name. For a few known * font names, matching logical font names are returned. For all * other font names, defaultFallback is returned. * defaultFallback differs between AWT and 2D. */ public abstract String getFallbackFamilyName(String fontName, String defaultFallback); /** * Returns the 1.1 equivalent for some old 1.0 font family names for * which we need to maintain compatibility in some configurations. * Returns null for other font names. */ protected String getCompatibilityFamilyName(String fontName) { fontName = fontName.toLowerCase(Locale.ENGLISH); if (fontName.equals("timesroman")) { return "serif"; } else if (fontName.equals("helvetica")) { return "sansserif"; } else if (fontName.equals("courier")) { return "monospaced"; } return null; } protected static String[] installedFallbackFontFiles = null; /** * Maps a file name given in the font configuration file * to a format appropriate for the platform. */ protected String mapFileName(String fileName) { return fileName; } ////////////////////////////////////////////////////////////////////// // reordering // ////////////////////////////////////////////////////////////////////// /* Mappings from file encoding to font config name for font supporting * the corresponding language. This is filled in by initReorderMap() */ protected HashMap reorderMap = null; /* Platform-specific mappings */ protected abstract void initReorderMap(); /* Move item at index "src" to "dst", shuffling all values in * between down */ private void shuffle(String[] seq, int src, int dst) { if (dst >= src) { return; } String tmp = seq[src]; for (int i=src; i>dst; i--) { seq[i] = seq[i-1]; } seq[dst] = tmp; } /* Called to determine if there's a re-order sequence for this locale/ * encoding. If there's none then the caller can "bail" and avoid * unnecessary work */ public static boolean willReorderForStartupLocale() { return getReorderSequence() != null; } private static Object getReorderSequence() { if (fontConfig.reorderMap == null) { fontConfig.initReorderMap(); } HashMap reorderMap = fontConfig.reorderMap; /* Find the most specific mapping */ String language = startupLocale.getLanguage(); String country = startupLocale.getCountry(); Object val = reorderMap.get(encoding + "." + language + "." + country); if (val == null) { val = reorderMap.get(encoding + "." + language); } if (val == null) { val = reorderMap.get(encoding); } return val; } /* This method reorders the sequence such that the matches for the * file encoding are moved ahead of other elements. * If an encoding uses more than one font, they are all moved up. */ private void reorderSequenceForLocale(String[] seq) { Object val = getReorderSequence(); if (val instanceof String) { for (int i=0; i< seq.length; i++) { if (seq[i].equals(val)) { shuffle(seq, i, 0); return; } } } else if (val instanceof String[]) { String[] fontLangs = (String[])val; for (int l=0; l<fontLangs.length;l++) { for (int i=0; i<seq.length;i++) { if (seq[i].equals(fontLangs[l])) { shuffle(seq, i, l); } } } } } private static Vector splitSequence(String sequence) { //String.split would be more convenient, but incurs big performance penalty Vector parts = new Vector(); int start = 0; int end; while ((end = sequence.indexOf(',', start)) >= 0) { parts.add(sequence.substring(start, end)); start = end + 1; } if (sequence.length() > start) { parts.add(sequence.substring(start, sequence.length())); } return parts; } protected String[] split(String sequence) { Vector v = splitSequence(sequence); return (String[])v.toArray(new String[0]); } //////////////////////////////////////////////////////////////////////// // Methods for extracting information from the fontconfig data for AWT// //////////////////////////////////////////////////////////////////////// private Hashtable charsetRegistry = new Hashtable(5); /** * Returns FontDescriptors describing the physical fonts used for the * given logical font name and style. The font name is interpreted * in a case insensitive way. * The style argument is interpreted as in java.awt.Font.Font. */ public FontDescriptor[] getFontDescriptors(String fontName, int style) { assert isLogicalFontFamilyName(fontName); fontName = fontName.toLowerCase(Locale.ENGLISH); int fontIndex = getFontIndex(fontName); int styleIndex = getStyleIndex(style); return getFontDescriptors(fontIndex, styleIndex); } private FontDescriptor[][][] fontDescriptors = new FontDescriptor[NUM_FONTS][NUM_STYLES][]; private FontDescriptor[] getFontDescriptors(int fontIndex, int styleIndex) { FontDescriptor[] descriptors = fontDescriptors[fontIndex][styleIndex]; if (descriptors == null) { descriptors = buildFontDescriptors(fontIndex, styleIndex); fontDescriptors[fontIndex][styleIndex] = descriptors; } return descriptors; } private FontDescriptor[] buildFontDescriptors(int fontIndex, int styleIndex) { String fontName = fontNames[fontIndex]; String styleName = styleNames[styleIndex]; short[] scriptIDs = getCoreScripts(fontIndex); short[] nameIDs = compFontNameIDs[fontIndex][styleIndex]; String[] sequence = new String[scriptIDs.length]; String[] names = new String[scriptIDs.length]; for (int i = 0; i < sequence.length; i++) { names[i] = getComponentFontName(nameIDs[i]); sequence[i] = getScriptName(scriptIDs[i]); if (alphabeticSuffix != null && "alphabetic".equals(sequence[i])) { sequence[i] = sequence[i] + "/" + alphabeticSuffix; } } int[][] fontExclusionRanges = compExclusions[fontIndex]; FontDescriptor[] descriptors = new FontDescriptor[names.length]; for (int i = 0; i < names.length; i++) { String awtFontName; String encoding; awtFontName = makeAWTFontName(names[i], sequence[i]); // look up character encoding encoding = getEncoding(names[i], sequence[i]); if (encoding == null) { encoding = "default"; } CharsetEncoder enc = getFontCharsetEncoder(encoding.trim(), awtFontName); // we already have the exclusion ranges int[] exclusionRanges = fontExclusionRanges[i]; // create descriptor descriptors[i] = new FontDescriptor(awtFontName, enc, exclusionRanges); } return descriptors; } /** * Returns the AWT font name for the given platform font name and * character subset. */ protected String makeAWTFontName(String platformFontName, String characterSubsetName) { return platformFontName; } /** * Returns the java.io name of the platform character encoding for the * given AWT font name and character subset. May return "default" * to indicate that getDefaultFontCharset should be called to obtain * a charset encoder. */ protected abstract String getEncoding(String awtFontName, String characterSubsetName); private CharsetEncoder getFontCharsetEncoder(final String charsetName, String fontName) { Charset fc = null; if (charsetName.equals("default")) { fc = (Charset) charsetRegistry.get(fontName); } else { fc = (Charset) charsetRegistry.get(charsetName); } if (fc != null) { return fc.newEncoder(); } if (!charsetName.startsWith("sun.awt.") && !charsetName.equals("default")) { fc = Charset.forName(charsetName); } else { Class fcc = (Class) AccessController.doPrivileged(new PrivilegedAction() { public Object run() { try { return Class.forName(charsetName, true, Thread.currentThread().getContextClassLoader()); } catch (ClassNotFoundException e) { } return null; } }); if (fcc != null) { try { fc = (Charset) fcc.newInstance(); } catch (Exception e) { } } } if (fc == null) { fc = getDefaultFontCharset(fontName); } if (charsetName.equals("default")){ charsetRegistry.put(fontName, fc); } else { charsetRegistry.put(charsetName, fc); } return fc.newEncoder(); } protected abstract Charset getDefaultFontCharset( String fontName); /* This retrieves the platform font directories (path) calculated * by setAWTFontPathSequence(String[]). The default implementation * returns null, its expected that X11 platforms may return * non-null. */ public HashSet<String> getAWTFontPathSet() { return null; } //////////////////////////////////////////////////////////////////////// // methods for extracting information from the fontconfig data for 2D // //////////////////////////////////////////////////////////////////////// /** * Returns an array of composite font descriptors for all logical font * faces. * If the font configuration file doesn't specify Lucida Sans Regular * or the given fallback font as component fonts, they are added here. */ public CompositeFontDescriptor[] get2DCompositeFontInfo() { CompositeFontDescriptor[] result = new CompositeFontDescriptor[NUM_FONTS * NUM_STYLES]; String defaultFontFile = fontManager.getDefaultFontFile(); String defaultFontFaceName = fontManager.getDefaultFontFaceName(); for (int fontIndex = 0; fontIndex < NUM_FONTS; fontIndex++) { String fontName = publicFontNames[fontIndex]; // determine exclusion ranges for font // AWT uses separate exclusion range array per component font. // 2D packs all range boundaries into one array. // Both use separate entries for lower and upper boundary. int[][] exclusions = compExclusions[fontIndex]; int numExclusionRanges = 0; for (int i = 0; i < exclusions.length; i++) { numExclusionRanges += exclusions[i].length; }