changeset 4308:8eb897ad8dc6

RT-31552: Improve font factory loading
author Felipe Heidrich <felipe.heidrich@oracle.com>
date Tue, 16 Jul 2013 08:32:44 -0700
parents 9138b9b61850
children d81166ee8ea0
files modules/graphics/src/main/java/com/sun/javafx/font/CompositeStrike.java modules/graphics/src/main/java/com/sun/javafx/font/MacFontFinder.java modules/graphics/src/main/java/com/sun/javafx/font/PrismFontFactory.java modules/graphics/src/main/java/com/sun/javafx/font/PrismFontLoader.java modules/graphics/src/main/java/com/sun/javafx/font/PrismFontStrike.java modules/graphics/src/main/java/com/sun/javafx/font/PrismFontUtils.java modules/graphics/src/main/java/com/sun/javafx/font/pango/PangoFactory.java modules/graphics/src/main/java/com/sun/prism/impl/PrismSettings.java modules/graphics/src/main/java/com/sun/prism/impl/ps/BaseShaderGraphics.java modules/graphics/src/main/java/com/sun/prism/impl/shape/ShapeUtil.java modules/graphics/src/main/java/com/sun/prism/sw/SWGraphics.java modules/graphics/src/main/native-font/fontpath.c
diffstat 12 files changed, 106 insertions(+), 99 deletions(-) [+]
line wrap: on
line diff
--- a/modules/graphics/src/main/java/com/sun/javafx/font/CompositeStrike.java	Tue Jul 16 14:01:17 2013 +0200
+++ b/modules/graphics/src/main/java/com/sun/javafx/font/CompositeStrike.java	Tue Jul 16 08:32:44 2013 -0700
@@ -82,7 +82,8 @@
     }
 
     public int getAAMode() {
-        if (PrismFontLoader.isLCDTextSupported()) {
+        PrismFontFactory factory = PrismFontFactory.getFontFactory();
+        if (factory.isLCDTextSupported()) {
             return this.aaMode;
         } else {
             return FontResource.AA_GREYSCALE;
--- a/modules/graphics/src/main/java/com/sun/javafx/font/MacFontFinder.java	Tue Jul 16 14:01:17 2013 +0200
+++ b/modules/graphics/src/main/java/com/sun/javafx/font/MacFontFinder.java	Tue Jul 16 08:32:44 2013 -0700
@@ -82,7 +82,7 @@
             String family = fontData[i++];
             String file = fontData[i++];
 
-            if (!PrismFontFactory.doCoreText) {
+            if (!PrismFontFactory.useNativeRasterizer) {
                 /* Skip OTF/CID keyed fonts for T2K (RT-15755) */
                 if (file.endsWith(".otf")) {
                     if (name.indexOf(" Pro W") != -1) continue;
--- a/modules/graphics/src/main/java/com/sun/javafx/font/PrismFontFactory.java	Tue Jul 16 14:01:17 2013 +0200
+++ b/modules/graphics/src/main/java/com/sun/javafx/font/PrismFontFactory.java	Tue Jul 16 08:32:44 2013 -0700
@@ -46,22 +46,24 @@
 public abstract class PrismFontFactory implements FontFactory {
 
     public static boolean debugFonts = false;
-    public static boolean doCoreText = false;
-    public static boolean doDirectWrite = false;
     public static final boolean isWindows;
     public static final boolean isLinux;
     public static final boolean isMacOSX;
     public static final boolean isIOS;
     public static final boolean isAndroid;
+    public static final boolean isEmbedded;
+    public static boolean useNativeRasterizer;
     private static boolean subPixelEnabled;
+    private static boolean lcdEnabled;
+    private static float lcdContrast = -1;
     private static String jreFontDir;
     private static final String jreDefaultFont   = "Lucida Sans Regular";
     private static final String jreDefaultFontLC = "lucida sans regular";
     private static final String jreDefaultFontFile = "LucidaSansRegular.ttf";
-
     private static final String T2K_FACTORY = "com.sun.javafx.font.t2k.T2KFactory";
     private static final String CT_FACTORY = "com.sun.javafx.font.coretext.CTFactory";
     private static final String DW_FACTORY = "com.sun.javafx.font.directwrite.DWFactory";
+    private static final String PANGO_FACTORY = "com.sun.javafx.font.pango.PangoFactory";
 
     /* We need two maps. One to hold pointers to the raw fonts, another
      * to hold pointers to the composite resources. Top level look ups
@@ -82,8 +84,9 @@
         isLinux   = PlatformUtil.isLinux();
         isIOS     = PlatformUtil.isIOS();
         isAndroid = PlatformUtil.isAndroid();
+        isEmbedded = PlatformUtil.isEmbedded();
 
-        String prismText = AccessController.doPrivileged(
+        AccessController.doPrivileged(
             new PrivilegedAction<String>() {
                 public String run() {
                     NativeLibLoader.loadLibrary("javafx-font");
@@ -104,18 +107,32 @@
                     }
                     s = System.getProperty("prism.subpixeltext");
                     subPixelEnabled = s == null || s.equalsIgnoreCase("true");
-                    String defaultFactory = "t2k";
-                    if (isMacOSX) defaultFactory = "coretext";
-                    if (isWindows) defaultFactory = "directwrite";
-                    return System.getProperty("prism.text", defaultFactory).toLowerCase();
+
+                    useNativeRasterizer = isMacOSX || isWindows;
+                    String defPrismText = useNativeRasterizer ? "native" : "t2k";
+                    String prismText = System.getProperty("prism.text", defPrismText);
+                    if (useNativeRasterizer) {
+                        useNativeRasterizer = !prismText.equals("t2k");
+                    } else {
+                        useNativeRasterizer = prismText.equals("native");
+                    }
+                    if (isAndroid) useNativeRasterizer = false;
+
+                    boolean lcdTextOff = (isMacOSX && !useNativeRasterizer) ||
+                                         isIOS || isAndroid || isEmbedded;
+                    String defLCDProp = lcdTextOff ? "false" : "true";
+                    String lcdProp = System.getProperty("prism.lcdtext", defLCDProp);
+                    lcdEnabled = lcdProp.equals("true");
+                    return null;
                 }
             });
-        if (isMacOSX || isIOS) {
-            doCoreText = prismText.equals("native") || prismText.equals("coretext");
-        }
-        if (isWindows) {
-            doDirectWrite = prismText.equals("native") || prismText.equals("directwrite");
-        }
+    }
+
+    private static String getNativeFactoryName() {
+        if (isWindows) return DW_FACTORY;
+        if (isMacOSX || isIOS) return CT_FACTORY;
+        if (isLinux) return PANGO_FACTORY;
+        return null;
     }
 
     static PrismFontFactory theFontFactory = null;
@@ -123,20 +140,34 @@
         if (theFontFactory != null) {
             return theFontFactory;
         }
-        String factoryClass = T2K_FACTORY;
-        if (doCoreText) factoryClass = CT_FACTORY;
-        if (doDirectWrite) factoryClass = DW_FACTORY;
+        String factoryClass = null;
+        if (useNativeRasterizer) {
+            factoryClass = getNativeFactoryName();
+        }
+        if (factoryClass == null) {
+            useNativeRasterizer = false;
+            factoryClass = T2K_FACTORY;
+        }
         if (debugFonts) {
             System.err.println("Loading FontFactory " + factoryClass);
         }
         theFontFactory = getFontFactory(factoryClass);
         if (theFontFactory == null) {
-            if (!factoryClass.equalsIgnoreCase(T2K_FACTORY)) {
-                if (debugFonts) {
-                    System.err.println("*** Loading primary font factory failed. ***");
-                    System.err.println("*** Fallbacking to T2K ***");
-                }
-                theFontFactory = getFontFactory(T2K_FACTORY);
+            if (useNativeRasterizer) {
+                // If native failed use T2K (i.e. Windows Vista)
+                useNativeRasterizer = false;
+                factoryClass = T2K_FACTORY;
+            } else {
+                // If T2K failed use native (i.e. OpenJFX build)
+                useNativeRasterizer = true;
+                factoryClass = getNativeFactoryName();
+            }
+            if (factoryClass != null) {
+                theFontFactory = getFontFactory(factoryClass);
+            }
+            if (debugFonts) {
+                System.err.println("*** Loading primary font factory failed. ***");
+                System.err.println("*** Fallbacking to " + factoryClass  + " ***");
             }
         }
         return theFontFactory;
@@ -1269,6 +1300,29 @@
         return subPixelEnabled;
     }
 
+    public boolean isLCDTextSupported() {
+        return lcdEnabled;
+    }
+
+    public static float getLCDContrast() {
+        if (lcdContrast == -1) {
+            if (isWindows) {
+                lcdContrast = getLCDContrastWin32() / 1000f;
+            } else {
+                /* REMIND: When using CoreText it likely already applies gamma
+                 * correction to the glyph images. The current implementation does
+                 * not take this into account when rasterizing the glyph. Thus,
+                 * it is possible gamma correction is been applied twice to the
+                 * final result.
+                 * Consider using "1" for lcdContrast possibly produces visually
+                 * more appealing results (although not strictly correct).
+                 */
+                lcdContrast = 1.3f;
+            }
+        }
+        return lcdContrast;
+    }
+
     private static Thread fileCloser = null;
 
     private synchronized void addFileCloserHook() {
@@ -1736,7 +1790,7 @@
         }
     }
 
-    static native int getLCDContrast();
+    static native int getLCDContrastWin32();
     private static native int getSystemFontSizeNative();
     private static native String getSystemFontNative();
     private static float systemFontSize;
--- a/modules/graphics/src/main/java/com/sun/javafx/font/PrismFontLoader.java	Tue Jul 16 14:01:17 2013 +0200
+++ b/modules/graphics/src/main/java/com/sun/javafx/font/PrismFontLoader.java	Tue Jul 16 08:32:44 2013 -0700
@@ -25,14 +25,11 @@
 
 package com.sun.javafx.font;
 
-import com.sun.javafx.PlatformUtil;
 import javafx.scene.text.*;
 import com.sun.javafx.tk.*;
 import java.lang.reflect.Method;
 import java.net.URL;
 import java.io.InputStream;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
 import java.util.Arrays;
 import java.util.Enumeration;
 import java.util.List;
@@ -42,28 +39,6 @@
     private static PrismFontLoader theInstance = new PrismFontLoader();
     public static PrismFontLoader getInstance() { return theInstance; }
 
-    private static boolean lcdEnabled;
-    static {
-        //property used for now.
-        AccessController.doPrivileged(new PrivilegedAction() {
-            public Object run() {
-                // Turn LCD text off on Mac unless native glyph rasterizer is
-                // enabled.
-                // LCD text should also be turned off by default for iOS and
-                // embedded.
-                boolean lcdTextOff = (PlatformUtil.isMac() &&
-                                      !PrismFontFactory.doCoreText) ||
-                                     PlatformUtil.isIOS() ||
-                                     PlatformUtil.isAndroid() ||
-                                     PlatformUtil.isEmbedded();
-                String defLCDProp = lcdTextOff ? "false" : "true";
-                String lcdProp = System.getProperty("prism.lcdtext", defLCDProp);
-                lcdEnabled = lcdProp.equals("true");
-               return null;
-            }
-        });
-    }
-
     /**
      * Flag to keep track whether the fontCache map has been initialized with
      * the embedded fonts.
@@ -255,12 +230,6 @@
         return PrismFontFactory.getSystemFontSize();
     }
 
-    // Called only from font code which means we must have already
-    // called getFontFactoryFromPipeline();
-    public static boolean isLCDTextSupported() {
-        return lcdEnabled;
-    }
-
     FontFactory installedFontFactory = null;
     private FontFactory getFontFactoryFromPipeline() {
         if (installedFontFactory != null) {
--- a/modules/graphics/src/main/java/com/sun/javafx/font/PrismFontStrike.java	Tue Jul 16 14:01:17 2013 +0200
+++ b/modules/graphics/src/main/java/com/sun/javafx/font/PrismFontStrike.java	Tue Jul 16 08:32:44 2013 -0700
@@ -51,7 +51,8 @@
         this.fontResource = fontResource;
         this.size = size;
         this.desc = desc;
-        boolean lcdEnabled = PrismFontLoader.isLCDTextSupported();
+        PrismFontFactory factory = PrismFontFactory.getFontFactory();
+        boolean lcdEnabled = factory.isLCDTextSupported();
         this.aaMode = lcdEnabled ? aaMode : FontResource.AA_GREYSCALE;
         if (tx.isTranslateOrIdentity()) {
             transform = BaseTransform.IDENTITY_TRANSFORM;
--- a/modules/graphics/src/main/java/com/sun/javafx/font/PrismFontUtils.java	Tue Jul 16 14:01:17 2013 +0200
+++ b/modules/graphics/src/main/java/com/sun/javafx/font/PrismFontUtils.java	Tue Jul 16 08:32:44 2013 -0700
@@ -25,7 +25,6 @@
 
 package com.sun.javafx.font;
 
-import com.sun.javafx.PlatformUtil;
 import com.sun.javafx.geom.transform.BaseTransform;
 
 public class PrismFontUtils {
@@ -33,27 +32,6 @@
     private PrismFontUtils() {
     }
 
-    private static float lcdContrast = -1;
-
-    public static float getLCDContrast() {
-        if (lcdContrast == -1) {
-            if (PlatformUtil.isWindows()) {
-                lcdContrast = PrismFontFactory.getLCDContrast() / 1000f;
-            } else {
-                /* REMIND: When using CoreText it likely already applies gamma
-                 * correction to the glyph images. The current implementation does
-                 * not take this into account when rasterizing the glyph. Thus,
-                 * it is possible gamma correction is been applied twice to the
-                 * final result.
-                 * Consider using "1" for lcdContrast possibly produces visually
-                 * more appealing results (although not strictly correct).
-                 */
-                lcdContrast = 1.3f;
-            }
-        }
-        return lcdContrast;
-    }
-
     static Metrics getFontMetrics(PGFont font) {
         FontStrike strike = font.getStrike(BaseTransform.IDENTITY_TRANSFORM,
                                            FontResource.AA_GREYSCALE);
--- a/modules/graphics/src/main/java/com/sun/javafx/font/pango/PangoFactory.java	Tue Jul 16 14:01:17 2013 +0200
+++ b/modules/graphics/src/main/java/com/sun/javafx/font/pango/PangoFactory.java	Tue Jul 16 08:32:44 2013 -0700
@@ -80,6 +80,11 @@
     }
 
     @Override
