default the font to java's SansSerif logical font

resolves to a native generic sans on every os (Arial/Helvetica on
windows/mac, DejaVu/Liberation on linux); other installed system font
families can also be picked by name without dropping a file, files in
fros/fonts/ still take priority
This commit is contained in:
froslanz
2026-10-22 11:34:30 -04:00
parent e453c948cc
commit 7b4fc41dba
2 changed files with 49 additions and 11 deletions
@@ -16,7 +16,7 @@ import static cc.fros.features.commands.MessageSignatures.GENERAL;
public class ClickGuiModule extends Module {
private static ClickGuiModule INSTANCE;
public final Setting<String> font = str("Font", "");
public final Setting<String> font = str("Font", "SansSerif");
public final Setting<Integer> fontSize = num("FontSize", 10, 6, 24);
public final Setting<String> prefix = str("Prefix", ".");
public final Setting<Color> color = color("Color", 0, 0, 255, 180);
+48 -10
View File
@@ -50,6 +50,14 @@ public final class FrosFont {
};
private static final char[] HEX = "0123456789abcdef".toCharArray();
// java guarantees these logical fonts on every os
private static final Map<String, String> LOGICAL_FONTS = Map.of(
"sansserif", "SansSerif",
"serif", "Serif",
"monospaced", "Monospaced");
private static String[] installedFamilies;
private static final Map<Key, Glyph> GLYPHS = new LinkedHashMap<>(128, 0.75f, true) {
@Override
protected boolean removeEldestEntry(Map.Entry<Key, Glyph> eldest) {
@@ -159,18 +167,19 @@ public final class FrosFont {
if (name.isBlank()) return;
try {
Path file = resolveFontFile(name);
if (file == null) {
if (verbose) LOGGER.warn("Font '{}' not found in {}", name, FONT_DIR);
if (file != null) {
applyFont(java.awt.Font.createFont(java.awt.Font.TRUETYPE_FONT, file.toFile()),
size, "Loaded font " + file.getFileName(), verbose);
return;
}
awtFont = java.awt.Font.createFont(java.awt.Font.TRUETYPE_FONT, file.toFile())
.deriveFont(java.awt.Font.PLAIN, size);
BufferedImage probe = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics = probe.createGraphics();
graphics.setFont(awtFont);
metrics = graphics.getFontMetrics();
graphics.dispose();
if (verbose) LOGGER.info("Loaded font {} ({}pt)", file.getFileName(), size);
java.awt.Font installed = installedFont(name);
if (installed != null) {
applyFont(installed, size, "Using system font '" + name + "'", verbose);
return;
}
if (verbose) LOGGER.warn("Font '{}' not found in {}", name, FONT_DIR);
} catch (Exception e) {
LOGGER.error("Failed to load font '{}'", name, e);
awtFont = null;
@@ -178,6 +187,35 @@ public final class FrosFont {
}
}
private static void applyFont(java.awt.Font font, float size, String source, boolean verbose) {
awtFont = font.deriveFont(java.awt.Font.PLAIN, size);
BufferedImage probe = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics = probe.createGraphics();
graphics.setFont(awtFont);
metrics = graphics.getFontMetrics();
graphics.dispose();
if (verbose) LOGGER.info("{} ({}pt)", source, size);
}
/**
* Resolves java's logical fonts (guaranteed on every os) and any font
* family already installed on the system, without needing a file.
*/
private static java.awt.Font installedFont(String name) {
String logical = LOGICAL_FONTS.get(name.toLowerCase(Locale.ROOT));
if (logical != null) return new java.awt.Font(logical, java.awt.Font.PLAIN, 1);
if (installedFamilies == null) {
installedFamilies = java.awt.GraphicsEnvironment
.getLocalGraphicsEnvironment()
.getAvailableFontFamilyNames();
}
for (String family : installedFamilies) {
if (family.equalsIgnoreCase(name)) return new java.awt.Font(family, java.awt.Font.PLAIN, 1);
}
return null;
}
private static Path resolveFontFile(String name) {
try {
Files.createDirectories(FONT_DIR);