Java字体渲染

我一直在尝试增强我用Java编写的GUI系统以使用子像素抗锯齿并且已经成功,除了两个剩余的exception。 这是几个星期前我的另一个问题的后续问题 。

第一个问题是将设置渲染提示KEY_ANTIALIASING设置为VALUE_ANTIALIAS_ON会导致KEY_TEXT_ANTIALIASING在设置为LCD(子像素)AA值时被忽略。 任何人都可以对此有所了解吗? 目前我在渲染文本之前被迫使用VALUE_ANTIALIAS_OFF,并在渲染文本后将其重新打开(以便其他绘画,如圆圈等,是AA’d)。 下面的独立测试程序certificate了这个问题。

第二个问题是我找不到查询AA的底层操作系统设置,所以我必须做一个相当大的解决方法,即创建一个Swing JLabel,获取它的FontMetrics,得到它的FontRenderContext然后得到AA提示。 除了在一个程序中涉及Swing,否则完全不使用Swing,它将无法在运行任何J2ME JVM的设备上运行。 谁能建议一个更好的方法来做到这一点? 如果它需要J5或J6就没关系,因为当前的kludge已经需要J6(但只需要J4就是最好的)。 我已经尝试了每个默认设置并使用AWT组件而不是JLabel。


测试程序

该程序validation要使子像素AA工作,必须首先禁用一般AA设置。 (PS:我写入后台缓冲区,因为我的底层GUI确实如此,我想在等效的上下文中进行测试)。

import java.awt.*; import java.awt.event.*; public class AwtTestFrame1b extends Panel { private final Font font=new Font(Font.SANS_SERIF, Font.PLAIN, 16); private final int line=25; AwtTestFrame1b() { setBackground(SystemColor.control); } public void paint(Graphics g) { Graphics2D g2d = (Graphics2D)g; int py=0; py=paintText(g2d,py,null ,false); py=paintText(g2d,py,null ,true ); py+=line; py=paintText(g2d,py,RenderingHints.VALUE_TEXT_ANTIALIAS_OFF ,false); py=paintText(g2d,py,RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT ,false); py=paintText(g2d,py,RenderingHints.VALUE_TEXT_ANTIALIAS_ON ,false); py=paintText(g2d,py,RenderingHints.VALUE_TEXT_ANTIALIAS_GASP ,false); py=paintText(g2d,py,RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB,false); py+=line; py=paintText(g2d,py,RenderingHints.VALUE_TEXT_ANTIALIAS_OFF ,true ); py=paintText(g2d,py,RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT ,true ); py=paintText(g2d,py,RenderingHints.VALUE_TEXT_ANTIALIAS_ON ,true ); py=paintText(g2d,py,RenderingHints.VALUE_TEXT_ANTIALIAS_GASP ,true ); py=paintText(g2d,py,RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB,true ); py+=line; } private int paintText(Graphics2D g2d, int py, Object val, boolean aa) { Graphics2D dgc=g2d; char[] txt=("The quick brown fox jumped over the lazy dog ("+val+", General AA: "+aa+")").toCharArray(); Image img=null; GraphicsConfiguration cfg=getGraphicsConfiguration(); img=cfg.createCompatibleImage(getWidth(),line); dgc=(Graphics2D)img.getGraphics(); dgc.setColor(getBackground()); dgc.fillRect(0,0,getWidth(),line); dgc.setColor(g2d.getColor()); if(aa ) { dgc.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON ); } else { dgc.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF); } if(val!=null) { dgc.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,val); } dgc.setFont(font); dgc.drawChars(txt,0,txt.length,10,line-5); g2d.drawImage(img, 0,py, null); dgc.dispose(); img.flush(); return (py+line); } public static void main(String[] args) { Frame wnd=new Frame("AWT Antialiased Text Sample"); wnd.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); wnd.add(new AwtTestFrame1b()); wnd.setSize(new Dimension(1000, 600)); wnd.setVisible(true); } } 

AWT桌面属性有什么帮助吗? 特别是,“awt.font.desktophints” – 这些包含本机组件使用的AA提示,但可以应用于您想要的任何Graphics2D。

只是在黑暗中拍摄,最近阅读了Filthy Rich Clients中的AA部分。

使用看起来像这样:

 String str = "A quick brown fox jumps over the lazy dog"; Toolkit tk = Toolkit.getDefaultToolkit(); Map desktopHints = (Map)(tk.getDesktopProperty("awt.font.desktophints")); Graphics2D g2d = (Graphics2D)g; if(desktopHints != null) { g2d.addRenderingHints(desktopHints); } g2d.drawString(str, someX, someY); 

我能够得到相同的结果(使用你的示例类和drawChars和drawImage,只是简单地键入drawString)作为LCD HRGB模式使用这些提示而我的机器上没有其他调用。

我不确定这需要什么版本的Java,如果它正是你要找的……

不要忘记:“实现可以完全忽略提示 。” 作为参考,这是我在24点看到的:

AwtTestFrame,24分http://sofzh.miximages.com/java/2eltw9l.png