Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/macosx/classes/sun/font/CFontManager.java
38827 views
/*1* Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.font;2627import java.awt.*;28import java.io.File;29import java.security.AccessController;30import java.security.PrivilegedAction;31import java.util.ArrayList;32import java.util.HashMap;33import java.util.Hashtable;34import java.util.Locale;35import java.util.TreeMap;36import java.util.Vector;3738import javax.swing.plaf.FontUIResource;3940import sun.awt.FontConfiguration;41import sun.awt.HeadlessToolkit;42import sun.misc.ThreadGroupUtils;43import sun.lwawt.macosx.*;4445public final class CFontManager extends SunFontManager {46private FontConfigManager fcManager = null;47private static Hashtable<String, Font2D> genericFonts = new Hashtable<String, Font2D>();4849@Override50protected FontConfiguration createFontConfiguration() {51FontConfiguration fc = new CFontConfiguration(this);52fc.init();53return fc;54}5556@Override57public FontConfiguration createFontConfiguration(boolean preferLocaleFonts,58boolean preferPropFonts)59{60return new CFontConfiguration(this, preferLocaleFonts, preferPropFonts);61}6263/*64* Returns an array of two strings. The first element is the65* name of the font. The second element is the file name.66*/67@Override68protected String[] getDefaultPlatformFont() {69return new String[]{"Lucida Grande",70"/System/Library/Fonts/LucidaGrande.ttc"};71}7273// This is a way to register any kind of Font2D, not just files and composites.74public static Font2D[] getGenericFonts() {75return (Font2D[])genericFonts.values().toArray(new Font2D[0]);76}7778public Font2D registerGenericFont(Font2D f)79{80return registerGenericFont(f, false);81}82public Font2D registerGenericFont(Font2D f, boolean logicalFont)83{84int rank = 4;8586String fontName = f.fullName;87String familyName = f.familyName;8889if (fontName == null || "".equals(fontName)) {90return null;91}9293// logical fonts always need to be added to the family94// plus they never need to be added to the generic font list95// or the fullNameToFont table since they are covers for96// already existing fonts in this list97if (logicalFont || !genericFonts.containsKey(fontName)) {98if (FontUtilities.debugFonts()) {99FontUtilities.getLogger().info("Add to Family "+familyName +100", Font " + fontName + " rank="+rank);101}102FontFamily family = FontFamily.getFamily(familyName);103if (family == null) {104family = new FontFamily(familyName, false, rank);105family.setFont(f, f.style);106} else if (family.getRank() >= rank) {107family.setFont(f, f.style);108}109if (!logicalFont)110{111genericFonts.put(fontName, f);112fullNameToFont.put(fontName.toLowerCase(Locale.ENGLISH), f);113}114return f;115} else {116return (Font2D)genericFonts.get(fontName);117}118}119120@Override121public Font2D[] getRegisteredFonts() {122Font2D[] regFonts = super.getRegisteredFonts();123124// Add in the Mac OS X native fonts125Font2D[] genericFonts = getGenericFonts();126Font2D[] allFonts = new Font2D[regFonts.length+genericFonts.length];127System.arraycopy(regFonts, 0, allFonts, 0, regFonts.length);128System.arraycopy(genericFonts, 0, allFonts, regFonts.length, genericFonts.length);129130return allFonts;131}132133@Override134protected void addNativeFontFamilyNames(TreeMap<String, String> familyNames, Locale requestedLocale) {135Font2D[] genericfonts = getGenericFonts();136for (int i=0; i < genericfonts.length; i++) {137if (!(genericfonts[i] instanceof NativeFont)) {138String name = genericfonts[i].getFamilyName(requestedLocale);139familyNames.put(name.toLowerCase(requestedLocale), name);140}141}142}143144@Override145public Font2D createFont2D(File fontFile, int fontFormat, boolean isCopy, CreatedFontTracker tracker) throws FontFormatException {146147String fontFilePath = fontFile.getPath();148Font2D font2D = null;149final File fFile = fontFile;150final CreatedFontTracker _tracker = tracker;151try {152switch (fontFormat) {153case Font.TRUETYPE_FONT:154font2D = new TrueTypeFont(fontFilePath, null, 0, true);155break;156case Font.TYPE1_FONT:157font2D = new Type1Font(fontFilePath, null, isCopy);158break;159default:160throw new FontFormatException("Unrecognised Font Format");161}162} catch (FontFormatException e) {163if (isCopy) {164java.security.AccessController.doPrivileged(165new java.security.PrivilegedAction<Object>() {166public Object run() {167if (_tracker != null) {168_tracker.subBytes((int)fFile.length());169}170fFile.delete();171return null;172}173});174}175throw(e);176}177if (isCopy) {178FileFont.setFileToRemove(font2D, fontFile, tracker);179synchronized (FontManager.class) {180181if (tmpFontFiles == null) {182tmpFontFiles = new Vector<File>();183}184tmpFontFiles.add(fontFile);185186if (fileCloser == null) {187final Runnable fileCloserRunnable = new Runnable() {188public void run() {189java.security.AccessController.doPrivileged(190new java.security.PrivilegedAction<Object>() {191public Object run() {192193for (int i=0;i<CHANNELPOOLSIZE;i++) {194if (fontFileCache[i] != null) {195try {196fontFileCache[i].close();197} catch (Exception e) {}198}199}200if (tmpFontFiles != null) {201File[] files = new File[tmpFontFiles.size()];202files = tmpFontFiles.toArray(files);203for (int f=0; f<files.length;f++) {204try {205files[f].delete();206} catch (Exception e) {}207}208}209return null;210}211});212}213};214AccessController.doPrivileged(215(PrivilegedAction<Void>) () -> {216/* The thread must be a member of a thread group217* which will not get GCed before VM exit.218* Make its parent the top-level thread group.219*/220ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup();221fileCloser = new Thread(rootTG, fileCloserRunnable);222fileCloser.setContextClassLoader(null);223Runtime.getRuntime().addShutdownHook(fileCloser);224return null;225}226);227}228}229}230return font2D;231}232233/*234public synchronized FontConfigManager getFontConfigManager() {235if (fcManager == null) {236fcManager = new FontConfigManager();237}238return fcManager;239}240*/241242protected void registerFontsInDir(String dirName, boolean useJavaRasterizer, int fontRank, boolean defer, boolean resolveSymLinks) {243loadNativeDirFonts(dirName);244super.registerFontsInDir(dirName, useJavaRasterizer, fontRank, defer, resolveSymLinks);245}246247private native void loadNativeDirFonts(String dirName);248private native void loadNativeFonts();249250void registerFont(String fontName, String fontFamilyName) {251final CFont font = new CFont(fontName, fontFamilyName);252253registerGenericFont(font);254}255256void registerItalicDerived() {257FontFamily[] famArr = FontFamily.getAllFontFamilies();258for (int i=0; i<famArr.length; i++) {259FontFamily family = famArr[i];260261Font2D f2dPlain = family.getFont(Font.PLAIN);262if (f2dPlain != null && !(f2dPlain instanceof CFont)) continue;263Font2D f2dBold = family.getFont(Font.BOLD);264if (f2dBold != null && !(f2dBold instanceof CFont)) continue;265Font2D f2dItalic = family.getFont(Font.ITALIC);266if (f2dItalic != null && !(f2dItalic instanceof CFont)) continue;267Font2D f2dBoldItalic = family.getFont(Font.BOLD|Font.ITALIC);268if (f2dBoldItalic != null && !(f2dBoldItalic instanceof CFont)) continue;269270CFont plain = (CFont)f2dPlain;271CFont bold = (CFont)f2dBold;272CFont italic = (CFont)f2dItalic;273CFont boldItalic = (CFont)f2dBoldItalic;274275if (bold == null) bold = plain;276if (plain == null && bold == null) continue;277if (italic != null && boldItalic != null) continue;278if (plain != null && italic == null) {279registerGenericFont(plain.createItalicVariant(), true);280}281if (bold != null && boldItalic == null) {282registerGenericFont(bold.createItalicVariant(), true);283}284}285}286287Object waitForFontsToBeLoaded = new Object();288private boolean loadedAllFonts = false;289290public void loadFonts()291{292synchronized(waitForFontsToBeLoaded)293{294super.loadFonts();295java.security.AccessController.doPrivileged(296new java.security.PrivilegedAction<Object>() {297public Object run() {298if (!loadedAllFonts) {299loadNativeFonts();300registerItalicDerived();301loadedAllFonts = true;302}303return null;304}305}306);307308String defaultFont = "Lucida Grande";309String defaultFallback = "Lucida Sans";310311setupLogicalFonts("Dialog", defaultFont, defaultFallback);312setupLogicalFonts("Serif", "Times", "Lucida Bright");313setupLogicalFonts("SansSerif", defaultFont, defaultFallback);314setupLogicalFonts("Monospaced", "Menlo", "Lucida Sans Typewriter");315setupLogicalFonts("DialogInput", defaultFont, defaultFallback);316}317}318319protected void setupLogicalFonts(String logicalName, String realName, String fallbackName) {320FontFamily realFamily = getFontFamilyWithExtraTry(logicalName, realName, fallbackName);321322cloneStyledFont(realFamily, logicalName, Font.PLAIN);323cloneStyledFont(realFamily, logicalName, Font.BOLD);324cloneStyledFont(realFamily, logicalName, Font.ITALIC);325cloneStyledFont(realFamily, logicalName, Font.BOLD | Font.ITALIC);326}327328protected FontFamily getFontFamilyWithExtraTry(String logicalName, String realName, String fallbackName){329FontFamily family = getFontFamily(realName, fallbackName);330if (family != null) return family;331332// at this point, we recognize that we probably needed a fallback font333super.loadFonts();334335family = getFontFamily(realName, fallbackName);336if (family != null) return family;337338System.err.println("Warning: the fonts \"" + realName + "\" and \"" + fallbackName + "\" are not available for the Java logical font \"" + logicalName + "\", which may have unexpected appearance or behavior. Re-enable the \""+ realName +"\" font to remove this warning.");339return null;340}341342protected FontFamily getFontFamily(String realName, String fallbackName){343FontFamily family = FontFamily.getFamily(realName);344if (family != null) return family;345346family = FontFamily.getFamily(fallbackName);347if (family != null){348System.err.println("Warning: the font \"" + realName + "\" is not available, so \"" + fallbackName + "\" has been substituted, but may have unexpected appearance or behavor. Re-enable the \""+ realName +"\" font to remove this warning.");349return family;350}351352return null;353}354355protected boolean cloneStyledFont(FontFamily realFamily, String logicalFamilyName, int style) {356if (realFamily == null) return false;357358Font2D realFont = realFamily.getFontWithExactStyleMatch(style);359if (realFont == null || !(realFont instanceof CFont)) return false;360361CFont newFont = new CFont((CFont)realFont, logicalFamilyName);362registerGenericFont(newFont, true);363364return true;365}366367@Override368public String getFontPath(boolean noType1Fonts) {369// In the case of the Cocoa toolkit, since we go through NSFont, we don't need to register /Library/Fonts370Toolkit tk = Toolkit.getDefaultToolkit();371if (tk instanceof HeadlessToolkit) {372tk = ((HeadlessToolkit)tk).getUnderlyingToolkit();373}374if (tk instanceof LWCToolkit) {375return "";376}377378// X11 case379return "/Library/Fonts";380}381382@Override383protected FontUIResource getFontConfigFUIR(384String family, int style, int size)385{386String mappedName = FontUtilities.mapFcName(family);387if (mappedName == null) {388mappedName = "sansserif";389}390return new FontUIResource(mappedName, style, size);391}392393// Only implemented on Windows394@Override395protected void populateFontFileNameMap(HashMap<String, String> fontToFileMap, HashMap<String, String> fontToFamilyNameMap,396HashMap<String, ArrayList<String>> familyToFontListMap, Locale locale) {}397}398399400