+    public boolean isLCDTextSupported() {
+        return LCD_SUPPORT && super.isLCDTextSupported();
+    }
+
+    @Override
     protected boolean registerEmbeddedFont(String path) {
         boolean result = false;
 
--- a/modules/graphics/src/main/java/com/sun/prism/impl/PrismSettings.java	Tue Jul 16 14:01:17 2013 +0200
+++ b/modules/graphics/src/main/java/com/sun/prism/impl/PrismSettings.java	Tue Jul 16 08:32:44 2013 -0700
@@ -58,7 +58,6 @@
     public static final boolean doPiscesText;
     public static final boolean doOpenPiscesText;
     public static final boolean doNativePisces;
-    public static final boolean doT2KText;
     public static final String refType;
     public static final boolean forceRepaint;
     public static final boolean isEmbededDevice;
@@ -225,15 +224,12 @@
             doNativePisces = Boolean.parseBoolean(npprop);
         }
 
-        /* Setting for text. t2k is the default.
+        /* Setting for text.
          */
-        String text = systemProperties.getProperty("prism.text", "t2k");
+        String text = systemProperties.getProperty("prism.text", "");
         doPiscesText = "pisces".equals(text);
         doOpenPiscesText = "openpisces".equals(text);
-        doT2KText = !doPiscesText && !doOpenPiscesText;
-        if (doT2KText) {
-             text = "t2k";
-        }
+
         String primtex = systemProperties.getProperty("prism.primtextures");
         if (primtex == null) {
             primTextureSize = PlatformUtil.isEmbedded() ? -1 : 0;
@@ -272,7 +268,11 @@
                 System.out.print(s+" ");
             }
             System.out.println("");
