diff --git a/src/main/java/cc/fros/features/gui/FrosGui.java b/src/main/java/cc/fros/features/gui/FrosGui.java index 3157ff0..7b328cc 100644 --- a/src/main/java/cc/fros/features/gui/FrosGui.java +++ b/src/main/java/cc/fros/features/gui/FrosGui.java @@ -146,10 +146,6 @@ public class FrosGui extends Screen { return this.widgets; } - public int getTextOffset() { - return -6; - } - public static Color getColorClipboard() { return colorClipboard; } diff --git a/src/main/java/cc/fros/features/gui/Widget.java b/src/main/java/cc/fros/features/gui/Widget.java index 601ddd7..96acc6a 100644 --- a/src/main/java/cc/fros/features/gui/Widget.java +++ b/src/main/java/cc/fros/features/gui/Widget.java @@ -77,7 +77,8 @@ public class Widget RenderUtil.rect(context, this.x, headerTop, this.x + this.width, panelBottom, 0x99000000, 1.0f); context.fill(this.x, headerBottom - 1, this.x + this.width, headerBottom, accent); - drawString(this.getName(), (float) this.x + 3.0f, (float) this.y - 4.0f - (float) FrosGui.getClickGui().getTextOffset(), -1); + drawString(this.getName(), (float) this.x + 3.0f, + (headerTop + headerBottom) / 2f - FrosFont.visualCenter(), -1); ScissorUtil.enable(context, x, 0, x + width, mc.getWindow().getGuiScaledHeight()); if (this.open) { diff --git a/src/main/java/cc/fros/features/gui/items/Item.java b/src/main/java/cc/fros/features/gui/items/Item.java index 52d1832..aed719c 100644 --- a/src/main/java/cc/fros/features/gui/items/Item.java +++ b/src/main/java/cc/fros/features/gui/items/Item.java @@ -83,6 +83,11 @@ public class Item FrosFont.draw(context, text, (int) x, (int) y, color); } + /** y coordinate that visually centers text inside this item */ + protected float textY() { + return this.y + this.height / 2f - FrosFont.visualCenter(); + } + public boolean isHovering(int mouseX, int mouseY) { return false; } diff --git a/src/main/java/cc/fros/features/gui/items/buttons/BindButton.java b/src/main/java/cc/fros/features/gui/items/buttons/BindButton.java index be8b565..b50c4c2 100644 --- a/src/main/java/cc/fros/features/gui/items/buttons/BindButton.java +++ b/src/main/java/cc/fros/features/gui/items/buttons/BindButton.java @@ -1,7 +1,6 @@ package cc.fros.features.gui.items.buttons; import cc.fros.Fros; -import cc.fros.features.gui.FrosGui; import cc.fros.features.modules.client.ClickGuiModule; import cc.fros.features.settings.Bind; import cc.fros.features.settings.Setting; @@ -29,10 +28,10 @@ public class BindButton int color = ClickGuiModule.getInstance().color.getValue().getRGB(); RenderUtil.rect(context, this.x, this.y, this.x + (float) this.width + 7.4f, this.y + (float) this.height - 0.5f, this.getState() ? (!this.isHovering(mouseX, mouseY) ? 0x11555555 : -2007673515) : (!this.isHovering(mouseX, mouseY) ? Fros.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().color.getValue().getAlpha()) : Fros.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().topColor.getValue().getAlpha()))); if (this.isListening) { - drawString(context, "Press a Key...", this.x + 2.3f, this.y - 1.7f - (float) FrosGui.getClickGui().getTextOffset(), -1); + drawString(context, "Press a Key...", this.x + 2.3f, textY(), -1); } else { String str = KeyboardUtil.getKeyName(setting.getValue()); - drawString(context, this.setting.getName() + " " + ChatFormatting.GRAY + str, this.x + 2.3f, this.y - 1.7f - (float) FrosGui.getClickGui().getTextOffset(), this.getState() ? -1 : -5592406); + drawString(context, this.setting.getName() + " " + ChatFormatting.GRAY + str, this.x + 2.3f, textY(), this.getState() ? -1 : -5592406); } } diff --git a/src/main/java/cc/fros/features/gui/items/buttons/BooleanButton.java b/src/main/java/cc/fros/features/gui/items/buttons/BooleanButton.java index 2bd00f5..b426c01 100644 --- a/src/main/java/cc/fros/features/gui/items/buttons/BooleanButton.java +++ b/src/main/java/cc/fros/features/gui/items/buttons/BooleanButton.java @@ -2,7 +2,6 @@ package cc.fros.features.gui.items.buttons; import cc.fros.Fros; -import cc.fros.features.gui.FrosGui; import cc.fros.features.modules.client.ClickGuiModule; import cc.fros.features.settings.Setting; import cc.fros.util.render.RenderUtil; @@ -23,7 +22,7 @@ public class BooleanButton @Override public void drawScreen(GuiGraphics context, int mouseX, int mouseY, float partialTicks) { RenderUtil.rect(context, this.x, this.y, this.x + (float) this.width + 7.4f, this.y + (float) this.height - 0.5f, this.getState() ? (!this.isHovering(mouseX, mouseY) ? Fros.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().color.getValue().getAlpha()) : Fros.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().topColor.getValue().getAlpha())) : (!this.isHovering(mouseX, mouseY) ? 0x11555555 : -2007673515)); - drawString(context, this.getName(), this.x + 2.3f, this.y - 1.7f - (float) FrosGui.getClickGui().getTextOffset(), this.getState() ? -1 : -5592406); + drawString(context, this.getName(), this.x + 2.3f, textY(), this.getState() ? -1 : -5592406); } @Override diff --git a/src/main/java/cc/fros/features/gui/items/buttons/Button.java b/src/main/java/cc/fros/features/gui/items/buttons/Button.java index 589c096..d114e68 100644 --- a/src/main/java/cc/fros/features/gui/items/buttons/Button.java +++ b/src/main/java/cc/fros/features/gui/items/buttons/Button.java @@ -22,7 +22,7 @@ public class Button @Override public void drawScreen(GuiGraphics context, int mouseX, int mouseY, float partialTicks) { RenderUtil.rect(context, this.x, this.y, this.x + (float) this.width, this.y + (float) this.height - 0.5f, this.getState() ? (!this.isHovering(mouseX, mouseY) ? Fros.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().color.getValue().getAlpha()) : Fros.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().topColor.getValue().getAlpha())) : (!this.isHovering(mouseX, mouseY) ? 0x11555555 : -2007673515)); - drawString(context, this.getName(), this.x + 2.3f, this.y - 2.0f - (float) FrosGui.getClickGui().getTextOffset(), this.getState() ? -1 : -5592406); + drawString(context, this.getName(), this.x + 2.3f, textY(), this.getState() ? -1 : -5592406); } @Override diff --git a/src/main/java/cc/fros/features/gui/items/buttons/ColorButton.java b/src/main/java/cc/fros/features/gui/items/buttons/ColorButton.java index 2bddd56..f6b2475 100644 --- a/src/main/java/cc/fros/features/gui/items/buttons/ColorButton.java +++ b/src/main/java/cc/fros/features/gui/items/buttons/ColorButton.java @@ -44,7 +44,7 @@ public class ColorButton extends Button { this.x + (float) this.width + 5.0f, this.y + (float) this.height - 2.5f, new Color(currentColor.getRGB(), false).getRGB()); - drawString(context, this.getName(), this.x + 2.3f, this.y - 1.7f - (float) FrosGui.getClickGui().getTextOffset(), -1); + drawString(context, this.getName(), this.x + 2.3f, textY(), -1); if (open) { float yOffset = this.height + 1; @@ -121,12 +121,12 @@ public class ColorButton extends Button { int buttonWidth = availableWidth / 2; RenderUtil.rect(context, pickerX, this.y + yOffset, pickerX + buttonWidth, this.y + yOffset + 14, hoveringCopy ? Fros.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().topColor.getValue().getAlpha()) : 0x11555555); - drawString(context, "Copy", pickerX + buttonWidth / 2.0 - FrosFont.width("Copy") / 2.0, this.y + yOffset + 3, -1); + drawString(context, "Copy", pickerX + buttonWidth / 2.0 - FrosFont.width("Copy") / 2.0, this.y + yOffset + 7f - FrosFont.visualCenter(), -1); hoveringCopy = isHoveringArea(mouseX, mouseY, pickerX, this.y + yOffset, pickerX + buttonWidth, this.y + yOffset + 14); RenderUtil.rect(context, pickerX + buttonWidth + 1, this.y + yOffset, pickerX + buttonWidth * 2 + 1, this.y + yOffset + 14, hoveringPaste ? Fros.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().topColor.getValue().getAlpha()) : 0x11555555); - drawString(context, "Paste", pickerX + buttonWidth + buttonWidth / 2.0 - FrosFont.width("Paste") / 2.0 + 1, this.y + yOffset + 3, -1); + drawString(context, "Paste", pickerX + buttonWidth + buttonWidth / 2.0 - FrosFont.width("Paste") / 2.0 + 1, this.y + yOffset + 7f - FrosFont.visualCenter(), -1); hoveringPaste = isHoveringArea(mouseX, mouseY, pickerX + buttonWidth + 1, this.y + yOffset, pickerX + buttonWidth * 2 + 1, this.y + yOffset + 14); } } diff --git a/src/main/java/cc/fros/features/gui/items/buttons/EnumButton.java b/src/main/java/cc/fros/features/gui/items/buttons/EnumButton.java index dbfeef5..5f07930 100644 --- a/src/main/java/cc/fros/features/gui/items/buttons/EnumButton.java +++ b/src/main/java/cc/fros/features/gui/items/buttons/EnumButton.java @@ -2,7 +2,6 @@ package cc.fros.features.gui.items.buttons; import cc.fros.Fros; -import cc.fros.features.gui.FrosGui; import cc.fros.features.modules.client.ClickGuiModule; import cc.fros.features.settings.Setting; import cc.fros.util.render.RenderUtil; @@ -24,7 +23,7 @@ public class EnumButton @Override public void drawScreen(GuiGraphics context, int mouseX, int mouseY, float partialTicks) { RenderUtil.rect(context, this.x, this.y, this.x + (float) this.width + 7.4f, this.y + (float) this.height - 0.5f, this.getState() ? (!this.isHovering(mouseX, mouseY) ? Fros.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().color.getValue().getAlpha()) : Fros.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().topColor.getValue().getAlpha())) : (!this.isHovering(mouseX, mouseY) ? 0x11555555 : -2007673515)); - drawString(context, this.setting.getName() + " " + ChatFormatting.GRAY + (this.setting.currentEnumName().equalsIgnoreCase("ABC") ? "ABC" : this.setting.currentEnumName()), this.x + 2.3f, this.y - 1.7f - (float) FrosGui.getClickGui().getTextOffset(), this.getState() ? -1 : -5592406); + drawString(context, this.setting.getName() + " " + ChatFormatting.GRAY + (this.setting.currentEnumName().equalsIgnoreCase("ABC") ? "ABC" : this.setting.currentEnumName()), this.x + 2.3f, textY(), this.getState() ? -1 : -5592406); } @Override diff --git a/src/main/java/cc/fros/features/gui/items/buttons/Slider.java b/src/main/java/cc/fros/features/gui/items/buttons/Slider.java index 233e0df..6477fad 100644 --- a/src/main/java/cc/fros/features/gui/items/buttons/Slider.java +++ b/src/main/java/cc/fros/features/gui/items/buttons/Slider.java @@ -32,7 +32,7 @@ public class Slider this.dragSetting(mouseX, mouseY); RenderUtil.rect(context, this.x, this.y, this.x + (float) this.width + 7.4f, this.y + (float) this.height - 0.5f, !(this.dragging || this.isHovering(mouseX, mouseY)) ? 0x11555555 : -2007673515); RenderUtil.rect(context, this.x, this.y, (this.setting.getValue()).floatValue() <= this.min.floatValue() ? this.x : this.x + ((float) this.width + 7.4f) * this.partialMultiplier(), this.y + (float) this.height - 0.5f, !(this.dragging || this.isHovering(mouseX, mouseY)) ? Fros.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().color.getValue().getAlpha()) : Fros.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().topColor.getValue().getAlpha())); - drawString(context, this.getName() + " " + ChatFormatting.GRAY + (this.setting.getValue() instanceof Float ? this.setting.getValue() : Double.valueOf((this.setting.getValue()).doubleValue())), this.x + 2.3f, this.y - 1.7f - (float) FrosGui.getClickGui().getTextOffset(), -1); + drawString(context, this.getName() + " " + ChatFormatting.GRAY + (this.setting.getValue() instanceof Float ? this.setting.getValue() : Double.valueOf((this.setting.getValue()).doubleValue())), this.x + 2.3f, textY(), -1); } @Override diff --git a/src/main/java/cc/fros/features/gui/items/buttons/StringButton.java b/src/main/java/cc/fros/features/gui/items/buttons/StringButton.java index b01f94d..59b7d33 100644 --- a/src/main/java/cc/fros/features/gui/items/buttons/StringButton.java +++ b/src/main/java/cc/fros/features/gui/items/buttons/StringButton.java @@ -1,7 +1,6 @@ package cc.fros.features.gui.items.buttons; import cc.fros.Fros; -import cc.fros.features.gui.FrosGui; import cc.fros.features.modules.client.ClickGuiModule; import cc.fros.features.settings.Setting; import cc.fros.util.models.Timer; @@ -38,9 +37,9 @@ public class StringButton public void drawScreen(GuiGraphics context, int mouseX, int mouseY, float partialTicks) { RenderUtil.rect(context, this.x, this.y, this.x + (float) this.width + 7.4f, this.y + (float) this.height - 0.5f, this.getState() ? (!this.isHovering(mouseX, mouseY) ? Fros.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().color.getValue().getAlpha()) : Fros.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().topColor.getValue().getAlpha())) : (!this.isHovering(mouseX, mouseY) ? 0x11555555 : -2007673515)); if (this.isListening) { - drawString(context, this.currentString.string() + getIdleSign(), this.x + 2.3f, this.y - 1.7f - (float) FrosGui.getClickGui().getTextOffset(), this.getState() ? -1 : -5592406); + drawString(context, this.currentString.string() + getIdleSign(), this.x + 2.3f, textY(), this.getState() ? -1 : -5592406); } else { - drawString(context, (this.setting.getName().equals("Buttons") ? "Buttons " : (this.setting.getName().equals("Prefix") ? "Prefix " + ChatFormatting.GRAY : "")) + this.setting.getValue(), this.x + 2.3f, this.y - 1.7f - (float) FrosGui.getClickGui().getTextOffset(), this.getState() ? -1 : -5592406); + drawString(context, (this.setting.getName().equals("Buttons") ? "Buttons " : (this.setting.getName().equals("Prefix") ? "Prefix " + ChatFormatting.GRAY : "")) + this.setting.getValue(), this.x + 2.3f, textY(), this.getState() ? -1 : -5592406); } } diff --git a/src/main/java/cc/fros/util/render/FrosFont.java b/src/main/java/cc/fros/util/render/FrosFont.java index 85fb454..2a0433e 100644 --- a/src/main/java/cc/fros/util/render/FrosFont.java +++ b/src/main/java/cc/fros/util/render/FrosFont.java @@ -83,6 +83,8 @@ public final class FrosFont { private static String loadedName; private static float loadedSize = Float.NaN; private static float loadedScale = 1; + /** raster pixels from the top of a line box to the middle of the cap band */ + private static float visualCenterRaster = 4f; private static long lastAttempt; private static int glyphCounter; @@ -218,10 +220,33 @@ public final class FrosFont { Graphics2D graphics = probe.createGraphics(); graphics.setFont(awtFont); metrics = graphics.getFontMetrics(); + // distance from the top of the line box to the middle of the cap band: + // drawString puts the baseline at metrics.getAscent(), and "A" spans + // from the baseline up to the cap line + java.awt.geom.Rectangle2D capBounds = awtFont + .createGlyphVector(graphics.getFontRenderContext(), "A") + .getVisualBounds(); + float capHeight = (float) capBounds.getHeight(); + if (capHeight <= 0f || capHeight > metrics.getAscent()) { + capHeight = metrics.getAscent(); + } + visualCenterRaster = metrics.getAscent() - capHeight / 2f; graphics.dispose(); if (verbose) LOGGER.info("{} ({}pt)", source, size); } + /** + * Distance from the top of a line box down to the visual center of its + * text (middle of the cap band), in gui units. lets callers center labels + * by what the eye sees instead of the line box, and behaves the same for + * the custom font and the vanilla fallback. + */ + public static float visualCenter() { + sync(); + if (awtFont == null) return mc.font.lineHeight / 2f - 1f; + return visualCenterRaster / loadedScale; + } + /** * Resolves java's logical fonts (guaranteed on every os) and any font * family already installed on the system, without needing a file.