/* * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package sun.font; import java.awt.Font; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.HashMap; import java.util.HashSet; import java.util.Locale; import java.util.Properties; import java.util.Scanner; import sun.awt.FcFontManager; import sun.awt.FontConfiguration; import sun.awt.FontDescriptor; import sun.awt.SunToolkit; import sun.font.CompositeFontDescriptor; import sun.font.FontManager; import sun.font.FontConfigManager.FontConfigInfo; import sun.font.FontConfigManager.FcCompFont; import sun.font.FontConfigManager.FontConfigFont; import sun.java2d.SunGraphicsEnvironment; import sun.util.logging.PlatformLogger; public class FcFontConfiguration extends FontConfiguration { /** Version of the cache file format understood by this code. * Its part of the file name so that we can rev this at * any time, even in a minor JDK update. * It is stored as the value of the "version" property. * This is distinct from the version of "libfontconfig" that generated * the cached results, and which is the "fcversion" property in the file. * {@code FontConfiguration.getVersion()} also returns a version string, * and has meant the version of the fontconfiguration.properties file * that was read. Since this class doesn't use such files, then what * that really means is whether the methods on this class return * values that are compatible with the classes that do directly read * from such files. It is a compatible subset of version "1". */ private static final String fileVersion = "1"; private String fcInfoFileName = null; private FcCompFont[] fcCompFonts = null; public FcFontConfiguration(SunFontManager fm) { super(fm); init(); } /* This isn't called but is needed to satisfy super-class contract. */ public FcFontConfiguration(SunFontManager fm, boolean preferLocaleFonts, boolean preferPropFonts) { super(fm, preferLocaleFonts, preferPropFonts); init(); } @Override public synchronized boolean init() { if (fcCompFonts != null) { return true; } setFontConfiguration(); readFcInfo(); FcFontManager fm = (FcFontManager) fontManager; FontConfigManager fcm = fm.getFontConfigManager(); if (fcCompFonts == null) { fcCompFonts = fcm.loadFontConfig(); if (fcCompFonts != null) { try { writeFcInfo(); } catch (Exception e) { if (FontUtilities.debugFonts()) { warning("Exception writing fcInfo " + e); } } } else if (FontUtilities.debugFonts()) { warning("Failed to get info from libfontconfig"); } } else { fcm.populateFontConfig(fcCompFonts); } if (fcCompFonts == null) { return false; // couldn't load fontconfig. } // NB already in a privileged block from SGE String javaHome = System.getProperty("java.home"); if (javaHome == null) { throw new Error("java.home property not set"); } String javaLib = javaHome + File.separator + "lib"; getInstalledFallbackFonts(javaLib); return true; } @Override public String getFallbackFamilyName(String fontName, String defaultFallback) { // maintain compatibility with old font.properties files, which either // had aliases for TimesRoman & Co. or defined mappings for them. String compatibilityName = getCompatibilityFamilyName(fontName); if (compatibilityName != null) { return compatibilityName; } return defaultFallback; } @Override protected String getFaceNameFromComponentFontName(String componentFontName) { return null; } @Override protected String getFileNameFromComponentFontName(String componentFontName) { return null; } @Override public String getFileNameFromPlatformName(String platformName) { /* Platform name is the file name, but rather than returning * the arg, return null*/ return null; } @Override protected Charset getDefaultFontCharset(String fontName) { return Charset.forName("ISO8859_1"); } @Override protected String getEncoding(String awtFontName, String characterSubsetName) { return "default"; } @Override protected void initReorderMap() { reorderMap = new HashMap<>(); } @Override protected FontDescriptor[] buildFontDescriptors(int fontIndex, int styleIndex) { CompositeFontDescriptor[] cfi = get2DCompositeFontInfo(); int idx = fontIndex * NUM_STYLES + styleIndex; String[] componentFaceNames = cfi[idx].getComponentFaceNames(); FontDescriptor[] ret = new FontDescriptor[componentFaceNames.length]; for (int i = 0; i < componentFaceNames.length; i++) { ret[i] = new FontDescriptor(componentFaceNames[i], StandardCharsets.ISO_8859_1.newEncoder(), new int[0]); } return ret; } @Override public int getNumberCoreFonts() { return 1; } @Override public String[] getPlatformFontNames() { HashSet nameSet = new HashSet(); FcFontManager fm = (FcFontManager) fontManager; FontConfigManager fcm = fm.getFontConfigManager(); FcCompFont[] fcCompFonts = fcm.loadFontConfig(); for (int i=0; i lastModified) { if (FontUtilities.debugFonts()) { warning("Out of date cache directories detected"); } return; } cacheDirIndex++; } String[] names = { "sansserif", "serif", "monospaced" }; String[] fcnames = { "sans", "serif", "monospace" }; int namesLen = names.length; int numStyles = 4; FcCompFont[] fci = new FcCompFont[namesLen*numStyles]; try { for (int i=0; i