42 private static final int POINT_SIZE_FIELD = 8;
43 private static final int RESOLUTION_X_FIELD = 9;
44 private static final int RESOLUTION_Y_FIELD = 10;
45 private static final int SPACING_FIELD = 11;
46 private static final int AVERAGE_WIDTH_FIELD = 12;
47 private static final int CHARSET_REGISTRY_FIELD = 13;
48 private static final int CHARSET_ENCODING_FIELD = 14;
49
50 /*
51 * fontNameMap is a map from a fontID (which is a substring of an XLFD like
52 * "-monotype-arial-bold-r-normal-iso8859-7")
53 * to font file path like
54 * /usr/openwin/lib/locale/iso_8859_7/X11/fonts/TrueType/ArialBoldItalic.ttf
55 * It's used in a couple of methods like
56 * getFileNameFomPlatformName(..) to help locate the font file.
57 * We use this substring of a full XLFD because the font configuration files
58 * define the XLFDs in a way that's easier to make into a request.
59 * E.g., the -0-0-0-0-p-0- reported by X is -*-%d-*-*-p-*- in the font
60 * configuration files. We need to remove that part for comparisons.
61 */
62 private static Map fontNameMap = new HashMap();
63
64 /*
65 * xlfdMap is a map from a platform path like
66 * /usr/openwin/lib/locale/ja/X11/fonts/TT/HG-GothicB.ttf to an XLFD like
67 * "-ricoh-hg gothic b-medium-r-normal--0-0-0-0-m-0-jisx0201.1976-0"
68 * Because there may be multiple native names, because the font is used
69 * to support multiple X encodings for example, the value of an entry in
70 * this map is always a vector where we store all the native names.
71 * For fonts which we don't understand the key isn't a pathname, its
72 * the full XLFD string like :-
73 * "-ricoh-hg gothic b-medium-r-normal--0-0-0-0-m-0-jisx0201.1976-0"
74 */
75 private static Map xlfdMap = new HashMap();
76
77 /* xFontDirsMap is also a map from a font ID to a font filepath.
78 * The difference from fontNameMap is just that it does not have
79 * resolved symbolic links. Normally this is not interesting except
80 * that we need to know the directory in which a font was found to
81 * add it to the X font server path, since although the files may
82 * be linked, the fonts.dir is different and specific to the encoding
83 * handled by that directory. This map is nulled out after use to free
84 * heap space. If the optimal path is taken, such that all fonts in
85 * font configuration files are referenced by filename, then the font
86 * dir can be directly derived as its parent directory.
87 * If a font is used by two XLFDs, each corresponding to a different
88 * X11 font directory, then precautions must be taken to include both
89 * directories.
90 */
91 private static Map xFontDirsMap;
92
93 /*
94 * This is the set of font directories needed to be on the X font path
95 * to enable AWT heavyweights to find all of the font configuration fonts.
96 * It is populated by :
97 * - awtfontpath entries in the fontconfig.properties
98 * - parent directories of "core" fonts used in the fontconfig.properties
99 * - looking up font dirs in the xFontDirsMap where the key is a fontID
100 * (cut down version of the XLFD read from the font configuration file).
101 * This set is nulled out after use to free heap space.
102 */
103 private static HashSet<String> fontConfigDirs = null;
104
105 /* These maps are used on Linux where we reference the Lucida oblique
106 * fonts in fontconfig files even though they aren't in the standard
107 * font directory. This explicitly remaps the XLFDs for these to the
108 * correct base font. This is needed to prevent composite fonts from
109 * defaulting to the Lucida Sans which is a bad substitute for the
110 * monospaced Lucida Sans Typewriter. Also these maps prevent the
111 * JRE from doing wasted work at start up.
112 */
113 HashMap<String, String> oblmap = null;
114
115
116 /*
117 * Used to eliminate redundant work. When a font directory is
118 * registered it added to this list. Subsequent registrations for the
119 * same directory can then be skipped by checking this Map.
120 * Access to this map is not synchronised here since creation
121 * of the singleton GE instance is already synchronised and that is
122 * the only code path that accesses this map.
123 */
124 private static HashMap registeredDirs = new HashMap();
125
126 /* Array of directories to be added to the X11 font path.
127 * Used by static method called from Toolkits which use X11 fonts.
128 * Specifically this means MToolkit
129 */
130 private static String[] fontdirs = null;
131
132 private static String[] defaultPlatformFont = null;
133
134 private FontConfigManager fcManager = null;
135
136 public static X11FontManager getInstance() {
137 return (X11FontManager) SunFontManager.getInstance();
138 }
139
140 /**
141 * Takes family name property in the following format:
142 * "-linotype-helvetica-medium-r-normal-sans-*-%d-*-*-p-*-iso8859-1"
143 * and returns the name of the corresponding physical font.
144 * This code is used to resolve font configuration fonts, and expects
166 fileName = super.getFileNameFromPlatformName(platName);
167 if (fileName != null) {
168 if (isHeadless() && fileName.startsWith("-")) {
169 /* if it's headless, no xlfd should be used */
170 return null;
171 }
172 if (fileName.startsWith("/")) {
173 /* If a path is assigned in the font configuration file,
174 * it is required that the config file also specify using the
175 * new awtfontpath key the X11 font directories
176 * which must be added to the X11 font path to support
177 * AWT access to that font. For that reason we no longer
178 * have code here to add the parent directory to the list
179 * of font config dirs, since the parent directory may not
180 * be sufficient if fonts are symbolically linked to a
181 * different directory.
182 *
183 * Add this XLFD (platform name) to the list of known
184 * ones for this file.
185 */
186 Vector xVal = (Vector) xlfdMap.get(fileName);
187 if (xVal == null) {
188 /* Try to be robust on Linux distros which move fonts
189 * around by verifying that the fileName represents a
190 * file that exists. If it doesn't, set it to null
191 * to trigger a search.
192 */
193 if (getFontConfiguration().needToSearchForFile(fileName)) {
194 fileName = null;
195 }
196 if (fileName != null) {
197 xVal = new Vector();
198 xVal.add(platName);
199 xlfdMap.put(fileName, xVal);
200 }
201 } else {
202 if (!xVal.contains(platName)) {
203 xVal.add(platName);
204 }
205 }
206 }
207 if (fileName != null) {
208 fontNameMap.put(fontID, fileName);
209 return fileName;
210 }
211 }
212
213 if (fontID != null) {
214 fileName = (String)fontNameMap.get(fontID);
215 /* On Linux check for the Lucida Oblique fonts */
216 if (fileName == null && FontUtilities.isLinux && !isOpenJDK()) {
217 if (oblmap == null) {
218 initObliqueLucidaFontMap();
219 }
220 String oblkey = getObliqueLucidaFontID(fontID);
221 if (oblkey != null) {
222 fileName = oblmap.get(oblkey);
223 }
224 }
225 if (fontPath == null &&
226 (fileName == null || !fileName.startsWith("/"))) {
227 if (FontUtilities.debugFonts()) {
228 FontUtilities.getLogger()
229 .warning("** Registering all font paths because " +
230 "can't find file for " + platName);
231 }
232 fontPath = getPlatformFontPath(noType1Font);
233 registerFontDirs(fontPath);
234 if (FontUtilities.debugFonts()) {
235 FontUtilities.getLogger()
236 .warning("** Finished registering all font paths");
237 }
238 fileName = (String)fontNameMap.get(fontID);
239 }
240 if (fileName == null && !isHeadless()) {
241 /* Query X11 directly to see if this font is available
242 * as a native font.
243 */
244 fileName = getX11FontName(platName);
245 }
246 if (fileName == null) {
247 fontID = switchFontIDForName(platName);
248 fileName = (String)fontNameMap.get(fontID);
249 }
250 if (fileName != null) {
251 fontNameMap.put(fontID, fileName);
252 }
253 }
254 return fileName;
255 }
256
257 @Override
258 protected String[] getNativeNames(String fontFileName,
259 String platformName) {
260 Vector nativeNames;
261 if ((nativeNames=(Vector)xlfdMap.get(fontFileName))==null) {
262 if (platformName == null) {
263 return null;
264 } else {
265 /* back-stop so that at least the name used in the
266 * font configuration file is known as a native name
267 */
268 String []natNames = new String[1];
269 natNames[0] = platformName;
270 return natNames;
271 }
272 } else {
273 int len = nativeNames.size();
274 return (String[])nativeNames.toArray(new String[len]);
275 }
276 }
277
278 /* NOTE: this method needs to be executed in a privileged context.
279 * The superclass constructor which is the primary caller of
280 * this method executes entirely in such a context. Additionally
281 * the loadFonts() method does too. So all should be well.
282
283 */
284 @Override
285 protected void registerFontDir(String path) {
286 /* fonts.dir file format looks like :-
287 * 47
288 * Arial.ttf -monotype-arial-regular-r-normal--0-0-0-0-p-0-iso8859-1
289 * Arial-Bold.ttf -monotype-arial-bold-r-normal--0-0-0-0-p-0-iso8859-1
290 * ...
291 */
292 if (FontUtilities.debugFonts()) {
293 FontUtilities.getLogger().info("ParseFontDir " + path);
294 }
349 if (ttype != StreamTokenizer.TT_EOL) {
350 break;
351 }
352 continue;
353 }
354 String fileName = st.sval.substring(0, breakPos);
355 /* TurboLinux 8.0 uses some additional syntax to
356 * indicate algorithmic styling values.
357 * Ignore ':' separated files at the beginning
358 * of the fileName
359 */
360 int lastColon = fileName.lastIndexOf(':');
361 if (lastColon > 0) {
362 if (lastColon+1 >= fileName.length()) {
363 continue;
364 }
365 fileName = fileName.substring(lastColon+1);
366 }
367 String fontPart = st.sval.substring(breakPos+1);
368 String fontID = specificFontIDForName(fontPart);
369 String sVal = (String) fontNameMap.get(fontID);
370
371 if (FontUtilities.debugFonts()) {
372 PlatformLogger logger = FontUtilities.getLogger();
373 logger.info("file=" + fileName +
374 " xlfd=" + fontPart);
375 logger.info("fontID=" + fontID +
376 " sVal=" + sVal);
377 }
378 String fullPath = null;
379 try {
380 File file = new File(path,fileName);
381 /* we may have a resolved symbolic link
382 * this becomes important for an xlfd we
383 * still need to know the location it was
384 * found to update the X server font path
385 * for use by AWT heavyweights - and when 2D
386 * wants to use the native rasteriser.
387 */
388 if (xFontDirsMap == null) {
389 xFontDirsMap = new HashMap();
390 }
391 xFontDirsMap.put(fontID, path);
392 fullPath = file.getCanonicalPath();
393 } catch (IOException e) {
394 fullPath = path + File.separator + fileName;
395 }
396 Vector xVal = (Vector) xlfdMap.get(fullPath);
397 if (FontUtilities.debugFonts()) {
398 FontUtilities.getLogger()
399 .info("fullPath=" + fullPath +
400 " xVal=" + xVal);
401 }
402 if ((xVal == null || !xVal.contains(fontPart)) &&
403 (sVal == null) || !sVal.startsWith("/")) {
404 if (FontUtilities.debugFonts()) {
405 FontUtilities.getLogger()
406 .info("Map fontID:"+fontID +
407 "to file:" + fullPath);
408 }
409 fontNameMap.put(fontID, fullPath);
410 if (xVal == null) {
411 xVal = new Vector();
412 xlfdMap.put (fullPath, xVal);
413 }
414 xVal.add(fontPart);
415 }
416
417 ttype = st.nextToken();
418 if (ttype != StreamTokenizer.TT_EOL) {
419 break;
420 }
421 }
422 }
423 }
424 fr.close();
425 }
426 } catch (IOException ioe1) {
427 } finally {
428 if (fr != null) {
429 try {
430 fr.close();
431 } catch (IOException ioe2) {
432 }
433 }
434 }
435 }
436
437 @Override
438 public void loadFonts() {
439 super.loadFonts();
440 /* These maps are greatly expanded during a loadFonts but
441 * can be reset to their initial state afterwards.
442 * Since preferLocaleFonts() and preferProportionalFonts() will
443 * trigger a partial repopulating from the FontConfiguration
444 * it has to be the inital (empty) state for the latter two, not
445 * simply nulling out.
446 * xFontDirsMap is a special case in that the implementation
447 * will typically not ever need to initialise it so it can be null.
448 */
449 xFontDirsMap = null;
450 xlfdMap = new HashMap(1);
451 fontNameMap = new HashMap(1);
452 }
453
454 private String getObliqueLucidaFontID(String fontID) {
455 if (fontID.startsWith("-lucidasans-medium-i-normal") ||
456 fontID.startsWith("-lucidasans-bold-i-normal") ||
457 fontID.startsWith("-lucidatypewriter-medium-i-normal") ||
458 fontID.startsWith("-lucidatypewriter-bold-i-normal")) {
459 return fontID.substring(0, fontID.indexOf("-i-"));
460 } else {
461 return null;
462 }
463 }
464
465 private static String getX11FontName(String platName) {
466 String xlfd = platName.replaceAll("%d", "*");
467 if (NativeFont.fontExists(xlfd)) {
468 return xlfd;
469 } else {
470 return null;
471 }
562 }
563 StringBuffer sb =
564 new StringBuffer(name.substring(hPos[FAMILY_NAME_FIELD-1],
565 hPos[SLANT_FIELD-1]+1));
566 sb.append(slant);
567 sb.append(name.substring(hPos[SLANT_FIELD],
568 hPos[SETWIDTH_NAME_FIELD]+1));
569 sb.append(registry);
570 sb.append(name.substring(hPos[CHARSET_ENCODING_FIELD-1]));
571 String retval = sb.toString().toLowerCase (Locale.ENGLISH);
572 return retval;
573 }
574
575 /**
576 * Returns the face name for the given XLFD.
577 */
578 public String getFileNameFromXLFD(String name) {
579 String fileName = null;
580 String fontID = specificFontIDForName(name);
581 if (fontID != null) {
582 fileName = (String)fontNameMap.get(fontID);
583 if (fileName == null) {
584 fontID = switchFontIDForName(name);
585 fileName = (String)fontNameMap.get(fontID);
586 }
587 if (fileName == null) {
588 fileName = getDefaultFontFile();
589 }
590 }
591 return fileName;
592 }
593
594 /* Register just the paths, (it doesn't register the fonts).
595 * If a font configuration file has specified a baseFontPath
596 * fontPath is just those directories, unless on usage we
597 * find it doesn't contain what we need for the logical fonts.
598 * Otherwise, we register all the paths on Solaris, because
599 * the fontPath we have here is the complete one from
600 * parsing /var/sadm/install/contents, not just
601 * what's on the X font path (may be this should be
602 * changed).
603 * But for now what it means is that if we didn't do
604 * this then if the font weren't listed anywhere on the
605 * less complete font path we'd trigger loadFonts which
668 // and add it to the X font path (if display is local)
669 // Here we make use of an already built map of xlfds to font locations
670 // to add the font location to the set of those required to build the
671 // x font path needed by AWT.
672 // These are added to the x font path later.
673 // All this is necessary because on Solaris the font.dir directories
674 // may contain not real font files, but symbolic links to the actual
675 // location but that location is not suitable for the x font path, since
676 // it probably doesn't have a font.dir at all and certainly not one
677 // with the required encodings
678 // If the fontconfiguration file is properly set up so that all fonts
679 // are mapped to files then we will never trigger initialising
680 // xFontDirsMap (it will be null). In this case the awtfontpath entries
681 // must specify all the X11 directories needed by AWT.
682 @Override
683 protected void addFontToPlatformFontPath(String platformName) {
684 // Lazily initialize fontConfigDirs.
685 getPlatformFontPathFromFontConfig();
686 if (xFontDirsMap != null) {
687 String fontID = specificFontIDForName(platformName);
688 String dirName = (String)xFontDirsMap.get(fontID);
689 if (dirName != null) {
690 fontConfigDirs.add(dirName);
691 }
692 }
693 return;
694 }
695
696 private void getPlatformFontPathFromFontConfig() {
697 if (fontConfigDirs == null) {
698 fontConfigDirs = getFontConfiguration().getAWTFontPathSet();
699 if (FontUtilities.debugFonts() && fontConfigDirs != null) {
700 String[] names = fontConfigDirs.toArray(new String[0]);
701 for (int i=0;i<names.length;i++) {
702 FontUtilities.getLogger().info("awtfontpath : " + names[i]);
703 }
704 }
705 }
706 }
707
708 @Override
|
42 private static final int POINT_SIZE_FIELD = 8;
43 private static final int RESOLUTION_X_FIELD = 9;
44 private static final int RESOLUTION_Y_FIELD = 10;
45 private static final int SPACING_FIELD = 11;
46 private static final int AVERAGE_WIDTH_FIELD = 12;
47 private static final int CHARSET_REGISTRY_FIELD = 13;
48 private static final int CHARSET_ENCODING_FIELD = 14;
49
50 /*
51 * fontNameMap is a map from a fontID (which is a substring of an XLFD like
52 * "-monotype-arial-bold-r-normal-iso8859-7")
53 * to font file path like
54 * /usr/openwin/lib/locale/iso_8859_7/X11/fonts/TrueType/ArialBoldItalic.ttf
55 * It's used in a couple of methods like
56 * getFileNameFomPlatformName(..) to help locate the font file.
57 * We use this substring of a full XLFD because the font configuration files
58 * define the XLFDs in a way that's easier to make into a request.
59 * E.g., the -0-0-0-0-p-0- reported by X is -*-%d-*-*-p-*- in the font
60 * configuration files. We need to remove that part for comparisons.
61 */
62 private static Map<String, String> fontNameMap = new HashMap<>();
63
64 /*
65 * xlfdMap is a map from a platform path like
66 * /usr/openwin/lib/locale/ja/X11/fonts/TT/HG-GothicB.ttf to an XLFD like
67 * "-ricoh-hg gothic b-medium-r-normal--0-0-0-0-m-0-jisx0201.1976-0"
68 * Because there may be multiple native names, because the font is used
69 * to support multiple X encodings for example, the value of an entry in
70 * this map is always a vector where we store all the native names.
71 * For fonts which we don't understand the key isn't a pathname, its
72 * the full XLFD string like :-
73 * "-ricoh-hg gothic b-medium-r-normal--0-0-0-0-m-0-jisx0201.1976-0"
74 */
75 private static Map<String, Vector<String>> xlfdMap = new HashMap<>();
76
77 /* xFontDirsMap is also a map from a font ID to a font filepath.
78 * The difference from fontNameMap is just that it does not have
79 * resolved symbolic links. Normally this is not interesting except
80 * that we need to know the directory in which a font was found to
81 * add it to the X font server path, since although the files may
82 * be linked, the fonts.dir is different and specific to the encoding
83 * handled by that directory. This map is nulled out after use to free
84 * heap space. If the optimal path is taken, such that all fonts in
85 * font configuration files are referenced by filename, then the font
86 * dir can be directly derived as its parent directory.
87 * If a font is used by two XLFDs, each corresponding to a different
88 * X11 font directory, then precautions must be taken to include both
89 * directories.
90 */
91 private static Map<String, String> xFontDirsMap;
92
93 /*
94 * This is the set of font directories needed to be on the X font path
95 * to enable AWT heavyweights to find all of the font configuration fonts.
96 * It is populated by :
97 * - awtfontpath entries in the fontconfig.properties
98 * - parent directories of "core" fonts used in the fontconfig.properties
99 * - looking up font dirs in the xFontDirsMap where the key is a fontID
100 * (cut down version of the XLFD read from the font configuration file).
101 * This set is nulled out after use to free heap space.
102 */
103 private static HashSet<String> fontConfigDirs = null;
104
105 /* These maps are used on Linux where we reference the Lucida oblique
106 * fonts in fontconfig files even though they aren't in the standard
107 * font directory. This explicitly remaps the XLFDs for these to the
108 * correct base font. This is needed to prevent composite fonts from
109 * defaulting to the Lucida Sans which is a bad substitute for the
110 * monospaced Lucida Sans Typewriter. Also these maps prevent the
111 * JRE from doing wasted work at start up.
112 */
113 HashMap<String, String> oblmap = null;
114
115
116 /*
117 * Used to eliminate redundant work. When a font directory is
118 * registered it added to this list. Subsequent registrations for the
119 * same directory can then be skipped by checking this Map.
120 * Access to this map is not synchronised here since creation
121 * of the singleton GE instance is already synchronised and that is
122 * the only code path that accesses this map.
123 */
124 private static HashMap<String, Object> registeredDirs = new HashMap<>();
125
126 /* Array of directories to be added to the X11 font path.
127 * Used by static method called from Toolkits which use X11 fonts.
128 * Specifically this means MToolkit
129 */
130 private static String[] fontdirs = null;
131
132 private static String[] defaultPlatformFont = null;
133
134 private FontConfigManager fcManager = null;
135
136 public static X11FontManager getInstance() {
137 return (X11FontManager) SunFontManager.getInstance();
138 }
139
140 /**
141 * Takes family name property in the following format:
142 * "-linotype-helvetica-medium-r-normal-sans-*-%d-*-*-p-*-iso8859-1"
143 * and returns the name of the corresponding physical font.
144 * This code is used to resolve font configuration fonts, and expects
166 fileName = super.getFileNameFromPlatformName(platName);
167 if (fileName != null) {
168 if (isHeadless() && fileName.startsWith("-")) {
169 /* if it's headless, no xlfd should be used */
170 return null;
171 }
172 if (fileName.startsWith("/")) {
173 /* If a path is assigned in the font configuration file,
174 * it is required that the config file also specify using the
175 * new awtfontpath key the X11 font directories
176 * which must be added to the X11 font path to support
177 * AWT access to that font. For that reason we no longer
178 * have code here to add the parent directory to the list
179 * of font config dirs, since the parent directory may not
180 * be sufficient if fonts are symbolically linked to a
181 * different directory.
182 *
183 * Add this XLFD (platform name) to the list of known
184 * ones for this file.
185 */
186 Vector<String> xVal = xlfdMap.get(fileName);
187 if (xVal == null) {
188 /* Try to be robust on Linux distros which move fonts
189 * around by verifying that the fileName represents a
190 * file that exists. If it doesn't, set it to null
191 * to trigger a search.
192 */
193 if (getFontConfiguration().needToSearchForFile(fileName)) {
194 fileName = null;
195 }
196 if (fileName != null) {
197 xVal = new Vector<>();
198 xVal.add(platName);
199 xlfdMap.put(fileName, xVal);
200 }
201 } else {
202 if (!xVal.contains(platName)) {
203 xVal.add(platName);
204 }
205 }
206 }
207 if (fileName != null) {
208 fontNameMap.put(fontID, fileName);
209 return fileName;
210 }
211 }
212
213 if (fontID != null) {
214 fileName = fontNameMap.get(fontID);
215 /* On Linux check for the Lucida Oblique fonts */
216 if (fileName == null && FontUtilities.isLinux && !isOpenJDK()) {
217 if (oblmap == null) {
218 initObliqueLucidaFontMap();
219 }
220 String oblkey = getObliqueLucidaFontID(fontID);
221 if (oblkey != null) {
222 fileName = oblmap.get(oblkey);
223 }
224 }
225 if (fontPath == null &&
226 (fileName == null || !fileName.startsWith("/"))) {
227 if (FontUtilities.debugFonts()) {
228 FontUtilities.getLogger()
229 .warning("** Registering all font paths because " +
230 "can't find file for " + platName);
231 }
232 fontPath = getPlatformFontPath(noType1Font);
233 registerFontDirs(fontPath);
234 if (FontUtilities.debugFonts()) {
235 FontUtilities.getLogger()
236 .warning("** Finished registering all font paths");
237 }
238 fileName = fontNameMap.get(fontID);
239 }
240 if (fileName == null && !isHeadless()) {
241 /* Query X11 directly to see if this font is available
242 * as a native font.
243 */
244 fileName = getX11FontName(platName);
245 }
246 if (fileName == null) {
247 fontID = switchFontIDForName(platName);
248 fileName = fontNameMap.get(fontID);
249 }
250 if (fileName != null) {
251 fontNameMap.put(fontID, fileName);
252 }
253 }
254 return fileName;
255 }
256
257 @Override
258 protected String[] getNativeNames(String fontFileName,
259 String platformName) {
260 Vector<String> nativeNames;
261 if ((nativeNames=xlfdMap.get(fontFileName))==null) {
262 if (platformName == null) {
263 return null;
264 } else {
265 /* back-stop so that at least the name used in the
266 * font configuration file is known as a native name
267 */
268 String []natNames = new String[1];
269 natNames[0] = platformName;
270 return natNames;
271 }
272 } else {
273 int len = nativeNames.size();
274 return nativeNames.toArray(new String[len]);
275 }
276 }
277
278 /* NOTE: this method needs to be executed in a privileged context.
279 * The superclass constructor which is the primary caller of
280 * this method executes entirely in such a context. Additionally
281 * the loadFonts() method does too. So all should be well.
282
283 */
284 @Override
285 protected void registerFontDir(String path) {
286 /* fonts.dir file format looks like :-
287 * 47
288 * Arial.ttf -monotype-arial-regular-r-normal--0-0-0-0-p-0-iso8859-1
289 * Arial-Bold.ttf -monotype-arial-bold-r-normal--0-0-0-0-p-0-iso8859-1
290 * ...
291 */
292 if (FontUtilities.debugFonts()) {
293 FontUtilities.getLogger().info("ParseFontDir " + path);
294 }
349 if (ttype != StreamTokenizer.TT_EOL) {
350 break;
351 }
352 continue;
353 }
354 String fileName = st.sval.substring(0, breakPos);
355 /* TurboLinux 8.0 uses some additional syntax to
356 * indicate algorithmic styling values.
357 * Ignore ':' separated files at the beginning
358 * of the fileName
359 */
360 int lastColon = fileName.lastIndexOf(':');
361 if (lastColon > 0) {
362 if (lastColon+1 >= fileName.length()) {
363 continue;
364 }
365 fileName = fileName.substring(lastColon+1);
366 }
367 String fontPart = st.sval.substring(breakPos+1);
368 String fontID = specificFontIDForName(fontPart);
369 String sVal = fontNameMap.get(fontID);
370
371 if (FontUtilities.debugFonts()) {
372 PlatformLogger logger = FontUtilities.getLogger();
373 logger.info("file=" + fileName +
374 " xlfd=" + fontPart);
375 logger.info("fontID=" + fontID +
376 " sVal=" + sVal);
377 }
378 String fullPath = null;
379 try {
380 File file = new File(path,fileName);
381 /* we may have a resolved symbolic link
382 * this becomes important for an xlfd we
383 * still need to know the location it was
384 * found to update the X server font path
385 * for use by AWT heavyweights - and when 2D
386 * wants to use the native rasteriser.
387 */
388 if (xFontDirsMap == null) {
389 xFontDirsMap = new HashMap<>();
390 }
391 xFontDirsMap.put(fontID, path);
392 fullPath = file.getCanonicalPath();
393 } catch (IOException e) {
394 fullPath = path + File.separator + fileName;
395 }
396 Vector<String> xVal = xlfdMap.get(fullPath);
397 if (FontUtilities.debugFonts()) {
398 FontUtilities.getLogger()
399 .info("fullPath=" + fullPath +
400 " xVal=" + xVal);
401 }
402 if ((xVal == null || !xVal.contains(fontPart)) &&
403 (sVal == null) || !sVal.startsWith("/")) {
404 if (FontUtilities.debugFonts()) {
405 FontUtilities.getLogger()
406 .info("Map fontID:"+fontID +
407 "to file:" + fullPath);
408 }
409 fontNameMap.put(fontID, fullPath);
410 if (xVal == null) {
411 xVal = new Vector<>();
412 xlfdMap.put (fullPath, xVal);
413 }
414 xVal.add(fontPart);
415 }
416
417 ttype = st.nextToken();
418 if (ttype != StreamTokenizer.TT_EOL) {
419 break;
420 }
421 }
422 }
423 }
424 fr.close();
425 }
426 } catch (IOException ioe1) {
427 } finally {
428 if (fr != null) {
429 try {
430 fr.close();
431 } catch (IOException ioe2) {
432 }
433 }
434 }
435 }
436
437 @Override
438 public void loadFonts() {
439 super.loadFonts();
440 /* These maps are greatly expanded during a loadFonts but
441 * can be reset to their initial state afterwards.
442 * Since preferLocaleFonts() and preferProportionalFonts() will
443 * trigger a partial repopulating from the FontConfiguration
444 * it has to be the inital (empty) state for the latter two, not
445 * simply nulling out.
446 * xFontDirsMap is a special case in that the implementation
447 * will typically not ever need to initialise it so it can be null.
448 */
449 xFontDirsMap = null;
450 xlfdMap = new HashMap<>(1);
451 fontNameMap = new HashMap<>(1);
452 }
453
454 private String getObliqueLucidaFontID(String fontID) {
455 if (fontID.startsWith("-lucidasans-medium-i-normal") ||
456 fontID.startsWith("-lucidasans-bold-i-normal") ||
457 fontID.startsWith("-lucidatypewriter-medium-i-normal") ||
458 fontID.startsWith("-lucidatypewriter-bold-i-normal")) {
459 return fontID.substring(0, fontID.indexOf("-i-"));
460 } else {
461 return null;
462 }
463 }
464
465 private static String getX11FontName(String platName) {
466 String xlfd = platName.replaceAll("%d", "*");
467 if (NativeFont.fontExists(xlfd)) {
468 return xlfd;
469 } else {
470 return null;
471 }
562 }
563 StringBuffer sb =
564 new StringBuffer(name.substring(hPos[FAMILY_NAME_FIELD-1],
565 hPos[SLANT_FIELD-1]+1));
566 sb.append(slant);
567 sb.append(name.substring(hPos[SLANT_FIELD],
568 hPos[SETWIDTH_NAME_FIELD]+1));
569 sb.append(registry);
570 sb.append(name.substring(hPos[CHARSET_ENCODING_FIELD-1]));
571 String retval = sb.toString().toLowerCase (Locale.ENGLISH);
572 return retval;
573 }
574
575 /**
576 * Returns the face name for the given XLFD.
577 */
578 public String getFileNameFromXLFD(String name) {
579 String fileName = null;
580 String fontID = specificFontIDForName(name);
581 if (fontID != null) {
582 fileName = fontNameMap.get(fontID);
583 if (fileName == null) {
584 fontID = switchFontIDForName(name);
585 fileName = fontNameMap.get(fontID);
586 }
587 if (fileName == null) {
588 fileName = getDefaultFontFile();
589 }
590 }
591 return fileName;
592 }
593
594 /* Register just the paths, (it doesn't register the fonts).
595 * If a font configuration file has specified a baseFontPath
596 * fontPath is just those directories, unless on usage we
597 * find it doesn't contain what we need for the logical fonts.
598 * Otherwise, we register all the paths on Solaris, because
599 * the fontPath we have here is the complete one from
600 * parsing /var/sadm/install/contents, not just
601 * what's on the X font path (may be this should be
602 * changed).
603 * But for now what it means is that if we didn't do
604 * this then if the font weren't listed anywhere on the
605 * less complete font path we'd trigger loadFonts which
668 // and add it to the X font path (if display is local)
669 // Here we make use of an already built map of xlfds to font locations
670 // to add the font location to the set of those required to build the
671 // x font path needed by AWT.
672 // These are added to the x font path later.
673 // All this is necessary because on Solaris the font.dir directories
674 // may contain not real font files, but symbolic links to the actual
675 // location but that location is not suitable for the x font path, since
676 // it probably doesn't have a font.dir at all and certainly not one
677 // with the required encodings
678 // If the fontconfiguration file is properly set up so that all fonts
679 // are mapped to files then we will never trigger initialising
680 // xFontDirsMap (it will be null). In this case the awtfontpath entries
681 // must specify all the X11 directories needed by AWT.
682 @Override
683 protected void addFontToPlatformFontPath(String platformName) {
684 // Lazily initialize fontConfigDirs.
685 getPlatformFontPathFromFontConfig();
686 if (xFontDirsMap != null) {
687 String fontID = specificFontIDForName(platformName);
688 String dirName = xFontDirsMap.get(fontID);
689 if (dirName != null) {
690 fontConfigDirs.add(dirName);
691 }
692 }
693 return;
694 }
695
696 private void getPlatformFontPathFromFontConfig() {
697 if (fontConfigDirs == null) {
698 fontConfigDirs = getFontConfiguration().getAWTFontPathSet();
699 if (FontUtilities.debugFonts() && fontConfigDirs != null) {
700 String[] names = fontConfigDirs.toArray(new String[0]);
701 for (int i=0;i<names.length;i++) {
702 FontUtilities.getLogger().info("awtfontpath : " + names[i]);
703 }
704 }
705 }
706 }
707
708 @Override
|