-            System.out.println("Using " + text + " for text rasterization");
+            if (PrismSettings.doPiscesText || PrismSettings.doOpenPiscesText) {
+                System.out.println("Using " + text + " for text rasterization");
+            } else {
+                System.out.println("Using platform text rasterizer");
+            }
             String piscestype = (doNativePisces ? "native" : "java");
             System.out.println("Using " + piscestype + "-based Pisces rasterizer");
             printBooleanOption(dirtyOptsEnabled, "Using dirty region optimizations");
@@ -315,7 +315,7 @@
                              ? getInt(systemProperties, "prism.mintexturesize",
                                       0, "Try -Dprism.mintexturesize=<number>")
                              : 0;
-        
+
         minRTTSize = getInt(systemProperties, "prism.minrttsize",
                                       isEmbededDevice ? 16 : 0, "Try -Dprism.minrttsize=<number>");
 
--- a/modules/graphics/src/main/java/com/sun/prism/impl/ps/BaseShaderGraphics.java	Tue Jul 16 14:01:17 2013 +0200
+++ b/modules/graphics/src/main/java/com/sun/prism/impl/ps/BaseShaderGraphics.java	Tue Jul 16 08:32:44 2013 -0700
@@ -41,7 +41,7 @@
 import com.sun.javafx.font.FontStrike;
 import com.sun.javafx.font.Metrics;
 import com.sun.javafx.scene.text.GlyphList;
-import com.sun.javafx.font.PrismFontUtils;
+import com.sun.javafx.font.PrismFontFactory;
 import com.sun.javafx.geom.transform.Affine2D;
 import com.sun.javafx.geom.transform.AffineBase;
 import com.sun.prism.CompositeMode;
@@ -2001,8 +2001,7 @@
             } else {
                 initLCDSampleRT();
             }
-
-            float invgamma = PrismFontUtils.getLCDContrast();
+            float invgamma = PrismFontFactory.getLCDContrast();
             float gamma = 1.0f/invgamma;
             textColor = new Color((float)Math.pow(textColor.getRed(),   invgamma),
                                   (float)Math.pow(textColor.getGreen(), invgamma),
--- a/modules/graphics/src/main/java/com/sun/prism/impl/shape/ShapeUtil.java	Tue Jul 16 14:01:17 2013 +0200
+++ b/modules/graphics/src/main/java/com/sun/prism/impl/shape/ShapeUtil.java	Tue Jul 16 08:32:44 2013 -0700
@@ -42,10 +42,10 @@
             shapeRasterizer = new OpenPiscesRasterizer();
         }
 
-        if (PrismSettings.doT2KText) {
+        if (PrismSettings.doPiscesText || PrismSettings.doOpenPiscesText) {
+            textRasterizer = shapeRasterizer;
+        } else {
             textRasterizer = null;
-        } else {
-            textRasterizer = shapeRasterizer;
         }
     }
 
