簡體   English   中英

如何配置簡單的 Java fontconfig.properties 文件以在 Linux 上使用

[英]How do I configure simple Java fontconfig.properties file for use on Linux

我在自定義 linux 硬件上使用自定義 Java 11 運行時,Java 運行時不是我構建的。 但是我有一個問題,我的應用程序需要訪問字體並且運行時沒有配置任何字體,所以我得到了這個堆棧跟蹤

Exception in thread "main" java.lang.InternalError: java.lang.reflect.InvocationTargetException
        at java.desktop/sun.font.FontManagerFactory$1.run(FontManagerFactory.java:86)
        at java.base/java.security.AccessController.doPrivileged(Native Method)
        at java.desktop/sun.font.FontManagerFactory.getInstance(FontManagerFactory.java:74)
        at java.desktop/java.awt.Font.getFont2D(Font.java:497)
        at java.desktop/java.awt.Font.getFamily(Font.java:1410)
        at java.desktop/java.awt.Font.getFamily_NoClientCode(Font.java:1384)
        at java.desktop/java.awt.Font.getFamily(Font.java:1376)
        at java.desktop/java.awt.Font.toString(Font.java:1869)
        at java.base/java.lang.String.valueOf(String.java:2951)
        at java.base/java.io.PrintStream.println(PrintStream.java:897)
        at Fonts.main(Fonts.java:7)
Caused by: java.lang.reflect.InvocationTargetException
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
        at java.desktop/sun.font.FontManagerFactory$1.run(FontManagerFactory.java:84)
        ... 10 more
Caused by: java.lang.NullPointerException
        at java.desktop/sun.awt.FontConfiguration.getVersion(FontConfiguration.java:1262)
        at java.desktop/sun.awt.FontConfiguration.readFontConfigFile(FontConfiguration.java:225)
        at java.desktop/sun.awt.FontConfiguration.init(FontConfiguration.java:107)
        at java.desktop/sun.awt.X11FontManager.createFontConfiguration(X11FontManager.java:719)
        at java.desktop/sun.font.SunFontManager$2.run(SunFontManager.java:367)
        at java.base/java.security.AccessController.doPrivileged(Native Method)
        at java.desktop/sun.font.SunFontManager.<init>(SunFontManager.java:312)
        at java.desktop/sun.awt.FcFontManager.<init>(FcFontManager.java:35)
        at java.desktop/sun.awt.X11FontManager.<init>(X11FontManager.java:56) 

我可以提供一些 fonts 並且我已經確定我需要創建一個fontconfig.properties並將我放入 Java 運行時lib文件夾中,但我很難理解我需要放入 fontconfig.properties 的內容。

有人可以給我一個示例,說明如何在 linux 上的 fontconfig.properties 中指定一組最小的 fonts 以防止發生異常。

More specificially, I have a set of truetype fonts that I have put into a fonts folder within the lib folder so how do I use this set as a set of fonts available to Java

  • LucidaBrightDemiItalic.ttf
  • LucidaBrightRegular.ttf
  • LucidaSansRegular.ttf
  • LucidaTypewriterRegular.ttf
  • LucidaBrightDemiBold.ttf
  • LucidaBrightItalic.ttf
  • LucidaSansDemiBold.ttf
  • LucidaTypewriterBold.ttf

如果我創建一個空的 fontconfig.properties 文件,那么第一個異常更改為

Caused by: java.lang.NullPointerException
        at java.desktop/sun.awt.FontConfiguration.getInitELC(FontConfiguration.java:465)
        at java.desktop/sun.awt.FontConfiguration.initFontConfig(FontConfiguration.java:441)
        at java.desktop/sun.awt.FontConfiguration.init(FontConfiguration.java:108)
        at java.desktop/sun.awt.X11FontManager.createFontConfiguration(X11FontManager.java:719)
        at java.desktop/sun.font.SunFontManager$2.run(SunFontManager.java:367)
        at java.base/java.security.AccessController.doPrivileged(Native Method)
        at java.desktop/sun.font.SunFontManager.<init>(SunFontManager.java:312)
        at java.desktop/sun.awt.FcFontManager.<init>(FcFontManager.java:35)
        at java.desktop/sun.awt.X11FontManager.<init>(X11FontManager.java:56)

所以這表明 Java 運行時至少找到(空)fontconfig.properties 文件,所以如果我可以正確配置它,這應該可以工作。

我試圖用一個文件創建一個非常小的 fontconfig.properties 文件,但它沒有用。

version=1

allfonts.plain.latin-1=-monotype-times new roman-medium-r-normal--*-%d-*-*-p-*-iso10646-1

filename.-monotype-times new roman-medium-r-normal--*-%d-*-*-p-*-iso10646-1=/mnt/app/opt/SongKong/songkong/jre/lib/fonts/ipag.ttf

awtfontpath.latin-1=/mnt/app/opt/SongKong/songkong/jre/lib/fonts

Jdk releases do not come with any fonts, Oracle releases generally do, so I had an idea to download an Oracle release and see what they do but the fontconfig.properties file differs significantly between Windows and UNIX releases so I needed a UNIX release.

我首先下載了 jdk-11.0.6_linux-x64_bin.tar.gz但這沒有 fontconfig.properties 文件,可能是因為它只是一個通用的 linux 構建,而不是特定於任何特定的。 由於我的主要開發機器是 Windows,因此我並不熱衷於嘗試 .deb 或 .rpm 構建,因為我沒有簡單的安裝它們的途徑。 因此,我下載了 Solaris jdk-11.0.6_solaris-sparcv9_bin.tar.gz 並將其解壓縮。

確實包含遵循此結構的 font.properties.src 文件

Version =1
# Component Font Mappings
# Search Sequences
# Font Filenames
# AWT X11 font paths

My understanding is the Component Font Mappings map from a Java component font to a logical font name , Search Sequence specifies an order to search for fonts based on the Java component fonts. 字體文件名map 從邏輯字體名稱到字體在機器上的實際文件名 AWT X11 字體路徑指定從組件字體名稱到包含機器上實際字體的實際文件夾

因此,我對文件進行了搜索和替換,將實際文件名替換為服務器上我的字體上的位置,並將實際文件夾替換為包含實際字體的文件夾上的位置。

然后我將這個修改后的fontconfig.proprties.src重命名為fontconfig.properties並將其存儲在 jre/lib 文件夾中

以前失敗的簡單測試程序現在可以工作了

import java.awt.*;
public class Fonts
{
     public static void main(String[] args) throws Exception
     {
         Font defaultFont = Font.decode(null);
         System.out.println(defaultFont);
     }
}

但是,我只指定了一種字體(ipag.ttf)用於不同的腳本和不同的 styles(普通、粗體等)。

當我運行程序時,需要 fonts 與 jakarta.poi 一起使用(用於創建 excel 電子表格文件),現在給出以下異常:

java.lang.ClassCastException: class sun.font.CompositeFont cannot be cast to class sun.font.PhysicalFont (sun.font.CompositeFont and sun.font.PhysicalFont are in module java.desktop of loader 'bootstrap')
    at java.desktop/sun.font.SunFontManager.getDefaultPhysicalFont(SunFontManager.java:1086)
    at java.desktop/sun.font.SunFontManager.initialiseDeferredFont(SunFontManager.java:965)
    at java.desktop/sun.font.SunFontManager.findOtherDeferredFont(SunFontManager.java:903)
    at java.desktop/sun.font.SunFontManager.findDeferredFont(SunFontManager.java:919)
    at java.desktop/sun.font.SunFontManager.findFont2D(SunFontManager.java:2120)
    at java.desktop/java.awt.Font.getFont2D(Font.java:506)
    at java.desktop/java.awt.Font.canDisplayUpTo(Font.java:2246)
    at java.desktop/java.awt.font.TextLayout.singleFont(TextLayout.java:469)
    at java.desktop/java.awt.font.TextLayout.<init>(TextLayout.java:530)
    at org.apache.poi.ss.util.SheetUtil.getDefaultCharWidth(SheetUtil.java:275)

我認為這里的問題是物理字體是預期的,但因為我沒有指定粗體、斜體 fonts ectera Java 嘗試根據對物理字體的修改創建字體,創建復合字體 但是 Java 總是希望為一些基本的 styles 提供物理 fonts。

所以我然后將 Lucida fonts 復制到 fonts 目錄,修改了 fontconfig。 屬性文件來使用這些字體變體,如下所示

filename.-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1=/mnt/app/opt/jre/lib/fonts/LucidaSansRegular.ttf
filename.-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1=/mnt/app/opt/jre/lib/fonts/LucidaSansRegular.ttf
filename.-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1=/mnt/app/opt/jre/lib/fonts/LucidaSansDemiBold.ttf
filename.-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1=/mnt/app/opt/jre/lib/fonts/LucidaSansDemiBold.ttf
filename.-monotype-courier_new-medium-r-normal--*-%d-*-*-p-*-iso10646-1=/mnt/app/opt/jre/lib/fonts/LucidaTypewriterRegular.ttf
filename.-monotype-courier_new-medium-i-normal--*-%d-*-*-p-*-iso10646-1=/mnt/app/opt/jre/lib/fonts/LucidaTypewriterRegular.ttf
filename.-monotype-courier_new-bold-r-normal--*-%d-*-*-p-*-iso10646-1=/mnt/app/opt/jre/lib/fonts/LucidaTypewriterBold.ttf
filename.-monotype-courier_new-bold-i-normal--*-%d-*-*-p-*-iso10646-1=/mnt/app/opt/jre/lib/fonts/LucidaTypewriterBold.ttf
filename.-monotype-times_new_roman-medium-r-normal--*-%d-*-*-p-*-iso10646-1=/mnt/app/opt/jre/lib/fonts/LucidaBrightRegular.ttf
filename.-monotype-times_new_roman-medium-i-normal--*-%d-*-*-p-*-iso10646-1=/mnt/app/opt/jre/lib/fonts/LucidaBrightItalic.ttf
filename.-monotype-times_new_roman-bold-r-normal--*-%d-*-*-p-*-iso10646-1=/mnt/app/opt/jre/lib/fonts/LucidaBrightDemiBold.ttf
filename.-monotype-times_new_roman-bold-i-normal--*-%d-*-*-p-*-iso10646-1=/mnt/app/opt/jre/lib/fonts/LucidaBrightDemiItalic.ttf

只保留東南亞腳本的 ipag.ttf 並重新啟動應用程序,然后就可以了。 我不確定這是否適用於所有情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM