Path: blob/master/src/java.desktop/macosx/classes/sun/font/CFontManager.java
41153 views
/*1* Copyright (c) 2011, 2021, 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.awt.util.ThreadGroupUtils;43import sun.lwawt.macosx.*;4445public final class CFontManager extends SunFontManager {46private static Hashtable<String, Font2D> genericFonts = new Hashtable<String, Font2D>();4748@Override49protected FontConfiguration createFontConfiguration() {50FontConfiguration fc = new CFontConfiguration(this);51fc.init();52return fc;53}5455@Override56public FontConfiguration createFontConfiguration(boolean preferLocaleFonts,57boolean preferPropFonts)58{59return new CFontConfiguration(this, preferLocaleFonts, preferPropFonts);60}6162/*63* Returns an array of two strings. The first element is the64* name of the font. The second element is the file name.65*/66@Override67protected String[] getDefaultPlatformFont() {68return new String[]{"Lucida Grande",69"/System/Library/Fonts/LucidaGrande.ttc"};70}7172// This is a way to register any kind of Font2D, not just files and composites.73public static Font2D[] getGenericFonts() {74return genericFonts.values().toArray(new Font2D[0]);75}7677public Font2D registerGenericFont(Font2D f)78{79return registerGenericFont(f, false);80}81public Font2D registerGenericFont(Font2D f, boolean logicalFont)82{83int rank = 4;8485String fontName = f.fullName;86String familyName = f.familyName;8788if (fontName == null || fontName.isEmpty()) {89return null;90}9192// logical fonts always need to be added to the family93// plus they never need to be added to the generic font list94// or the fullNameToFont table since they are covers for95// already existing fonts in this list96if (logicalFont || !genericFonts.containsKey(fontName)) {97if (FontUtilities.debugFonts()) {98FontUtilities.logInfo("Add to Family " + familyName +99", Font " + fontName + " rank=" + rank);100}101FontFamily family = FontFamily.getFamily(familyName);102if (family == null) {103family = new FontFamily(familyName, false, rank);104family.setFont(f, f.style);105} else if (family.getRank() >= rank) {106family.setFont(f, f.style);107}108if (!logicalFont)109{110genericFonts.put(fontName, f);111fullNameToFont.put(fontName.toLowerCase(Locale.ENGLISH), f);112}113return f;114} else {115return genericFonts.get(fontName);116}117}118119@Override120public Font2D[] getRegisteredFonts() {121Font2D[] regFonts = super.getRegisteredFonts();122123// Add in the Mac OS X native fonts124Font2D[] genericFonts = getGenericFonts();125Font2D[] allFonts = new Font2D[regFonts.length+genericFonts.length];126System.arraycopy(regFonts, 0, allFonts, 0, regFonts.length);127System.arraycopy(genericFonts, 0, allFonts, regFonts.length, genericFonts.length);128129return allFonts;130}131132@Override133protected void addNativeFontFamilyNames(TreeMap<String, String> familyNames, Locale requestedLocale) {134Font2D[] genericfonts = getGenericFonts();135for (int i=0; i < genericfonts.length; i++) {136if (!(genericfonts[i] instanceof NativeFont)) {137String name = genericfonts[i].getFamilyName(requestedLocale);138familyNames.put(name.toLowerCase(requestedLocale), name);139}140}141}142143protected void registerFontsInDir(final String dirName, boolean useJavaRasterizer,144int fontRank, boolean defer, boolean resolveSymLinks) {145146@SuppressWarnings("removal")147String[] files = AccessController.doPrivileged((PrivilegedAction<String[]>) () -> {148return new File(dirName).list(getTrueTypeFilter());149});150151if (files == null) {152return;153} else {154for (String f : files) {155loadNativeDirFonts(dirName+File.separator+f);156}157}158super.registerFontsInDir(dirName, useJavaRasterizer, fontRank, defer, resolveSymLinks);159}160161private native void loadNativeDirFonts(String fontPath);162private native void loadNativeFonts();163164void registerFont(String fontName, String fontFamilyName) {165final CFont font = new CFont(fontName, fontFamilyName);166167registerGenericFont(font);168}169170void registerItalicDerived() {171FontFamily[] famArr = FontFamily.getAllFontFamilies();172for (int i=0; i<famArr.length; i++) {173FontFamily family = famArr[i];174175Font2D f2dPlain = family.getFont(Font.PLAIN);176if (f2dPlain != null && !(f2dPlain instanceof CFont)) continue;177Font2D f2dBold = family.getFont(Font.BOLD);178if (f2dBold != null && !(f2dBold instanceof CFont)) continue;179Font2D f2dItalic = family.getFont(Font.ITALIC);180if (f2dItalic != null && !(f2dItalic instanceof CFont)) continue;181Font2D f2dBoldItalic = family.getFont(Font.BOLD|Font.ITALIC);182if (f2dBoldItalic != null && !(f2dBoldItalic instanceof CFont)) continue;183184CFont plain = (CFont)f2dPlain;185CFont bold = (CFont)f2dBold;186CFont italic = (CFont)f2dItalic;187CFont boldItalic = (CFont)f2dBoldItalic;188189if (bold == null) bold = plain;190if (plain == null && bold == null) continue;191if (italic != null && boldItalic != null) continue;192if (plain != null && italic == null) {193registerGenericFont(plain.createItalicVariant(), true);194}195if (bold != null && boldItalic == null) {196registerGenericFont(bold.createItalicVariant(), true);197}198}199}200201Object waitForFontsToBeLoaded = new Object();202private boolean loadedAllFonts = false;203204@SuppressWarnings("removal")205public void loadFonts()206{207synchronized(waitForFontsToBeLoaded)208{209super.loadFonts();210java.security.AccessController.doPrivileged(211new java.security.PrivilegedAction<Object>() {212public Object run() {213if (!loadedAllFonts) {214loadNativeFonts();215registerItalicDerived();216loadedAllFonts = true;217}218return null;219}220}221);222223String defaultFont = "Lucida Grande";224String defaultFallback = "Lucida Grande";225226setupLogicalFonts("Dialog", defaultFont, defaultFallback);227setupLogicalFonts("Serif", "Times", "Times");228setupLogicalFonts("SansSerif", defaultFont, defaultFallback);229setupLogicalFonts("Monospaced", "Menlo", "Courier");230setupLogicalFonts("DialogInput", defaultFont, defaultFallback);231}232}233234protected void setupLogicalFonts(String logicalName, String realName, String fallbackName) {235FontFamily realFamily = getFontFamilyWithExtraTry(logicalName, realName, fallbackName);236237cloneStyledFont(realFamily, logicalName, Font.PLAIN);238cloneStyledFont(realFamily, logicalName, Font.BOLD);239cloneStyledFont(realFamily, logicalName, Font.ITALIC);240cloneStyledFont(realFamily, logicalName, Font.BOLD | Font.ITALIC);241}242243protected FontFamily getFontFamilyWithExtraTry(String logicalName, String realName, String fallbackName){244FontFamily family = getFontFamily(realName, fallbackName);245if (family != null) return family;246247// at this point, we recognize that we probably needed a fallback font248super.loadFonts();249250family = getFontFamily(realName, fallbackName);251if (family != null) return family;252253System.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.");254return null;255}256257protected FontFamily getFontFamily(String realName, String fallbackName){258FontFamily family = FontFamily.getFamily(realName);259if (family != null) return family;260261family = FontFamily.getFamily(fallbackName);262if (family != null){263System.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.");264return family;265}266267return null;268}269270protected boolean cloneStyledFont(FontFamily realFamily, String logicalFamilyName, int style) {271if (realFamily == null) return false;272273Font2D realFont = realFamily.getFontWithExactStyleMatch(style);274if (realFont == null || !(realFont instanceof CFont)) return false;275276CFont newFont = new CFont((CFont)realFont, logicalFamilyName);277registerGenericFont(newFont, true);278279return true;280}281282@Override283public String getFontPath(boolean noType1Fonts) {284// In the case of the Cocoa toolkit, since we go through NSFont, we don't need to register /Library/Fonts285Toolkit tk = Toolkit.getDefaultToolkit();286if (tk instanceof HeadlessToolkit) {287tk = ((HeadlessToolkit)tk).getUnderlyingToolkit();288}289if (tk instanceof LWCToolkit) {290return "";291}292293// X11 case294return "/Library/Fonts";295}296297@Override298protected FontUIResource getFontConfigFUIR(299String family, int style, int size)300{301String mappedName = FontUtilities.mapFcName(family);302if (mappedName == null) {303mappedName = "sansserif";304}305return new FontUIResource(mappedName, style, size);306}307308// Only implemented on Windows309@Override310protected void populateFontFileNameMap(HashMap<String, String> fontToFileMap, HashMap<String, String> fontToFamilyNameMap,311HashMap<String, ArrayList<String>> familyToFontListMap, Locale locale) {}312}313314315