added FontTTF

This commit is contained in:
DaniTheSkunk 2022-09-21 03:10:12 +02:00
parent fd42674cee
commit febe5786b9
12 changed files with 151 additions and 6 deletions

View File

@ -8,9 +8,10 @@ public class Test {
var tex2 = window.loadTexture("C:\\art\\pixel stuff.png");
var tileset = window.loadTextureArray("C:\\stream\\coding\\rlc\\tilemap.png", new Vec2i(16, 16));
var font = window.loadFontTileset("EGA8x14.png");
var font2 = window.loadFontTTF("fonts\\LiberationSans-Regular.ttf", 16*8.f);
//img.drawImage(img2, Vec2i.ZERO);
var tex = window.loadTexture(img);
window.setDebug(false);
window.setDebug(true);
while(!window.shouldClose()) {
window.tick();
@ -30,6 +31,7 @@ public class Test {
);
renderContext.drawString(new Vec2i(100, 100), "hello world mew", font);
renderContext.drawString(new Vec2i(710, 140), "hello world mew", font2);
window.renderFinish(renderContext);
}
}

View File

@ -17,8 +17,9 @@ abstract class BaseRenderContext implements IRenderContext {
for(int i = 0; i < string.length(); ++i) {
int ch = buf.get(i);
var tex = font.getTexture(ch);
drawTextureRectangle(new Recti(new Vec2i(x, y), tex.getSize()), tex);
x += font.getCharWidth(ch);
var off = font.getOffset(ch);
drawTextureRectangle(new Recti(Vec2i.add(new Vec2i(x, y), off), tex.getSize()), tex);
x += font.getXAdvance(ch);
}
}
}

View File

@ -1,5 +1,8 @@
package com.danitheskunk.skunkworks;
import org.lwjgl.stb.STBTTFontinfo;
import static org.lwjgl.stb.STBTruetype.*;
abstract class BaseWindow implements IWindow {
protected final Engine engine;
@ -7,6 +10,12 @@ abstract class BaseWindow implements IWindow {
this.engine = engine;
}
@Override
public Engine getEngine() {
return engine;
}
@Override
public IFont loadFontTileset(String path) {
var img = engine.loadImage(path);
var charSize = Vec2i.div(img.getSize(), 16);
@ -14,4 +23,12 @@ abstract class BaseWindow implements IWindow {
assert tex.size() == 256;
return new FontTileset(tex);
}
@Override
public IFont loadFontTTF(String path, float size) {
var bytes = engine.loadBytes(path);
return new FontTTF(bytes, size, this);
}
}

View File

@ -0,0 +1,111 @@
package com.danitheskunk.skunkworks;
import org.lwjgl.BufferUtils;
import org.lwjgl.stb.STBTTFontinfo;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.HashMap;
import static org.lwjgl.stb.STBTruetype.*;
import static org.lwjgl.stb.STBTruetype.stbtt_ScaleForPixelHeight;
public class FontTTF implements IFont {
HashMap<Integer, Char> chars;
int lineHeight;
float size;
float unscaled_size;
STBTTFontinfo info;
IWindow window;
FontTTF(ByteBuffer buffer, float size, IWindow window) {
int[] ascent = {0};
int[] descent = {0};
int[] lineGap = {0};
this.window = window;
this.chars = new HashMap<>();
this.info = STBTTFontinfo.create();
if(!stbtt_InitFont(info, buffer)) {
throw new IllegalStateException("Failed to initialize font information.");
}
//todo: save these
stbtt_GetFontVMetrics(info, ascent, descent, lineGap);
lineHeight = lineGap[0];
this.unscaled_size = size;
this.size = stbtt_ScaleForPixelHeight(info, size);
//precache ascii characters
for(int i = 32; i < 128; ++i)
cacheChar(i);
}
void cacheChar(int ch) {
if(chars.containsKey(ch))
return;
int[] width = {0};
int[] height = {0};
int[] xoff = {0};
int[] yoff = {0};
int[] advanceWidth = {0};
int[] leftSideBearing = {0};
ITexture tex;
var bufmono = stbtt_GetCodepointBitmap(info, size, size, ch, width, height, xoff, yoff);
if(bufmono != null) {
var buf = ByteBuffer.allocate(bufmono.remaining() * 4);
while(bufmono.hasRemaining()) {
var b = bufmono.get();
buf.put((byte) 0xff);
buf.put((byte) 0xff);
buf.put((byte) 0xff);
buf.put(b);
}
buf.flip();
tex = window.loadTexture(new Image(buf, new Vec2i(width[0], height[0])));
} else {
tex = window.loadTexture(new Image(Vec2i.ZERO));
}
stbtt_GetCodepointHMetrics(info, ch, advanceWidth, leftSideBearing);
var c = new Char(tex, (int)(advanceWidth[0] * size), new Vec2i(xoff[0], yoff[0]));
chars.put(ch, c);
}
@Override
public int getXAdvance(int ch) {
cacheChar(ch);
return chars.get(ch).advance;
}
@Override
public int getLineHeight(int ch) {
cacheChar(ch);
return lineHeight;
}
@Override
public Vec2i getOffset(int ch) {
cacheChar(ch);
return chars.get(ch).off;
}
@Override
public ITexture getTexture(int ch) {
cacheChar(ch);
return chars.get(ch).tex;
}
private class Char {
ITexture tex;
int advance;
Vec2i off;
Char(ITexture tex, int advance, Vec2i off) {
this.tex = tex;
this.advance = advance;
this.off = off;
}
}
}

View File

@ -12,7 +12,7 @@ class FontTileset implements IFont {
}
@Override
public int getCharWidth(int ch) {
public int getXAdvance(int ch) {
return charSize.getX();
}
@ -21,6 +21,11 @@ class FontTileset implements IFont {
return charSize.getY();
}
@Override
public Vec2i getOffset(int ch) {
return Vec2i.ZERO;
}
@Override
public ITexture getTexture(int ch) {
if(ch >= 256 || ch < 0) {

View File

@ -1,7 +1,8 @@
package com.danitheskunk.skunkworks;
public interface IFont {
int getCharWidth(int ch);
int getLineHeight(int ch);
Vec2i getOffset(int ch);
ITexture getTexture(int ch);
int getXAdvance(int ch);
}

View File

@ -3,7 +3,9 @@ package com.danitheskunk.skunkworks;
import java.util.List;
public interface IWindow {
Engine getEngine();
IFont loadFontTileset(String path);
IFont loadFontTTF(String path, float size);
ITexture loadTexture(Image image);
ITexture loadTexture(String path);
List<ITexture> loadTextureArray(Image image, Vec2i tileSize);

View File

@ -9,7 +9,7 @@ public class Image {
private final Vec2i size;
//constructors
Image(ByteBuffer buffer) {
Image(ByteBuffer buffer) { //png or similar
//todo: resource system
int[] x = {0}, y = {0}, n = {0};
var img = STBImage.stbi_load_from_memory(buffer, x, y, n, 4);
@ -24,6 +24,12 @@ public class Image {
data = new byte[size.getX() * size.getY() * 4];
}
Image(ByteBuffer buffer, Vec2i size) {
data = new byte[buffer.remaining()];
buffer.get(data);
this.size = size;
}
//getters
public byte[] getData() {
return data;

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.