Как настроить простой файл Java fontconfig.properties для использования на Linux - PullRequest
2 голосов
/ 04 апреля 2020

Я использую пользовательскую Java 11 среду выполнения на пользовательском linux оборудовании, 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) 

Я могу предоставить некоторые шрифты, и я решил, что мне нужно создать fontconfig.properties и поместите меня в папку Java runtimes lib , но я пытаюсь понять, что мне нужно поместить в fontconfig.properties.

Может кто-то приведите пример того, как задать минимальный набор шрифтов в fontconfig.properties для linux, чтобы предотвратить возникновение исключения.

В частности, у меня есть набор шрифтов TrueType, которые я поместил в fonts в папке lib , так как использовать этот набор в качестве набора шрифтов, доступных для Java

  • LucidaBrightDemiItali c .ttf
  • LucidaBrightRegular.ttf
  • LucidaSansRegular.ttf
  • LucidaTypewriterRegular.ttf
  • LucidaBrightDemiBold.ttf
  • LucidaBrightItali.
  • 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

1 Ответ

0 голосов
/ 07 апреля 2020

Jdk-релизы не поставляются со шрифтами, Oracle релизы обычно делают, поэтому у меня была идея скачать Oracle релиз и посмотреть, что они делают, но файл fontconfig.properties значительно отличается между Windows и * Выпуски 1063 *, поэтому мне нужен был UNIX выпуск.

Я сначала скачал jdk-11.0.6_ linux -x64_bin.tar.gz , но, вероятно, у него не было файла fontconfig.properties потому что это был просто обобщенный c linux сборник, а не привязанный к какому-либо конкретному. Так как моя основная машинная машина - Windows, я не хотел опробовать сборки .deb или .rpm, потому что мне было нелегко их установить. Поэтому вместо этого я загружаю Solaris jdk-11.0.6_solaris-sparcv9_bin.tar.gz и распаковываю его.

, который содержит файл font.properties.sr c, следующий этой структуре

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

Насколько я понимаю, Сопоставление шрифтов компонентов сопоставляется с Java компонентным шрифтом с логическим именем шрифта , Последовательность поиска указывает порядок поиска шрифтов на основе компонентных шрифтов Java. Имена файлов шрифтов сопоставляют логическое имя шрифта с фактическим именем файла , где шрифт находится на компьютере. Пути шрифта AWT X11 указывает от имени шрифта компонента на фактическую папку , содержащую фактический шрифт на компьютере.

Итак, я выполнил поиск и заменил в файле, заменив фактическое имя файла на местоположение моего шрифта на сервере и заменив фактическую папку с расположением в папке, содержащей фактический шрифт.

Затем я переименовал этот измененный fontconfig.proprties.sr c в 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), который будет использоваться для разных скриптов и для различные стили (обычный, полужирный и т. д. c).

Когда я запускаю программу, шрифты требуются для использования с 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)

Я думаю, что проблема здесь в том, что Физический шрифт ожидался, но поскольку я не указал жирный шрифт, itali c fonts ectera Java пытается создать шрифт на основе модификации к физический шрифт, создающий составной шрифт . Но Java всегда ожидает, что физические шрифты будут предоставлены для некоторых базовых c стилей.

Поэтому я скопировал шрифты Lucida в каталог шрифтов и изменил 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 для скриптов Юго-Восточной Азии и перезапустил приложение, и это сработало. Будет ли это работать при любых обстоятельствах, я не уверен.

...