Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/main/java/top/fpsmaster/font/impl/UFontRenderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,22 @@ private int drawStringInternal(String text, float x, float y, int color, boolean
}

private int edge$drawStringInternal(String text, float x, float y, int color, boolean dropShadow, float shadowOffset) {
// Vanilla treats a colour with no alpha bits as opaque — its drawString does
// `if ((color & 0xFC000000) == 0) color |= 0xFF000000` and the custom-font mixin keeps
// the rule for the vanilla-replacement path. Without it here, callers that pass opaque
// colours the vanilla way (the custom scoreboard passes 0xFFFFFF) draw fully transparent
// once routed through this renderer. This class extends FontRenderer and is handed around
// as one — LevelTag picks between it and fontRendererObj at runtime — so a vanilla-shaped
// colour has to mean what it means everywhere else.
//
// The cost is that alpha 1-3 can no longer be asked for: a caller fading its own text out
// must stop above three rather than run to zero, which is what MixinGuiNewChat, the OOBE
// screen and every other fade in the client do. The global fade is unaffected — Alpha.apply
// runs after this, so Alpha.set(0f) still reaches zero and stays invisible. Do not move
// this below that call; a0860d7 removed the rule from TextRenderer for exactly that reason.
if ((color & 0xFC000000) == 0) {
color |= 0xFF000000;
}
color = apply(color);
int i;
if (dropShadow) {
Expand Down
15 changes: 15 additions & 0 deletions src/main/java/top/fpsmaster/ui/custom/Component.java
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,22 @@ public void drawString(int fontSize, String text, float x, float y, int color) {
drawString(fontSize, false, text, x, y, color);
}

/**
* Draws a component's text.
*
* <p>Colours here come from {@link top.fpsmaster.features.settings.impl.ColorSetting}, whose
* alpha slider reaches zero and whose Wave mode scales what it returns, so alpha means what it
* says: below four there is nothing to draw. Both renderers underneath read it vanilla's way
* instead — no alpha bits set means opaque — and would turn a string the user hid into a solid
* one. Components must therefore pass a real alpha, not a bare {@code 0xRRGGBB}.
*
* <p>Only text is affected. Backgrounds and shapes go through {@code drawRect} and {@code Rects}
* and never come through here, so a fully transparent background stays transparent.
*/
public void drawString(int fontSize, boolean bold, String text, float x, float y, int color) {
if (((color >>> 24) & 0xFF) <= 3) {
return;
}
double scaled = (int) (scale * 100) / 100.0;
fontSize = (int) (fontSize * scale);
UFontRenderer font = FPSMaster.fontManager.getFont(fontSize);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,13 @@ public void draw(float x, float y) {
width = maxWidth + 6;
height = (lines.size() + 1) * lineHeight + 4;
drawRect(x, y, width, height, mod.backgroundColor.getColor());
drawString(FONT_SIZE, title, x + 3 * scale, y + 2 * scale, 0xFFFFFF);
// Opaque white as -1, the way every other component writes it. A bare 0xFFFFFF is vanilla's
// spelling of the same colour, and Component.drawString does not read alpha vanilla's way.
drawString(FONT_SIZE, title, x + 3 * scale, y + 2 * scale, -1);
// Row offsets are positions, so they scale here.
float offsetY = y + (2 + lineHeight) * scale;
for (String line : lines) {
drawString(FONT_SIZE, line, x + 3 * scale, offsetY, 0xFFFFFF);
drawString(FONT_SIZE, line, x + 3 * scale, offsetY, -1);
offsetY += lineHeight * scale;
}
}
Expand Down
31 changes: 23 additions & 8 deletions src/main/java/top/fpsmaster/ui/screens/oobe/OobeScreen.java
Original file line number Diff line number Diff line change
Expand Up @@ -372,11 +372,17 @@ private void renderTutorialPage(int mouseX, int mouseY) {
Color titleColor = new Color(24, 32, 54, alpha);
Color descColor = new Color(92, 101, 118, alpha);

GL11.glPushMatrix();
GL11.glTranslatef(0f, (1f - tutorialSlideTransition) * 8f, 0f);
FPSMaster.fontManager.s18.drawString(slides[tutorialIndex][0], x + 24f, cardY + 54f, titleColor.getRGB());
drawMultilineBodyTextWithAlpha(extendTutorialDescription(slides[tutorialIndex][1], tutorialIndex), x + 24f, cardY + 94f, width - 48f, 4, alpha);
GL11.glPopMatrix();
// Below four the renderer reads the colour as vanilla does - no alpha bits set means opaque -
// so a fade this shallow comes out solid rather than invisible. updateTutorialAutoplay resets
// the transition after updateAnimations has advanced it, which puts the frame a slide flips on
// at exactly zero: without this the new slide pops in at full opacity before its fade starts.
if (alpha > 3) {
GL11.glPushMatrix();
GL11.glTranslatef(0f, (1f - tutorialSlideTransition) * 8f, 0f);
FPSMaster.fontManager.s18.drawString(slides[tutorialIndex][0], x + 24f, cardY + 54f, titleColor.getRGB());
drawMultilineBodyTextWithAlpha(extendTutorialDescription(slides[tutorialIndex][1], tutorialIndex), x + 24f, cardY + 94f, width - 48f, 4, alpha);
GL11.glPopMatrix();
}
}

private void renderFeaturesPage() {
Expand Down Expand Up @@ -987,14 +993,23 @@ private void renderAnimatedGreeting(float x, float y) {
int currentAlpha = Math.min(255, Math.max(0, Math.round(eased * 255f)));
Color currentColor = new Color(accentText().getRed(), accentText().getGreen(), accentText().getBlue(), currentAlpha);

// Both passes stop at four rather than zero: the renderer reads a colour with no alpha bits
// as opaque, the way vanilla's does, so anything below that comes out solid. The fade-out is
// the one that matters - it is cubic, so previousAlpha sits in that band for the last 30-odd
// frames of the half-second crossfade, and the outgoing greeting would hold full opacity
// there and then vanish. Neither pass has anything left to show by four.
if (greetingTransition < 1f && greetingPreviousText != null && !greetingPreviousText.isEmpty()) {
float previousProgress = 1f - eased;
int previousAlpha = Math.min(255, Math.max(0, Math.round(previousProgress * 255f)));
Color previousColor = new Color(accentText().getRed(), accentText().getGreen(), accentText().getBlue(), previousAlpha);
FPSMaster.fontManager.s18.drawString(greetingPreviousText, x, y - eased * 8f, previousColor.getRGB());
if (previousAlpha > 3) {
Color previousColor = new Color(accentText().getRed(), accentText().getGreen(), accentText().getBlue(), previousAlpha);
FPSMaster.fontManager.s18.drawString(greetingPreviousText, x, y - eased * 8f, previousColor.getRGB());
}
}

FPSMaster.fontManager.s18.drawString(greetingCurrentText, x, y + (1f - eased) * 8f, currentColor.getRGB());
if (currentAlpha > 3) {
FPSMaster.fontManager.s18.drawString(greetingCurrentText, x, y + (1f - eased) * 8f, currentColor.getRGB());
}
}

private void switchLanguage(int newLanguage) {
Expand Down
Loading