gpt4 book ai didi

java - 如何在 Java2D/Graphics2D 中指定后备字体

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:50:42 30 4
gpt4 key购买 nike

我正在使用 g.drawString(str, x, y) 绘制带有 Graphics2D 对象 g 的字符串。 g 的当前字体没有覆盖 str 的所有字符(我在那里有中文字符)。在 Mac OS X 上,后备字体似乎会自动使用,但在 Windows 上不会,出现黑色方形轮廓而不是所需字符。

  • 为什么行为因平台而异?
  • 如果缺少字符,如何指定后备字体(或几种后备字体)?

(例如,一种漂亮的字体 there 。)

更新/更多信息

因此,不支持所有字符的原始字体不是 JVM 的 logical fonts 之一。 , 但它是我的应用程序附带的捆绑字体,是通过 Font.createFont() 获得的。因此,将字体添加到 JRE 的 lib/fonts/fallback 文件夹在这里不起作用。

最佳答案

我们可以通过属性字符串来切换“错误”符号上的字体,并使用 Graphics2D.drawString(AttributedCharacterIterator iterator, int x, int y) 来呈现结果。 优点:这适用于任何字体。 缺点:如果没有某种中间对象的缓存,这将工作得更慢且更脏。

所以,我建议使用 AttributedString在整个字符串上具有主要字体属性:

AttributedString astr = new AttributedString(text);
astr.addAttribute(TextAttribute.FONT, mainFont, 0, textLength);

并在特定部分使用后备字体:

astr.addAttribute(TextAttribute.FONT, fallbackFont, fallbackBegin, fallbackEnd);

渲染本身:

g2d.drawString(astr.getIterator(), 20, 30);

结果(物理“Segoe Print”作为主要字体,逻辑“Serif”作为后备):

enter image description here

完整的假定 SSCCE 代码:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.font.TextAttribute;
import java.text.AttributedString;

import javax.swing.JComponent;
import javax.swing.JFrame;

public class FontTest extends JFrame {

public FontTest() {
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
getContentPane().setLayout(new BorderLayout());
getContentPane().add(new TestStringComponent());
pack();
}

public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new FontTest().setVisible(true);
}
});
}
}

class TestStringComponent extends JComponent {

protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g.setColor(getBackground());
g.fillRect(0, 0, getWidth(), getHeight());

g.setColor(getForeground());

Font mainFont = new Font("Segoe Print", Font.PLAIN, 25);
Font fallbackFont = new Font("Serif", Font.PLAIN, 25);

String s = "Test 漢鼎繁古印 Test 漢鼎繁古印 Test";

g2d.drawString(createFallbackString(s, mainFont, fallbackFont).getIterator(), 20, 30);
}

public Dimension getPreferredSize() {
return new Dimension(500, 40);
}

private AttributedString createFallbackString(String text, Font mainFont, Font fallbackFont) {
AttributedString result = new AttributedString(text);

int textLength = text.length();
result.addAttribute(TextAttribute.FONT, mainFont, 0, textLength);

boolean fallback = false;
int fallbackBegin = 0;
for (int i = 0; i < text.length(); i++) {
boolean curFallback = !mainFont.canDisplay(text.charAt(i));
if (curFallback != fallback) {
fallback = curFallback;
if (fallback) {
fallbackBegin = i;
} else {
result.addAttribute(TextAttribute.FONT, fallbackFont, fallbackBegin, i);
}
}
}
return result;
}
}

关于java - 如何在 Java2D/Graphics2D 中指定后备字体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9482255/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com