package net.minecraft.client.gui.font.glyphs; import com.mojang.blaze3d.vertex.VertexConsumer; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.gui.Font; import net.minecraft.client.gui.font.GlyphRenderTypes; import net.minecraft.client.renderer.RenderType; import net.minecraft.network.chat.Style; import org.joml.Matrix4f; @Environment(EnvType.CLIENT) public class BakedGlyph { public static final float Z_FIGHTER = 0.001F; private final GlyphRenderTypes renderTypes; private final float u0; private final float u1; private final float v0; private final float v1; private final float left; private final float right; private final float up; private final float down; public BakedGlyph(GlyphRenderTypes renderTypes, float u0, float u1, float v0, float v1, float left, float right, float up, float down) { this.renderTypes = renderTypes; this.u0 = u0; this.u1 = u1; this.v0 = v0; this.v1 = v1; this.left = left; this.right = right; this.up = up; this.down = down; } public void renderChar(BakedGlyph.GlyphInstance glyph, Matrix4f pose, VertexConsumer buffer, int packedLight) { Style style = glyph.style(); boolean bl = style.isItalic(); float f = glyph.x(); float g = glyph.y(); int i = glyph.color(); int j = glyph.shadowColor(); boolean bl2 = style.isBold(); if (glyph.hasShadow()) { this.render(bl, f + glyph.shadowOffset(), g + glyph.shadowOffset(), pose, buffer, j, bl2, packedLight); this.render(bl, f, g, 0.03F, pose, buffer, i, bl2, packedLight); } else { this.render(bl, f, g, pose, buffer, i, bl2, packedLight); } if (bl2) { if (glyph.hasShadow()) { this.render(bl, f + glyph.boldOffset() + glyph.shadowOffset(), g + glyph.shadowOffset(), 0.001F, pose, buffer, j, true, packedLight); this.render(bl, f + glyph.boldOffset(), g, 0.03F, pose, buffer, i, true, packedLight); } else { this.render(bl, f + glyph.boldOffset(), g, pose, buffer, i, true, packedLight); } } } private void render(boolean italic, float x, float y, Matrix4f pose, VertexConsumer buffer, int color, boolean bold, int packedLight) { this.render(italic, x, y, 0.0F, pose, buffer, color, bold, packedLight); } private void render(boolean italic, float x, float y, float z, Matrix4f pose, VertexConsumer buffer, int color, boolean bold, int packedLight) { float f = x + this.left; float g = x + this.right; float h = y + this.up; float i = y + this.down; float j = italic ? 1.0F - 0.25F * this.up : 0.0F; float k = italic ? 1.0F - 0.25F * this.down : 0.0F; float l = bold ? 0.1F : 0.0F; buffer.addVertex(pose, f + j - l, h - l, z).setColor(color).setUv(this.u0, this.v0).setLight(packedLight); buffer.addVertex(pose, f + k - l, i + l, z).setColor(color).setUv(this.u0, this.v1).setLight(packedLight); buffer.addVertex(pose, g + k + l, i + l, z).setColor(color).setUv(this.u1, this.v1).setLight(packedLight); buffer.addVertex(pose, g + j + l, h - l, z).setColor(color).setUv(this.u1, this.v0).setLight(packedLight); } public void renderEffect(BakedGlyph.Effect effect, Matrix4f pose, VertexConsumer buffer, int packedLight) { if (effect.hasShadow()) { this.buildEffect(effect, effect.shadowOffset(), 0.0F, effect.shadowColor(), buffer, packedLight, pose); this.buildEffect(effect, 0.0F, 0.03F, effect.color, buffer, packedLight, pose); } else { this.buildEffect(effect, 0.0F, 0.0F, effect.color, buffer, packedLight, pose); } } private void buildEffect( BakedGlyph.Effect effect, float shadowOffset, float depthOffset, int shadowColor, VertexConsumer buffer, int packedLight, Matrix4f pose ) { buffer.addVertex(pose, effect.x0 + shadowOffset, effect.y0 + shadowOffset, effect.depth + depthOffset) .setColor(shadowColor) .setUv(this.u0, this.v0) .setLight(packedLight); buffer.addVertex(pose, effect.x1 + shadowOffset, effect.y0 + shadowOffset, effect.depth + depthOffset) .setColor(shadowColor) .setUv(this.u0, this.v1) .setLight(packedLight); buffer.addVertex(pose, effect.x1 + shadowOffset, effect.y1 + shadowOffset, effect.depth + depthOffset) .setColor(shadowColor) .setUv(this.u1, this.v1) .setLight(packedLight); buffer.addVertex(pose, effect.x0 + shadowOffset, effect.y1 + shadowOffset, effect.depth + depthOffset) .setColor(shadowColor) .setUv(this.u1, this.v0) .setLight(packedLight); } public RenderType renderType(Font.DisplayMode displayMode) { return this.renderTypes.select(displayMode); } @Environment(EnvType.CLIENT) public record Effect(float x0, float y0, float x1, float y1, float depth, int color, int shadowColor, float shadowOffset) { public Effect(float x0, float y0, float x1, float y1, float depth, int color) { this(x0, y0, x1, y1, depth, color, 0, 0.0F); } boolean hasShadow() { return this.shadowColor() != 0; } } @Environment(EnvType.CLIENT) public record GlyphInstance(float x, float y, int color, int shadowColor, BakedGlyph glyph, Style style, float boldOffset, float shadowOffset) { boolean hasShadow() { return this.shadowColor() != 0; } } }