Java font diacritics support check
Having a Java application that generates image text or PDFs, you may sometimes want to verify the supported fonts. Usually, when generating text, you can choose the typeface (e.g., serif, sans-serif, monospaced) or/and a specific font name (e.g., Consolas). Not having a WYSIWYG editor that shares the same environment and fonts, you may end up with question marks in the generated text on the target environment. Thus, It's important for the fonts to be dockerized under some shared base image.
Java AWT Fonts
For a quick verification of available fonts and their support for specific characters (e.g. diacritics), take a look at the AWT (Abstract Window Toolkit) API. The AWT package interfaces that the Java libraries use to load fonts can do more than just the font listing. It can also verify whether the font fully supports the display of some specific characters.
To get the graphical environment and then the list of loaded fonts, use the static function
GraphicsEnvironment.getLocalGraphicsEnvironment()
and call the getAllFonts()
method on the returned object.
We can then check (canDisplayUpTo()
) whether the font is able to display some given text. If it returns the value of -1,
all characters specified in the parameter are supported by this font.
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
class FontDiag {
public static void main(String... args) {
if (args == null || args.length != 1) {
System.out.println("Usage: FontDiag.main(\"<your_font_characters>\")");
return;
}
String fontCharacters = args[0];
System.out.printf("Verifying which fonts support the following characters: %s%n%n", fontCharacters);
GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
List<Font> fonts = Arrays.asList(environment.getAllFonts());
fonts.sort(Comparator.comparing(Font::getFontName));
List<Font> supportedFonts = new ArrayList<>();
for (Font font : fonts) {
if (font.canDisplayUpTo(fontCharacters) == -1) {
supportedFonts.add(font);
}
}
System.out.printf("All fonts: %s%n%n", fonts.stream().map(Font::getFontName).toList());
System.out.printf("Supported fonts: %s%n%n", supportedFonts.stream().map(Font::getFontName).toList());
System.out.printf("Supported font families: %s%n%n", supportedFonts.stream().map(Font::getFamily).collect(Collectors.toSet()));
}
}
You can compile the above program using the javac
tool and run it by specifying the text with the characters to be verified java FontDiag "abc"
.
In response, it will display all loaded fonts and lastly, only those that can display the text fully, broken down into
names and families. The easiest way to run it, however, is to invoke this program in the jshell
: