Mainly small fonts are looking really bad compared with SWT fonts.
With autoScale=100 (for none 4k displays) the AWT font rendering is as good as SWT but autoScale > 100 has this issue.
Is there any AWT/SWT parameter to disable AWT font/image scaling when swt.autoScale > 100 ?
package test4k;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.PaletteData;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class SWTvsAWT_FontsAndImages {
private static int AUTO_SCALE;
private static int IMAGE_WIDTH;
private static int IMAGE_HEIGHT;
private static final String FONT_NAME = "Segoe UI";
private static int[] FONT_SIZE;
private static final int MARGIN = 2;
private static final int SHELL_X = 1500;
private static final int SHELL_Y = 100;
private static final int FOREGROUND_COLOR_SWT = SWT.COLOR_BLACK;
private static final int BACKGROUND_COLOR_SWT = SWT.COLOR_WHITE;
private static final java.awt.Color FOREGROUND_COLOR_AWT = java.awt.Color.black;
private static final java.awt.Color BACKGROUND_COLOR_AWT = java.awt.Color.white;
private static Display _swtDisplay;
private static Font[] _swtFont;
private static int[] _swtFontHeight;
static {
AUTO_SCALE = 200;
AUTO_SCALE = 100;
AUTO_SCALE = 150;
FONT_SIZE = new int[] {
10,
12,
16,
20,
24,
// 28,
36
};
System.setProperty("swt.autoScale", Integer.toString(AUTO_SCALE));
_swtDisplay = new Display();
int numFonts = FONT_SIZE.length;
int allFontHeights = 0;
_swtFont = new Font[numFonts];
_swtFontHeight = new int[numFonts];
for (int fontIndex = 0; fontIndex < numFonts; fontIndex++) {
Font swtFont = new Font(_swtDisplay, FONT_NAME, FONT_SIZE[fontIndex], SWT.NORMAL);
FontData swtFontData = swtFont.getFontData()[0];
int fontHeight = swtFontData.getHeight();
_swtFont[fontIndex] = swtFont;
_swtFontHeight[fontIndex] = fontHeight;
allFontHeights += fontHeight;
}
IMAGE_WIDTH = 1500;
IMAGE_HEIGHT = (int) (allFontHeights * 1.8);
}
private static String getTestText(int fontIndex) {
return " autoScale=%d FONT SIZE=%d".formatted(AUTO_SCALE, FONT_SIZE[fontIndex]);
}
private static Image convertAWTtoSWT(final BufferedImage awtImage) {
final int imageWidth = awtImage.getWidth();
final int imageHeight = awtImage.getHeight();
final ImageData swtImageData = new ImageData(imageWidth, imageHeight, 24, new PaletteData(0xFF0000, 0xFF00, 0xFF));
final int scansize = (((imageWidth * 3) + 3) * 4) / 4;
final WritableRaster alphaRaster = awtImage.getAlphaRaster();
final byte[] alphaBytes = new byte[imageWidth];
for (int y = 0; y < imageHeight; y++) {
final int[] buff = awtImage.getRGB(0, y, imageWidth, 1, null, 0, scansize);
swtImageData.setPixels(0, y, imageWidth, buff, 0);
if (alphaRaster != null) {
final int[] alpha = alphaRaster.getPixels(0, y, imageWidth, 1, (int[]) null);
for (int i = 0; i < imageWidth; i++) {
alphaBytes[i] = (byte) alpha[i];
}
swtImageData.setAlphas(0, y, imageWidth, alphaBytes, 0);
}
}
return new Image(_swtDisplay, swtImageData);
}
private static BufferedImage createAWTImage() {
final BufferedImage awtImage = new BufferedImage(IMAGE_WIDTH, IMAGE_HEIGHT, BufferedImage.TYPE_4BYTE_ABGR);
final Graphics2D g2d = awtImage.createGraphics();
try {
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setBackground(BACKGROUND_COLOR_AWT);
g2d.clearRect(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);
int devY = 0;
for (int fontIndex = 0; fontIndex < FONT_SIZE.length; fontIndex++) {
java.awt.Font font = new java.awt.Font(FONT_NAME, java.awt.Font.PLAIN, FONT_SIZE[fontIndex]);
g2d.setFont(font);
final FontMetrics fontMetrics = g2d.getFontMetrics();
final int textHeight = fontMetrics.getHeight();
devY += textHeight;
g2d.setColor(FOREGROUND_COLOR_AWT);
g2d.drawString(" AWT" + getTestText(fontIndex), MARGIN, devY);
}
} finally {
g2d.dispose();
}
return awtImage;
}
private static Image createSWTImage() {
final Image swtImage = new Image(_swtDisplay, IMAGE_WIDTH, IMAGE_HEIGHT);
final GC gc = new GC(swtImage);
{
gc.setAntialias(SWT.ON);
gc.setBackground(_swtDisplay.getSystemColor(BACKGROUND_COLOR_SWT));
gc.fillRectangle(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);
int devY = 0;
for (int fontIndex = 0; fontIndex < FONT_SIZE.length; fontIndex++) {
gc.setFont(_swtFont[fontIndex]);
gc.setForeground(_swtDisplay.getSystemColor(FOREGROUND_COLOR_SWT));
gc.drawString(" SWT" + getTestText(fontIndex), MARGIN, devY, true);
devY += _swtFontHeight[fontIndex] + 10;
}
}
gc.dispose();
return swtImage;
}
public static void main(final String[] args) {
final Image swtImage = createSWTImage();
final BufferedImage awtImage = createAWTImage();
final Image swtImageFromAwt = convertAWTtoSWT(awtImage);
final Shell shell = new Shell(_swtDisplay);
shell.setText("SWT vs AWT scaling");
shell.setLocation(SHELL_X, SHELL_Y);
shell.setSize(IMAGE_WIDTH + 50, IMAGE_HEIGHT * 2 + 30);
shell.addListener(SWT.Paint, event -> {
int devY = MARGIN;
GC gc = event.gc;
gc.drawImage(swtImage, MARGIN, devY);
devY += IMAGE_HEIGHT + MARGIN;
gc.drawImage(swtImageFromAwt, MARGIN, devY);
});
shell.open();
while (!shell.isDisposed()) {
if (!_swtDisplay.readAndDispatch()) {
_swtDisplay.sleep();
}
}
swtImage.dispose();
swtImageFromAwt.dispose();
for (Font font : _swtFont) {
font.dispose();
}
_swtDisplay.dispose();
}
}
Describe the bug
Mainly small fonts are looking really bad compared with SWT fonts.
Why do I use AWT fonts? SWT has a limit with antialiasing when drawing into an image, see here mytourbook/mytourbook#1376 (comment)
With autoScale=100 (for none 4k displays) the AWT font rendering is as good as SWT but autoScale > 100 has this issue.
Is there any AWT/SWT parameter to disable AWT font/image scaling when swt.autoScale > 100 ?
To Reproduce
Expected behavior
AWT within SWT should scale fonts with the same quality as SWT
Screenshots
This screenshot should be viewed without github scaling !
Environment:
Additional OS info (e.g. OS version, Linux Desktop, etc)
Windows 10
JRE/JDK version
java.vendor.version=Temurin-21.0.4+7
Version since
4.23 and older
Workaround (or) Additional context
Have not yet found