Started the rework of the font system so the system works better.
This commit is contained in:
parent
62b91f0f1d
commit
7fdbe645e4
|
@ -14,8 +14,8 @@ import speiger.src.coreengine.assets.base.IAsset;
|
||||||
import speiger.src.coreengine.assets.base.IAssetPackage;
|
import speiger.src.coreengine.assets.base.IAssetPackage;
|
||||||
import speiger.src.coreengine.assets.base.IAssetProvider;
|
import speiger.src.coreengine.assets.base.IAssetProvider;
|
||||||
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.UnbakedGlyth;
|
||||||
import speiger.src.coreengine.rendering.gui.font.glyth.GlythData.GlythBaker;
|
import speiger.src.coreengine.rendering.gui.font.glyth.UnbakedGlyth.GlythBaker;
|
||||||
import speiger.src.coreengine.rendering.gui.font.glyth.IGlythSheetInfo;
|
import speiger.src.coreengine.rendering.gui.font.glyth.IGlythSheetInfo;
|
||||||
import speiger.src.coreengine.rendering.gui.font.providers.IFontProvider;
|
import speiger.src.coreengine.rendering.gui.font.providers.IFontProvider;
|
||||||
import speiger.src.coreengine.rendering.gui.font.providers.STBTrueTypeProvider;
|
import speiger.src.coreengine.rendering.gui.font.providers.STBTrueTypeProvider;
|
||||||
|
@ -99,7 +99,7 @@ public class NewInputTest {
|
||||||
else if(T.key() == GLFW.GLFW_KEY_Z) {
|
else if(T.key() == GLFW.GLFW_KEY_Z) {
|
||||||
T.cancel();
|
T.cancel();
|
||||||
texture.bind();
|
texture.bind();
|
||||||
GlythData data = provider.glythData("C".codePointAt(0), 0);
|
UnbakedGlyth data = provider.glythData("C".codePointAt(0), 0);
|
||||||
data.bake(new GlythBaker() {
|
data.bake(new GlythBaker() {
|
||||||
@Override
|
@Override
|
||||||
public Glyth bake(IGlythSheetInfo info) {
|
public Glyth bake(IGlythSheetInfo info) {
|
||||||
|
@ -108,8 +108,7 @@ public class NewInputTest {
|
||||||
info.upload(half - (width >> 2), half - (height >> 2));
|
info.upload(half - (width >> 2), half - (height >> 2));
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
});
|
}, 1F, 1F);
|
||||||
System.out.println("Testing: "+data.advance()+", "+bit.getCharacter("C".codePointAt(0), false).getXAdvance());
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
package speiger.src.coreengine.rendering.gui.font;
|
||||||
|
|
||||||
|
import speiger.src.collections.ints.maps.impl.hash.Int2ObjectOpenHashMap;
|
||||||
|
import speiger.src.collections.ints.maps.interfaces.Int2ObjectMap;
|
||||||
|
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.UnbakedGlyth.GlythBaker;
|
||||||
|
|
||||||
|
public class Font {
|
||||||
|
FontGroup fonts;
|
||||||
|
GlythBaker baker;
|
||||||
|
float size;
|
||||||
|
float oversample;
|
||||||
|
GlythCache[] styledCache = new GlythCache[] {new GlythCache(0), new GlythCache(1), new GlythCache(2), new GlythCache(3)};
|
||||||
|
|
||||||
|
private Font(FontGroup fonts, GlythBaker baker, float size, float oversample) {
|
||||||
|
this.fonts = fonts;
|
||||||
|
this.baker = baker;
|
||||||
|
this.size = size;
|
||||||
|
this.oversample = oversample;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GlythData data(int codepoint, int style) {
|
||||||
|
return styledCache[style & 0x3].data(codepoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Glyth glyth(int codepoint, int style) {
|
||||||
|
return styledCache[style & 0x3].glyth(codepoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class GlythCache {
|
||||||
|
final int style;
|
||||||
|
Int2ObjectMap<GlythData> data = new Int2ObjectOpenHashMap<>();
|
||||||
|
Int2ObjectMap<Glyth> glyth = new Int2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
|
public GlythCache(int style) {
|
||||||
|
this.style = style;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GlythData data(int codepoint) {
|
||||||
|
return data.computeIfAbsent(codepoint, this::compute);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Glyth glyth(int codepoint) {
|
||||||
|
return glyth.computeIfAbsent(codepoint, this::bake);
|
||||||
|
}
|
||||||
|
|
||||||
|
private GlythData compute(int codepoint) {
|
||||||
|
return new GlythData(fonts.data(codepoint, style), size);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Glyth bake(int codepoint) {
|
||||||
|
return fonts.data(codepoint, style).bake(baker, size, oversample);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,31 +5,23 @@ import java.util.List;
|
||||||
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.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.UnbakedGlyth;
|
||||||
import speiger.src.coreengine.rendering.gui.font.glyth.GlythData;
|
|
||||||
import speiger.src.coreengine.rendering.gui.font.glyth.GlythData.GlythBaker;
|
|
||||||
import speiger.src.coreengine.rendering.gui.font.providers.IFontProvider;
|
import speiger.src.coreengine.rendering.gui.font.providers.IFontProvider;
|
||||||
|
|
||||||
public class FontGroup {
|
public class FontGroup {
|
||||||
AssetLocation locations;
|
AssetLocation locations;
|
||||||
List<IFontProvider> providers;
|
List<IFontProvider> providers;
|
||||||
GlythBaker baker;
|
|
||||||
StyledFont[] cache = new StyledFont[] {new StyledFont(0), new StyledFont(1), new StyledFont(2), new StyledFont(3)};
|
StyledFont[] cache = new StyledFont[] {new StyledFont(0), new StyledFont(1), new StyledFont(2), new StyledFont(3)};
|
||||||
|
|
||||||
public FontGroup(AssetLocation locations, List<IFontProvider> providers, GlythBaker baker) {
|
public FontGroup(AssetLocation locations, List<IFontProvider> providers) {
|
||||||
this.locations = locations;
|
this.locations = locations;
|
||||||
this.providers = providers;
|
this.providers = providers;
|
||||||
this.baker = baker;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public GlythData data(int codepoint, int style) {
|
public UnbakedGlyth data(int codepoint, int style) {
|
||||||
return cache[style & 0x3].data(codepoint);
|
return cache[style & 0x3].data(codepoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Glyth glyth(int codepoint, int style) {
|
|
||||||
return cache[style & 0x3].glyth(codepoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void close() {
|
public void close() {
|
||||||
providers.forEach(IFontProvider::close);
|
providers.forEach(IFontProvider::close);
|
||||||
providers.clear();
|
providers.clear();
|
||||||
|
@ -37,35 +29,22 @@ public class FontGroup {
|
||||||
|
|
||||||
private class StyledFont {
|
private class StyledFont {
|
||||||
final int style;
|
final int style;
|
||||||
Int2ObjectMap<Glyth> bakedGlyths = new Int2ObjectOpenHashMap<>();
|
Int2ObjectMap<UnbakedGlyth> dataGlyths = new Int2ObjectOpenHashMap<>();
|
||||||
Int2ObjectMap<GlythData> dataGlyths = new Int2ObjectOpenHashMap<>();
|
|
||||||
|
|
||||||
public StyledFont(int style) {
|
public StyledFont(int style) {
|
||||||
this.style = style;
|
this.style = style;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GlythData data(int codepoint) {
|
public UnbakedGlyth data(int codepoint) {
|
||||||
return dataGlyths.computeIfAbsent(codepoint, this::compute);
|
return dataGlyths.computeIfAbsent(codepoint, this::compute);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Glyth glyth(int codepoint) {
|
private UnbakedGlyth compute(int codepoint) {
|
||||||
return bakedGlyths.computeIfAbsent(codepoint, this::bake);
|
|
||||||
}
|
|
||||||
|
|
||||||
private GlythData compute(int codepoint) {
|
|
||||||
for(int i = 0,m=providers.size();i<m;i++) {
|
for(int i = 0,m=providers.size();i<m;i++) {
|
||||||
GlythData data = providers.get(i).glythData(codepoint, style);
|
UnbakedGlyth data = providers.get(i).glythData(codepoint, style);
|
||||||
if(data != null) return data;
|
if(data != null) return data;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Glyth bake(int codepoint) {
|
|
||||||
for(int i = 0,m=providers.size();i<m;i++) {
|
|
||||||
GlythData data = providers.get(i).glythData(codepoint, style);
|
|
||||||
if(data != null) return data.bake(baker);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,13 @@
|
||||||
package speiger.src.coreengine.rendering.gui.font.glyth;
|
package speiger.src.coreengine.rendering.gui.font.glyth;
|
||||||
|
|
||||||
public record Glyth(int texture, float minU, float minV, float maxU, float maxV) {
|
public record Glyth(int texture, float minU, float minV, float maxU, float maxV, int left, int right, int top, int bottom) {
|
||||||
public static final Glyth EMPTY = new Glyth(-1, 0, 0, 0, 0);
|
public static final Glyth EMPTY = new Glyth();
|
||||||
|
|
||||||
|
private Glyth() {
|
||||||
|
this(-1, 0F, 0F, 0F, 0F, 0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Glyth(int texture, float minU, float minV, float maxU, float maxV) {
|
||||||
|
this(texture, minU, minV, maxU, maxV, 0, 0, 0, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,26 @@
|
||||||
package speiger.src.coreengine.rendering.gui.font.glyth;
|
package speiger.src.coreengine.rendering.gui.font.glyth;
|
||||||
|
|
||||||
public interface GlythData {
|
import speiger.src.collections.ints.functions.function.Int2FloatFunction;
|
||||||
public float advance();
|
import speiger.src.collections.ints.maps.impl.hash.Int2FloatOpenHashMap;
|
||||||
public default float shadowOffset() { return 1F; }
|
import speiger.src.collections.ints.maps.interfaces.Int2FloatMap;
|
||||||
public Glyth bake(GlythBaker baker);
|
|
||||||
|
public class GlythData {
|
||||||
|
float advance;
|
||||||
|
float shadowOffset;
|
||||||
|
Int2FloatMap kernlings = new Int2FloatOpenHashMap();
|
||||||
|
Int2FloatFunction kernling;
|
||||||
|
|
||||||
|
public GlythData(float advance, float shadowOffset, Int2FloatFunction kernling) {
|
||||||
public static record EmptyGlythData(float advance) implements GlythData {
|
this.advance = advance;
|
||||||
@Override
|
this.shadowOffset = shadowOffset;
|
||||||
public Glyth bake(GlythBaker baker) { return Glyth.EMPTY; }
|
this.kernling = kernling;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static interface GlythBaker {
|
public GlythData(UnbakedGlyth glyth, float size) {
|
||||||
Glyth bake(IGlythSheetInfo info);
|
this(glyth.advance(size), glyth.shadowOffset(), glyth::kernling);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public float advance() { return advance; }
|
||||||
|
public float shadowOffset() { return shadowOffset; }
|
||||||
|
public float kernling(int codepoint) { return kernlings.computeFloatIfAbsent(codepoint, kernling); }
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
package speiger.src.coreengine.rendering.gui.font.glyth;
|
||||||
|
|
||||||
|
public interface UnbakedGlyth {
|
||||||
|
public float advance(float size);
|
||||||
|
public float kernling(int codepoint);
|
||||||
|
public default float shadowOffset() { return 1F; }
|
||||||
|
public Glyth bake(GlythBaker baker, float size, float oversample);
|
||||||
|
|
||||||
|
|
||||||
|
public static record EmptyGlythData(float advance) implements UnbakedGlyth {
|
||||||
|
@Override
|
||||||
|
public Glyth bake(GlythBaker baker, float size, float oversample) { return Glyth.EMPTY; }
|
||||||
|
@Override
|
||||||
|
public float advance(float size) { return advance; }
|
||||||
|
@Override
|
||||||
|
public float kernling(int codepoint) { return 0F; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static interface GlythBaker {
|
||||||
|
Glyth bake(IGlythSheetInfo info);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,13 +1,13 @@
|
||||||
package speiger.src.coreengine.rendering.gui.font.providers;
|
package speiger.src.coreengine.rendering.gui.font.providers;
|
||||||
|
|
||||||
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.UnbakedGlyth;
|
||||||
|
|
||||||
public class BitmapProivder implements IFontProvider {
|
public class BitmapProivder implements IFontProvider {
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GlythData glythData(int codepoint, int style) {
|
public UnbakedGlyth glythData(int codepoint, int style) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,23 +16,26 @@ public class BitmapProivder implements IFontProvider {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class BitmapGlyth implements GlythData {
|
private static class BitmapGlyth implements UnbakedGlyth {
|
||||||
int minX;
|
int minX;
|
||||||
int minY;
|
int minY;
|
||||||
int maxX;
|
int maxX;
|
||||||
int maxY;
|
int maxY;
|
||||||
int glyth;
|
int glyth;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float advance() {
|
public Glyth bake(GlythBaker baker, float size, float oversample) {
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Glyth bake(GlythBaker baker) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float advance(float size) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float kernling(int codepoint) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package speiger.src.coreengine.rendering.gui.font.providers;
|
package speiger.src.coreengine.rendering.gui.font.providers;
|
||||||
|
|
||||||
import speiger.src.coreengine.rendering.gui.font.glyth.GlythData;
|
import speiger.src.coreengine.rendering.gui.font.glyth.UnbakedGlyth;
|
||||||
|
|
||||||
public interface IFontProvider extends AutoCloseable {
|
public interface IFontProvider extends AutoCloseable {
|
||||||
public static final int REGULAR = 0;
|
public static final int REGULAR = 0;
|
||||||
|
@ -9,7 +9,7 @@ public interface IFontProvider extends AutoCloseable {
|
||||||
public static final int ITALIC_BOLD = 3;
|
public static final int ITALIC_BOLD = 3;
|
||||||
|
|
||||||
|
|
||||||
public GlythData glythData(int codepoint, int style);
|
public UnbakedGlyth glythData(int codepoint, int style);
|
||||||
@Override
|
@Override
|
||||||
void close();
|
void close();
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,8 @@ import speiger.src.coreengine.assets.base.IAssetProvider;
|
||||||
import speiger.src.coreengine.assets.parsers.NativeMemoryParser;
|
import speiger.src.coreengine.assets.parsers.NativeMemoryParser;
|
||||||
import speiger.src.coreengine.rendering.gui.font.FontTexture;
|
import speiger.src.coreengine.rendering.gui.font.FontTexture;
|
||||||
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.UnbakedGlyth;
|
||||||
import speiger.src.coreengine.rendering.gui.font.glyth.GlythData.EmptyGlythData;
|
import speiger.src.coreengine.rendering.gui.font.glyth.UnbakedGlyth.EmptyGlythData;
|
||||||
import speiger.src.coreengine.rendering.gui.font.glyth.IGlythSheetInfo;
|
import speiger.src.coreengine.rendering.gui.font.glyth.IGlythSheetInfo;
|
||||||
import speiger.src.coreengine.rendering.textures.custom.Drawable;
|
import speiger.src.coreengine.rendering.textures.custom.Drawable;
|
||||||
import speiger.src.coreengine.utils.helpers.JsonUtil;
|
import speiger.src.coreengine.utils.helpers.JsonUtil;
|
||||||
|
@ -115,7 +115,7 @@ public class STBTrueTypeProvider implements IFontProvider {
|
||||||
data = 0L;
|
data = 0L;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GlythData glythData(int codepoint) {
|
public UnbakedGlyth glythData(int codepoint) {
|
||||||
if(skip.contains(codepoint)) return null;
|
if(skip.contains(codepoint)) return null;
|
||||||
int glyth = STBTruetype.nstbtt_FindGlyphIndex(info.address(), codepoint);
|
int glyth = STBTruetype.nstbtt_FindGlyphIndex(info.address(), codepoint);
|
||||||
if(glyth == 0) return null;
|
if(glyth == 0) return null;
|
||||||
|
@ -143,7 +143,7 @@ public class STBTrueTypeProvider implements IFontProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GlythData glythData(int codepoint, int style) {
|
public UnbakedGlyth glythData(int codepoint, int style) {
|
||||||
TrueTypeInstance instance = instances[style & 0x3];
|
TrueTypeInstance instance = instances[style & 0x3];
|
||||||
return instance == null ? null : instance.glythData(codepoint);
|
return instance == null ? null : instance.glythData(codepoint);
|
||||||
}
|
}
|
||||||
|
@ -158,7 +158,7 @@ public class STBTrueTypeProvider implements IFontProvider {
|
||||||
instances = null;
|
instances = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class STBGlyth implements GlythData {
|
private static class STBGlyth implements UnbakedGlyth {
|
||||||
final TrueTypeInstance owner;
|
final TrueTypeInstance owner;
|
||||||
final int width;
|
final int width;
|
||||||
final int height;
|
final int height;
|
||||||
|
@ -174,12 +174,13 @@ public class STBTrueTypeProvider implements IFontProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float advance() { return advance; }
|
public float advance(float size) { return advance; }
|
||||||
@Override
|
@Override
|
||||||
public float shadowOffset() { return owner.shadowOffset; }
|
public float shadowOffset() { return owner.shadowOffset; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Glyth bake(GlythBaker baker) {
|
public float kernling(int codepoint) { return STBTruetype.stbtt_GetCodepointKernAdvance(owner.info, codepoint, glyth); }
|
||||||
|
@Override
|
||||||
|
public Glyth bake(GlythBaker baker, float size, float oversample) {
|
||||||
return baker.bake(new IGlythSheetInfo() {
|
return baker.bake(new IGlythSheetInfo() {
|
||||||
@Override
|
@Override
|
||||||
public int width() { return width; }
|
public int width() { return width; }
|
||||||
|
@ -196,6 +197,5 @@ public class STBTrueTypeProvider implements IFontProvider {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue