New engine font and UI is flooring.

This commit is contained in:
Kapendev 2025-01-03 23:28:40 +02:00
parent 419451f650
commit 65f800f595
8 changed files with 25 additions and 15 deletions

4
assets/README.md Normal file
View file

@ -0,0 +1,4 @@
# Assets
* [Atlas](atlas.png): By [Kapendev](https://kapendev.itch.io), CC0
* [Monogram](monogram.png): By [DATAGOBLIN](https://datagoblin.itch.io/monogram), CC0

View file

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

Before After
Before After

BIN
assets/monogram.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -9,6 +9,9 @@
"dependencies": {
"joka": "*"
},
"stringImportPaths": [
"assets"
],
"subPackages" : [
"setup",
"web"

View file

@ -4,7 +4,7 @@ This folder provides example projects to help you get started.
> [!NOTE]
> If an example uses textures,
> be sure to download the [atlas.png](atlas.png) file and place it in the project's assets folder.
> be sure to download the [atlas.png](../assets/atlas.png) file and place it in the project's assets folder.
## Categories

View file

@ -14,7 +14,7 @@ bool update(float dt) {
setUiFocus(0);
setUiStartPoint(Vec2(8));
// Toggle the limit of the drag handle.
if (uiButton(Vec2(80, 30), "Limit: {}".format(handleOptions.dragLimit))) {
if (uiButton(Vec2(100, 30), "Limit: {}".format(handleOptions.dragLimit))) {
if (handleOptions.dragLimit) handleOptions.dragLimit = UiDragLimit.none;
else handleOptions.dragLimit = UiDragLimit.viewport;
}

View file

@ -169,6 +169,7 @@ enum Mouse : ubyte {
/// A type representing a limited set of gamepad buttons.
enum Gamepad : ubyte {
none = rl.GAMEPAD_BUTTON_UNKNOWN, /// Not a button.
left = rl.GAMEPAD_BUTTON_LEFT_FACE_LEFT, /// The left button.
right = rl.GAMEPAD_BUTTON_LEFT_FACE_RIGHT, /// The right button.
up = rl.GAMEPAD_BUTTON_LEFT_FACE_UP, /// The up button.
@ -973,6 +974,7 @@ struct EngineState {
EngineResources resources;
EngineFullscreenState fullscreenState;
Font font;
Color borderColor;
Sz tickCount;
LStr assetsPath;
@ -995,6 +997,7 @@ struct EngineState {
// }
viewport.free();
resources.free();
font.free();
tempText.free();
assetsPath.free();
this = EngineState();
@ -1106,17 +1109,16 @@ 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.
// NOTE: The number of items allocated for this font is calculated as: (font width / tile width) * (font height / tile height)
// NOTE: This function assumes that raylib uses malloc.
@trusted
Font toFont(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;
@ -1291,7 +1293,7 @@ TextureId loadTexture(IStr path, Sz tag = 0) {
Result!Font loadRawFont(IStr path, int size, int runeSpacing, int lineSpacing, IStr32 runes = "") {
auto targetPath = canUseAssetsPath ? path.toAssetsPath() : path;
auto value = rl.LoadFontEx(targetPath.toCStr().getOr(), size, runes == "" ? null : cast(int*) runes.ptr, cast(int) runes.length).toParin();
if (value.data.texture.id == engineFont.data.texture.id) {
if (value.data.texture.id == rl.GetFontDefault().texture.id) {
value = Font();
}
value.runeSpacing = runeSpacing;
@ -1420,9 +1422,7 @@ void openUrl(IStr url = "https://github.com/Kapendev/parin") {
/// You should avoid calling this function manually.
@trusted
void openWindow(int width, int height, IStr appPath, IStr title = "Parin") {
if (rl.IsWindowReady) {
return;
}
if (rl.IsWindowReady) return;
rl.SetConfigFlags(rl.FLAG_WINDOW_RESIZABLE | rl.FLAG_VSYNC_HINT);
rl.SetTraceLogLevel(rl.LOG_ERROR);
rl.InitWindow(width, height, title.toCStr().getOr());
@ -1438,6 +1438,12 @@ void openWindow(int width, int height, IStr appPath, IStr title = "Parin") {
engineState.tempText.reserve(8192);
// NOTE: This line is used for fixing an alpha bug with render textures.
rl.rlSetBlendFactorsSeparate(0x0302, 0x0303, 1, 0x0303, 0x8006, 0x8006);
// Load default engine assets.
auto monogramData = cast(const(ubyte)[]) import("monogram.png");
auto monogramImage = rl.LoadImageFromMemory(".png", monogramData.ptr, cast(int) monogramData.length);
auto monogramTexture = rl.LoadTextureFromImage(monogramImage);
engineState.font = monogramTexture.toParin().toFont(6, 12);
rl.UnloadImage(monogramImage);
}
/// Updates the window every frame with the given function.
@ -1668,10 +1674,7 @@ void setBorderColor(Color value) {
/// Returns the default engine font. This font should not be freed.
@trusted
Font engineFont() {
auto result = rl.GetFontDefault().toParin();
result.runeSpacing = 1;
result.lineSpacing = 10;
return result;
return engineState.font;
}
/// Returns the default filter mode for textures.

View file

@ -358,10 +358,10 @@ void drawUiText(Vec2 size, IStr text, Vec2 point, UiOptions options = UiOptions(
case Alignment.center: break;
case Alignment.right: textPoint.x -= options.alignmentOffset; break;
}
auto textOptions = DrawOptions(options.alignment, cast(int) size.x.round());
auto textOptions = DrawOptions(options.alignment, cast(int) size.x.floor());
textOptions.hook = Hook.center;
if (options.isDisabled) textOptions.color.a = defaultUiAlpha;
drawText(font, text, textPoint.round(), textOptions);
drawText(font, text, textPoint.floor(), textOptions);
}
void uiText(Vec2 size, IStr text, UiOptions options = UiOptions()) {
@ -581,7 +581,7 @@ void drawUiTextField(Vec2 size, Str text, Vec2 point, UiOptions options = UiOpti
if (!options.isDisabled) {
auto rect = Rect(textPoint.x + textSize.x + 1.0f, textPoint.y, font.size * 0.05f, font.size).area(Hook.center);
rect.subTopBottom(rect.size.y * 0.1f);
rect = rect.round();
rect = rect.floor();
if (rect.size.x == 0.0f) rect.size.x = 1.0f;
drawRect(rect, defaultUiDisabledColor);
}