feat: add mach-freetype, render a glyph
parent
f22a9ac2a9
commit
7fdc7a9dfc
10
build.zig
10
build.zig
|
@ -24,5 +24,15 @@ pub fn build(b: *std.Build) void {
|
||||||
|
|
||||||
exe.addIncludePath(.{ .path = "deps/font8x8/" });
|
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);
|
b.installArtifact(exe);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
42
src/main.zig
42
src/main.zig
|
@ -1,5 +1,7 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const wayland = @import("root.zig");
|
const wayland = @import("root.zig");
|
||||||
|
const freetype = @import("freetype");
|
||||||
|
const font_assets = @import("font-assets");
|
||||||
|
|
||||||
const Conn = wayland.Conn;
|
const Conn = wayland.Conn;
|
||||||
const Context = wayland.Context(&.{
|
const Context = wayland.Context(&.{
|
||||||
|
@ -63,6 +65,12 @@ pub fn main() !void {
|
||||||
var conn = try Conn.init(gpa, display_path);
|
var conn = try Conn.init(gpa, display_path);
|
||||||
defer conn.deinit();
|
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
|
// Register all globals
|
||||||
var ctx = try Context.init(&conn);
|
var ctx = try Context.init(&conn);
|
||||||
|
|
||||||
|
@ -85,6 +93,8 @@ pub fn main() !void {
|
||||||
.ctx = &ctx,
|
.ctx = &ctx,
|
||||||
.ally = gpa,
|
.ally = gpa,
|
||||||
.callbacks = std.AutoHashMap(u32, App.Callback).init(gpa),
|
.callbacks = std.AutoHashMap(u32, App.Callback).init(gpa),
|
||||||
|
.freetype_lib = freetype_lib,
|
||||||
|
.font_face = face,
|
||||||
.state = .{ .init = .{} },
|
.state = .{ .init = .{} },
|
||||||
.display = display,
|
.display = display,
|
||||||
.shm = shm,
|
.shm = shm,
|
||||||
|
@ -154,6 +164,8 @@ const App = struct {
|
||||||
ctx: *Context,
|
ctx: *Context,
|
||||||
ally: std.mem.Allocator,
|
ally: std.mem.Allocator,
|
||||||
callbacks: std.AutoHashMap(u32, Callback),
|
callbacks: std.AutoHashMap(u32, Callback),
|
||||||
|
freetype_lib: freetype.Library,
|
||||||
|
font_face: freetype.Face,
|
||||||
|
|
||||||
display: wayland.core.Display,
|
display: wayland.core.Display,
|
||||||
shm: wayland.core.Shm,
|
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 {
|
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
|
// render
|
||||||
const canvas = try pool.getFramebuffer(.{ width, height });
|
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.renderGradient();
|
||||||
|
canvas.blitFreetypeBitmap(bitmap, .{ 0, 0 });
|
||||||
try canvas.attach(app.surface);
|
try canvas.attach(app.surface);
|
||||||
try app.callbacks.put(canvas.buffer.id, bufferHandler);
|
try app.callbacks.put(canvas.buffer.id, bufferHandler);
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue