Search code examples
javaunicodefontsawtgraphics2d

Can't render unicode characters with Graphics2D even though they are supported by the font


I try to render text to a BufferedImage and that works quite great but I can't render any characters that are not ASCII (at least as far as I can see). All I could find was that it's because of the font so I downloaded Google's "Noto" fonts that seem to support literally every script but I still get the boxes.

I'm not even trying to render something particularly exotic. Only German umlauts and the sharp s (Ää Öö Üü ß).

I create the font like this

Font font = Font.createFont(Font.TRUETYPE_FONT, new FileInputStream("NotoSans-Regular.ttf")).deriveFont(12f);

And render the whole thing like this

Graphics2D g2 = image.createGraphics();
g2.setFont(font);
g2.setColor(Color.white);
g2.drawString(string, 0, g2.getFontMetrics().getAscent());
g2.dispose();

It works with ASCII.

Google either lead me to very simple tutorials (which is literally the code I've got at the moment) or says that the problem is the font but it isn't since it works perfectly in the editor.

Thanks

Edit1: Here my full code

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class Test {
    public static void main(String[] args) throws IOException, FontFormatException {
        String string = "ÄäÖöÜüß";
        BufferedImage image;

        Font font = Font.createFont(Font.TRUETYPE_FONT, new FileInputStream("NotoSans-Regular.ttf")).deriveFont(50f);
        Rectangle2D rec = font.getStringBounds(string, new FontRenderContext(null, false, false));
        image = new BufferedImage((int)rec.getWidth(), (int)rec.getHeight(), BufferedImage.TYPE_INT_RGB);

        Graphics2D g2 = image.createGraphics();
        g2.setFont(font);
        g2.setColor(Color.white);
        g2.drawString(string, 0, g2.getFontMetrics().getAscent());
        g2.dispose();

        File f = new File("image.png");
        if (!f.exists()) {
            if (!f.createNewFile()) {
                System.err.println("Can't create image file.");
            }
        }
        ImageIO.write(image, "png", f);
    }
}

The font can be downloaded here from google

And this is my result

Result

I think I got the quads generally with all other fonts. It compiles and saves the result in a PNG.

And it works with ASCII characters.

Sorry for not using proper images but I can't do that without at least 10 reputation.

Edit2: It works now but not on my PC. It works on Linux if I recompile, though...

Edit3: Same with the newest JDK.


Solution

  • I'm an idiot... sometimes I wonder how I get through the day without accidentally getting myself killed...

    If you can't use a unicode string properly and you couldn't find an answer even after fighting with Google for 2 days, check the encoding of your source file... Mine was set to Windows-1252...