remove font.zig from platform layer

This commit is contained in:
Rokas Puzonas 2026-09-15 00:15:08 +03:00
parent 782ccae6e2
commit fff22349de
3 changed files with 118 additions and 118 deletions

View File

@ -18,6 +18,7 @@ const Rect = Platform.Rect;
const Color = Platform.Color;
const CanvasScaler = @import("./canvas_scaler.zig");
const Font = @import("./font.zig");
const App = @This();
@ -100,7 +101,7 @@ const Entity = struct {
const Id = SlotMap.Id;
};
roboto_font: Gfx.Font,
roboto_font: Font,
tilemap: Tilemap,
entities: Entity.SlotMap,
@ -164,7 +165,7 @@ const Tilesheet = struct {
};
pub fn init(self: *App, plt: Platform.Init) !?u8 {
const roboto_font = try Gfx.Font.init(plt.gpa, .{
const roboto_font = try Font.init(plt.gpa, .{
.spritesheet = Gfx.initSpritesheet(.{ .format = .r8 }),
.ttf_data = plt.assets.readFile("roboto-font/Roboto-Regular.ttf")
});
@ -406,11 +407,11 @@ pub fn frame(self: *App, plt: Platform.Frame) !void {
}
}
// self.roboto_font.drawText(.{
// .text = try std.fmt.allocPrint(plt.frame, "Hello {:.0}!", .{plt.time()}),
// .pos = .init(0, 0),
// .height = 32,
// });
self.roboto_font.drawText(.{
.text = try std.fmt.allocPrint(plt.frame, "Hello {:.0}!", .{plt.time()}),
.pos = .init(0, 0),
.height = 32,
});
}
pub fn deinit(self: *App, plt: Platform.Deinit) void {

View File

@ -4,12 +4,13 @@ const assert = std.debug.assert;
const Allocator = std.mem.Allocator;
const Io = std.Io;
const Math = @import("math");
const Vec2 = Math.Vec2;
const Rect = Math.Rect;
const Platform = @import("platform/root.zig");
const Gfx = Platform.Gfx;
const SlotMapType = Platform.SlotMapType;
const Vec2 = Platform.Vec2;
const Rect = Platform.Rect;
const Color = Platform.Color;
const Gfx = @import("./graphics.zig");
const SlotMapType = @import("slot_map.zig").SlotMapType;
const STBTrueType = @import("stb_truetype");
const Font = @This();
@ -737,3 +738,107 @@ pub const TextRunLayout = struct {
};
}
};
pub const TextBuilder = struct {
gpa: std.mem.Allocator,
glyphs: std.ArrayList(TextBuilder.Glyph),
color: Color,
baseline: f32,
layout: ?Font.TextRunLayout,
bounds: Rect,
const Glyph = struct {
sprite: Gfx.Sprite.Id,
rect: Rect,
color: Color
};
pub fn init(gpa: std.mem.Allocator) TextBuilder {
return TextBuilder{
.gpa = gpa,
.glyphs = .empty,
.color = .white,
.baseline = 0,
.layout = null,
.bounds = .init(0, 0, 0, 0)
};
}
pub fn font(self: *TextBuilder, new_font: *Font, height: f32) void {
var new_layout = Font.TextRunLayout.init(new_font, height);
if (self.layout) |layout| {
if (new_layout.font == layout.font and
new_layout.scale_x == layout.scale_x and
new_layout.scale_y == layout.scale_y
) {
return;
}
}
const font_baseline = new_font.getAscent(height);
if (font_baseline > self.baseline) {
// Fixup previously drawn glyph to match the new larger baseline
const offset_y = font_baseline - self.baseline;
for (self.glyphs.items) |*glyph| {
glyph.rect.pos.y += offset_y;
}
self.bounds.pos.y += offset_y;
self.baseline = font_baseline;
}
if (self.layout) |layout| {
new_layout.pen_pos = layout.pen_pos;
if (layout.font == new_layout.font) {
new_layout.prev_glyph = layout.prev_glyph;
}
}
self.layout = new_layout;
}
pub fn putCodepoint(self: *TextBuilder, codepoint: u21) !void {
if (self.layout == null) {
return;
}
const layout = &self.layout.?;
const glyph_index = layout.font.getGlyphIndex(codepoint) orelse return;
const glyph_layout = layout.next(glyph_index) orelse return;
var rect = glyph_layout.rect;
rect.pos.y += self.baseline;
try self.glyphs.append(self.gpa, TextBuilder.Glyph{
.sprite = glyph_layout.sprite,
.rect = rect,
.color = self.color
});
if (self.bounds.size.x > 0 and self.bounds.size.y > 0) {
self.bounds = self.bounds.expand(rect);
} else {
self.bounds = rect;
}
}
pub fn put(self: *TextBuilder, text: []const u8) !void {
var iter = std.unicode.Utf8Iterator{ .bytes = text, .i = 0 };
while (iter.nextCodepoint()) |codepoint| {
try self.putCodepoint(codepoint);
}
}
pub fn draw(self: *TextBuilder, pos: Vec2) void {
for (self.glyphs.items) |glyph| {
Gfx.drawSprite(glyph.sprite, glyph.rect.pos.add(pos), glyph.rect.size, glyph.color);
}
}
pub fn offset(self: *TextBuilder, vec2: Vec2) void {
if (self.layout) |*layout| {
layout.pen_pos = layout.pen_pos.add(vec2);
}
}
};

