feat: add mach-freetype, render a glyph

dev
Louis Pearson 2024-02-16 17:58:42 -07:00
parent f22a9ac2a9
commit 7fdc7a9dfc
3 changed files with 67 additions and 0 deletions

View File

@ -24,5 +24,15 @@ pub fn build(b: *std.Build) void {
exe.addIncludePath(.{ .path = "deps/font8x8/" });
const mach_freetype_dep = b.dependency("mach_freetype", .{
.target = target,
.optimize = optimize,
});
exe.root_module.addImport("freetype", mach_freetype_dep.module("mach-freetype"));
exe.root_module.addImport("harfbuzz", mach_freetype_dep.module("mach-harfbuzz"));
const font_assets_dep = b.dependency("font_assets", .{});
exe.root_module.addImport("font-assets", font_assets_dep.module("font-assets"));
b.installArtifact(exe);
}

15
build.zig.zon Normal file
View File

@ -0,0 +1,15 @@
.{
.name = "pinephone-test",
.version = "0.0.0",
.paths = .{""},
.dependencies = .{
.mach_freetype = .{
.url = "https://pkg.machengine.org/mach-freetype/dc4a5d8ce14f8678f35bdaf197303091e22b1f27.tar.gz",
.hash = "122070070dd2c402d94c279d64d4a4d154691ad49f46fa2c24ed7c6e4e4f5c531477",
},
.font_assets = .{
.url = "https://pkg.machengine.org/font-assets/6b43c160451e8fa5c64620ffb614929feacf2f5d.tar.gz",
.hash = "12202039304f0603a9706105788e450fd4f901c3e20eca28a52a2173879b14c606c7",
},
},
}

View File

@ -1,5 +1,7 @@
const std = @import("std");
const wayland = @import("root.zig");
const freetype = @import("freetype");
const font_assets = @import("font-assets");
const Conn = wayland.Conn;
const Context = wayland.Context(&.{
@ -63,6 +65,12 @@ pub fn main() !void {
var conn = try Conn.init(gpa, display_path);
defer conn.deinit();
const freetype_lib = try freetype.Library.init();
defer freetype_lib.deinit();
const face = try freetype_lib.createFaceMemory(font_assets.fira_sans_regular_ttf, 0);
try face.setCharSize(60 * 48, 0, 50, 0);
// Register all globals
var ctx = try Context.init(&conn);
@ -85,6 +93,8 @@ pub fn main() !void {
.ctx = &ctx,
.ally = gpa,
.callbacks = std.AutoHashMap(u32, App.Callback).init(gpa),
.freetype_lib = freetype_lib,
.font_face = face,
.state = .{ .init = .{} },
.display = display,
.shm = shm,
@ -154,6 +164,8 @@ const App = struct {
ctx: *Context,
ally: std.mem.Allocator,
callbacks: std.AutoHashMap(u32, Callback),
freetype_lib: freetype.Library,
font_face: freetype.Face,
display: wayland.core.Display,
shm: wayland.core.Shm,
@ -438,6 +450,33 @@ const Canvas = struct {
}
}
}
fn blitFreetypeBitmap(canvas: Canvas, bitmap: freetype.Bitmap, pos: [2]u32) void {
const fb = canvas.fb;
const width = canvas.size[0];
const height = canvas.size[1];
const rows = bitmap.rows();
const cols = bitmap.width();
const left = pos[0];
const top = pos[1];
const right = @min(left + cols, width);
const bottom = @min(top + rows, height);
const buffer = bitmap.buffer().?;
if (pos[0] > width or pos[1] > height) return;
for (top..bottom, 0..) |y, i| {
const row = fb[y * width .. (y + 1) * width];
for (left..right, 0..) |x, a| {
const pixel = &row[x];
const intensity = buffer[i * cols + a];
pixel.* = .{
intensity,
intensity,
intensity,
0xFF,
};
}
}
}
};
fn wmbaseHandler(app: *App, header: wayland.Header, body: []const u32) !void {
@ -484,7 +523,10 @@ fn surfaceDesktopHandler(app: *App, header: wayland.Header, body: []const u32) !
// render
const canvas = try pool.getFramebuffer(.{ width, height });
try app.font_face.loadChar('H', .{ .render = true });
const bitmap = app.font_face.glyph().bitmap();
canvas.renderGradient();
canvas.blitFreetypeBitmap(bitmap, .{ 0, 0 });
try canvas.attach(app.surface);
try app.callbacks.put(canvas.buffer.id, bufferHandler);
},