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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26 package sun.awt;
27
28 import java.awt.Font;
29 import java.io.DataInputStream;
30 import java.io.DataOutputStream;
31 import java.io.File;
32 import java.io.FileInputStream;
33 import java.io.FileOutputStream;
34 import java.io.InputStream;
35 import java.io.IOException;
36 import java.io.OutputStream;
37 import java.nio.charset.Charset;
38 import java.nio.charset.CharsetEncoder;
39 import java.security.AccessController;
40 import java.security.PrivilegedAction;
41 import java.util.logging.Logger;
42 import java.util.HashMap;
43 import java.util.HashSet;
44 import java.util.Hashtable;
45 import java.util.Iterator;
46 import java.util.Locale;
47 import java.util.Map.Entry;
48 import java.util.Properties;
49 import java.util.Set;
50 import java.util.Vector;
51 import sun.font.CompositeFontDescriptor;
52 import sun.java2d.SunGraphicsEnvironment;
53
54 /**
55 * Provides the definitions of the five logical fonts: Serif, SansSerif,
56 * Monospaced, Dialog, and DialogInput. The necessary information
57 * is obtained from fontconfig files.
58 */
59 public abstract class FontConfiguration {
60
61 //static global runtime env
62 protected static String osVersion;
63 protected static String osName;
64 protected static String encoding; // canonical name of default nio charset
65 protected static Locale startupLocale = null;
66 protected static Hashtable localeMap = null;
67 private static FontConfiguration fontConfig;
68 private static Logger logger;
69 protected static boolean isProperties = true;
70
71 protected SunGraphicsEnvironment environment;
72 protected boolean preferLocaleFonts;
73 protected boolean preferPropFonts;
74
75 private File fontConfigFile;
76 private boolean foundOsSpecificFile;
77 private boolean inited;
78 private String javaLib;
79
80 /* A default FontConfiguration must be created before an alternate
81 * one to ensure proper static initialisation takes place.
82 */
83 public FontConfiguration(SunGraphicsEnvironment environment) {
84 if (SunGraphicsEnvironment.debugFonts && logger == null) {
85 logger = Logger.getLogger("sun.awt.FontConfiguration");
86 }
87 this.environment = environment;
88 setOsNameAndVersion(); /* static initialization */
89 setEncoding(); /* static initialization */
90 /* Separating out the file location from the rest of the
91 * initialisation, so the caller has the option of doing
92 * something else if a suitable file isn't found.
93 */
94 findFontConfigFile();
95 }
96
97 public synchronized boolean init() {
98 if (!inited) {
99 this.preferLocaleFonts = false;
100 this.preferPropFonts = false;
101 setFontConfiguration();
102 readFontConfigFile(fontConfigFile);
103 initFontConfig();
104 inited = true;
105 }
106 return true;
107 }
108
109 public FontConfiguration(SunGraphicsEnvironment environment,
110 boolean preferLocaleFonts,
111 boolean preferPropFonts) {
112 this.environment = environment;
113 this.preferLocaleFonts = preferLocaleFonts;
114 this.preferPropFonts = preferPropFonts;
115 /* fontConfig should be initialised by default constructor, and
116 * its data tables can be shared, since readFontConfigFile doesn't
117 * update any other state. Also avoid a doPrivileged block.
118 */
119 initFontConfig();
120 }
121
122 /**
123 * Fills in this instance's osVersion and osName members. By
124 * default uses the system properties os.name and os.version;
125 * subclasses may override.
126 */
127 protected void setOsNameAndVersion() {
128 osName = System.getProperty("os.name");
129 osVersion = System.getProperty("os.version");
130 }
131
132 private void setEncoding() {
181 }
182 }
183
184 private void readFontConfigFile(File f) {
185 /* This is invoked here as readFontConfigFile is only invoked
186 * once per VM, and always in a privileged context, thus the
187 * directory containing installed fall back fonts is accessed
188 * from this context
189 */
190 getInstalledFallbackFonts(javaLib);
191
192 if (f != null) {
193 try {
194 FileInputStream in = new FileInputStream(f.getPath());
195 if (isProperties) {
196 loadProperties(in);
197 } else {
198 loadBinary(in);
199 }
200 in.close();
201 if (SunGraphicsEnvironment.debugFonts) {
202 logger.config("Read logical font configuration from " + f);
203 }
204 } catch (IOException e) {
205 if (SunGraphicsEnvironment.debugFonts) {
206 logger.config("Failed to read logical font configuration from " + f);
207 }
208 }
209 }
210 String version = getVersion();
211 if (!"1".equals(version) && SunGraphicsEnvironment.debugFonts) {
212 logger.config("Unsupported fontconfig version: " + version);
213 }
214 }
215
216 protected void getInstalledFallbackFonts(String javaLib) {
217 String fallbackDirName = javaLib + File.separator +
218 "fonts" + File.separator + "fallback";
219
220 File fallbackDir = new File(fallbackDirName);
221 if (fallbackDir.exists() && fallbackDir.isDirectory()) {
222 String[] ttfs = fallbackDir.list(SunGraphicsEnvironment.ttFilter);
223 String[] t1s = fallbackDir.list(SunGraphicsEnvironment.t1Filter);
224 int numTTFs = (ttfs == null) ? 0 : ttfs.length;
225 int numT1s = (t1s == null) ? 0 : t1s.length;
226 int len = numTTFs + numT1s;
227 if (numTTFs + numT1s == 0) {
228 return;
229 }
230 installedFallbackFontFiles = new String[len];
231 for (int i=0; i<numTTFs; i++) {
232 installedFallbackFontFiles[i] =
233 fallbackDir + File.separator + ttfs[i];
234 }
235 for (int i=0; i<numT1s; i++) {
236 installedFallbackFontFiles[i+numTTFs] =
237 fallbackDir + File.separator + t1s[i];
238 }
239 environment.registerFontsInDir(fallbackDirName);
240 }
241 }
242
243 private File findImpl(String fname) {
244 File f = new File(fname + ".properties");
245 if (f.canRead()) {
246 isProperties = true;
247 return f;
248 }
249 f = new File(fname + ".bfc");
250 if (f.canRead()) {
251 isProperties = false;
252 return f;
253 }
254 return null;
255 }
256
257 private File findFontConfigFile(String javaLib) {
258 String baseName = javaLib + File.separator + "fontconfig";
259 File configFile;
448 System.out.println("coreScriptID=" + table_sequences[initELC * 5 + fontIndex]);
449 for (int i = 0; i < coreScripts.length; i++) {
450 System.out.println(" " + i + " :" + getString(table_scriptIDs[coreScripts[i]]));
451 }
452 */
453 //init exclusionRanges
454 int[][] exclusions = new int[coreScripts.length][];
455 for (int i = 0; i < coreScripts.length; i++) {
456 exclusions[i] = getExclusionRanges(coreScripts[i]);
457 }
458 compExclusions[fontIndex] = exclusions;
459 //init componentFontNames
460 for (int styleIndex = 0; styleIndex < NUM_STYLES; styleIndex++) {
461 int index;
462 short[] nameIDs = new short[coreScripts.length + fallbackScripts.length];
463 //core
464 for (index = 0; index < coreScripts.length; index++) {
465 nameIDs[index] = getComponentFontID(coreScripts[index],
466 fontIndex, styleIndex);
467 if (preferLocaleFonts && localeMap != null &&
468 sun.font.FontManager.usingAlternateFontforJALocales()) {
469 nameIDs[index] = remapLocaleMap(fontIndex, styleIndex,
470 coreScripts[index], nameIDs[index]);
471 }
472 if (preferPropFonts) {
473 nameIDs[index] = remapProportional(fontIndex, nameIDs[index]);
474 }
475 //System.out.println("nameid=" + nameIDs[index]);
476 coreFontNameIDs.add(nameIDs[index]);
477 }
478 //fallback
479 for (int i = 0; i < fallbackScripts.length; i++) {
480 short id = getComponentFontID(fallbackScripts[i],
481 fontIndex, styleIndex);
482 if (preferLocaleFonts && localeMap != null &&
483 sun.font.FontManager.usingAlternateFontforJALocales()) {
484 id = remapLocaleMap(fontIndex, styleIndex, fallbackScripts[i], id);
485 }
486 if (preferPropFonts) {
487 id = remapProportional(fontIndex, id);
488 }
489 if (contains(nameIDs, id, index)) {
490 continue;
491 }
492 /*
493 System.out.println("fontIndex=" + fontIndex + ", styleIndex=" + styleIndex
494 + ", fbIndex=" + i + ",fbS=" + fallbackScripts[i] + ", id=" + id);
495 */
496 fallbackFontNameIDs.add(id);
497 nameIDs[index++] = id;
498 }
499 if (index < nameIDs.length) {
500 short[] newNameIDs = new short[index];
501 System.arraycopy(nameIDs, 0, newNameIDs, 0, index);
502 nameIDs = newNameIDs;
503 }
956 * returns null, its expected that X11 platforms may return
957 * non-null.
958 */
959 public HashSet<String> getAWTFontPathSet() {
960 return null;
961 }
962
963 ////////////////////////////////////////////////////////////////////////
964 // methods for extracting information from the fontconfig data for 2D //
965 ////////////////////////////////////////////////////////////////////////
966
967 /**
968 * Returns an array of composite font descriptors for all logical font
969 * faces.
970 * If the font configuration file doesn't specify Lucida Sans Regular
971 * or the given fallback font as component fonts, they are added here.
972 */
973 public CompositeFontDescriptor[] get2DCompositeFontInfo() {
974 CompositeFontDescriptor[] result =
975 new CompositeFontDescriptor[NUM_FONTS * NUM_STYLES];
976 String defaultFontFile = environment.getDefaultFontFile();
977 String defaultFontFaceName = environment.getDefaultFontFaceName();
978
979 for (int fontIndex = 0; fontIndex < NUM_FONTS; fontIndex++) {
980 String fontName = publicFontNames[fontIndex];
981
982 // determine exclusion ranges for font
983 // AWT uses separate exclusion range array per component font.
984 // 2D packs all range boundaries into one array.
985 // Both use separate entries for lower and upper boundary.
986 int[][] exclusions = compExclusions[fontIndex];
987 int numExclusionRanges = 0;
988 for (int i = 0; i < exclusions.length; i++) {
989 numExclusionRanges += exclusions[i].length;
990 }
991 int[] exclusionRanges = new int[numExclusionRanges];
992 int[] exclusionRangeLimits = new int[exclusions.length];
993 int exclusionRangeIndex = 0;
994 int exclusionRangeLimitIndex = 0;
995 for (int i = 0; i < exclusions.length; i++) {
996 int[] componentRanges = exclusions[i];
997 for (int j = 0; j < componentRanges.length; ) {
1104 }
1105
1106 protected abstract String getFaceNameFromComponentFontName(String componentFontName);
1107 protected abstract String getFileNameFromComponentFontName(String componentFontName);
1108
1109 /*
1110 public class 2dFont {
1111 public String platformName;
1112 public String fontfileName;
1113 }
1114 private 2dFont [] componentFonts = null;
1115 */
1116
1117 /* Used on Linux to test if a file referenced in a font configuration
1118 * file exists in the location that is expected. If it does, no need
1119 * to search for it. If it doesn't then unless its a fallback font,
1120 * return that expensive code should be invoked to search for the font.
1121 */
1122 HashMap<String, Boolean> existsMap;
1123 public boolean needToSearchForFile(String fileName) {
1124 if (!environment.isLinux) {
1125 return false;
1126 } else if (existsMap == null) {
1127 existsMap = new HashMap<String, Boolean>();
1128 }
1129 Boolean exists = existsMap.get(fileName);
1130 if (exists == null) {
1131 /* call getNumberCoreFonts() to ensure these are initialised, and
1132 * if this file isn't for a core component, ie, is a for a fallback
1133 * font which very typically isn't available, then can't afford
1134 * to take the start-up penalty to search for it.
1135 */
1136 getNumberCoreFonts();
1137 if (!coreFontFileNames.contains(fileName)) {
1138 exists = Boolean.TRUE;
1139 } else {
1140 exists = Boolean.valueOf((new File(fileName)).exists());
1141 existsMap.put(fileName, exists);
1142 if (SunGraphicsEnvironment.debugFonts &&
1143 exists == Boolean.FALSE) {
1144 logger.warning("Couldn't locate font file " + fileName);
1145 }
1146 }
1147 }
1148 return exists == Boolean.FALSE;
1149 }
1150
1151 private int numCoreFonts = -1;
1152 private String[] componentFonts = null;
1153 HashMap <String, String> filenamesMap = new HashMap<String, String>();
1154 HashSet <String> coreFontFileNames = new HashSet<String>();
1155
1156 /* Return the number of core fonts. Note this isn't thread safe but
1157 * a calling thread can call this and getPlatformFontNames() in either
1158 * order.
1159 */
1160 public int getNumberCoreFonts() {
1161 if (numCoreFonts == -1) {
1162 numCoreFonts = coreFontNameIDs.size();
2050 lower = exclusions.substring(pos, newPos);
2051 pos = newPos + 1;
2052 newPos = exclusions.indexOf(',', pos);
2053 if (newPos == -1) {
2054 newPos = exclusions.length();
2055 }
2056 upper = exclusions.substring(pos, newPos);
2057 pos = newPos + 1;
2058 int lowerLength = lower.length();
2059 int upperLength = upper.length();
2060 if (lowerLength != 4 && lowerLength != 6
2061 || upperLength != 4 && upperLength != 6) {
2062 throw new Exception();
2063 }
2064 lo = Integer.parseInt(lower, 16);
2065 up = Integer.parseInt(upper, 16);
2066 if (lo > up) {
2067 throw new Exception();
2068 }
2069 } catch (Exception e) {
2070 if (SunGraphicsEnvironment.debugFonts && logger != null) {
2071 logger.config("Failed parsing " + key +
2072 " property of font configuration.");
2073
2074 }
2075 return EMPTY_INT_ARRAY;
2076 }
2077 exclusionRanges[j++] = lo;
2078 exclusionRanges[j++] = up;
2079 }
2080 return exclusionRanges;
2081 }
2082
2083 private Short getID(HashMap<String, Short> map, String key) {
2084 Short ret = map.get(key);
2085 if ( ret == null) {
2086 map.put(key, (short)map.size());
2087 return map.get(key);
2088 }
2089 return ret;
2090 }
|
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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26 package sun.awt;
27
28 import java.awt.Font;
29 import java.io.DataInputStream;
30 import java.io.DataOutputStream;
31 import java.io.File;
32 import java.io.FileInputStream;
33 import java.io.InputStream;
34 import java.io.IOException;
35 import java.io.OutputStream;
36 import java.nio.charset.Charset;
37 import java.nio.charset.CharsetEncoder;
38 import java.security.AccessController;
39 import java.security.PrivilegedAction;
40 import java.util.logging.Logger;
41 import java.util.HashMap;
42 import java.util.HashSet;
43 import java.util.Hashtable;
44 import java.util.Iterator;
45 import java.util.Locale;
46 import java.util.Map.Entry;
47 import java.util.Properties;
48 import java.util.Set;
49 import java.util.Vector;
50 import sun.font.CompositeFontDescriptor;
51 import sun.font.SunFontManager;
52 import sun.font.FontManagerFactory;
53 import sun.font.FontUtilities;
54
55 /**
56 * Provides the definitions of the five logical fonts: Serif, SansSerif,
57 * Monospaced, Dialog, and DialogInput. The necessary information
58 * is obtained from fontconfig files.
59 */
60 public abstract class FontConfiguration {
61
62 //static global runtime env
63 protected static String osVersion;
64 protected static String osName;
65 protected static String encoding; // canonical name of default nio charset
66 protected static Locale startupLocale = null;
67 protected static Hashtable localeMap = null;
68 private static FontConfiguration fontConfig;
69 private static Logger logger;
70 protected static boolean isProperties = true;
71
72 protected SunFontManager fontManager;
73 protected boolean preferLocaleFonts;
74 protected boolean preferPropFonts;
75
76 private File fontConfigFile;
77 private boolean foundOsSpecificFile;
78 private boolean inited;
79 private String javaLib;
80
81 /* A default FontConfiguration must be created before an alternate
82 * one to ensure proper static initialisation takes place.
83 */
84 public FontConfiguration(SunFontManager fm) {
85 if (FontUtilities.debugFonts() && logger == null) {
86 logger = Logger.getLogger("sun.awt.FontConfiguration");
87 }
88 fontManager = fm;
89 setOsNameAndVersion(); /* static initialization */
90 setEncoding(); /* static initialization */
91 /* Separating out the file location from the rest of the
92 * initialisation, so the caller has the option of doing
93 * something else if a suitable file isn't found.
94 */
95 findFontConfigFile();
96 }
97
98 public synchronized boolean init() {
99 if (!inited) {
100 this.preferLocaleFonts = false;
101 this.preferPropFonts = false;
102 setFontConfiguration();
103 readFontConfigFile(fontConfigFile);
104 initFontConfig();
105 inited = true;
106 }
107 return true;
108 }
109
110 public FontConfiguration(SunFontManager fm,
111 boolean preferLocaleFonts,
112 boolean preferPropFonts) {
113 fontManager = fm;
114 this.preferLocaleFonts = preferLocaleFonts;
115 this.preferPropFonts = preferPropFonts;
116 /* fontConfig should be initialised by default constructor, and
117 * its data tables can be shared, since readFontConfigFile doesn't
118 * update any other state. Also avoid a doPrivileged block.
119 */
120 initFontConfig();
121 }
122
123 /**
124 * Fills in this instance's osVersion and osName members. By
125 * default uses the system properties os.name and os.version;
126 * subclasses may override.
127 */
128 protected void setOsNameAndVersion() {
129 osName = System.getProperty("os.name");
130 osVersion = System.getProperty("os.version");
131 }
132
133 private void setEncoding() {
182 }
183 }
184
185 private void readFontConfigFile(File f) {
186 /* This is invoked here as readFontConfigFile is only invoked
187 * once per VM, and always in a privileged context, thus the
188 * directory containing installed fall back fonts is accessed
189 * from this context
190 */
191 getInstalledFallbackFonts(javaLib);
192
193 if (f != null) {
194 try {
195 FileInputStream in = new FileInputStream(f.getPath());
196 if (isProperties) {
197 loadProperties(in);
198 } else {
199 loadBinary(in);
200 }
201 in.close();
202 if (FontUtilities.debugFonts()) {
203 logger.config("Read logical font configuration from " + f);
204 }
205 } catch (IOException e) {
206 if (FontUtilities.debugFonts()) {
207 logger.config("Failed to read logical font configuration from " + f);
208 }
209 }
210 }
211 String version = getVersion();
212 if (!"1".equals(version) && FontUtilities.debugFonts()) {
213 logger.config("Unsupported fontconfig version: " + version);
214 }
215 }
216
217 protected void getInstalledFallbackFonts(String javaLib) {
218 String fallbackDirName = javaLib + File.separator +
219 "fonts" + File.separator + "fallback";
220
221 File fallbackDir = new File(fallbackDirName);
222 if (fallbackDir.exists() && fallbackDir.isDirectory()) {
223 String[] ttfs = fallbackDir.list(fontManager.getTrueTypeFilter());
224 String[] t1s = fallbackDir.list(fontManager.getType1Filter());
225 int numTTFs = (ttfs == null) ? 0 : ttfs.length;
226 int numT1s = (t1s == null) ? 0 : t1s.length;
227 int len = numTTFs + numT1s;
228 if (numTTFs + numT1s == 0) {
229 return;
230 }
231 installedFallbackFontFiles = new String[len];
232 for (int i=0; i<numTTFs; i++) {
233 installedFallbackFontFiles[i] =
234 fallbackDir + File.separator + ttfs[i];
235 }
236 for (int i=0; i<numT1s; i++) {
237 installedFallbackFontFiles[i+numTTFs] =
238 fallbackDir + File.separator + t1s[i];
239 }
240 fontManager.registerFontsInDir(fallbackDirName);
241 }
242 }
243
244 private File findImpl(String fname) {
245 File f = new File(fname + ".properties");
246 if (f.canRead()) {
247 isProperties = true;
248 return f;
249 }
250 f = new File(fname + ".bfc");
251 if (f.canRead()) {
252 isProperties = false;
253 return f;
254 }
255 return null;
256 }
257
258 private File findFontConfigFile(String javaLib) {
259 String baseName = javaLib + File.separator + "fontconfig";
260 File configFile;
449 System.out.println("coreScriptID=" + table_sequences[initELC * 5 + fontIndex]);
450 for (int i = 0; i < coreScripts.length; i++) {
451 System.out.println(" " + i + " :" + getString(table_scriptIDs[coreScripts[i]]));
452 }
453 */
454 //init exclusionRanges
455 int[][] exclusions = new int[coreScripts.length][];
456 for (int i = 0; i < coreScripts.length; i++) {
457 exclusions[i] = getExclusionRanges(coreScripts[i]);
458 }
459 compExclusions[fontIndex] = exclusions;
460 //init componentFontNames
461 for (int styleIndex = 0; styleIndex < NUM_STYLES; styleIndex++) {
462 int index;
463 short[] nameIDs = new short[coreScripts.length + fallbackScripts.length];
464 //core
465 for (index = 0; index < coreScripts.length; index++) {
466 nameIDs[index] = getComponentFontID(coreScripts[index],
467 fontIndex, styleIndex);
468 if (preferLocaleFonts && localeMap != null &&
469 fontManager.usingAlternateFontforJALocales()) {
470 nameIDs[index] = remapLocaleMap(fontIndex, styleIndex,
471 coreScripts[index], nameIDs[index]);
472 }
473 if (preferPropFonts) {
474 nameIDs[index] = remapProportional(fontIndex, nameIDs[index]);
475 }
476 //System.out.println("nameid=" + nameIDs[index]);
477 coreFontNameIDs.add(nameIDs[index]);
478 }
479 //fallback
480 for (int i = 0; i < fallbackScripts.length; i++) {
481 short id = getComponentFontID(fallbackScripts[i],
482 fontIndex, styleIndex);
483 if (preferLocaleFonts && localeMap != null &&
484 fontManager.usingAlternateFontforJALocales()) {
485 id = remapLocaleMap(fontIndex, styleIndex, fallbackScripts[i], id);
486 }
487 if (preferPropFonts) {
488 id = remapProportional(fontIndex, id);
489 }
490 if (contains(nameIDs, id, index)) {
491 continue;
492 }
493 /*
494 System.out.println("fontIndex=" + fontIndex + ", styleIndex=" + styleIndex
495 + ", fbIndex=" + i + ",fbS=" + fallbackScripts[i] + ", id=" + id);
496 */
497 fallbackFontNameIDs.add(id);
498 nameIDs[index++] = id;
499 }
500 if (index < nameIDs.length) {
501 short[] newNameIDs = new short[index];
502 System.arraycopy(nameIDs, 0, newNameIDs, 0, index);
503 nameIDs = newNameIDs;
504 }
957 * returns null, its expected that X11 platforms may return
958 * non-null.
959 */
960 public HashSet<String> getAWTFontPathSet() {
961 return null;
962 }
963
964 ////////////////////////////////////////////////////////////////////////
965 // methods for extracting information from the fontconfig data for 2D //
966 ////////////////////////////////////////////////////////////////////////
967
968 /**
969 * Returns an array of composite font descriptors for all logical font
970 * faces.
971 * If the font configuration file doesn't specify Lucida Sans Regular
972 * or the given fallback font as component fonts, they are added here.
973 */
974 public CompositeFontDescriptor[] get2DCompositeFontInfo() {
975 CompositeFontDescriptor[] result =
976 new CompositeFontDescriptor[NUM_FONTS * NUM_STYLES];
977 String defaultFontFile = fontManager.getDefaultFontFile();
978 String defaultFontFaceName = fontManager.getDefaultFontFaceName();
979
980 for (int fontIndex = 0; fontIndex < NUM_FONTS; fontIndex++) {
981 String fontName = publicFontNames[fontIndex];
982
983 // determine exclusion ranges for font
984 // AWT uses separate exclusion range array per component font.
985 // 2D packs all range boundaries into one array.
986 // Both use separate entries for lower and upper boundary.
987 int[][] exclusions = compExclusions[fontIndex];
988 int numExclusionRanges = 0;
989 for (int i = 0; i < exclusions.length; i++) {
990 numExclusionRanges += exclusions[i].length;
991 }
992 int[] exclusionRanges = new int[numExclusionRanges];
993 int[] exclusionRangeLimits = new int[exclusions.length];
994 int exclusionRangeIndex = 0;
995 int exclusionRangeLimitIndex = 0;
996 for (int i = 0; i < exclusions.length; i++) {
997 int[] componentRanges = exclusions[i];
998 for (int j = 0; j < componentRanges.length; ) {
1105 }
1106
1107 protected abstract String getFaceNameFromComponentFontName(String componentFontName);
1108 protected abstract String getFileNameFromComponentFontName(String componentFontName);
1109
1110 /*
1111 public class 2dFont {
1112 public String platformName;
1113 public String fontfileName;
1114 }
1115 private 2dFont [] componentFonts = null;
1116 */
1117
1118 /* Used on Linux to test if a file referenced in a font configuration
1119 * file exists in the location that is expected. If it does, no need
1120 * to search for it. If it doesn't then unless its a fallback font,
1121 * return that expensive code should be invoked to search for the font.
1122 */
1123 HashMap<String, Boolean> existsMap;
1124 public boolean needToSearchForFile(String fileName) {
1125 if (!FontUtilities.isLinux) {
1126 return false;
1127 } else if (existsMap == null) {
1128 existsMap = new HashMap<String, Boolean>();
1129 }
1130 Boolean exists = existsMap.get(fileName);
1131 if (exists == null) {
1132 /* call getNumberCoreFonts() to ensure these are initialised, and
1133 * if this file isn't for a core component, ie, is a for a fallback
1134 * font which very typically isn't available, then can't afford
1135 * to take the start-up penalty to search for it.
1136 */
1137 getNumberCoreFonts();
1138 if (!coreFontFileNames.contains(fileName)) {
1139 exists = Boolean.TRUE;
1140 } else {
1141 exists = Boolean.valueOf((new File(fileName)).exists());
1142 existsMap.put(fileName, exists);
1143 if (FontUtilities.debugFonts() &&
1144 exists == Boolean.FALSE) {
1145 logger.warning("Couldn't locate font file " + fileName);
1146 }
1147 }
1148 }
1149 return exists == Boolean.FALSE;
1150 }
1151
1152 private int numCoreFonts = -1;
1153 private String[] componentFonts = null;
1154 HashMap <String, String> filenamesMap = new HashMap<String, String>();
1155 HashSet <String> coreFontFileNames = new HashSet<String>();
1156
1157 /* Return the number of core fonts. Note this isn't thread safe but
1158 * a calling thread can call this and getPlatformFontNames() in either
1159 * order.
1160 */
1161 public int getNumberCoreFonts() {
1162 if (numCoreFonts == -1) {
1163 numCoreFonts = coreFontNameIDs.size();
2051 lower = exclusions.substring(pos, newPos);
2052 pos = newPos + 1;
2053 newPos = exclusions.indexOf(',', pos);
2054 if (newPos == -1) {
2055 newPos = exclusions.length();
2056 }
2057 upper = exclusions.substring(pos, newPos);
2058 pos = newPos + 1;
2059 int lowerLength = lower.length();
2060 int upperLength = upper.length();
2061 if (lowerLength != 4 && lowerLength != 6
2062 || upperLength != 4 && upperLength != 6) {
2063 throw new Exception();
2064 }
2065 lo = Integer.parseInt(lower, 16);
2066 up = Integer.parseInt(upper, 16);
2067 if (lo > up) {
2068 throw new Exception();
2069 }
2070 } catch (Exception e) {
2071 if (FontUtilities.debugFonts() &&
2072 logger != null) {
2073 logger.config("Failed parsing " + key +
2074 " property of font configuration.");
2075
2076 }
2077 return EMPTY_INT_ARRAY;
2078 }
2079 exclusionRanges[j++] = lo;
2080 exclusionRanges[j++] = up;
2081 }
2082 return exclusionRanges;
2083 }
2084
2085 private Short getID(HashMap<String, Short> map, String key) {
2086 Short ret = map.get(key);
2087 if ( ret == null) {
2088 map.put(key, (short)map.size());
2089 return map.get(key);
2090 }
2091 return ret;
2092 }
|