Implemented Dynamic sized fonts that adjust based on your need.

This commit is contained in:
Speiger 2024-12-28 09:59:44 +01:00
parent a1453f0a6c
commit 9ba9e81686
6 changed files with 70 additions and 36 deletions

View File

@ -80,7 +80,7 @@ public class NewInputTest {
assets.addListener(fonts);
assets.reload();
System.out.println("Testing: "+GL.getCapabilities().OpenGL46);
System.out.println("Testing: "+GL.getCapabilities().OpenGL41);
System.out.println("Testing: "+Integer.divideUnsigned(-1, 255));
IFontProvider provider = STBTrueTypeProvider.create(AssetLocation.of("font/roboto/font.json"), assets);
@ -150,16 +150,24 @@ public class NewInputTest {
builder.pos(-0.5F, 0.5F, 0).tex(0F, 0F).rgba(-1).endVertex();
builder.pos(-0.5F, -0.5F, 0).tex(0F, 1F).rgba(-1).endVertex();
Font font = fonts.createFont(18F, 1F);
Font font = fonts.createFont(1F);
TestModel model = new TestModel(builder.getBytes());
TestModel[] guiModel = new TestModel[1];
List<GLDraw> draws = new ObjectArrayList<>();
font.drawText("The Quick brown fox Jumps over the Lazy dog", 50, 50, -1, new TexturedBuffer((K, V) -> {
TexturedBuffer buffer = new TexturedBuffer((K, V) -> {
draws.addAll(K);
guiModel[0] = new TestModel(V);
System.out.println("Testing: "+V.length+" bytes, "+K.size());
}));
});
// String s = "The Quick brown fox Jumps over the Lazy dog";
float offset = font.drawText("The Quick ", 50, 50, -1, buffer, false);
offset += font.drawText(Font.DEFAULT.with(25F), "Brown ", 50+offset, 50, -1, buffer, false);
offset += font.drawText(Font.DEFAULT, "Fox ", 50+offset, 50, -1, buffer, false);
offset += font.drawText(Font.DEFAULT.with(10F), "Jumps ", 50+offset, 50, -1, buffer, false);
offset += font.drawText(Font.DEFAULT, "over the Lazy dog", 50+offset, 50, -1, buffer, true);
// font.drawText(s, 50, 50, -1, buffer, true);
GLStateTracker tracker = GLStateTracker.instance();
GL11.glClearColor(0.2F, 0.55F, 0.66F, 1F);

View File

@ -6,28 +6,21 @@ import java.util.function.Consumer;
import speiger.src.coreengine.assets.AssetLocation;
import speiger.src.coreengine.rendering.gui.font.glyth.Glyth;
import speiger.src.coreengine.rendering.gui.font.glyth.GlythData;
import speiger.src.coreengine.rendering.gui.font.glyth.MissingGlyth;
import speiger.src.coreengine.rendering.gui.font.glyth.UnbakedGlyth.GlythBaker;
import speiger.src.coreengine.rendering.tesselation.buffer.IVertexBuilder;
public class Font {
private static final AssetLocation DEFAULT = AssetLocation.of("default");
public static final FontStyle DEFAULT = new FontStyle(AssetLocation.of("default"), 18);
Map<AssetLocation, FontGroup> fonts;
GlythBaker baker;
float size;
float oversample;
GlythCache[] styledCache = new GlythCache[] {new GlythCache(this, 0), new GlythCache(this, 1), new GlythCache(this, 2), new GlythCache(this, 3)};
MissingGlyth missingGlyth;
GlythData missingData;
protected Font(Map<AssetLocation, FontGroup> fonts, GlythBaker baker, float size, float oversample, Consumer<Runnable> clearing) {
protected Font(Map<AssetLocation, FontGroup> fonts, GlythBaker baker, float oversample, Consumer<Runnable> clearing) {
this.fonts = fonts;
this.baker = baker;
this.size = size;
this.oversample = oversample;
this.missingGlyth = new MissingGlyth(size, oversample * 2F);
missingData = new GlythData(missingGlyth);
clearing.accept(this::reset);
}
@ -35,15 +28,13 @@ public class Font {
for(int i = 0;i<4;i++) {
styledCache[i].reset();
}
missingGlyth.cleanCache();
missingData.cleanCache();
}
public GlythData data(AssetLocation font, int codepoint, int style) {
public GlythData data(FontStyle font, int codepoint, int style) {
return styledCache[style & 0x3].data(font, codepoint);
}
public Glyth glyth(AssetLocation font, int codepoint, int style) {
public Glyth glyth(FontStyle font, int codepoint, int style) {
return styledCache[style & 0x3].glyth(font, codepoint);
}
@ -51,15 +42,20 @@ public class Font {
return fonts.get(font);
}
public void drawText(String text, float x, float y, int color, TexturedBuffer buffer) {
public float drawText(String text, float x, float y, int color, TexturedBuffer buffer, boolean end) {
return drawText(DEFAULT, text, x, y, color, buffer, end);
}
public float drawText(FontStyle style, String text, float x, float y, int color, TexturedBuffer buffer, boolean end) {
float xStart = x;
int previousCodepoint = -1;
for(int i = 0,m=text.length();i<m;) {
int codepoint = text.codePointAt(i);
GlythData data = data(DEFAULT, codepoint, 0);
GlythData data = data(style, codepoint, 0);
if(previousCodepoint != -1) {
x -= data.kerning(previousCodepoint);
}
Glyth glyth = glyth(DEFAULT, codepoint, 0);
Glyth glyth = glyth(style, codepoint, 0);
if(glyth.isValid()) {
float minX = glyth.left() + x;
float minY = glyth.top() + y;
@ -78,7 +74,8 @@ public class Font {
i += Character.charCount(codepoint);
previousCodepoint = codepoint;
}
buffer.end();
if(end) buffer.end();
return x - xStart;
}
public static interface TexturedBuffer {

View File

@ -82,12 +82,12 @@ public class FontManager extends SteppedReloadableAsset<Map<AssetLocation, Objec
fonts.clear();
}
public Font createFont(float size) {
return createFont(size, 1F);
public Font createFont() {
return createFont(1F);
}
public Font createFont(float size, float oversample) {
return new Font(fonts, this::stitch, size, oversample, listeners::add);
public Font createFont(float oversample) {
return new Font(fonts, this::stitch, oversample, listeners::add);
}
private Glyth stitch(IGlythSheetInfo info) {

View File

@ -0,0 +1,18 @@
package speiger.src.coreengine.rendering.gui.font;
import speiger.src.coreengine.assets.AssetLocation;
public record FontStyle(AssetLocation font, float size) {
public FontStyle with(AssetLocation font, float size) {
return new FontStyle(font, size);
}
public FontStyle with(AssetLocation font) {
return new FontStyle(font, size);
}
public FontStyle with(float size) {
return new FontStyle(font, size);
}
}

View File

@ -5,15 +5,15 @@ import java.util.Map;
import speiger.src.collections.ints.maps.impl.hash.Int2ObjectOpenHashMap;
import speiger.src.collections.ints.maps.interfaces.Int2ObjectMap;
import speiger.src.collections.objects.maps.impl.hash.Object2ObjectOpenHashMap;
import speiger.src.coreengine.assets.AssetLocation;
import speiger.src.coreengine.rendering.gui.font.glyth.Glyth;
import speiger.src.coreengine.rendering.gui.font.glyth.GlythData;
import speiger.src.coreengine.rendering.gui.font.glyth.MissingGlyth;
import speiger.src.coreengine.rendering.gui.font.glyth.UnbakedGlyth;
public class GlythCache {
private Font font;
final int style;
Map<AssetLocation, FontCache> cache = new Object2ObjectOpenHashMap<>();
Map<FontStyle, FontCache> cache = new Object2ObjectOpenHashMap<>();
public GlythCache(Font font, int style) {
this.font = font;
@ -21,28 +21,39 @@ public class GlythCache {
}
public void reset() {
cache.values().forEach(FontCache::reset);
cache.clear();
}
private FontCache cache(AssetLocation font) {
private FontCache cache(FontStyle font) {
return cache.computeIfAbsent(font, FontCache::new);
}
public GlythData data(AssetLocation fontId, int codepoint) {
public GlythData data(FontStyle fontId, int codepoint) {
return cache(fontId).data(codepoint);
}
public Glyth glyth(AssetLocation fontId, int codepoint) {
public Glyth glyth(FontStyle fontId, int codepoint) {
return cache(fontId).glyth(codepoint);
}
public class FontCache {
Int2ObjectMap<GlythData> data = new Int2ObjectOpenHashMap<>();
Int2ObjectMap<Glyth> glyth = new Int2ObjectOpenHashMap<>();
AssetLocation fontId;
FontStyle fontStyle;
MissingGlyth missingGlyth;
GlythData missingData;
public FontCache(AssetLocation fontId) {
this.fontId = fontId;
public FontCache(FontStyle fontStyle) {
this.fontStyle = fontStyle;
this.missingGlyth = new MissingGlyth(fontStyle.size(), font.oversample * 2F);
missingData = new GlythData(missingGlyth);
}
private void reset() {
missingGlyth.cleanCache();
missingData.cleanCache();
}
public GlythData data(int codepoint) {
@ -54,8 +65,8 @@ public class GlythCache {
}
private GlythData compute(int codepoint) {
UnbakedGlyth data = font.font(fontId).data(codepoint, style, font.size, font.oversample);
return data == null ? font.missingData : new GlythData(data);
UnbakedGlyth data = font.font(fontStyle.font()).data(codepoint, style, fontStyle.size(), font.oversample);
return data == null ? missingData : new GlythData(data);
}
private Glyth bake(int codepoint) {

View File

@ -4,7 +4,7 @@
"file": "font/roboto/Roboto-Medium.ttf",
"oversample": 3,
"shadowOffset": 1,
"skip": "s",
"skip": "",
"offset": { "x": 0, "y": 0 }
}
}