< prev index next >

src/java.desktop/unix/classes/sun/font/FcFontConfiguration.java

Print this page
rev 11361 : imported patch refactor-fm.patch


  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.font;
  27 
  28 import java.awt.Font;
  29 import java.io.File;
  30 import java.io.FileInputStream;
  31 import java.io.FileOutputStream;
  32 import java.io.IOException;
  33 import java.net.InetAddress;
  34 import java.net.UnknownHostException;
  35 import java.nio.charset.Charset;
  36 import java.nio.charset.StandardCharsets;
  37 import java.nio.file.Files;
  38 import java.util.HashMap;
  39 import java.util.HashSet;
  40 import java.util.Properties;
  41 import java.util.Scanner;

  42 import sun.awt.FontConfiguration;
  43 import sun.awt.FontDescriptor;
  44 import sun.awt.SunToolkit;
  45 import sun.awt.X11FontManager;
  46 import sun.font.CompositeFontDescriptor;
  47 import sun.font.FontManager;
  48 import sun.font.FontConfigManager.FontConfigInfo;
  49 import sun.font.FontConfigManager.FcCompFont;
  50 import sun.font.FontConfigManager.FontConfigFont;
  51 import sun.java2d.SunGraphicsEnvironment;
  52 import sun.util.logging.PlatformLogger;
  53 
  54 public class FcFontConfiguration extends FontConfiguration {
  55 
  56     /** Version of the cache file format understood by this code.
  57      * Its part of the file name so that we can rev this at
  58      * any time, even in a minor JDK update.
  59      * It is stored as the value of the "version" property.
  60      * This is distinct from the version of "libfontconfig" that generated
  61      * the cached results, and which is the "fcversion" property in the file.
  62      * {@code FontConfiguration.getVersion()} also returns a version string,
  63      * and has meant the version of the fontconfiguration.properties file
  64      * that was read. Since this class doesn't use such files, then what
  65      * that really means is whether the methods on this class return


  75         super(fm);
  76         init();
  77     }
  78 
  79     /* This isn't called but is needed to satisfy super-class contract. */
  80     public FcFontConfiguration(SunFontManager fm,
  81                                boolean preferLocaleFonts,
  82                                boolean preferPropFonts) {
  83         super(fm, preferLocaleFonts, preferPropFonts);
  84         init();
  85     }
  86 
  87     @Override
  88     public synchronized boolean init() {
  89         if (fcCompFonts != null) {
  90             return true;
  91         }
  92 
  93         setFontConfiguration();
  94         readFcInfo();
  95         X11FontManager fm = (X11FontManager) fontManager;
  96         FontConfigManager fcm = fm.getFontConfigManager();
  97         if (fcCompFonts == null) {
  98             fcCompFonts = fcm.loadFontConfig();
  99             if (fcCompFonts != null) {
 100                 try {
 101                     writeFcInfo();
 102                 } catch (Exception e) {
 103                     if (FontUtilities.debugFonts()) {
 104                         warning("Exception writing fcInfo " + e);
 105                     }
 106                 }
 107             } else if (FontUtilities.debugFonts()) {
 108                 warning("Failed to get info from libfontconfig");
 109             }
 110         } else {
 111             fcm.populateFontConfig(fcCompFonts);
 112         }
 113 
 114         if (fcCompFonts == null) {
 115             return false; // couldn't load fontconfig.


 177     protected FontDescriptor[] buildFontDescriptors(int fontIndex, int styleIndex) {
 178         CompositeFontDescriptor[] cfi = get2DCompositeFontInfo();
 179         int idx = fontIndex * NUM_STYLES + styleIndex;
 180         String[] componentFaceNames = cfi[idx].getComponentFaceNames();
 181         FontDescriptor[] ret = new FontDescriptor[componentFaceNames.length];
 182         for (int i = 0; i < componentFaceNames.length; i++) {
 183             ret[i] = new FontDescriptor(componentFaceNames[i], StandardCharsets.ISO_8859_1.newEncoder(), new int[0]);
 184         }
 185 
 186         return ret;
 187     }
 188 
 189     @Override
 190     public int getNumberCoreFonts() {
 191         return 1;
 192     }
 193 
 194     @Override
 195     public String[] getPlatformFontNames() {
 196         HashSet<String> nameSet = new HashSet<String>();
 197         X11FontManager fm = (X11FontManager) fontManager;
 198         FontConfigManager fcm = fm.getFontConfigManager();
 199         FcCompFont[] fcCompFonts = fcm.loadFontConfig();
 200         for (int i=0; i<fcCompFonts.length; i++) {
 201             for (int j=0; j<fcCompFonts[i].allFonts.length; j++) {
 202                 nameSet.add(fcCompFonts[i].allFonts[j].fontFile);
 203             }
 204         }
 205         return nameSet.toArray(new String[0]);
 206     }
 207 
 208     @Override
 209     public String getExtraFontPath() {
 210         return null;
 211     }
 212 
 213     @Override
 214     public boolean needToSearchForFile(String fileName) {
 215         return false;
 216     }
 217 
 218     private FontConfigFont[] getFcFontList(FcCompFont[] fcFonts,
 219                                            String fontname, int style) {
 220 
 221         if (fontname.equals("dialog")) {
 222             fontname = "sansserif";
 223         } else if (fontname.equals("dialoginput")) {
 224             fontname = "monospaced";
 225         }
 226         for (int i=0; i<fcFonts.length; i++) {
 227             if (fontname.equals(fcFonts[i].jdkName) &&
 228                 style == fcFonts[i].style) {
 229                 return fcFonts[i].allFonts;
 230             }
 231         }
 232         return fcFonts[0].allFonts;
 233     }
 234 
 235     @Override
 236     public CompositeFontDescriptor[] get2DCompositeFontInfo() {
 237 
 238         X11FontManager fm = (X11FontManager) fontManager;
 239         FontConfigManager fcm = fm.getFontConfigManager();
 240         FcCompFont[] fcCompFonts = fcm.loadFontConfig();
 241 
 242         CompositeFontDescriptor[] result =
 243                 new CompositeFontDescriptor[NUM_FONTS * NUM_STYLES];
 244 
 245         for (int fontIndex = 0; fontIndex < NUM_FONTS; fontIndex++) {
 246             String fontName = publicFontNames[fontIndex];
 247 
 248             for (int styleIndex = 0; styleIndex < NUM_STYLES; styleIndex++) {
 249 
 250                 String faceName = fontName + "." + styleNames[styleIndex];
 251                 FontConfigFont[] fcFonts =
 252                     getFcFontList(fcCompFonts,
 253                                   fontNames[fontIndex], styleIndex);
 254 
 255                 int numFonts = fcFonts.length;
 256                 // fall back fonts listed in the lib/fonts/fallback directory
 257                 if (installedFallbackFontFiles != null) {
 258                     numFonts += installedFallbackFontFiles.length;


 351             try {
 352                 hostname = InetAddress.getLocalHost().getHostName();
 353             } catch (UnknownHostException e) {
 354                 hostname = "localhost";
 355             }
 356             String userDir = System.getProperty("user.home");
 357             String version = System.getProperty("java.version");
 358             String fs = File.separator;
 359             String dir = userDir+fs+".java"+fs+"fonts"+fs+version;
 360             String lang = SunToolkit.getStartupLocale().getLanguage();
 361             String name = "fcinfo-"+fileVersion+"-"+hostname+"-"+
 362                 osName+"-"+osVersion+"-"+lang+".properties";
 363             fcInfoFileName = dir+fs+name;
 364         }
 365         return new File(fcInfoFileName);
 366     }
 367 
 368     private void writeFcInfo() {
 369         Properties props = new Properties();
 370         props.setProperty("version", fileVersion);
 371         X11FontManager fm = (X11FontManager) fontManager;
 372         FontConfigManager fcm = fm.getFontConfigManager();
 373         FontConfigInfo fcInfo = fcm.getFontConfigInfo();
 374         props.setProperty("fcversion", Integer.toString(fcInfo.fcVersion));
 375         if (fcInfo.cacheDirs != null) {
 376             for (int i=0;i<fcInfo.cacheDirs.length;i++) {
 377                 if (fcInfo.cacheDirs[i] != null) {
 378                    props.setProperty("cachedir."+i,  fcInfo.cacheDirs[i]);
 379                 }
 380             }
 381         }
 382         for (int i=0; i<fcCompFonts.length; i++) {
 383             FcCompFont fci = fcCompFonts[i];
 384             String styleKey = fci.jdkName+"."+fci.style;
 385             props.setProperty(styleKey+".length",
 386                               Integer.toString(fci.allFonts.length));
 387             for (int j=0; j<fci.allFonts.length; j++) {
 388                 props.setProperty(styleKey+"."+j+".family",
 389                                   fci.allFonts[j].familyName);
 390                 props.setProperty(styleKey+"."+j+".file",
 391                                   fci.allFonts[j].fontFile);


 410                 warning("Failed renaming file to "+ getFcInfoFile());
 411             }
 412         } catch (Exception e) {
 413             if (FontUtilities.debugFonts()) {
 414                 warning("IOException writing to "+ getFcInfoFile());
 415             }
 416         }
 417     }
 418 
 419     /* We want to be able to use this cache instead of invoking
 420      * fontconfig except when we can detect the system cache has changed.
 421      * But there doesn't seem to be a way to find the location of
 422      * the system cache.
 423      */
 424     private void readFcInfo() {
 425         File fcFile = getFcInfoFile();
 426         if (!fcFile.exists()) {
 427             return;
 428         }
 429         Properties props = new Properties();
 430         X11FontManager fm = (X11FontManager) fontManager;
 431         FontConfigManager fcm = fm.getFontConfigManager();
 432         try {
 433             FileInputStream fis = new FileInputStream(fcFile);
 434             props.load(fis);
 435             fis.close();
 436         } catch (IOException e) {
 437             if (FontUtilities.debugFonts()) {
 438                 warning("IOException reading from "+fcFile.toString());
 439             }
 440             return;
 441         }
 442         String version = (String)props.get("version");
 443         if (version == null || !version.equals(fileVersion)) {
 444             return;
 445         }
 446 
 447         // If there's a new, different fontconfig installed on the
 448         // system, we invalidate our fontconfig file.
 449         String fcVersionStr = (String)props.get("fcversion");
 450         if (fcVersionStr != null) {




  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.font;
  27 
  28 import java.awt.Font;
  29 import java.io.File;
  30 import java.io.FileInputStream;
  31 import java.io.FileOutputStream;
  32 import java.io.IOException;
  33 import java.net.InetAddress;
  34 import java.net.UnknownHostException;
  35 import java.nio.charset.Charset;
  36 import java.nio.charset.StandardCharsets;
  37 import java.nio.file.Files;
  38 import java.util.HashMap;
  39 import java.util.HashSet;
  40 import java.util.Properties;
  41 import java.util.Scanner;
  42 import sun.awt.FcFontManager;
  43 import sun.awt.FontConfiguration;
  44 import sun.awt.FontDescriptor;
  45 import sun.awt.SunToolkit;

  46 import sun.font.CompositeFontDescriptor;
  47 import sun.font.FontManager;
  48 import sun.font.FontConfigManager.FontConfigInfo;
  49 import sun.font.FontConfigManager.FcCompFont;
  50 import sun.font.FontConfigManager.FontConfigFont;
  51 import sun.java2d.SunGraphicsEnvironment;
  52 import sun.util.logging.PlatformLogger;
  53 
  54 public class FcFontConfiguration extends FontConfiguration {
  55 
  56     /** Version of the cache file format understood by this code.
  57      * Its part of the file name so that we can rev this at
  58      * any time, even in a minor JDK update.
  59      * It is stored as the value of the "version" property.
  60      * This is distinct from the version of "libfontconfig" that generated
  61      * the cached results, and which is the "fcversion" property in the file.
  62      * {@code FontConfiguration.getVersion()} also returns a version string,
  63      * and has meant the version of the fontconfiguration.properties file
  64      * that was read. Since this class doesn't use such files, then what
  65      * that really means is whether the methods on this class return


  75         super(fm);
  76         init();
  77     }
  78 
  79     /* This isn't called but is needed to satisfy super-class contract. */
  80     public FcFontConfiguration(SunFontManager fm,
  81                                boolean preferLocaleFonts,
  82                                boolean preferPropFonts) {
  83         super(fm, preferLocaleFonts, preferPropFonts);
  84         init();
  85     }
  86 
  87     @Override
  88     public synchronized boolean init() {
  89         if (fcCompFonts != null) {
  90             return true;
  91         }
  92 
  93         setFontConfiguration();
  94         readFcInfo();
  95         FcFontManager fm = (FcFontManager) fontManager;
  96         FontConfigManager fcm = fm.getFontConfigManager();
  97         if (fcCompFonts == null) {
  98             fcCompFonts = fcm.loadFontConfig();
  99             if (fcCompFonts != null) {
 100                 try {
 101                     writeFcInfo();
 102                 } catch (Exception e) {
 103                     if (FontUtilities.debugFonts()) {
 104                         warning("Exception writing fcInfo " + e);
 105                     }
 106                 }
 107             } else if (FontUtilities.debugFonts()) {
 108                 warning("Failed to get info from libfontconfig");
 109             }
 110         } else {
 111             fcm.populateFontConfig(fcCompFonts);
 112         }
 113 
 114         if (fcCompFonts == null) {
 115             return false; // couldn't load fontconfig.


 177     protected FontDescriptor[] buildFontDescriptors(int fontIndex, int styleIndex) {
 178         CompositeFontDescriptor[] cfi = get2DCompositeFontInfo();
 179         int idx = fontIndex * NUM_STYLES + styleIndex;
 180         String[] componentFaceNames = cfi[idx].getComponentFaceNames();
 181         FontDescriptor[] ret = new FontDescriptor[componentFaceNames.length];
 182         for (int i = 0; i < componentFaceNames.length; i++) {
 183             ret[i] = new FontDescriptor(componentFaceNames[i], StandardCharsets.ISO_8859_1.newEncoder(), new int[0]);
 184         }
 185 
 186         return ret;
 187     }
 188 
 189     @Override
 190     public int getNumberCoreFonts() {
 191         return 1;
 192     }
 193 
 194     @Override
 195     public String[] getPlatformFontNames() {
 196         HashSet<String> nameSet = new HashSet<String>();
 197         FcFontManager fm = (FcFontManager) fontManager;
 198         FontConfigManager fcm = fm.getFontConfigManager();
 199         FcCompFont[] fcCompFonts = fcm.loadFontConfig();
 200         for (int i=0; i<fcCompFonts.length; i++) {
 201             for (int j=0; j<fcCompFonts[i].allFonts.length; j++) {
 202                 nameSet.add(fcCompFonts[i].allFonts[j].fontFile);
 203             }
 204         }
 205         return nameSet.toArray(new String[0]);
 206     }
 207 
 208     @Override
 209     public String getExtraFontPath() {
 210         return null;
 211     }
 212 
 213     @Override
 214     public boolean needToSearchForFile(String fileName) {
 215         return false;
 216     }
 217 
 218     private FontConfigFont[] getFcFontList(FcCompFont[] fcFonts,
 219                                            String fontname, int style) {
 220 
 221         if (fontname.equals("dialog")) {
 222             fontname = "sansserif";
 223         } else if (fontname.equals("dialoginput")) {
 224             fontname = "monospaced";
 225         }
 226         for (int i=0; i<fcFonts.length; i++) {
 227             if (fontname.equals(fcFonts[i].jdkName) &&
 228                 style == fcFonts[i].style) {
 229                 return fcFonts[i].allFonts;
 230             }
 231         }
 232         return fcFonts[0].allFonts;
 233     }
 234 
 235     @Override
 236     public CompositeFontDescriptor[] get2DCompositeFontInfo() {
 237 
 238         FcFontManager fm = (FcFontManager) fontManager;
 239         FontConfigManager fcm = fm.getFontConfigManager();
 240         FcCompFont[] fcCompFonts = fcm.loadFontConfig();
 241 
 242         CompositeFontDescriptor[] result =
 243                 new CompositeFontDescriptor[NUM_FONTS * NUM_STYLES];
 244 
 245         for (int fontIndex = 0; fontIndex < NUM_FONTS; fontIndex++) {
 246             String fontName = publicFontNames[fontIndex];
 247 
 248             for (int styleIndex = 0; styleIndex < NUM_STYLES; styleIndex++) {
 249 
 250                 String faceName = fontName + "." + styleNames[styleIndex];
 251                 FontConfigFont[] fcFonts =
 252                     getFcFontList(fcCompFonts,
 253                                   fontNames[fontIndex], styleIndex);
 254 
 255                 int numFonts = fcFonts.length;
 256                 // fall back fonts listed in the lib/fonts/fallback directory
 257                 if (installedFallbackFontFiles != null) {
 258                     numFonts += installedFallbackFontFiles.length;


 351             try {
 352                 hostname = InetAddress.getLocalHost().getHostName();
 353             } catch (UnknownHostException e) {
 354                 hostname = "localhost";
 355             }
 356             String userDir = System.getProperty("user.home");
 357             String version = System.getProperty("java.version");
 358             String fs = File.separator;
 359             String dir = userDir+fs+".java"+fs+"fonts"+fs+version;
 360             String lang = SunToolkit.getStartupLocale().getLanguage();
 361             String name = "fcinfo-"+fileVersion+"-"+hostname+"-"+
 362                 osName+"-"+osVersion+"-"+lang+".properties";
 363             fcInfoFileName = dir+fs+name;
 364         }
 365         return new File(fcInfoFileName);
 366     }
 367 
 368     private void writeFcInfo() {
 369         Properties props = new Properties();
 370         props.setProperty("version", fileVersion);
 371         FcFontManager fm = (FcFontManager) fontManager;
 372         FontConfigManager fcm = fm.getFontConfigManager();
 373         FontConfigInfo fcInfo = fcm.getFontConfigInfo();
 374         props.setProperty("fcversion", Integer.toString(fcInfo.fcVersion));
 375         if (fcInfo.cacheDirs != null) {
 376             for (int i=0;i<fcInfo.cacheDirs.length;i++) {
 377                 if (fcInfo.cacheDirs[i] != null) {
 378                    props.setProperty("cachedir."+i,  fcInfo.cacheDirs[i]);
 379                 }
 380             }
 381         }
 382         for (int i=0; i<fcCompFonts.length; i++) {
 383             FcCompFont fci = fcCompFonts[i];
 384             String styleKey = fci.jdkName+"."+fci.style;
 385             props.setProperty(styleKey+".length",
 386                               Integer.toString(fci.allFonts.length));
 387             for (int j=0; j<fci.allFonts.length; j++) {
 388                 props.setProperty(styleKey+"."+j+".family",
 389                                   fci.allFonts[j].familyName);
 390                 props.setProperty(styleKey+"."+j+".file",
 391                                   fci.allFonts[j].fontFile);


 410                 warning("Failed renaming file to "+ getFcInfoFile());
 411             }
 412         } catch (Exception e) {
 413             if (FontUtilities.debugFonts()) {
 414                 warning("IOException writing to "+ getFcInfoFile());
 415             }
 416         }
 417     }
 418 
 419     /* We want to be able to use this cache instead of invoking
 420      * fontconfig except when we can detect the system cache has changed.
 421      * But there doesn't seem to be a way to find the location of
 422      * the system cache.
 423      */
 424     private void readFcInfo() {
 425         File fcFile = getFcInfoFile();
 426         if (!fcFile.exists()) {
 427             return;
 428         }
 429         Properties props = new Properties();
 430         FcFontManager fm = (FcFontManager) fontManager;
 431         FontConfigManager fcm = fm.getFontConfigManager();
 432         try {
 433             FileInputStream fis = new FileInputStream(fcFile);
 434             props.load(fis);
 435             fis.close();
 436         } catch (IOException e) {
 437             if (FontUtilities.debugFonts()) {
 438                 warning("IOException reading from "+fcFile.toString());
 439             }
 440             return;
 441         }
 442         String version = (String)props.get("version");
 443         if (version == null || !version.equals(fileVersion)) {
 444             return;
 445         }
 446 
 447         // If there's a new, different fontconfig installed on the
 448         // system, we invalidate our fontconfig file.
 449         String fcVersionStr = (String)props.get("fcversion");
 450         if (fcVersionStr != null) {


< prev index next >