39 import java.util.HashSet;
40 import java.util.Iterator;
41 import java.util.Locale;
42
43 import com.sun.glass.ui.Screen;
44 import com.sun.glass.utils.NativeLibLoader;
45 import com.sun.javafx.PlatformUtil;
46 import com.sun.javafx.text.GlyphLayout;
47 import static com.sun.javafx.FXPermissions.LOAD_FONT_PERMISSION;
48
49 public abstract class PrismFontFactory implements FontFactory {
50
51 public static final boolean debugFonts;
52 public static final boolean isWindows;
53 public static final boolean isLinux;
54 public static final boolean isMacOSX;
55 public static final boolean isIOS;
56 public static final boolean isAndroid;
57 public static final boolean isEmbedded;
58 public static final int cacheLayoutSize;
59 static boolean useNativeRasterizer;
60 private static int subPixelMode;
61 public static final int SUB_PIXEL_ON = 1;
62 public static final int SUB_PIXEL_Y = 2;
63 public static final int SUB_PIXEL_NATIVE = 4;
64 private static float fontSizeLimit = 80f;
65
66 private static boolean lcdEnabled;
67 private static float lcdContrast = -1;
68 private static String jreFontDir;
69 private static final String jreDefaultFont = "Lucida Sans Regular";
70 private static final String jreDefaultFontLC = "lucida sans regular";
71 private static final String jreDefaultFontFile = "LucidaSansRegular.ttf";
72 private static final String T2K_FACTORY = "com.sun.javafx.font.t2k.T2KFactory";
73 private static final String CT_FACTORY = "com.sun.javafx.font.coretext.CTFactory";
74 private static final String DW_FACTORY = "com.sun.javafx.font.directwrite.DWFactory";
75 private static final String FT_FACTORY = "com.sun.javafx.font.freetype.FTFactory";
76
77 /* We need two maps. One to hold pointers to the raw fonts, another
78 * to hold pointers to the composite resources. Top level look ups
79 * to createFont() will look first in the compResourceMap, and
80 * only go to the second map to create a wrapped resource.
81 * Logical Fonts are handled separately.
82 */
83 HashMap<String, FontResource> fontResourceMap =
84 new HashMap<String, FontResource>();
85
86 HashMap<String, CompositeFontResource> compResourceMap =
87 new HashMap<String, CompositeFontResource>();
88
89 static {
90 isWindows = PlatformUtil.isWindows();
91 isMacOSX = PlatformUtil.isMac();
92 isLinux = PlatformUtil.isLinux();
117 }
118 if (s.indexOf("native") != -1) {
119 subPixelMode |= SUB_PIXEL_NATIVE | SUB_PIXEL_ON;
120 }
121 if (s.indexOf("vertical") != -1) {
122 subPixelMode |= SUB_PIXEL_Y | SUB_PIXEL_NATIVE | SUB_PIXEL_ON;
123 }
124
125 s = System.getProperty("prism.fontSizeLimit");
126 if (s != null) {
127 try {
128 fontSizeLimit = Float.parseFloat(s);
129 if (fontSizeLimit <= 0) {
130 fontSizeLimit = Float.POSITIVE_INFINITY;
131 }
132 } catch (NumberFormatException nfe) {
133 System.err.println("Cannot parse fontSizeLimit '" + s + "'");
134 }
135 }
136
137 useNativeRasterizer = isMacOSX || isWindows || isLinux;
138 String defPrismText = useNativeRasterizer ? "native" : "t2k";
139 String prismText = System.getProperty("prism.text", defPrismText);
140 if (useNativeRasterizer) {
141 useNativeRasterizer = !prismText.equals("t2k");
142 } else {
143 useNativeRasterizer = prismText.equals("native");
144 }
145
146 boolean lcdTextOff = (isMacOSX && !useNativeRasterizer) ||
147 isIOS || isAndroid || isEmbedded;
148 String defLCDProp = lcdTextOff ? "false" : "true";
149 String lcdProp = System.getProperty("prism.lcdtext", defLCDProp);
150 lcdEnabled = lcdProp.equals("true");
151
152 s = System.getProperty("prism.cacheLayoutSize");
153 if (s != null) {
154 try {
155 tempCacheLayoutSize[0] = Integer.parseInt(s);
156 if (tempCacheLayoutSize[0] < 0) {
157 tempCacheLayoutSize[0] = 0;
158 }
159 } catch (NumberFormatException nfe) {
160 System.err.println("Cannot parse cache layout size '"
161 + s + "'");
162 }
163 }
164
165 return debug;
166 }
167 );
184 System.getProperty("java.home","") + File.separator +
185 "lib" + File.separator + "fonts" + File.separator;
186 }
187
188 private static String getNativeFactoryName() {
189 if (isWindows) return DW_FACTORY;
190 if (isMacOSX || isIOS) return CT_FACTORY;
191 if (isLinux || isAndroid) return FT_FACTORY;
192 return null;
193 }
194
195 public static float getFontSizeLimit() {
196 return fontSizeLimit;
197 }
198
199 private static PrismFontFactory theFontFactory = null;
200 public static synchronized PrismFontFactory getFontFactory() {
201 if (theFontFactory != null) {
202 return theFontFactory;
203 }
204 String factoryClass = null;
205 if (useNativeRasterizer) {
206 factoryClass = getNativeFactoryName();
207 }
208 if (factoryClass == null) {
209 useNativeRasterizer = false;
210 factoryClass = T2K_FACTORY;
211 }
212 if (debugFonts) {
213 System.err.println("Loading FontFactory " + factoryClass);
214 if (subPixelMode != 0) {
215 String s = "Subpixel: enabled";
216 if ((subPixelMode & SUB_PIXEL_Y) != 0) {
217 s += ", vertical";
218 }
219 if ((subPixelMode & SUB_PIXEL_NATIVE) != 0) {
220 s += ", native";
221 }
222 System.err.println(s);
223 }
224 }
225 theFontFactory = getFontFactory(factoryClass);
226 if (theFontFactory == null) {
227 if (useNativeRasterizer) {
228 // If native failed use T2K (i.e. Windows Vista)
229 useNativeRasterizer = false;
230 factoryClass = T2K_FACTORY;
231 } else {
232 // If T2K failed use native (i.e. OpenJFX build)
233 useNativeRasterizer = true;
234 factoryClass = getNativeFactoryName();
235 }
236 if (factoryClass != null) {
237 theFontFactory = getFontFactory(factoryClass);
238 }
239 if (debugFonts) {
240 System.err.println("*** Loading primary font factory failed. ***");
241 System.err.println("*** Fallbacking to " + factoryClass + " ***");
242 }
243 }
244 return theFontFactory;
245 }
246
247 private static synchronized PrismFontFactory getFontFactory(String factoryClass) {
248 try {
249 Class<?> clazz = Class.forName(factoryClass);
250 Method mid = clazz.getMethod("getFactory", (Class[])null);
251 return (PrismFontFactory)mid.invoke(null);
252 } catch (Throwable t) {
253 if (debugFonts) {
254 System.err.println("Loading font factory failed "+ factoryClass);
255 }
256 }
257 return null;
258 }
259
260 private HashMap<String, PrismFontFile>
261 fileNameToFontResourceMap = new HashMap<String, PrismFontFile>();
262
509 getFullNameToFileMap();
510 ArrayList<String> family = familyToFontListMap.get(lcFamilyName);
511 if (family == null) {
512 return null;
513 }
514
515 FontResource plainFR = null, boldFR = null,
516 italicFR = null, boldItalicFR = null;
517 for (String fontName : family) {
518 String lcFontName = fontName.toLowerCase();
519 fr = fontResourceMap.get(lcFontName);
520 if (fr == null) {
521 String file = findFile(lcFontName);
522 if (file != null) {
523 fr = getFontResource(fontName, file);
524 }
525 if (fr == null) {
526 continue;
527 }
528 storeInMap(lcFontName, fr);
529 // if (wantComp) {
530 // // wrap with fallback support
531 // fr = new T2KCompositeFontResource(fr, lcFontName);
532 // }
533 }
534 if (bold == fr.isBold() && italic == fr.isItalic()) {
535 storeInMap(lcFamilyName+styleStr, fr);
536 if (wantComp) { // wrap with fallback support
537 fr = new PrismCompositeFontResource(fr,
538 lcFamilyName+styleStr);
539 }
540 return fr;
541 }
542 if (!fr.isBold()) {
543 if (!fr.isItalic()) {
544 plainFR = fr;
545 } else {
546 italicFR = fr;
547 }
548 } else {
549 if (!fr.isItalic()) {
550 boldFR = fr;
551 } else {
552 boldItalicFR = fr;
2026 return "Times New Roman";
2027 } else /* if (name.equals(LogicalFont.MONOSPACED)) */ {
2028 if (monospaceFontFamily == null) {
2029 if (isMacOSX) {
2030 /* This code is intentionally commented:
2031 * On the OS X the preferred monospaced font is Monaco,
2032 * although this can be a good choice for most Mac application
2033 * it is not suitable for JavaFX because Monaco does not
2034 * have neither bold nor italic.
2035 */
2036 // monospaceFontFamily = MacFontFinder.getMonospacedFont();
2037 }
2038 }
2039 if (monospaceFontFamily == null) {
2040 monospaceFontFamily = "Courier New";
2041 }
2042 return monospaceFontFamily;
2043 }
2044 }
2045
2046 /* Called from T2KFontFile which caches the return value */
2047 static native short getSystemLCID();
2048 }
|
39 import java.util.HashSet;
40 import java.util.Iterator;
41 import java.util.Locale;
42
43 import com.sun.glass.ui.Screen;
44 import com.sun.glass.utils.NativeLibLoader;
45 import com.sun.javafx.PlatformUtil;
46 import com.sun.javafx.text.GlyphLayout;
47 import static com.sun.javafx.FXPermissions.LOAD_FONT_PERMISSION;
48
49 public abstract class PrismFontFactory implements FontFactory {
50
51 public static final boolean debugFonts;
52 public static final boolean isWindows;
53 public static final boolean isLinux;
54 public static final boolean isMacOSX;
55 public static final boolean isIOS;
56 public static final boolean isAndroid;
57 public static final boolean isEmbedded;
58 public static final int cacheLayoutSize;
59 private static int subPixelMode;
60 public static final int SUB_PIXEL_ON = 1;
61 public static final int SUB_PIXEL_Y = 2;
62 public static final int SUB_PIXEL_NATIVE = 4;
63 private static float fontSizeLimit = 80f;
64
65 private static boolean lcdEnabled;
66 private static float lcdContrast = -1;
67 private static String jreFontDir;
68 private static final String jreDefaultFont = "Lucida Sans Regular";
69 private static final String jreDefaultFontLC = "lucida sans regular";
70 private static final String jreDefaultFontFile = "LucidaSansRegular.ttf";
71 private static final String CT_FACTORY = "com.sun.javafx.font.coretext.CTFactory";
72 private static final String DW_FACTORY = "com.sun.javafx.font.directwrite.DWFactory";
73 private static final String FT_FACTORY = "com.sun.javafx.font.freetype.FTFactory";
74
75 /* We need two maps. One to hold pointers to the raw fonts, another
76 * to hold pointers to the composite resources. Top level look ups
77 * to createFont() will look first in the compResourceMap, and
78 * only go to the second map to create a wrapped resource.
79 * Logical Fonts are handled separately.
80 */
81 HashMap<String, FontResource> fontResourceMap =
82 new HashMap<String, FontResource>();
83
84 HashMap<String, CompositeFontResource> compResourceMap =
85 new HashMap<String, CompositeFontResource>();
86
87 static {
88 isWindows = PlatformUtil.isWindows();
89 isMacOSX = PlatformUtil.isMac();
90 isLinux = PlatformUtil.isLinux();
115 }
116 if (s.indexOf("native") != -1) {
117 subPixelMode |= SUB_PIXEL_NATIVE | SUB_PIXEL_ON;
118 }
119 if (s.indexOf("vertical") != -1) {
120 subPixelMode |= SUB_PIXEL_Y | SUB_PIXEL_NATIVE | SUB_PIXEL_ON;
121 }
122
123 s = System.getProperty("prism.fontSizeLimit");
124 if (s != null) {
125 try {
126 fontSizeLimit = Float.parseFloat(s);
127 if (fontSizeLimit <= 0) {
128 fontSizeLimit = Float.POSITIVE_INFINITY;
129 }
130 } catch (NumberFormatException nfe) {
131 System.err.println("Cannot parse fontSizeLimit '" + s + "'");
132 }
133 }
134
135 boolean lcdTextOff = isIOS || isAndroid || isEmbedded;
136 String defLCDProp = lcdTextOff ? "false" : "true";
137 String lcdProp = System.getProperty("prism.lcdtext", defLCDProp);
138 lcdEnabled = lcdProp.equals("true");
139
140 s = System.getProperty("prism.cacheLayoutSize");
141 if (s != null) {
142 try {
143 tempCacheLayoutSize[0] = Integer.parseInt(s);
144 if (tempCacheLayoutSize[0] < 0) {
145 tempCacheLayoutSize[0] = 0;
146 }
147 } catch (NumberFormatException nfe) {
148 System.err.println("Cannot parse cache layout size '"
149 + s + "'");
150 }
151 }
152
153 return debug;
154 }
155 );
172 System.getProperty("java.home","") + File.separator +
173 "lib" + File.separator + "fonts" + File.separator;
174 }
175
176 private static String getNativeFactoryName() {
177 if (isWindows) return DW_FACTORY;
178 if (isMacOSX || isIOS) return CT_FACTORY;
179 if (isLinux || isAndroid) return FT_FACTORY;
180 return null;
181 }
182
183 public static float getFontSizeLimit() {
184 return fontSizeLimit;
185 }
186
187 private static PrismFontFactory theFontFactory = null;
188 public static synchronized PrismFontFactory getFontFactory() {
189 if (theFontFactory != null) {
190 return theFontFactory;
191 }
192 String factoryClass = getNativeFactoryName();
193 if (factoryClass == null) {
194 throw new InternalError("cannot find a native font factory");
195 }
196 if (debugFonts) {
197 System.err.println("Loading FontFactory " + factoryClass);
198 if (subPixelMode != 0) {
199 String s = "Subpixel: enabled";
200 if ((subPixelMode & SUB_PIXEL_Y) != 0) {
201 s += ", vertical";
202 }
203 if ((subPixelMode & SUB_PIXEL_NATIVE) != 0) {
204 s += ", native";
205 }
206 System.err.println(s);
207 }
208 }
209 theFontFactory = getFontFactory(factoryClass);
210 if (theFontFactory == null) {
211 throw new InternalError("cannot load font factory: "+ factoryClass);
212 }
213 return theFontFactory;
214 }
215
216 private static synchronized PrismFontFactory getFontFactory(String factoryClass) {
217 try {
218 Class<?> clazz = Class.forName(factoryClass);
219 Method mid = clazz.getMethod("getFactory", (Class[])null);
220 return (PrismFontFactory)mid.invoke(null);
221 } catch (Throwable t) {
222 if (debugFonts) {
223 System.err.println("Loading font factory failed "+ factoryClass);
224 }
225 }
226 return null;
227 }
228
229 private HashMap<String, PrismFontFile>
230 fileNameToFontResourceMap = new HashMap<String, PrismFontFile>();
231
478 getFullNameToFileMap();
479 ArrayList<String> family = familyToFontListMap.get(lcFamilyName);
480 if (family == null) {
481 return null;
482 }
483
484 FontResource plainFR = null, boldFR = null,
485 italicFR = null, boldItalicFR = null;
486 for (String fontName : family) {
487 String lcFontName = fontName.toLowerCase();
488 fr = fontResourceMap.get(lcFontName);
489 if (fr == null) {
490 String file = findFile(lcFontName);
491 if (file != null) {
492 fr = getFontResource(fontName, file);
493 }
494 if (fr == null) {
495 continue;
496 }
497 storeInMap(lcFontName, fr);
498 }
499 if (bold == fr.isBold() && italic == fr.isItalic()) {
500 storeInMap(lcFamilyName+styleStr, fr);
501 if (wantComp) { // wrap with fallback support
502 fr = new PrismCompositeFontResource(fr,
503 lcFamilyName+styleStr);
504 }
505 return fr;
506 }
507 if (!fr.isBold()) {
508 if (!fr.isItalic()) {
509 plainFR = fr;
510 } else {
511 italicFR = fr;
512 }
513 } else {
514 if (!fr.isItalic()) {
515 boldFR = fr;
516 } else {
517 boldItalicFR = fr;
1991 return "Times New Roman";
1992 } else /* if (name.equals(LogicalFont.MONOSPACED)) */ {
1993 if (monospaceFontFamily == null) {
1994 if (isMacOSX) {
1995 /* This code is intentionally commented:
1996 * On the OS X the preferred monospaced font is Monaco,
1997 * although this can be a good choice for most Mac application
1998 * it is not suitable for JavaFX because Monaco does not
1999 * have neither bold nor italic.
2000 */
2001 // monospaceFontFamily = MacFontFinder.getMonospacedFont();
2002 }
2003 }
2004 if (monospaceFontFamily == null) {
2005 monospaceFontFamily = "Courier New";
2006 }
2007 return monospaceFontFamily;
2008 }
2009 }
2010
2011 /* Called from PrismFontFile which caches the return value */
2012 static native short getSystemLCID();
2013 }
|