darken colored text segments when rasterizing shadows

the shadow pass only darkened the base color, so any segment with an
explicit color code (the watermark's accent from {global}, the slider
value's section-7 gray) punched through at full brightness, drawing a
colored ghost one pixel off the text. shadow rasters now pass the
original color plus a shadow flag, and every segment is darkened at
flush time with the vanilla rule ((c & 0xFCFCFC) >> 2, alpha kept), so
accent text gets a dark accent shadow and gray gets a dark gray one
This commit is contained in:
froslanz
2026-10-22 13:19:07 -04:00
parent 9b6a55d66c
commit 7fc42b34d8
+15 -11
View File
@@ -72,7 +72,7 @@ public final class FrosFont {
private static final List<Identifier> PENDING_RELEASE = new ArrayList<>();
private static long lastQueuedAt;
private record Key(int color, String text) {
private record Key(int color, String text, boolean shadow) {
}
private record Glyph(Identifier id, int width, int height) {
@@ -142,8 +142,8 @@ public final class FrosFont {
context.drawString(mc.font, text, x, y, color, shadow);
return;
}
if (shadow) drawGlyphs(context, text, x + 1, y + 1, shadowColor(color));
drawGlyphs(context, text, x, y, color);
if (shadow) drawGlyphs(context, text, x + 1, y + 1, color, true);
drawGlyphs(context, text, x, y, color, false);
}
public static void draw(GuiGraphics context, Component component, int x, int y, int color) {
@@ -319,12 +319,12 @@ public final class FrosFont {
// --- rasterizing ---
private static void drawGlyphs(GuiGraphics context, String text, int x, int y, int color) {
private static void drawGlyphs(GuiGraphics context, String text, int x, int y, int color, boolean shadow) {
flushReleases();
Key key = new Key(color, text);
Key key = new Key(color, text, shadow);
Glyph glyph = GLYPHS.get(key);
if (glyph == null) {
glyph = createGlyph(text, color);
glyph = createGlyph(text, color, shadow);
if (glyph == null) return;
GLYPHS.put(key, glyph);
}
@@ -341,7 +341,7 @@ public final class FrosFont {
context.pose().popMatrix();
}
private static Glyph createGlyph(String text, int baseColor) {
private static Glyph createGlyph(String text, int baseColor, boolean shadow) {
String plain = stripCodes(text);
if (plain.isEmpty()) return null;
@@ -355,7 +355,7 @@ public final class FrosFont {
Graphics2D graphics = image.createGraphics();
graphics.setFont(awtFont);
graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
drawSegments(graphics, text, baseColor);
drawSegments(graphics, text, baseColor, shadow);
graphics.dispose();
NativeImage nativeImage = new NativeImage(imageWidth, imageHeight, false);
@@ -377,7 +377,7 @@ public final class FrosFont {
return new Glyph(id, imageWidth, imageHeight);
}
private static void drawSegments(Graphics2D graphics, String text, int baseColor) {
private static void drawSegments(Graphics2D graphics, String text, int baseColor, boolean shadow) {
int baseline = metrics.getAscent() + Math.round(loadedScale);
int cursor = 1;
int current = baseColor;
@@ -386,7 +386,10 @@ public final class FrosFont {
while (i < text.length()) {
if (text.charAt(i) == '\u00A7' && i + 1 < text.length()) {
cursor = flush(graphics, text, segmentStart, i, cursor, current, baseline);
// colored segments darken like vanilla's shadows do, instead
// of punching through at full brightness
cursor = flush(graphics, text, segmentStart, i, cursor,
shadow ? shadowColor(current) : current, baseline);
char code = Character.toLowerCase(text.charAt(i + 1));
i += 2;
@@ -414,7 +417,8 @@ public final class FrosFont {
}
i++;
}
flush(graphics, text, segmentStart, text.length(), cursor, current, baseline);
flush(graphics, text, segmentStart, text.length(), cursor,
shadow ? shadowColor(current) : current, baseline);
}
private static int flush(Graphics2D graphics, String text, int start, int end, int cursor, int color, int baseline) {