在Java/Swing中尊重字体连字功能

5

我在处理Java中的Swing对象(以及JFX,但我稍后再考虑...)时遇到了一个让我非常困惑的问题。

这是我用来在程序中打开字体的代码。 这很标准。

public static Font getFontFromFile(String filePath) throws FontFormatException, IOException {
    File fontFile = new File(filePath);
    return Font.createFont(Font.TRUETYPE_FONT, fontFile);
}

我的问题是,当我实际使用这些字体时,它们内部的连字没有得到应用。我的程序的核心特性之一允许用户加载自定义字体,其中许多具有专门的连字。但这些连字并没有被正确应用,我不确定自己做错了什么。如果用户键入两个字符应该缩成一个连字,第二个字符就会正常显示,没有任何转换发生。但是,当我将这些字体加载到其他任何程序或文本编辑器中时,我看到连字被完全按照我预期的那样应用。
我已经把设置字体的代码削减到绝对最简单的形式,并在一些地方看到(错误的)行为,即使我只是做像下面这样简单的事情:
jTextField.setFont(myFont);

我是否错过了导入时的某些设置?或是需要在2D图形对象上进行全局翻转?非常感谢您的任何帮助。谢谢。

2个回答

6

找到了。

好的。这个问题让人沮丧,因为我一直在正确设置TextAttributes,同时通过一种存在长期bug的方法加载字体...连字号应该在JTextFieldJTextArea对象中表示,但在某些情况下它们不会被表示出来。需要记住两件事:

  1. 有一个旧的bug(https://bugs.openjdk.java.net/browse/JDK-8139741),当使用该模式时,会导致连字号无法被识别。
// BROKEN PATTERN
Font myFont = new Font(<FONT_FAMILY_NAME>, Font.PLAIN, 72);

相反,只有从二进制位置加载字体连字才会被识别:

// WORKING PATTERN
File myFontFile = new File(<FILE_LOCATION>);
Font fixed = Font.createFont(Font.TRUETYPE_FONT, myFontFile);

一旦字体从二进制文件中加载,必须通过TextAttributes设置连字,如下所示:
Map attributes = fixed.getAttributes();
attributes.put(TextAttribute.LIGATURES, TextAttribute.LIGATURES_ON);
fixed = fixed.deriveFont(attributes);

当直接从操作系统加载字体时,我会找到实际的字体文件并将其作为二进制文件加载。这很繁琐,但它能够正常工作。


0

至少就Java2D而言,我认为这里 - 见图4-13的意思是Java将简单地采用提供的代码点列表并呈现每个字形,而不进行组合以制作连字。

在JavaFX 2之前,javafx.scene.text.Font上曾有一个布尔型ligatures属性,声称控制是否使用连字,但现在似乎已经没有了

从历史上看(至少已经有7年了),我必须解析TT / OT字体以获取连字,并手动进行组合(有时甚至需要成对调整字距)。


你能给我提供一个展示如何手动处理的链接吗?我真的很困惑,虽然让Swing自动处理这个问题显然是最好的选择,但我也愿意自己实现一些东西。 - Draque Thompson
抱歉,那是很多年前的事情,而且这个代码归公司所有(我已不再在公司工作)。基本上,我们根据字体定义建立了一个查找表,列出了所有需要处理的情况(例如,“ffl”或小写“a”后面跟随大写字母“V”,需要调整字距),然后扫描文本流。对于连字,我们进行字形替换;对于字距调整,我们将字符串分割并调整下一段文本的起始点。(我们还需要做智能/正确的断词处理,因此我们需要扫描文本流。) - DavidW

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接