aboutsummaryrefslogtreecommitdiff
path: root/src/share/classes/sun
diff options
context:
space:
mode:
authorprr <none@none>2008-06-12 13:17:33 -0700
committerprr <none@none>2008-06-12 13:17:33 -0700
commit952999dcaf5ba7639a2c55b725ae18b33cace22a (patch)
tree95d1c79aa7f0346c12e06d67a5ba85d7c5c1324b /src/share/classes/sun
parent633a1fda50c5260a9ae5643ade9bd5e0a2ddd613 (diff)
6378099: RFE: Use libfontconfig to create/synthesise a fontconfig.properties
Reviewed-by: tdv, igor
Diffstat (limited to 'src/share/classes/sun')
-rw-r--r--src/share/classes/sun/awt/FontConfiguration.java80
-rw-r--r--src/share/classes/sun/font/FontManager.java157
-rw-r--r--src/share/classes/sun/java2d/SunGraphicsEnvironment.java31
3 files changed, 201 insertions, 67 deletions
diff --git a/src/share/classes/sun/awt/FontConfiguration.java b/src/share/classes/sun/awt/FontConfiguration.java
index a6b94870b..d3d6ed819 100644
--- a/src/share/classes/sun/awt/FontConfiguration.java
+++ b/src/share/classes/sun/awt/FontConfiguration.java
@@ -72,6 +72,11 @@ public abstract class FontConfiguration {
protected boolean preferLocaleFonts;
protected boolean preferPropFonts;
+ private File fontConfigFile;
+ private boolean foundOsSpecificFile;
+ private boolean inited;
+ private String javaLib;
+
/* A default FontConfiguration must be created before an alternate
* one to ensure proper static initialisation takes place.
*/
@@ -80,14 +85,25 @@ public abstract class FontConfiguration {
logger = Logger.getLogger("sun.awt.FontConfiguration");
}
this.environment = environment;
- this.preferLocaleFonts = false;
- this.preferPropFonts = false;
setOsNameAndVersion(); /* static initialization */
setEncoding(); /* static initialization */
- fontConfig = this; /* static initialization */
+ /* Separating out the file location from the rest of the
+ * initialisation, so the caller has the option of doing
+ * something else if a suitable file isn't found.
+ */
+ findFontConfigFile();
+ }
- readFontConfigFile();
- initFontConfig();
+ public synchronized boolean init() {
+ if (!inited) {
+ this.preferLocaleFonts = false;
+ this.preferPropFonts = false;
+ fontConfig = this; /* static initialization */
+ readFontConfigFile(fontConfigFile);
+ initFontConfig();
+ inited = true;
+ }
+ return true;
}
public FontConfiguration(SunGraphicsEnvironment environment,
@@ -121,21 +137,51 @@ public abstract class FontConfiguration {
/////////////////////////////////////////////////////////////////////
// methods for loading the FontConfig file //
/////////////////////////////////////////////////////////////////////
- private void readFontConfigFile() {
- // Find fontconfig file
- File f = null;
+
+ public boolean foundOsSpecificFile() {
+ return foundOsSpecificFile;
+ }
+
+ /* Smoke test to see if we can trust this configuration by testing if
+ * the first slot of a composite font maps to an installed file.
+ */
+ public boolean fontFilesArePresent() {
+ init();
+ short fontNameID = compFontNameIDs[0][0][0];
+ short fileNameID = getComponentFileID(fontNameID);
+ final String fileName = mapFileName(getComponentFileName(fileNameID));
+ Boolean exists = (Boolean)java.security.AccessController.doPrivileged(
+ new java.security.PrivilegedAction() {
+ public Object run() {
+ try {
+ File f = new File(fileName);
+ return Boolean.valueOf(f.exists());
+ }
+ catch (Exception e) {
+ return false;
+ }
+ }
+ });
+ return exists.booleanValue();
+ }
+
+ private void findFontConfigFile() {
+
+ foundOsSpecificFile = true; // default assumption.
String javaHome = System.getProperty("java.home");
if (javaHome == null) {
throw new Error("java.home property not set");
}
- String javaLib = javaHome + File.separator + "lib";
+ javaLib = javaHome + File.separator + "lib";
String userConfigFile = System.getProperty("sun.awt.fontconfig");
if (userConfigFile != null) {
- f = new File(userConfigFile);
+ fontConfigFile = new File(userConfigFile);
} else {
- f = findFontConfigFile(javaLib);
+ fontConfigFile = findFontConfigFile(javaLib);
}
+ }
+ private void readFontConfigFile(File f) {
/* This is invoked here as readFontConfigFile is only invoked
* once per VM, and always in a privileged context, thus the
* directory containing installed fall back fonts is accessed
@@ -167,7 +213,7 @@ public abstract class FontConfiguration {
}
}
- private void getInstalledFallbackFonts(String javaLib) {
+ protected void getInstalledFallbackFonts(String javaLib) {
String fallbackDirName = javaLib + File.separator +
"fonts" + File.separator + "fallback";
@@ -229,6 +275,8 @@ public abstract class FontConfiguration {
return configFile;
}
}
+ foundOsSpecificFile = false;
+
configFile = findImpl(baseName);
if (configFile != null) {
return configFile;
@@ -506,12 +554,12 @@ public abstract class FontConfiguration {
/////////////////////////////////////////////////////////////////////
protected static final int NUM_FONTS = 5;
protected static final int NUM_STYLES = 4;
- private static final String[] fontNames
+ protected static final String[] fontNames
= {"serif", "sansserif", "monospaced", "dialog", "dialoginput"};
- private static final String[] publicFontNames
+ protected static final String[] publicFontNames
= {Font.SERIF, Font.SANS_SERIF, Font.MONOSPACED, Font.DIALOG,
Font.DIALOG_INPUT};
- private static final String[] styleNames
+ protected static final String[] styleNames
= {"plain", "bold", "italic", "bolditalic"};
/**
@@ -656,7 +704,7 @@ public abstract class FontConfiguration {
return null;
}
- private static String[] installedFallbackFontFiles = null;
+ protected static String[] installedFallbackFontFiles = null;
/**
* Maps a file name given in the font configuration file
diff --git a/src/share/classes/sun/font/FontManager.java b/src/share/classes/sun/font/FontManager.java
index 09f181f12..a9a7257e4 100644
--- a/src/share/classes/sun/font/FontManager.java
+++ b/src/share/classes/sun/font/FontManager.java
@@ -148,6 +148,7 @@ public final class FontManager {
static HashSet<String> jreLucidaFontFiles;
static String[] jreOtherFontFiles;
static boolean noOtherJREFontFiles = false; // initial assumption.
+ static boolean fontConfigFailed = false;
/* Used to indicate required return type from toArray(..); */
private static String[] STR_ARRAY = new String[0];
@@ -3100,19 +3101,30 @@ public final class FontManager {
"monospace:bold:italic",
};
- /* This class is just a data structure.
+ /* These next three classes are just data structures.
*/
- private static class FontConfigInfo {
+ static class FontConfigFont {
+ String familyName; // eg Bitstream Vera Sans
+ String styleStr; // eg Bold
+ String fullName; // eg Bitstream Vera Sans Bold
+ String fontFile; // eg /usr/X11/lib/fonts/foo.ttf
+ }
+
+ static class FcCompFont {
String fcName; // eg sans
String fcFamily; // eg sans
String jdkName; // eg sansserif
int style; // eg 0=PLAIN
- String familyName; // eg Bitstream Vera Sans
- String fontFile; // eg /usr/X11/lib/fonts/foo.ttf
+ FontConfigFont firstFont;
+ FontConfigFont[] allFonts;
//boolean preferBitmaps; // if embedded bitmaps preferred over AA
CompositeFont compFont; // null if not yet created/known.
}
+ static class FontConfigInfo {
+ int fcVersion;
+ String[] cacheDirs = new String[4];
+ }
private static String getFCLocaleStr() {
Locale l = SunToolkit.getStartupLocale();
@@ -3124,6 +3136,12 @@ public final class FontManager {
return localeStr;
}
+ /* This does cause the native libfontconfig to be loaded and unloaded,
+ * but it does not incur the overhead of initialisation of its
+ * data structures, so shouldn't have a measurable impact.
+ */
+ public static native int getFontConfigVersion();
+
private static native int
getFontConfigAASettings(String locale, String fcFamily);
@@ -3157,17 +3175,35 @@ public final class FontManager {
return getFontConfigAAHint("sans");
}
+ /* This is populated by native */
+ private static final FontConfigInfo fcInfo = new FontConfigInfo();
+
/* This array has the array elements created in Java code and is
* passed down to native to be filled in.
*/
- private static FontConfigInfo[] fontConfigFonts;
+ private static FcCompFont[] fontConfigFonts;
- /* Return an array of FontConfigInfo structs describing the primary
+ /* Return an array of FcCompFont structs describing the primary
* font located for each of fontconfig/GTK/Pango's logical font names.
*/
private static native void getFontConfig(String locale,
- FontConfigInfo[] fonts);
+ FontConfigInfo fcInfo,
+ FcCompFont[] fonts,
+ boolean includeFallbacks);
+ static void populateFontConfig(FcCompFont[] fcInfo) {
+ fontConfigFonts = fcInfo;
+ }
+
+ static FcCompFont[] loadFontConfig() {
+ initFontConfigFonts(true);
+ return fontConfigFonts;
+ }
+
+ static FontConfigInfo getFontConfigInfo() {
+ initFontConfigFonts(true);
+ return fcInfo;
+ }
/* This can be made public if it's needed to force a re-read
* rather than using the cached values. The re-read would be needed
@@ -3175,54 +3211,80 @@ public final class FontManager {
* In that event this method would need to return directly the array
* to be used by the caller in case it subsequently changed.
*/
- private static void initFontConfigFonts() {
+ private static synchronized void
+ initFontConfigFonts(boolean includeFallbacks) {
if (fontConfigFonts != null) {
- return;
+ if (!includeFallbacks || (fontConfigFonts[0].allFonts != null)) {
+ return;
+ }
}
- if (isWindows) {
+ if (isWindows || fontConfigFailed) {
return;
}
long t0 = 0;
if (logging) {
- t0 = System.currentTimeMillis();
+ t0 = System.nanoTime();
}
- FontConfigInfo[] fontArr = new FontConfigInfo[fontConfigNames.length];
+ FcCompFont[] fontArr = new FcCompFont[fontConfigNames.length];
for (int i = 0; i< fontArr.length; i++) {
- fontArr[i] = new FontConfigInfo();
+ fontArr[i] = new FcCompFont();
fontArr[i].fcName = fontConfigNames[i];
int colonPos = fontArr[i].fcName.indexOf(':');
fontArr[i].fcFamily = fontArr[i].fcName.substring(0, colonPos);
fontArr[i].jdkName = mapFcName(fontArr[i].fcFamily);
fontArr[i].style = i % 4; // depends on array order.
}
- getFontConfig(getFCLocaleStr(), fontArr);
+ getFontConfig(getFCLocaleStr(), fcInfo, fontArr, includeFallbacks);
+ /* If don't find anything (eg no libfontconfig), then just return */
+ for (int i = 0; i< fontArr.length; i++) {
+ FcCompFont fci = fontArr[i];
+ if (fci.firstFont == null) {
+ if (logging) {
+ logger.info("Fontconfig returned no fonts.");
+ }
+ fontConfigFailed = true;
+ return;
+ }
+ }
fontConfigFonts = fontArr;
if (logging) {
- long t1 = System.currentTimeMillis();
- logger.info("Time spent accessing fontconfig="+(t1-t0)+"ms.");
+ long t1 = System.nanoTime();
+ logger.info("Time spent accessing fontconfig="+
+ (t1-t0)/1000000+"ms.");
for (int i = 0; i< fontConfigFonts.length; i++) {
- FontConfigInfo fci = fontConfigFonts[i];
+ FcCompFont fci = fontConfigFonts[i];
logger.info("FC font " + fci.fcName+" maps to family " +
- fci.familyName + " in file " + fci.fontFile);
+ fci.firstFont.familyName +
+ " in file " + fci.firstFont.fontFile);
+ if (fci.allFonts != null) {
+ for (int f=0;f<fci.allFonts.length;f++) {
+ FontConfigFont fcf = fci.allFonts[f];
+ logger.info("Family=" + fcf.familyName +
+ " Style="+ fcf.styleStr +
+ " Fullname="+fcf.fullName +
+ " File="+fcf.fontFile);
+ }
+ }
}
}
}
- private static PhysicalFont registerFromFcInfo(FontConfigInfo fcInfo) {
+ private static PhysicalFont registerFromFcInfo(FcCompFont fcInfo) {
/* If it's a TTC file we need to know that as we will need to
* make sure we return the right font */
- int offset = fcInfo.fontFile.length()-4;
+ String fontFile = fcInfo.firstFont.fontFile;
+ int offset = fontFile.length()-4;
if (offset <= 0) {
return null;
}
- String ext = fcInfo.fontFile.substring(offset).toLowerCase();
+ String ext = fontFile.substring(offset).toLowerCase();
boolean isTTC = ext.equals(".ttc");
/* If this file is already registered, can just return its font.
@@ -3230,10 +3292,10 @@ public final class FontManager {
* a specific font, so rather than directly returning it, let
* findFont2D resolve that.
*/
- PhysicalFont physFont = registeredFontFiles.get(fcInfo.fontFile);
+ PhysicalFont physFont = registeredFontFiles.get(fontFile);
if (physFont != null) {
if (isTTC) {
- Font2D f2d = findFont2D(fcInfo.familyName,
+ Font2D f2d = findFont2D(fcInfo.firstFont.familyName,
fcInfo.style, NO_FALLBACK);
if (f2d instanceof PhysicalFont) { /* paranoia */
return (PhysicalFont)f2d;
@@ -3249,18 +3311,20 @@ public final class FontManager {
* Lucida Sans), we want to use the JRE version, so make it
* point to the JRE font.
*/
- physFont = findJREDeferredFont(fcInfo.familyName, fcInfo.style);
+ physFont = findJREDeferredFont(fcInfo.firstFont.familyName,
+ fcInfo.style);
/* It is also possible the font file is on the "deferred" list,
* in which case we can just initialise it now.
*/
if (physFont == null &&
- deferredFontFiles.get(fcInfo.fontFile) != null) {
- physFont = initialiseDeferredFont(fcInfo.fontFile);
+ deferredFontFiles.get(fontFile) != null)
+ {
+ physFont = initialiseDeferredFont(fcInfo.firstFont.fontFile);
/* use findFont2D to get the right font from TTC's */
if (physFont != null) {
if (isTTC) {
- Font2D f2d = findFont2D(fcInfo.familyName,
+ Font2D f2d = findFont2D(fcInfo.firstFont.familyName,
fcInfo.style, NO_FALLBACK);
if (f2d instanceof PhysicalFont) { /* paranoia */
return (PhysicalFont)f2d;
@@ -3287,7 +3351,7 @@ public final class FontManager {
fontFormat = FONTFORMAT_TYPE1;
fontRank = Font2D.TYPE1_RANK;
}
- physFont = registerFontFile(fcInfo.fontFile, null,
+ physFont = registerFontFile(fcInfo.firstFont.fontFile, null,
fontFormat, true, fontRank);
}
return physFont;
@@ -3345,12 +3409,12 @@ public final class FontManager {
}
info[1] = info[1] + File.separator + "arial.ttf";
} else {
- initFontConfigFonts();
+ initFontConfigFonts(false);
for (int i=0; i<fontConfigFonts.length; i++) {
if ("sans".equals(fontConfigFonts[i].fcFamily) &&
0 == fontConfigFonts[i].style) {
- info[0] = fontConfigFonts[i].familyName;
- info[1] = fontConfigFonts[i].fontFile;
+ info[0] = fontConfigFonts[i].firstFont.familyName;
+ info[1] = fontConfigFonts[i].firstFont.fontFile;
break;
}
}
@@ -3360,9 +3424,9 @@ public final class FontManager {
*/
if (info[0] == null) {
if (fontConfigFonts.length > 0 &&
- fontConfigFonts[0].fontFile != null) {
- info[0] = fontConfigFonts[0].familyName;
- info[1] = fontConfigFonts[0].fontFile;
+ fontConfigFonts[0].firstFont.fontFile != null) {
+ info[0] = fontConfigFonts[0].firstFont.familyName;
+ info[1] = fontConfigFonts[0].firstFont.fontFile;
} else {
info[0] = "Dialog";
info[1] = "/dialog.ttf";
@@ -3373,8 +3437,8 @@ public final class FontManager {
return defaultPlatformFont;
}
- private FontConfigInfo getFontConfigInfo() {
- initFontConfigFonts();
+ private FcCompFont getFcCompFont() {
+ initFontConfigFonts(false);
for (int i=0; i<fontConfigFonts.length; i++) {
if ("sans".equals(fontConfigFonts[i].fcFamily) &&
0 == fontConfigFonts[i].style) {
@@ -3391,9 +3455,9 @@ public final class FontManager {
name = name.toLowerCase();
- initFontConfigFonts();
+ initFontConfigFonts(false);
- FontConfigInfo fcInfo = null;
+ FcCompFont fcInfo = null;
for (int i=0; i<fontConfigFonts.length; i++) {
if (name.equals(fontConfigFonts[i].fcFamily) &&
style == fontConfigFonts[i].style) {
@@ -3407,7 +3471,8 @@ public final class FontManager {
if (logging) {
logger.info("FC name=" + name + " style=" + style + " uses " +
- fcInfo.familyName + " in file: " + fcInfo.fontFile);
+ fcInfo.firstFont.familyName +
+ " in file: " + fcInfo.firstFont.fontFile);
}
if (fcInfo.compFont != null) {
@@ -3420,7 +3485,8 @@ public final class FontManager {
CompositeFont jdkFont = (CompositeFont)
findFont2D(fcInfo.jdkName, style, LOGICAL_FALLBACK);
- if (fcInfo.familyName == null || fcInfo.fontFile == null) {
+ if (fcInfo.firstFont.familyName == null ||
+ fcInfo.firstFont.fontFile == null) {
return (fcInfo.compFont = jdkFont);
}
@@ -3432,7 +3498,7 @@ public final class FontManager {
* will fall through this code, but the regisration code will
* find that file already registered and return its font.
*/
- FontFamily family = FontFamily.getFamily(fcInfo.familyName);
+ FontFamily family = FontFamily.getFamily(fcInfo.firstFont.familyName);
PhysicalFont physFont = null;
if (family != null) {
Font2D f2D = family.getFontWithExactStyleMatch(fcInfo.style);
@@ -3441,7 +3507,8 @@ public final class FontManager {
}
}
- if (physFont == null || !fcInfo.fontFile.equals(physFont.platName)) {
+ if (physFont == null ||
+ !fcInfo.firstFont.fontFile.equals(physFont.platName)) {
physFont = registerFromFcInfo(fcInfo);
if (physFont == null) {
return (fcInfo.compFont = jdkFont);
@@ -3459,10 +3526,10 @@ public final class FontManager {
* together to prevent synthetic styling.
*/
for (int i=0; i<fontConfigFonts.length; i++) {
- FontConfigInfo fc = fontConfigFonts[i];
+ FcCompFont fc = fontConfigFonts[i];
if (fc != fcInfo &&
- physFont.getFamilyName(null).equals(fc.familyName) &&
- !fc.fontFile.equals(physFont.platName) &&
+ physFont.getFamilyName(null).equals(fc.firstFont.familyName) &&
+ !fc.firstFont.fontFile.equals(physFont.platName) &&
family.getFontWithExactStyleMatch(fc.style) == null) {
registerFromFcInfo(fontConfigFonts[i]);
diff --git a/src/share/classes/sun/java2d/SunGraphicsEnvironment.java b/src/share/classes/sun/java2d/SunGraphicsEnvironment.java
index 63b942bf4..d4f9424ef 100644
--- a/src/share/classes/sun/java2d/SunGraphicsEnvironment.java
+++ b/src/share/classes/sun/java2d/SunGraphicsEnvironment.java
@@ -78,6 +78,7 @@ public abstract class SunGraphicsEnvironment extends GraphicsEnvironment
public static boolean isLinux;
public static boolean isSolaris;
+ public static boolean isOpenSolaris;
public static boolean isWindows;
public static boolean noType1Font;
private static Font defaultFont;
@@ -167,6 +168,23 @@ public abstract class SunGraphicsEnvironment extends GraphicsEnvironment
isLinux = true;
} else if ("SunOS".equals(osName)) {
isSolaris = true;
+ String version = System.getProperty("os.version", "0.0");
+ try {
+ float ver = Float.parseFloat(version);
+ if (ver > 5.10f) {
+ File f = new File("/etc/release");
+ FileInputStream fis = new FileInputStream(f);
+ InputStreamReader isr
+ = new InputStreamReader(fis, "ISO-8859-1");
+ BufferedReader br = new BufferedReader(isr);
+ String line = br.readLine();
+ if (line.indexOf("OpenSolaris") >= 0) {
+ isOpenSolaris = true;
+ }
+ fis.close();
+ }
+ } catch (Exception e) {
+ }
} else if ("Windows".equals(osName)) {
isWindows = true;
}
@@ -174,11 +192,7 @@ public abstract class SunGraphicsEnvironment extends GraphicsEnvironment
noType1Font = "true".
equals(System.getProperty("sun.java2d.noType1Font"));
- if (isOpenJDK()) {
- String[] fontInfo = FontManager.getDefaultPlatformFont();
- defaultFontName = fontInfo[0];
- defaultFontFileName = fontInfo[1];
- } else {
+ if (!isOpenJDK()) {
defaultFontName = lucidaFontName;
if (useAbsoluteFontFileNames()) {
defaultFontFileName =
@@ -244,6 +258,11 @@ public abstract class SunGraphicsEnvironment extends GraphicsEnvironment
* that might be specified.
*/
fontConfig = createFontConfiguration();
+ if (isOpenJDK()) {
+ String[] fontInfo = FontManager.getDefaultPlatformFont();
+ defaultFontName = fontInfo[0];
+ defaultFontFileName = fontInfo[1];
+ }
getPlatformFontPathFromFontConfig();
String extraFontPath = fontConfig.getExtraFontPath();
@@ -1069,7 +1088,7 @@ public abstract class SunGraphicsEnvironment extends GraphicsEnvironment
String fontFileName =
getFileNameFromPlatformName(platformFontName);
String[] nativeNames = null;
- if (fontFileName == null) {
+ if (fontFileName == null || fontFileName.equals(platformFontName)){
/* No file located, so register using the platform name,
* i.e. as a native font.
*/