--- a/modules/graphics/src/main/java/com/sun/prism/sw/SWGraphics.java	Tue Jul 16 14:01:17 2013 +0200
+++ b/modules/graphics/src/main/java/com/sun/prism/sw/SWGraphics.java	Tue Jul 16 08:32:44 2013 -0700
@@ -30,7 +30,7 @@
 import com.sun.javafx.font.FontStrike;
 import com.sun.javafx.font.Glyph;
 import com.sun.javafx.font.Metrics;
-import com.sun.javafx.font.PrismFontUtils;
+import com.sun.javafx.font.PrismFontFactory;
 import com.sun.javafx.scene.text.GlyphList;
 import com.sun.javafx.geom.Ellipse2D;
 import com.sun.javafx.geom.Line2D;
@@ -756,7 +756,7 @@
                     tx.is2D();
 
             if (doLCDText) {
-                this.pr.setLCDGammaCorrection(1f / PrismFontUtils.getLCDContrast());
+                this.pr.setLCDGammaCorrection(1f / PrismFontFactory.getLCDContrast());
             } else {
                 final FontResource fr = strike.getFontResource();
                 final float origSize = strike.getSize();
--- a/modules/graphics/src/main/native-font/fontpath.c	Tue Jul 16 14:01:17 2013 +0200
+++ b/modules/graphics/src/main/native-font/fontpath.c	Tue Jul 16 08:32:44 2013 -0700
@@ -698,10 +698,10 @@
 
 /*
  * Class:     Java_com_sun_javafx_font_PrismFontFactory
- * Method:    getLCDContrast
+ * Method:    getLCDContrastWin32
  * Signature: ()I
  */
-JNIEXPORT jint JNICALL Java_com_sun_javafx_font_PrismFontFactory_getLCDContrast
+JNIEXPORT jint JNICALL Java_com_sun_javafx_font_PrismFontFactory_getLCDContrastWin32
   (JNIEnv *env, jobject klass) {
 
     unsigned int fontSmoothingContrast;