Added bitmap font support.

This commit is contained in:
Kapendev 2024-12-08 20:53:28 +02:00
parent 261cccc221
commit c9eddc6495
2 changed files with 66 additions and 0 deletions

View file

@ -173,11 +173,13 @@ These functions handle both forward slashes and backslashes in file paths, ensur
TextId loadText(IStr path, Sz tag = 0);
TextureId loadTexture(IStr path, Sz tag = 0);
FontId loadFont(IStr path, int size, int runeSpacing, int lineSpacing, IStr32 runes = "", Sz tag = 0);
FontId loadAsciiFont(IStr path, int tileWidth, int tileHeight, Sz tag = 0);
SoundId loadSound(IStr path, float volume, float pitch, Sz tag = 0);
Result!LStr loadRawText(IStr path);
Result!Texture loadRawTexture(IStr path);
Result!Font loadRawFont(IStr path, int size, int runeSpacing, int lineSpacing, IStr32 runes = "");
Result!Font loadRawAsciiFont(IStr path, int tileWidth, int tileHeight);
Result!Sound loadRawSound(IStr path, float volume, float pitch);
Result!IStr loadTempText(IStr path);

View file

@ -14,6 +14,7 @@
module parin.engine;
import rl = parin.rl;
import stdc = joka.stdc;
import joka.unions;
import joka.ascii;
import joka.io;
@ -1070,6 +1071,38 @@ rl.Camera2D toRl(Camera camera, Viewport viewport = Viewport()) {
);
}
/// Converts an ASCII bitmap font texture into a font.
/// The texture will be freed when the font is freed.
@trusted
Font toAsciiFont(Texture texture, int tileWidth, int tileHeight) {
if (texture.isEmpty || tileWidth <= 0|| tileHeight <= 0) return Font();
auto result = Font();
result.lineSpacing = tileHeight;
auto rowCount = texture.height / tileHeight;
auto colCount = texture.width / tileWidth;
auto maxCount = rowCount * colCount;
result.data.baseSize = tileHeight;
result.data.glyphCount = maxCount;
result.data.glyphPadding = 0;
result.data.texture = texture.data;
result.data.recs = cast(rl.Rectangle*) stdc.malloc(maxCount * rl.Rectangle.sizeof);
foreach (i; 0 .. maxCount) {
result.data.recs[i].x = (i % colCount) * tileWidth;
result.data.recs[i].y = (i / colCount) * tileHeight;
result.data.recs[i].width = tileWidth;
result.data.recs[i].height = tileHeight;
}
result.data.glyphs = cast(rl.GlyphInfo*) stdc.malloc(maxCount * rl.GlyphInfo.sizeof);
foreach (i; 0 .. maxCount) {
result.data.glyphs[i] = rl.GlyphInfo();
result.data.glyphs[i].value = i + 32;
}
return result;
}
/// Returns the opposite flip value.
/// The opposite of every flip value except none is none.
/// The fallback value is returned if the flip value is none.
@ -1263,6 +1296,37 @@ FontId loadFont(IStr path, int size, int runeSpacing, int lineSpacing, IStr32 ru
}
}
/// Loads an ASCII bitmap font file (PNG) from the assets folder.
/// The resource must be manually freed.
/// Supports both forward slashes and backslashes in file paths.
Result!Font loadRawAsciiFont(IStr path, int tileWidth, int tileHeight) {
auto value = loadRawTexture(path).getOr();
return Result!Font(value.toAsciiFont(tileWidth, tileHeight), value.isEmpty.toFault(Fault.cantFind));
}
/// Loads an ASCII bitmap font file (PNG) from the assets folder.
/// Optionally assigns a tag for resource management.
/// The resource is managed by the engine and can be freed manually or with the `freeResources` function.
/// Supports both forward slashes and backslashes in file paths.
FontId loadAsciiFont(IStr path, int tileWidth, int tileHeight, Sz tag = 0) {
if (engineState.resources.fonts.length == 0) {
engineState.resources.fonts.appendEmpty();
}
foreach (id; engineState.resources.fonts.ids) {
if (engineState.resources.fonts.names[id] == path) {
return FontId(id);
}
}
auto result = loadRawAsciiFont(path, tileWidth, tileHeight);
if (result.isSome) {
return FontId(FontId(engineState.resources.fonts.append(result.get(), path, tag)));
} else {
return FontId();
}
}
/// Loads a sound file (WAV, OGG, MP3) from the assets folder.
/// The resource must be manually freed.
/// Supports both forward slashes and backslashes in file paths.