View File

@ -21,8 +21,6 @@ pub const Color = @import("./color.zig");
const shd = @import("shader");
const SlotMapType = @import("slot_map.zig").SlotMapType;
pub const Font = @import("./font.zig");
const Frame = struct {
index: u32,
quads: std.ArrayList(VertexQuad),
@ -1203,110 +1201,6 @@ pub fn deinitSpritesheet(id: Spritesheet.Id) void {
}
}
pub const TextBuilder = struct {
gpa: std.mem.Allocator,
glyphs: std.ArrayList(Glyph),
color: Color,
baseline: f32,
layout: ?Font.TextRunLayout,
bounds: Rect,
const Glyph = struct {
sprite: Sprite.Id,
rect: Rect,
color: Color
};
pub fn init(gpa: std.mem.Allocator) TextBuilder {
return TextBuilder{
.gpa = gpa,
.glyphs = .empty,
.color = .white,
.baseline = 0,
.layout = null,
.bounds = .init(0, 0, 0, 0)
};
}
pub fn font(self: *TextBuilder, new_font: *Font, height: f32) void {
var new_layout = Font.TextRunLayout.init(new_font, height);
if (self.layout) |layout| {
if (new_layout.font == layout.font and
new_layout.scale_x == layout.scale_x and
new_layout.scale_y == layout.scale_y
) {
return;
}
}
const font_baseline = new_font.getAscent(height);
if (font_baseline > self.baseline) {
// Fixup previously drawn glyph to match the new larger baseline
const offset_y = font_baseline - self.baseline;
for (self.glyphs.items) |*glyph| {
glyph.rect.pos.y += offset_y;
}
self.bounds.pos.y += offset_y;
self.baseline = font_baseline;
}
if (self.layout) |layout| {
new_layout.pen_pos = layout.pen_pos;
if (layout.font == new_layout.font) {
new_layout.prev_glyph = layout.prev_glyph;
}
}
self.layout = new_layout;
}
pub fn putCodepoint(self: *TextBuilder, codepoint: u21) !void {
if (self.layout == null) {
return;
}
const layout = &self.layout.?;
const glyph_index = layout.font.getGlyphIndex(codepoint) orelse return;
const glyph_layout = layout.next(glyph_index) orelse return;
var rect = glyph_layout.rect;
rect.pos.y += self.baseline;
try self.glyphs.append(self.gpa, Glyph{
.sprite = glyph_layout.sprite,
.rect = rect,
.color = self.color
});
if (self.bounds.size.x > 0 and self.bounds.size.y > 0) {
self.bounds = self.bounds.expand(rect);
} else {
self.bounds = rect;
}
}
pub fn put(self: *TextBuilder, text: []const u8) !void {
var iter = std.unicode.Utf8Iterator{ .bytes = text, .i = 0 };
while (iter.nextCodepoint()) |codepoint| {
try self.putCodepoint(codepoint);
}
}
pub fn draw(self: *TextBuilder, pos: Vec2) void {
for (self.glyphs.items) |glyph| {
drawSprite(glyph.sprite, glyph.rect.pos.add(pos), glyph.rect.size, glyph.color);
}
}
pub fn offset(self: *TextBuilder, vec2: Vec2) void {
if (self.layout) |*layout| {
layout.pen_pos = layout.pen_pos.add(vec2);
}
}
};
pub const ImageData = struct {
const Format = enum {
rgba8,