Frage Wie erzwinge ich Java-Text-Antialiasing?


Laufendes Xilinx Vivado FPGA-Design-Tool in Kubuntu 14.04 verwendet antialiased Schriftarten nur in einigen Teilen der Benutzeroberfläche, so dass es sogar schwer zu bedienen, um nicht zu sagen hässlich aussehende. Andere scheinen dasselbe zu haben Problem.

Wie es scheint zumindest teilweise in Java geschrieben zu sein, habe ich versucht, die vorgeschlagenen Lösungen nach einigem googlen gefunden

export _JAVA_OPTIONS="-Dawt.useSystemAAFontSettings=on -Dswing.aatext=true -Dsun.java2d.xrender=true"

ohne visuelle Wirkung.

Ein kleines Testprogramm unten machte es offensichtlich, dass die Font - Rendering - Hinweise explizit gesetzt sind (aber nicht auf RenderingHints.KEY_TEXT_ANTIALIASING) erhalten Sie nicht-antialiased Text. Dies geschieht sowohl in OpenJDK als auch in Oracle JDK.

import java.awt.*;
import java.awt.event.*;

// partially taken from http://stackoverflow.com/questions/2018102/java-font-rendering                                                     

public class AwtAA extends Panel {

    private final Font font = new Font(Font.SANS_SERIF, Font.BOLD, 16);
    private final int line = 24;
    private final int medskip = 16;

    AwtAA() {
    setBackground(SystemColor.control);
    }

    public void paint(Graphics g) {
    Graphics2D g2d = (Graphics2D)g;
    int py = 0;

    py = paintText(g2d, py, null, null);
    py += medskip;

    py = paintText(g2d, py, null, RenderingHints.VALUE_ANTIALIAS_DEFAULT);
    py = paintText(g2d, py, null, RenderingHints.VALUE_ANTIALIAS_ON);
    py += medskip;

    py = paintText(g2d, py, RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT, null);
    py = paintText(g2d, py, RenderingHints.VALUE_TEXT_ANTIALIAS_ON,      null);
    py += medskip;

    py = paintText(g2d, py, RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT, RenderingHints.VALUE_ANTIALIAS_DEFAULT);
    py = paintText(g2d, py, RenderingHints.VALUE_TEXT_ANTIALIAS_ON,      RenderingHints.VALUE_ANTIALIAS_DEFAULT);
    py += medskip;

    py = paintText(g2d, py, RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT, RenderingHints.VALUE_ANTIALIAS_ON);
    py = paintText(g2d, py, RenderingHints.VALUE_TEXT_ANTIALIAS_ON,      RenderingHints.VALUE_ANTIALIAS_ON);
    }

    private int paintText(Graphics2D g2d, int py, Object text, Object aa) {
    Graphics2D dgc = g2d;
    Image img = null;

    String text_aa = "none";
    if (text != null) {
        if (text.equals(RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT)) text_aa = "VALUE_TEXT_ANTIALIAS_DEFAULT";
        if (text.equals(RenderingHints.VALUE_TEXT_ANTIALIAS_OFF)) text_aa = "VALUE_TEXT_ANTIALIAS_OFF";
        if (text.equals(RenderingHints.VALUE_TEXT_ANTIALIAS_ON)) text_aa = "VALUE_TEXT_ANTIALIAS_ON";
    }

    String value_aa = "none";
    if (aa != null) {
        if (aa.equals(RenderingHints.VALUE_ANTIALIAS_DEFAULT)) value_aa = "VALUE_ANTIALIAS_DEFAULT";
        if (aa.equals(RenderingHints.VALUE_ANTIALIAS_OFF)) value_aa = "VALUE_ANTIALIAS_OFF";
        if (aa.equals(RenderingHints.VALUE_ANTIALIAS_ON)) value_aa = "VALUE_ANTIALIAS_ON";
    }

    char[] txt = ("ABCDEFGHIJKLMNOPQRSTUVWXYZ (" + text_aa + ", " + value_aa + ")").toCharArray();
    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 (text != null) dgc.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, text);
    if (aa != null) dgc.setRenderingHint(RenderingHints.KEY_ANTIALIASING, aa);

    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 AwtAA());
    wnd.setSize(new Dimension(850, 330));
    wnd.setVisible(true);
    }
}

Die Frage ist also, wie ich den Standardwert ändern soll (entweder keine Hinweise gesetzt oder auf gesetzt) VALUE_TEXT_ANTIALIAS_DEFAULT) um Antialiasing beim Font Rendering zu verwenden?

Da alle Antworten, die ich finden konnte, um diese wenigen Eigenschaften oben festgelegt wurden, fing ich an, auf die Quelle zu schauen ... und machte eine grobe "Reparatur" in openjdk-7 in der Klasse SunGraphics2D Konstrukteur:

apt-get source openjdk-7-jre
cd openjdk-7-7u55-2.4.7
tar zxf jdk.tar.gz

cd jdk-9448fff93286/src/share/classes/sun/java2d
patch -p1 <<"__EOF__"
--- a/SunGraphics2D.java    2014-06-29 23:39:34.183177958 +0300
+++ b/SunGraphics2D.java    2014-06-29 23:39:18.675177667 +0300
@@ -244,7 +244,10 @@

         renderHint = SunHints.INTVAL_RENDER_DEFAULT;
         antialiasHint = SunHints.INTVAL_ANTIALIAS_OFF;
-        textAntialiasHint = SunHints.INTVAL_TEXT_ANTIALIAS_DEFAULT;
+        textAntialiasHint = SunHints.INTVAL_TEXT_ANTIALIAS_ON;
         fractionalMetricsHint = SunHints.INTVAL_FRACTIONALMETRICS_OFF;
         lcdTextContrast = lcdTextContrastDefaultValue;
         interpolationHint = -1;
__EOF__
javac SunGraphics2D.java
cd ../..
jar cvf /tmp/rt.jar sun/java2d/SunGraphics2D.class

und dann lief es als

java -Xbootclasspath/p:/tmp/rt.jar AwtAA

Und das machte den Test für das Testprogramm und auch für das Vivado-Tool (außer Vidado wird irgendwie anders gestartet und scheint nicht zu Ehren -Xbootclasspath, also musste ich das wirklich updaten SunGraphics2D Klasse im System rt.jar). Dies scheint mit OpenJDK und Oracle zu funktionieren.

Und die letzte Frage ... es muss nur eine andere Art sein, um antialiased Text als Standard als Affe Patching System Gläser zu zwingen?


6
2018-06-30 18:31


Ursprung


Antworten:


Danke für die Patched-Jar-Lösung, es funktioniert, wenn auch ein bisschen unordentlich.

Ich weiß nicht, ob es eine bessere Möglichkeit gibt, den Antialias-Text zu erzwingen, als das Glas zu patchen, aber es ist möglich, das Folgende zu benutzen, bevor man Vivado startet, um das Patch zu benutzen rt.jar ohne das Hauptsystem zu ersetzen:

export _JAVA_OPTIONS="-Xbootclasspath/p:<PATH TO JAR>/rt.jar"

ersetzen <PATH TO JAR> mit wo auch immer Sie das geflickte setzen rt.jar (Ich benutze /opt/Xilinx/Vivado/)


2
2017-08-16 14:28