From 76740bd2a49d2574383edafacf4c86c963276044 Mon Sep 17 00:00:00 2001 From: linyuxuan Date: Fri, 5 Jan 2024 10:36:13 +0800 Subject: [PATCH 3/4] Implements the FONTCONFIGURATION_FALLBACK on Linux Uses FcFontConfiguration to build a fallback composite font. Gets the information for the fallback font from fontconfig. --- .../unix/classes/sun/awt/FcFontManager.java | 41 +++++++++++++++- .../classes/sun/font/FcFontConfiguration.java | 36 +++++++++++++- .../classes/sun/font/FontConfigManager.java | 49 ++++++++++++++++--- 3 files changed, 116 insertions(+), 10 deletions(-) diff --git a/src/java.desktop/unix/classes/sun/awt/FcFontManager.java b/src/java.desktop/unix/classes/sun/awt/FcFontManager.java index ecd7ac0ad35..1457252ee22 100644 --- a/src/java.desktop/unix/classes/sun/awt/FcFontManager.java +++ b/src/java.desktop/unix/classes/sun/awt/FcFontManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, 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 @@ -25,8 +25,12 @@ package sun.awt; +import sun.font.CompositeFont; +import sun.font.CompositeFontDescriptor; import sun.font.FcFontConfiguration; +import sun.font.Font2D; import sun.font.FontConfigManager; +import sun.font.FontUtilities; import sun.font.SunFontManager; /** @@ -67,6 +71,41 @@ public FontConfiguration createFontConfiguration(boolean preferLocaleFonts, } } + @Override + public Font2D getFontFromFontConfiguration(String name, int style) { + CompositeFont cf = createCompositeFont(name, style); + if (cf == null) { + if (FontUtilities.debugFonts()) { + FontUtilities.logWarning("can't get font from fontconfiguration."); + } + return super.getDefaultLogicalFont(style); + } + return cf; + } + + /** + * Builds a composite font using the information from fontconfig + */ + protected CompositeFont createCompositeFont(String name, int style) { + FcFontConfiguration fcFontConfig = (FcFontConfiguration)createFontConfiguration(); + CompositeFontDescriptor fontInfo = fcFontConfig.get2DCompositeFontInfo(name, style); + if (fontInfo == null) { + return null; + } + + String[] componentFileNames = fontInfo.getComponentFileNames(); + String[] componentFaceNames = fontInfo.getComponentFaceNames(); + + CompositeFont cf = new CompositeFont(fontInfo.getFaceName(), + componentFileNames, + componentFaceNames, + fontInfo.getCoreComponentCount(), + fontInfo.getExclusionRanges(), + fontInfo.getExclusionRangeLimits(), + true, this); + return cf; + } + @Override protected String[] getDefaultPlatformFont() { final String[] info = new String[2]; diff --git a/src/java.desktop/unix/classes/sun/font/FcFontConfiguration.java b/src/java.desktop/unix/classes/sun/font/FcFontConfiguration.java index 8638bd3f594..4233b0ce98c 100644 --- a/src/java.desktop/unix/classes/sun/font/FcFontConfiguration.java +++ b/src/java.desktop/unix/classes/sun/font/FcFontConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2023, 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 @@ -231,6 +231,40 @@ private FontConfigFont[] getFcFontList(FcCompFont[] fcFonts, return fcFonts[0].allFonts; } + /** + * Gets the information for the specified font from Fontconfig + */ + public CompositeFontDescriptor get2DCompositeFontInfo(String name, int style) { + FcFontManager fm = (FcFontManager) fontManager; + FontConfigManager fcm = fm.getFontConfigManager(); + FcCompFont fcCompFont = fcm.getFontConfigMatch(name, style, true); + if (fcCompFont == null) { + return null; + } + + String faceName = name + "." + styleNames[style]; + FontConfigFont[] fcFonts = fcCompFont.allFonts; + + int numFonts = fcFonts.length; + String[] fileNames = new String[numFonts]; + String[] faceNames = new String[numFonts]; + + int index; + for (index = 0; index < fcFonts.length; index++) { + faceNames[index] = fcFonts[index].fullName; + fileNames[index] = fcFonts[index].fontFile; + } + + CompositeFontDescriptor result + = new CompositeFontDescriptor( + faceName, + 1, + faceNames, + fileNames, + null, null); + return result; + } + @Override public CompositeFontDescriptor[] get2DCompositeFontInfo() { diff --git a/src/java.desktop/unix/classes/sun/font/FontConfigManager.java b/src/java.desktop/unix/classes/sun/font/FontConfigManager.java index 6e3b83f4b66..627b7fb3e55 100644 --- a/src/java.desktop/unix/classes/sun/font/FontConfigManager.java +++ b/src/java.desktop/unix/classes/sun/font/FontConfigManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2023, 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 @@ -96,6 +96,13 @@ public static class FontConfigInfo { "monospace:bold:italic", }; + private static String[] fontConfigStyles = { + "regular:roman", + "bold:roman", + "regular:italic", + "bold:italic" + }; + /* This array has the array elements created in Java code and is * passed down to native to be filled in. */ @@ -188,7 +195,8 @@ public synchronized void initFontConfigFonts(boolean includeFallbacks) { fontArr[i].jdkName = FontUtilities.mapFcName(fontArr[i].fcFamily); fontArr[i].style = i % 4; // depends on array order. } - getFontConfig(getFCLocaleStr(), fcInfo, fontArr, includeFallbacks); + getFontConfigInfo(fcInfo); + getFontConfigMatch(getFCLocaleStr(), fontArr, includeFallbacks); FontConfigFont anyFont = null; /* If don't find anything (eg no libfontconfig), then just return */ for (int i = 0; i< fontArr.length; i++) { @@ -432,13 +440,10 @@ public FcCompFont[] getFontConfigFonts() { return fontConfigFonts; } - /* Return an array of FcCompFont structs describing the primary - * font located for each of fontconfig/GTK/Pango's logical font names. + /* Return a FontConfigInfo struct describing the version + * and cache directory information for fontconfig */ - private static native void getFontConfig(String locale, - FontConfigInfo fcInfo, - FcCompFont[] fonts, - boolean includeFallbacks); + private static native void getFontConfigInfo(FontConfigInfo fcInfo); void populateFontConfig(FcCompFont[] fcInfo) { fontConfigFonts = fcInfo; @@ -454,6 +459,34 @@ FontConfigInfo getFontConfigInfo() { return fcInfo; } + /* 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 + getFontConfigMatch(String locale, FcCompFont[] fonts, boolean includeFallbacks); + + FcCompFont getFontConfigMatch(String name, int style, boolean includeFallbacks) { + if (FontUtilities.isWindows || fontConfigFailed) { + return null; + } + + FcCompFont[] fontArr = new FcCompFont[1]; + fontArr[0] = new FcCompFont(); + + fontArr[0].fcName = name + ":" + fontConfigStyles[style]; + + getFontConfigMatch(getFCLocaleStr(), fontArr, includeFallbacks); + + if (fontArr[0].firstFont == null) { + if (FontUtilities.isLogging()) { + FontUtilities.logInfo("Fontconfig returned no font for " + fontArr[0].fcName); + } + fontConfigFailed = true; + return null; + } + return fontArr[0]; + } + private static native int getFontConfigAASettings(String locale, String fcFamily); } -- 2.39.2