Implemented Dynamic sized fonts that adjust based on your need.
This commit is contained in:
parent
a1453f0a6c
commit
9ba9e81686
|
@ -80,7 +80,7 @@ public class NewInputTest {
|
||||||
assets.addListener(fonts);
|
assets.addListener(fonts);
|
||||||
assets.reload();
|
assets.reload();
|
||||||
|
|
||||||
System.out.println("Testing: "+GL.getCapabilities().OpenGL46);
|
System.out.println("Testing: "+GL.getCapabilities().OpenGL41);
|
||||||
System.out.println("Testing: "+Integer.divideUnsigned(-1, 255));
|
System.out.println("Testing: "+Integer.divideUnsigned(-1, 255));
|
||||||
|
|
||||||
IFontProvider provider = STBTrueTypeProvider.create(AssetLocation.of("font/roboto/font.json"), assets);
|
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, 0F).rgba(-1).endVertex();
|
||||||
builder.pos(-0.5F, -0.5F, 0).tex(0F, 1F).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 model = new TestModel(builder.getBytes());
|
||||||
TestModel[] guiModel = new TestModel[1];
|
TestModel[] guiModel = new TestModel[1];
|
||||||
List<GLDraw> draws = new ObjectArrayList<>();
|
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);
|
draws.addAll(K);
|
||||||
guiModel[0] = new TestModel(V);
|
guiModel[0] = new TestModel(V);
|
||||||
System.out.println("Testing: "+V.length+" bytes, "+K.size());
|
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();
|
GLStateTracker tracker = GLStateTracker.instance();
|
||||||
GL11.glClearColor(0.2F, 0.55F, 0.66F, 1F);
|
GL11.glClearColor(0.2F, 0.55F, 0.66F, 1F);
|
||||||
|
|
|
@ -6,28 +6,21 @@ import java.util.function.Consumer;
|
||||||
import speiger.src.coreengine.assets.AssetLocation;
|
import speiger.src.coreengine.assets.AssetLocation;
|
||||||
import speiger.src.coreengine.rendering.gui.font.glyth.Glyth;
|
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.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.gui.font.glyth.UnbakedGlyth.GlythBaker;
|
||||||
import speiger.src.coreengine.rendering.tesselation.buffer.IVertexBuilder;
|
import speiger.src.coreengine.rendering.tesselation.buffer.IVertexBuilder;
|
||||||
|
|
||||||
public class Font {
|
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;
|
Map<AssetLocation, FontGroup> fonts;
|
||||||
GlythBaker baker;
|
GlythBaker baker;
|
||||||
float size;
|
|
||||||
float oversample;
|
float oversample;
|
||||||
GlythCache[] styledCache = new GlythCache[] {new GlythCache(this, 0), new GlythCache(this, 1), new GlythCache(this, 2), new GlythCache(this, 3)};
|
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.fonts = fonts;
|
||||||
this.baker = baker;
|
this.baker = baker;
|
||||||
this.size = size;
|
|
||||||
this.oversample = oversample;
|
this.oversample = oversample;
|
||||||
this.missingGlyth = new MissingGlyth(size, oversample * 2F);
|
|
||||||
missingData = new GlythData(missingGlyth);
|
|
||||||
clearing.accept(this::reset);
|
clearing.accept(this::reset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,15 +28,13 @@ public class Font {
|
||||||
for(int i = 0;i<4;i++) {
|
for(int i = 0;i<4;i++) {
|
||||||
styledCache[i].reset();
|
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);
|
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);
|
return styledCache[style & 0x3].glyth(font, codepoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,15 +42,20 @@ public class Font {
|
||||||
return fonts.get(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;
|
int previousCodepoint = -1;
|
||||||
for(int i = 0,m=text.length();i<m;) {
|
for(int i = 0,m=text.length();i<m;) {
|
||||||
int codepoint = text.codePointAt(i);
|
int codepoint = text.codePointAt(i);
|
||||||
GlythData data = data(DEFAULT, codepoint, 0);
|
GlythData data = data(style, codepoint, 0);
|
||||||
if(previousCodepoint != -1) {
|
if(previousCodepoint != -1) {
|
||||||
x -= data.kerning(previousCodepoint);
|
x -= data.kerning(previousCodepoint);
|
||||||
}
|
}
|
||||||
Glyth glyth = glyth(DEFAULT, codepoint, 0);
|
Glyth glyth = glyth(style, codepoint, 0);
|
||||||
if(glyth.isValid()) {
|
if(glyth.isValid()) {
|
||||||
float minX = glyth.left() + x;
|
float minX = glyth.left() + x;
|
||||||
float minY = glyth.top() + y;
|
float minY = glyth.top() + y;
|
||||||
|
@ -78,7 +74,8 @@ public class Font {
|
||||||
i += Character.charCount(codepoint);
|
i += Character.charCount(codepoint);
|
||||||
previousCodepoint = codepoint;
|
previousCodepoint = codepoint;
|
||||||
}
|
}
|
||||||
buffer.end();
|
if(end) buffer.end();
|
||||||
|
return x - xStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static interface TexturedBuffer {
|
public static interface TexturedBuffer {
|
||||||
|
|
|
@ -82,12 +82,12 @@ public class FontManager extends SteppedReloadableAsset<Map<AssetLocation, Objec
|
||||||
fonts.clear();
|
fonts.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Font createFont(float size) {
|
public Font createFont() {
|
||||||
return createFont(size, 1F);
|
return createFont(1F);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Font createFont(float size, float oversample) {
|
public Font createFont(float oversample) {
|
||||||
return new Font(fonts, this::stitch, size, oversample, listeners::add);
|
return new Font(fonts, this::stitch, oversample, listeners::add);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Glyth stitch(IGlythSheetInfo info) {
|
private Glyth stitch(IGlythSheetInfo info) {
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,15 +5,15 @@ import java.util.Map;
|
||||||
import speiger.src.collections.ints.maps.impl.hash.Int2ObjectOpenHashMap;
|
import speiger.src.collections.ints.maps.impl.hash.Int2ObjectOpenHashMap;
|
||||||
import speiger.src.collections.ints.maps.interfaces.Int2ObjectMap;
|
import speiger.src.collections.ints.maps.interfaces.Int2ObjectMap;
|
||||||
import speiger.src.collections.objects.maps.impl.hash.Object2ObjectOpenHashMap;
|
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.Glyth;
|
||||||
import speiger.src.coreengine.rendering.gui.font.glyth.GlythData;
|
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;
|
import speiger.src.coreengine.rendering.gui.font.glyth.UnbakedGlyth;
|
||||||
|
|
||||||
public class GlythCache {
|
public class GlythCache {
|
||||||
private Font font;
|
private Font font;
|
||||||
final int style;
|
final int style;
|
||||||
Map<AssetLocation, FontCache> cache = new Object2ObjectOpenHashMap<>();
|
Map<FontStyle, FontCache> cache = new Object2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
public GlythCache(Font font, int style) {
|
public GlythCache(Font font, int style) {
|
||||||
this.font = font;
|
this.font = font;
|
||||||
|
@ -21,28 +21,39 @@ public class GlythCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reset() {
|
public void reset() {
|
||||||
|
cache.values().forEach(FontCache::reset);
|
||||||
cache.clear();
|
cache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private FontCache cache(AssetLocation font) {
|
private FontCache cache(FontStyle font) {
|
||||||
return cache.computeIfAbsent(font, FontCache::new);
|
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);
|
return cache(fontId).data(codepoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Glyth glyth(AssetLocation fontId, int codepoint) {
|
public Glyth glyth(FontStyle fontId, int codepoint) {
|
||||||
return cache(fontId).glyth(codepoint);
|
return cache(fontId).glyth(codepoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class FontCache {
|
public class FontCache {
|
||||||
Int2ObjectMap<GlythData> data = new Int2ObjectOpenHashMap<>();
|
Int2ObjectMap<GlythData> data = new Int2ObjectOpenHashMap<>();
|
||||||
Int2ObjectMap<Glyth> glyth = 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) {
|
public GlythData data(int codepoint) {
|
||||||
|
@ -54,8 +65,8 @@ public class GlythCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
private GlythData compute(int codepoint) {
|
private GlythData compute(int codepoint) {
|
||||||
UnbakedGlyth data = font.font(fontId).data(codepoint, style, font.size, font.oversample);
|
UnbakedGlyth data = font.font(fontStyle.font()).data(codepoint, style, fontStyle.size(), font.oversample);
|
||||||
return data == null ? font.missingData : new GlythData(data);
|
return data == null ? missingData : new GlythData(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Glyth bake(int codepoint) {
|
private Glyth bake(int codepoint) {
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
"file": "font/roboto/Roboto-Medium.ttf",
|
"file": "font/roboto/Roboto-Medium.ttf",
|
||||||
"oversample": 3,
|
"oversample": 3,
|
||||||
"shadowOffset": 1,
|
"shadowOffset": 1,
|
||||||
"skip": "s",
|
"skip": "",
|
||||||
"offset": { "x": 0, "y": 0 }
|
"offset": { "x": 0, "y": 0 }
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue