remove the HUDScale slider

FontSize already scales the hud's text, and the extra pose scaling
complicated every hit test, drag clamp and glyph raster. HUD elements
draw unscaled again; FrosFont keeps per-gui-scale raster states so a
window scale change still never clears the glyph cache.
This commit is contained in:
froslanz
2026-10-24 17:20:05 -04:00
parent 53630c5ea3
commit 3d2383766e
3 changed files with 18 additions and 60 deletions
@@ -18,7 +18,6 @@ public class ClickGuiModule extends Module {
public final Setting<String> font = str("Font", "SansSerif"); public final Setting<String> font = str("Font", "SansSerif");
public final Setting<Integer> fontSize = num("FontSize", 10, 6, 24); public final Setting<Integer> fontSize = num("FontSize", 10, 6, 24);
public final Setting<Float> hudScale = num("HUDScale", 1.0f, 0.5f, 2.0f);
public final Setting<String> prefix = str("Prefix", "."); public final Setting<String> prefix = str("Prefix", ".");
public final Setting<Color> color = color("Color", 0, 0, 255, 180); public final Setting<Color> color = color("Color", 0, 0, 255, 180);
public final Setting<Color> topColor = color("TopColor", 0, 0, 150, 240); public final Setting<Color> topColor = color("TopColor", 0, 0, 150, 240);
@@ -74,9 +73,4 @@ public class ClickGuiModule extends Module {
public static ClickGuiModule getInstance() { public static ClickGuiModule getInstance() {
return INSTANCE; return INSTANCE;
} }
/** scale factor applied to the client's own hud modules */
public static float hudScale() {
return INSTANCE == null ? 1f : Math.max(0.5f, INSTANCE.hudScale.getValue());
}
} }
@@ -37,40 +37,19 @@ public abstract class HudModule extends Module {
} }
public float getY() { public float getY() {
float scaledHeight = getHeight() * ClickGuiModule.hudScale();
float heightWithChat = mc.getWindow().getGuiScaledHeight() - 14; float heightWithChat = mc.getWindow().getGuiScaledHeight() - 14;
float baseY = mc.getWindow().getGuiScaledHeight() * pos.getValue().y(); float baseY = mc.getWindow().getGuiScaledHeight() * pos.getValue().y();
float combined = baseY + scaledHeight; float combined = baseY + getHeight();
if (mc.screen instanceof ChatScreen) { if (mc.screen instanceof ChatScreen) {
baseY = Math.min(combined, heightWithChat) - scaledHeight; baseY = Math.min(combined, heightWithChat) - getHeight();
} }
return baseY; return baseY;
} }
@Subscribe @Subscribe
public void onRender2DHud(Render2DEvent e) { public void onRender2DHud(Render2DEvent e) {
float scale = ClickGuiModule.hudScale(); render(e);
// glyphs rasterize for the hud's transform so they stay crisp
FrosFont.setContextScale(scale);
if (scale == 1f) {
render(e);
return;
}
// scale the element about its own position anchor so content,
// editor box and hover label all grow together
float anchorX = getX();
float anchorY = getY();
e.getContext().pose().pushMatrix();
e.getContext().pose().translate(anchorX * (1f - scale), anchorY * (1f - scale));
e.getContext().pose().scale(scale, scale);
try {
render(e);
} finally {
e.getContext().pose().popMatrix();
// everything else in the frame draws unscaled
FrosFont.setContextScale(1f);
}
} }
@Subscribe @Subscribe
@@ -103,14 +82,13 @@ public abstract class HudModule extends Module {
} }
if (dragging) { if (dragging) {
float scale = ClickGuiModule.hudScale(); float maxX = mc.getWindow().getGuiScaledWidth() - width;
float maxX = mc.getWindow().getGuiScaledWidth() - width * scale; float maxY = mc.getWindow().getGuiScaledHeight() - height;
float maxY = mc.getWindow().getGuiScaledHeight() - height * scale;
float rawX = Math.min(Math.max(getMouseX() - dragX, 0), maxX); float rawX = Math.min(Math.max(getMouseX() - dragX, 0), maxX);
float rawY = Math.min(Math.max(getMouseY() - dragY, 0), maxY); float rawY = Math.min(Math.max(getMouseY() - dragY, 0), maxY);
// snap to other elements first, grid otherwise, then re-clamp // snap to other elements first, grid otherwise, then re-clamp
float snappedX = Math.min(Math.max(snapAxis(rawX, width * scale, true, scale), 0), maxX); float snappedX = Math.min(Math.max(snapAxis(rawX, width, true), 0), maxX);
float snappedY = Math.min(Math.max(snapAxis(rawY, height * scale, false, scale), 0), maxY); float snappedY = Math.min(Math.max(snapAxis(rawY, height, false), 0), maxY);
pos.setValue(new Vector2f(snappedX, snappedY) pos.setValue(new Vector2f(snappedX, snappedY)
.div(mc.getWindow().getGuiScaledWidth(), mc.getWindow().getGuiScaledHeight())); .div(mc.getWindow().getGuiScaledWidth(), mc.getWindow().getGuiScaledHeight()));
@@ -127,10 +105,9 @@ public abstract class HudModule extends Module {
if (shouldDrawDescription) { if (shouldDrawDescription) {
int textWidth = FrosFont.width(getName()); int textWidth = FrosFont.width(getName());
int textHeight = FrosFont.lineHeight(); int textHeight = FrosFont.lineHeight();
float scale = ClickGuiModule.hudScale();
float textX = x + width + 5; float textX = x + width + 5;
// the label is drawn inside the element's scale transform // flip the label to the other side when it would leave the screen
if (x + (textX + textWidth - x) * scale > mc.getWindow().getGuiScaledWidth()) { if (textX + textWidth > mc.getWindow().getGuiScaledWidth()) {
textX = x - 5 - textWidth; textX = x - 5 - textWidth;
} }
FrosFont.draw(e.getContext(), getName(), FrosFont.draw(e.getContext(), getName(),
@@ -163,10 +140,9 @@ public abstract class HudModule extends Module {
float y = getY(); float y = getY();
int mouseX = getMouseX(); int mouseX = getMouseX();
int mouseY = getMouseY(); int mouseY = getMouseY();
float scale = ClickGuiModule.hudScale();
return mouseX >= x - 1 && mouseX <= x + width * scale + 1 && return mouseX >= x - 1 && mouseX <= x + width + 1 &&
mouseY >= y - 1 && mouseY <= y + height * scale + 1; mouseY >= y - 1 && mouseY <= y + height + 1;
} }
/** /**
@@ -174,14 +150,14 @@ public abstract class HudModule extends Module {
* top/middle/bottom) when within {@link #SNAP_RANGE}; otherwise rounds * top/middle/bottom) when within {@link #SNAP_RANGE}; otherwise rounds
* onto the {@link #SNAP_GRID} grid so everything stays tidy. * onto the {@link #SNAP_GRID} grid so everything stays tidy.
*/ */
private float snapAxis(float position, float size, boolean horizontal, float scale) { private float snapAxis(float position, float size, boolean horizontal) {
float bestDelta = 0f; float bestDelta = 0f;
boolean aligned = false; boolean aligned = false;
for (HudModule other : hudModules()) { for (HudModule other : hudModules()) {
if (other == this || !other.isEnabled()) continue; if (other == this || !other.isEnabled()) continue;
float otherPos = horizontal ? other.getX() : other.getY(); float otherPos = horizontal ? other.getX() : other.getY();
float otherSize = horizontal ? other.getWidth() * scale : other.getHeight() * scale; float otherSize = horizontal ? other.getWidth() : other.getHeight();
float[] mine = {position, position + size / 2f, position + size}; float[] mine = {position, position + size / 2f, position + size};
float[] theirs = {otherPos, otherPos + otherSize / 2f, otherPos + otherSize}; float[] theirs = {otherPos, otherPos + otherSize / 2f, otherPos + otherSize};
for (float mineAnchor : mine) { for (float mineAnchor : mine) {
@@ -74,16 +74,15 @@ public final class FrosFont {
private record Glyph(Identifier id, int width, int height) { private record Glyph(Identifier id, int width, int height) {
} }
/** a raster font for one ui scale; the clickgui and the scaled hud each get their own */ /** a raster font for one ui scale */
private record FontState(java.awt.Font font, FontMetrics metrics, float visualCenterRaster) { private record FontState(java.awt.Font font, FontMetrics metrics, float visualCenterRaster) {
} }
// the family picked in the settings, independent of any scale // the family picked in the settings, independent of any scale
private static java.awt.Font baseFont; private static java.awt.Font baseFont;
// one raster state per ui scale, so a gui scale change never
// invalidates the glyph cache
private static final Map<Float, FontState> STATES = new HashMap<>(); private static final Map<Float, FontState> STATES = new HashMap<>();
// outer transform applied by the hud's render pose; glyphs rasterize for
// it so they stay 1:1 device pixels at any hud scale
private static float contextScale = 1f;
// current state pointers, re-pointed by sync() for the active context // current state pointers, re-pointed by sync() for the active context
private static java.awt.Font awtFont; private static java.awt.Font awtFont;
@@ -95,16 +94,6 @@ public final class FrosFont {
private static float visualCenterRaster = 4f; private static float visualCenterRaster = 4f;
private static int glyphCounter; private static int glyphCounter;
/**
* Sets the ui transform currently applied to drawing outside this class.
* hud modules scale their pose by HUDScale, so glyphs rasterize larger for
* them; the unscaled clickgui keeps its own, so switching between the two
* never invalidates the other's glyph cache.
*/
public static void setContextScale(float scale) {
contextScale = Math.max(0.5f, scale);
}
private FrosFont() { private FrosFont() {
} }
@@ -134,9 +123,8 @@ public final class FrosFont {
private static float currentScale() { private static float currentScale() {
try { try {
// one raster pixel per screen pixel, following mc's gui scale and // one raster pixel per screen pixel, following mc's gui scale
// the hud's own scale (contextScale) return Math.max(0.5f, (float) mc.getWindow().getGuiScale());
return Math.max(0.5f, (float) (mc.getWindow().getGuiScale() * contextScale));
} catch (Exception e) { } catch (Exception e) {
return 1f; return 1f;
} }