Running Xilinx Vivado FPGA design tool in Kubuntu 14.04 it uses antialiased fonts pnly in some parts of the UI making it even hard to use, not to say ugly looking. Others seem to have same issue.
As it seems to be written at least partially in Java, I tried the suggested solutions found after some googling
export _JAVA_OPTIONS="-Dawt.useSystemAAFontSettings=on -Dswing.aatext=true -Dsun.java2d.xrender=true"
without any visual effect.
A small test program below made it obvious that unless the font rendering hints are explicitly set (but not to RenderingHints.KEY_TEXT_ANTIALIASING
) you will get non-antialiased text. This happens in both OpenJDK and 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);
}
}
So the question is how do I change the default (either no hints set or set to VALUE_TEXT_ANTIALIAS_DEFAULT
) to use antialiasing in font rendering?
As all the answers I could found went around setting those few properties above, I started to look at the source... and made some crude "fix" into openjdk-7 in class SunGraphics2D
constructor:
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
and then ran it as
java -Xbootclasspath/p:/tmp/rt.jar AwtAA
And this did the trick for the test program and also for the Vivado tool (except Vidado gets launched somehow differently and does not seem to honor -Xbootclasspath
, so I really had to update the SunGraphics2D
class in system rt.jar
). This seems to work with both OpenJDK and Oracle.
And the final question... there just has to be some other way of forcing antialiased text as the default than monkey patching system jars?
Thanks for the patched jar solution, it works, even if a bit messy.
I don't know if there's a better way to force the antialiased text than patching the jar, but it's possible to use the following before launching Vivado to make it use the patched rt.jar
without replacing the main system one:
export _JAVA_OPTIONS="-Xbootclasspath/p:<PATH TO JAR>/rt.jar"
replacing <PATH TO JAR>
with wherever you put the patched rt.jar
(I use /opt/Xilinx/Vivado/
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With