Визуализация шрифтов Java

Я пытался улучшить свою систему графического интерфейса, написанную на Java, для использования субпиксельного сглаживания, и мне это удалось, за исключением двух оставшихся аномалий. Это продолжение моего другой вопрос, заданный несколько недель назад.

Первая проблема заключается в том, что установка подсказок рендеринга KEY_ANTIALIASING в VALUE_ANTIALIAS_ON приводит к игнорированию KEY_TEXT_ANTIALIASING, когда он установлен на значение AA ЖК-дисплея (субпикселя). Может кто-нибудь пролить некоторый свет на это? В настоящее время я вынужден VALUE_ANTIALIAS_OFF перед рендерингом текста и снова включать его после рендеринга текста (чтобы другие рисунки, такие как круги и т. Д., Были AA). Эта проблема подтверждается приведенной ниже автономной программой тестирования.

Вторая проблема заключается в том, что я не могу найти способ запросить базовую настройку O / S для AA, поэтому мне нужно сделать довольно сложный обходной путь, а именно создать Swing JLabel, получить его FontMetrics, получить FontRenderContext, а затем получить АА намек от этого. Помимо включения Swing в программу, которая в противном случае совершенно не использует Swing, он не будет работать на устройстве, на котором запущена J2ME JVM. Может ли кто-нибудь предложить лучший способ сделать это? Ничего страшного, если для этого требуется J5 или J6, поскольку текущий кладж уже требует 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);
    }

}

person Lawrence Dol    schedule 07.01.2010    source источник


Ответы (2)


Являются ли свойства рабочего стола AWT какой-либо помощи? В частности, «awt.font.desktophints» - они содержат подсказки AA, которые используют собственные компоненты, но могут быть применены к любому Graphics2D, который вы хотите.

Просто выстрел в темноте, недавно прочитав раздел AA в Filthy Rich Clients.

Использование будет выглядеть примерно так:

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 для этого требуется, если это то, что вы ищете ...

person Joshua McKinnon    schedule 07.01.2010
comment
Я не знал об этом ... посмотрю завтра. - person Lawrence Dol; 07.01.2010
comment
Проголосовали и приняли - прекрасно работает в J6 и хорошо деградирует до стандартного AA в J5 и ранее. Больше не нужно создавать поддельные ярлыки Swing - большое спасибо. Угадайте, что мораль этой истории в том, что нам все еще нужно прочитать столько уроков, на которые мы сможем найти время. - person Lawrence Dol; 07.01.2010

Не забывайте: "Реализации могут игнорировать намекает полностью." Для справки, вот что я вижу в 24 точках:

AwtTestFrame, 24 балла

person trashgod    schedule 07.01.2010
comment
Да, я знаю; а в случае Mac он прекрасно отображается независимо от подсказки. Я просто пытаюсь убедить Java сделать все, что в ее силах, при работе в другой операционной системе. - person Lawrence Dol; 07.01.2010