代码之家  ›  专栏  ›  技术社区  ›  L. Cornelius Dol

Java字体渲染

  •  10
  • L. Cornelius Dol  · 技术社区  · 16 年前

    我一直在尝试用Java编写的GUI系统来使用亚像素反走样,并且已经成功了,除了两个剩余的异常。这是我的后续 other question from a few weeks ago .

    第一个问题是,如果将“渲染提示”键“抗锯齿”设置为“值”,则当键“文本”抗锯齿设置为LCD(子像素)AA值时,它将被忽略。有人能解释一下吗?目前,我被迫在渲染文本之前关闭“Antialias”,并在渲染文本之后重新打开它(这样其他绘画,如圆形等,就可以被禁用)。这个问题通过下面的独立测试程序得到了证明。

    第二个问题是我找不到查询AA的底层O/S设置的方法,所以我必须做一个相当笨拙的解决方案,即创建一个Swing jLabel,获取它的fontMetrics,获取它的fontrenderContext,然后从中获取AA提示。除了将Swing包含在一个完全不使用Swing的程序中之外,它不会在运行任何J2ME JVM的设备上工作。有人能提出一个更好的方法吗?如果它需要J5或J6就可以了,因为当前的kludge已经需要J6(但只需要J4最好)。我已经尝试了每个默认设置,并使用了一个awt组件而不是jlabel。


    测试程序

    此程序验证要使子像素AA工作,必须首先禁用常规AA设置。(PS:我写回一个缓冲区,因为我的底层图形用户界面是这样的,我想在一个等价的上下文中进行测试)。

    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);
        }
    
    }
    
    2 回复  |  直到 16 年前
        1
  •  10
  •   Joshua McKinnon    16 年前

    AWT Desktop Properties 有什么帮助吗?特别是“awt.font.desktophints”-这些包含本机组件使用的aa提示,但可以应用于任何需要的graphics2d。

    只是在黑暗中的一个镜头,最近读过肮脏的有钱客户的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);
    

    我能够得到与使用这些提示的LCD HRGB模式相同的结果(使用您的示例类和drawchars和drawimage,为了简单起见,只需键入drawstring)。

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

        2
  •  5
  •   trashgod    16 年前

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

    AwtTestFrame, 24 points http://i45.tinypic.com/2eltw9l.png