如何在Java2D / Graphics2D中指定备用字体 [英] How do I specify fallback fonts in Java2D/Graphics2D
问题描述
g.drawString(str,x,y)
来绘制一个带有 Graphics2D
对象 g
。当前字体 g
不包含 str
的所有字符(例如,我有中文字符)。在Mac OS X上,后备字体似乎是自动使用的,但不是在Windows上出现黑色方框轮廓而不是所需字符。 - 为什么行为会因平台不同而有所不同?
- 如何在缺少字符的情况下指定备用字体(或多个备用字体)?
(例如,其中一个很好的字体那里。
更新/更多信息 不支持所有字符不是JVM的逻辑字体 a>,但是是一个捆绑的字体,与我的应用程序,并获得与 Font.createFont()
。因此,在JRE的 lib / fonts / fallback
文件夹中添加字体在这里不起作用。
我们可以将字符串属性切换为坏符号的字体,并使用 Graphics2D.drawString(AttributedCharacterIterator iterator,int x,int y)
来渲染结果。 优点:这将适用于任何字体。 缺点:没有某种中间对象的缓存,这将工作得更慢更脏。
所以,我建议使用 以及特定部分的备用字体: 渲染本身: / p> 完成所谓的SSCCE代码: I'm using (For instance, one of the nice fonts there.) Update/More Info So, the original font that doesn't support all characters is not one of the JVM's logical fonts, but is a bundled font that comes with my app and was obtained with We could attribute string to switch font on "bad" symbols and use So, i suggest using and with fallback font on specific parts: The rendering itself: The result (Physical "Segoe Print" as main font, logical "Serif" as fallback): Complete supposed-to-be-SSCCE code:
这篇关于如何在Java2D / Graphics2D中指定备用字体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
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打印作为主要字体,逻辑Serif作为后备): $ / code>
$ p $ 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;
$ b $ public class FontTest extends JFrame {
$ b $ public FontTest(){$ b $ 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(){$ b $ public void run() {
new FontTest()。setVisible(true);
}
});
class TestStringComponent extends JComponent {
$ b $ protected void paintComponent(Graphics g){
Graphics2D g2d =(Graphics2D)g ;
g.setColor(getBackground());
g.fillRect(0,0,getWidth(),getHeight());
g.setColor(getForeground());
字体mainFont = new Font(Segoe Print,Font.PLAIN,25);
字体fallbackFont =新字体(Serif,Font.PLAIN,25);
String s =汉德繁古印汉考繁古印Test Test;
g2d.drawString(createFallbackString(s,mainFont,fallbackFont).getIterator(),20,30);
}
public Dimension getPreferredSize(){
return new Dimension(500,40);
$ b私有AttributedString createFallbackString(字符串文本,字体mainFont,字体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);
}
}
}
返回结果;
}
}
g.drawString(str, x, y)
to draw a String with a Graphics2D
object g
. The current font of g
does not cover all the characters of str
(I have e.g. Chinese chars in there). On Mac OS X, a fallback font seems to be automatically used, but not on Windows, where black square outlines appear instead of the wanted characters.
Font.createFont()
. So, adding fonts to the JRE's lib/fonts/fallback
folder doesn't work here.Graphics2D.drawString(AttributedCharacterIterator iterator, int x, int y)
to render result. Advantage: this will work with any font. Drawback: without some sort of caching of intermediate objects this will work slower and dirtier. AttributedString
with main font attribute on whole string: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);
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;
}
}