From 2b3e8de5158122d0366d9e5b641825ee624805ad Mon Sep 17 00:00:00 2001 From: Wide-Cat Date: Mon, 29 Jan 2024 18:32:08 +0000 Subject: [PATCH 1/3] Increase the amount of rasterized characters --- .../meteorclient/renderer/text/Font.java | 69 +++++++++++-------- 1 file changed, 42 insertions(+), 27 deletions(-) diff --git a/src/main/java/meteordevelopment/meteorclient/renderer/text/Font.java b/src/main/java/meteordevelopment/meteorclient/renderer/text/Font.java index dfa0654dd8..5a1d0c2b4d 100644 --- a/src/main/java/meteordevelopment/meteorclient/renderer/text/Font.java +++ b/src/main/java/meteordevelopment/meteorclient/renderer/text/Font.java @@ -5,15 +5,13 @@ package meteordevelopment.meteorclient.renderer.text; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import meteordevelopment.meteorclient.renderer.Mesh; import meteordevelopment.meteorclient.utils.render.ByteTexture; import meteordevelopment.meteorclient.utils.render.color.Color; import net.minecraft.client.texture.AbstractTexture; import org.lwjgl.BufferUtils; -import org.lwjgl.stb.STBTTFontinfo; -import org.lwjgl.stb.STBTTPackContext; -import org.lwjgl.stb.STBTTPackedchar; -import org.lwjgl.stb.STBTruetype; +import org.lwjgl.stb.*; import org.lwjgl.system.MemoryStack; import java.nio.ByteBuffer; @@ -21,11 +19,11 @@ public class Font { public AbstractTexture texture; - private final int height; private final float scale; private final float ascent; - private final CharData[] charData; + private final Int2ObjectOpenHashMap charMap = new Int2ObjectOpenHashMap<>(); + private final static int size = 2048; public Font(ByteBuffer buffer, int height) { this.height = height; @@ -34,20 +32,35 @@ public Font(ByteBuffer buffer, int height) { STBTTFontinfo fontInfo = STBTTFontinfo.create(); STBTruetype.stbtt_InitFont(fontInfo, buffer); - // Allocate STBTTPackedchar buffer - charData = new CharData[128]; - STBTTPackedchar.Buffer cdata = STBTTPackedchar.create(charData.length); - ByteBuffer bitmap = BufferUtils.createByteBuffer(2048 * 2048); - - // Create font texture + // Allocate buffers + ByteBuffer bitmap = BufferUtils.createByteBuffer(size * size); + STBTTPackedchar.Buffer[] cdata = { + STBTTPackedchar.create(95), // Basic Latin + STBTTPackedchar.create(96), // Latin 1 Supplement + STBTTPackedchar.create(128), // Latin Extended-A + STBTTPackedchar.create(144), // Greek and Coptic + STBTTPackedchar.create(256) // Cyrillic + }; + + // create and initialise packing context STBTTPackContext packContext = STBTTPackContext.create(); - STBTruetype.stbtt_PackBegin(packContext, bitmap, 2048, 2048, 0, 1); - STBTruetype.stbtt_PackSetOversampling(packContext, 2, 2); - STBTruetype.stbtt_PackFontRange(packContext, buffer, 0, height, 32, cdata); + STBTruetype.stbtt_PackBegin(packContext, bitmap, size, size, 0 ,1); + + // create the pack range, populate with the specific packing ranges + STBTTPackRange.Buffer packRange = STBTTPackRange.create(5); + packRange.put(STBTTPackRange.create().set(height, 32, null, 95, cdata[0], (byte) 2, (byte) 2)); + packRange.put(STBTTPackRange.create().set(height, 160, null, 96, cdata[1], (byte) 2, (byte) 2)); + packRange.put(STBTTPackRange.create().set(height, 256, null, 128, cdata[2], (byte) 2, (byte) 2)); + packRange.put(STBTTPackRange.create().set(height, 880, null, 144, cdata[3], (byte) 2, (byte) 2)); + packRange.put(STBTTPackRange.create().set(height, 1024, null, 256, cdata[4], (byte) 2, (byte) 2)); + packRange.flip(); + + // write and finish + STBTruetype.stbtt_PackFontRanges(packContext, buffer, 0, packRange); STBTruetype.stbtt_PackEnd(packContext); // Create texture object and get font scale - texture = new ByteTexture(2048, 2048, bitmap, ByteTexture.Format.A, ByteTexture.Filter.Linear, ByteTexture.Filter.Linear); + texture = new ByteTexture(size, size, bitmap, ByteTexture.Format.A, ByteTexture.Filter.Linear, ByteTexture.Filter.Linear); scale = STBTruetype.stbtt_ScaleForPixelHeight(fontInfo, height); // Get font vertical ascent @@ -57,14 +70,17 @@ public Font(ByteBuffer buffer, int height) { this.ascent = ascent.get(0); } - // Populate charData array - for (int i = 0; i < charData.length; i++) { - STBTTPackedchar packedChar = cdata.get(i); + for (int i = 0; i < cdata.length; i++) { + STBTTPackedchar.Buffer cbuf = cdata[i]; + int offset = packRange.get(i).first_unicode_codepoint_in_range(); - float ipw = 1f / 2048; - float iph = 1f / 2048; + for (int j = 0; j < cbuf.capacity(); j++) { + STBTTPackedchar packedChar = cbuf.get(j); - charData[i] = new CharData( + float ipw = 1f / size; // pixel width and height + float iph = 1f / size; + + charMap.put(j + offset, new CharData( packedChar.xoff(), packedChar.yoff(), packedChar.xoff2(), @@ -74,7 +90,8 @@ public Font(ByteBuffer buffer, int height) { packedChar.x1() * ipw, packedChar.y1() * iph, packedChar.xadvance() - ); + )); + } } } @@ -83,8 +100,7 @@ public double getWidth(String string, int length) { for (int i = 0; i < length; i++) { int cp = string.charAt(i); - if (cp < 32 || cp > 128) cp = 32; - CharData c = charData[cp - 32]; + CharData c = (charMap.containsKey(cp) ? charMap.get(cp) : charMap.get(32)); width += c.xAdvance; } @@ -101,8 +117,7 @@ public double render(Mesh mesh, String string, double x, double y, Color color, for (int i = 0; i < string.length(); i++) { int cp = string.charAt(i); - if (cp < 32 || cp > 128) cp = 32; - CharData c = charData[cp - 32]; + CharData c = (charMap.containsKey(cp) ? charMap.get(cp) : charMap.get(32)); mesh.quad( mesh.vec2(x + c.x0 * scale, y + c.y0 * scale).vec2(c.u0, c.v0).color(color).next(), From 876f40ddf00f52d21668cbce18e264afa2a55e07 Mon Sep 17 00:00:00 2001 From: Wide-Cat Date: Mon, 29 Jan 2024 19:17:09 +0000 Subject: [PATCH 2/3] resolve potion timers hud todo --- .../meteordevelopment/meteorclient/renderer/text/Font.java | 6 ++++-- .../meteorclient/systems/hud/elements/PotionTimersHud.java | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/meteordevelopment/meteorclient/renderer/text/Font.java b/src/main/java/meteordevelopment/meteorclient/renderer/text/Font.java index 5a1d0c2b4d..b6409b3bd9 100644 --- a/src/main/java/meteordevelopment/meteorclient/renderer/text/Font.java +++ b/src/main/java/meteordevelopment/meteorclient/renderer/text/Font.java @@ -39,7 +39,8 @@ public Font(ByteBuffer buffer, int height) { STBTTPackedchar.create(96), // Latin 1 Supplement STBTTPackedchar.create(128), // Latin Extended-A STBTTPackedchar.create(144), // Greek and Coptic - STBTTPackedchar.create(256) // Cyrillic + STBTTPackedchar.create(256), // Cyrillic + STBTTPackedchar.create(1) // infinity symbol }; // create and initialise packing context @@ -47,12 +48,13 @@ public Font(ByteBuffer buffer, int height) { STBTruetype.stbtt_PackBegin(packContext, bitmap, size, size, 0 ,1); // create the pack range, populate with the specific packing ranges - STBTTPackRange.Buffer packRange = STBTTPackRange.create(5); + STBTTPackRange.Buffer packRange = STBTTPackRange.create(cdata.length); packRange.put(STBTTPackRange.create().set(height, 32, null, 95, cdata[0], (byte) 2, (byte) 2)); packRange.put(STBTTPackRange.create().set(height, 160, null, 96, cdata[1], (byte) 2, (byte) 2)); packRange.put(STBTTPackRange.create().set(height, 256, null, 128, cdata[2], (byte) 2, (byte) 2)); packRange.put(STBTTPackRange.create().set(height, 880, null, 144, cdata[3], (byte) 2, (byte) 2)); packRange.put(STBTTPackRange.create().set(height, 1024, null, 256, cdata[4], (byte) 2, (byte) 2)); + packRange.put(STBTTPackRange.create().set(height, 8734, null, 1, cdata[5], (byte) 2, (byte) 2)); // lol packRange.flip(); // write and finish diff --git a/src/main/java/meteordevelopment/meteorclient/systems/hud/elements/PotionTimersHud.java b/src/main/java/meteordevelopment/meteorclient/systems/hud/elements/PotionTimersHud.java index 5d3f0e99c3..332c9ef4a0 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/hud/elements/PotionTimersHud.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/hud/elements/PotionTimersHud.java @@ -14,7 +14,7 @@ import meteordevelopment.meteorclient.utils.render.color.SettingColor; import net.minecraft.entity.effect.StatusEffect; import net.minecraft.entity.effect.StatusEffectInstance; -import net.minecraft.util.StringHelper; +import net.minecraft.entity.effect.StatusEffectUtil; import java.util.ArrayList; import java.util.List; @@ -241,7 +241,7 @@ public void render(HudRenderer renderer) { } private String getString(StatusEffectInstance statusEffectInstance) { - return String.format("%s %d (%s)", Names.get(statusEffectInstance.getEffectType()), statusEffectInstance.getAmplifier() + 1, statusEffectInstance.isInfinite() ? "inf" : StringHelper.formatTicks(statusEffectInstance.getDuration(), mc.world.getTickManager().getTickRate())); //todo remove "inf" when font rendering can use symbols + return String.format("%s %d (%s)", Names.get(statusEffectInstance.getEffectType()), statusEffectInstance.getAmplifier() + 1, StatusEffectUtil.getDurationText(statusEffectInstance, 1, mc.world.getTickManager().getTickRate()).getString()); } private double getScale() { From 280314f5e3a36a099c7ee8c67e1b4978e452588e Mon Sep 17 00:00:00 2001 From: Wide-Cat Date: Mon, 29 Jan 2024 19:27:23 +0000 Subject: [PATCH 3/3] small improvement --- .../meteordevelopment/meteorclient/renderer/text/Font.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/meteordevelopment/meteorclient/renderer/text/Font.java b/src/main/java/meteordevelopment/meteorclient/renderer/text/Font.java index b6409b3bd9..5a7a71d32f 100644 --- a/src/main/java/meteordevelopment/meteorclient/renderer/text/Font.java +++ b/src/main/java/meteordevelopment/meteorclient/renderer/text/Font.java @@ -102,7 +102,8 @@ public double getWidth(String string, int length) { for (int i = 0; i < length; i++) { int cp = string.charAt(i); - CharData c = (charMap.containsKey(cp) ? charMap.get(cp) : charMap.get(32)); + CharData c = charMap.get(cp); + if (c == null) c = charMap.get(32); width += c.xAdvance; } @@ -119,7 +120,8 @@ public double render(Mesh mesh, String string, double x, double y, Color color, for (int i = 0; i < string.length(); i++) { int cp = string.charAt(i); - CharData c = (charMap.containsKey(cp) ? charMap.get(cp) : charMap.get(32)); + CharData c = charMap.get(cp); + if (c == null) c = charMap.get(32); mesh.quad( mesh.vec2(x + c.x0 * scale, y + c.y0 * scale).vec2(c.u0, c.v0).color(color).next(),