added FontTTF
This commit is contained in:
parent
fd42674cee
commit
febe5786b9
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
Loading…
Reference in New Issue