10

Java (最新バージョン 6u23) で不透明なテキストをレンダリングするとサブピクセル AA がうまく使用されますが、半透明のテキストをレンダリングするとうまくいかないことがわかりました。

サブピクセル AA:

代替テキスト 代替テキスト

色だけが 0xFFFFFFFF から 0xBFFFFFFF に変更された同じテキスト:

代替テキスト 代替テキスト

ご覧のとおり、半透明のテキストは明らかに標準の AA であり、きれいな半透明のレンダリングではなく、90 年代の恐ろしい「蜘蛛の巣」のような外観になっています。

これは、一般的なサブピクセル AA の技術的な制限によるものですか、それとも Java のバグによるものですか、それとも単に Java が半透明のテキストを試みさえしないためですか、それとも何かを見逃したのでしょうか?


グラフィックの初期化

dbGraphics=(Graphics2D)dbImage.getGraphics();
if(dctRoot.properties.getBoolean("Antialias",true)) {
    try {
        Map hnts=(Map)(dctRoot.awtComponent.getToolkit().getDesktopProperty("awt.font.desktophints"));

        // SET AA ON OVERALL (NOTE: GENERAL AA MUST BE OFF FOR SUBPIXEL AA TO BE HONORED - TEXT WIDGETS MUST DO THIS THEMSELVES)
        dbGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);

        if(hnts!=null) {
            // SET FONT RENDERING HINTS FROM DESKTOP
            dbGraphics.addRenderingHints(hnts);
            }
        else {
            try {
                // SET TEXT AA TO FONT-SPECIFIED GASP AA (JAVA 6+)
                dbGraphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.class.getField("VALUE_TEXT_ANTIALIAS_GASP").get(null));
                }
            catch(Throwable thr3) {
                // SET TEXT AA TO DEFAULT
                dbGraphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
                }
            }
        }
    catch(Throwable thr) {
        dctRoot.log.println("Antialiasing not supported on this JVM ("+thr+").");
        dctRoot.setProperty("Antialias","False");           // turn off AA for subsequent painting
        }
    }
else {
    try {
        dbGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF);
        dbGraphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
        }
    catch(Throwable thr) {;}                                // ignore exception
    }

テキストのレンダリング

Object oaa=disableGeneralAA(gc);
...
gc.drawString(tl,xx,(ty+(xa*met.getHeight())));
restoreGeneralAA(gc,oaa);

...


static private volatile boolean         hasRenderingHints=true;

// *****************************************************************************
// STATIC INIT & MAIN
// *****************************************************************************

// *****************************************************************************
// STATIC METHODS
// *****************************************************************************

/**
 * Disable the general anti-aliasing rendering hint, returning whether the old value was RenderingHints.VALUE_ANTIALIAS_ON.
 * <p>
 * This method is needed for text rendering due to a bug in AWT; as of Java 6_20 when general AA is on text is not rendered using subpixel
 * AA, so general AA has to be turned off before rendering text and turned back on when done.  This method abstracts that work and deals
 * with the possibility that the JVM does not support rendering hints, such as is the case with JME JVMs.
 */
static public Object disableGeneralAA(Graphics2D gc) {
    Object                              old=null;

    if(hasRenderingHints) {
        try {
            old=gc.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
            gc.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF);
            }
        catch(NoClassDefFoundError thr) { hasRenderingHints=false; }
        catch(NoSuchFieldError     thr) { hasRenderingHints=false; }
        catch(NoSuchMethodError    thr) { hasRenderingHints=false; }
        }
    return old;
    }

/**
 * Disable the general anti-aliasing rendering hint, returning whether the old value was RenderingHints.VALUE_ANTIALIAS_ON.
 * <p>
 * This method is needed for text rendering due to a bug in AWT; as of Java 6_20 when general AA is on text is not rendered using subpixel
 * AA, so general AA has to be turned off before rendering text and turned back on when done.  This method abstracts that work and deals
 * with the possibility that the JVM does not support rendering hints, such as is the case with JME JVMs.
 */
static public void restoreGeneralAA(Graphics2D gc, Object val) {
    Object                              old=null;

    if(hasRenderingHints && val!=null) {
        try { gc.setRenderingHint(RenderingHints.KEY_ANTIALIASING,val); }
        catch(NoClassDefFoundError thr) { hasRenderingHints=false; }
        catch(NoSuchFieldError     thr) { hasRenderingHints=false; }
        catch(NoSuchMethodError    thr) { hasRenderingHints=false; }
        }
    }
4

3 に答える 3

1

これらのバグレポートからわかるように、透明な背景へのテキストのレンダリングは (完全に) サポートされていないようです:

于 2011-01-13T09:15:36.663 に答える
0

使用している Java のバージョンは何ですか? 本当なの。しかし、どうやらこれは Java 6 update 12 (J6u12) または JDK7 b43 の時点で修正されているようです

ここを参照してください: http://bugs.sun.com/view_bug.do?bug_id=6749060

Java = または J6u12 以上で再度テストしてもまだバグが見られる場合は、Sun のバグ データベースでコメントできる RFE があります。

Java プラットフォームで問題を解決するには、次のいずれかを行います。

  1. Sun の BugParade でバグ レポートに投票して優先順位を上げ、Sun/Oracle プログラマーがそれに到達するまで待つか、
  2. Java はオープンソースになったので、自分で修正してください。(ho.io/jkp5 のメーリング リストに参加してください :-)

投票またはコメントしたい Bugparade レポートはここにあります (j6u12 でテストし、まだ存在する場合): ho.io/jkp2

既知の回避策を実装して、古い JRE でもテキストが適切に表示されるようにする場合は、ここで回避策を提供します。

URL: ho.io/jkpy

「必要な前景色とコンポーネントの背景色を混ぜて半透明性をエミュレートするために使用しているソリューションは、ネイティブ ラスタライザーが確実に使用されるようにするための方法のようです。」

幸運を!

于 2011-01-15T10:38:22.797 に答える
0

フォントスタイルからポイントを取るGASPを使用しているからだと思います。VALUE_TEXT_ANTIALIAS_DEFAULT と VALUE_ALPHA_INTERPOLATION_DEFAULT を使用してみましたか? 試してみる価値があります。

http://download.oracle.com/javase/6/docs/api/java/awt/RenderingHints.html

于 2010-12-28T05:03:04.643 に答える