Compare commits

..

3 Commits

Author SHA1 Message Date
a2bca12bc7
upgrade to zig 0.12.0 2024-04-30 21:27:37 -07:00
bd8b3a1da3
update zig-action-cache to GitHub friendly version 2024-04-30 20:18:07 -07:00
8c1381daf4
add standard zig workflow 2024-04-29 16:36:11 -07:00
7 changed files with 80 additions and 46 deletions

29
.github/workflows/zig-build.yaml vendored Normal file
View File

@ -0,0 +1,29 @@
name: Generic zig build
on:
workflow_dispatch:
push:
branches:
- '*'
- '!zig-develop*'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: elerch/setup-zig@v3
with:
version: 0.12.0
- uses: elerch/zig-action-cache@v1.1.6
- name: Build project
run: zig build --summary all
- name: Run tests
run: zig build test --summary all
- name: Notify
uses: elerch/action-notify-ntfy@v2.github
if: env.GITEA_ACTIONS == 'true'
with:
host: ${{ secrets.NTFY_HOST }}
topic: ${{ secrets.NTFY_TOPIC }}
status: ${{ job.status }}
user: ${{ secrets.NTFY_USER }}
password: ${{ secrets.NTFY_PASSWORD }}

View File

@ -11,7 +11,7 @@ path: []const u8,
pub fn create(b: *std.build.Builder, opt: struct { pub fn create(b: *std.build.Builder, opt: struct {
path: []const u8, path: []const u8,
}) *AsciiPrintableStep { }) *AsciiPrintableStep {
var result = b.allocator.create(AsciiPrintableStep) catch @panic("OOM"); const result = b.allocator.create(AsciiPrintableStep) catch @panic("OOM");
result.* = AsciiPrintableStep{ result.* = AsciiPrintableStep{
.step = std.build.Step.init(.{ .step = std.build.Step.init(.{
.id = .custom, .id = .custom,
@ -40,7 +40,7 @@ fn hasDependency(step: *const std.build.Step, dep_candidate: *const std.build.St
} }
fn make(step: *std.build.Step, _: *std.Progress.Node) !void { fn make(step: *std.build.Step, _: *std.Progress.Node) !void {
const self = @fieldParentPtr(AsciiPrintableStep, "step", step); const self: AsciiPrintableStep = @fieldParentPtr("step", step);
const zig_file = std.fmt.allocPrint(self.builder.allocator, "{s}/images.zig", .{self.path}) catch @panic("OOM"); const zig_file = std.fmt.allocPrint(self.builder.allocator, "{s}/images.zig", .{self.path}) catch @panic("OOM");
defer self.builder.allocator.free(zig_file); defer self.builder.allocator.free(zig_file);
@ -67,7 +67,7 @@ fn make(step: *std.build.Step, _: *std.Progress.Node) !void {
// try writer.print(" \"\",\n", .{}); // try writer.print(" \"\",\n", .{});
// continue; // continue;
// } // }
const char_str = [_]u8{@intCast(u8, i)}; const char_str = [_]u8{@intCast(i)};
// Need to escape the following chars: 32 (' ') 92 ('\') // Need to escape the following chars: 32 (' ') 92 ('\')
const label_param = parm: { const label_param = parm: {
switch (i) { switch (i) {

View File

@ -1,7 +1,7 @@
const std = @import("std"); const std = @import("std");
const AsciiPrintableStep = @import("AsciiPrintableStep.zig"); const AsciiPrintableStep = @import("AsciiPrintableStep.zig");
pub fn build(b: *std.build.Builder) !void { pub fn build(b: *std.Build) !void {
// comptime { // comptime {
// const current_zig = builtin.zig_version; // const current_zig = builtin.zig_version;
// const min_zig = std.SemanticVersion.parse("0.11.0-dev.1254+1f8f79cd5") catch return; // add helper functions to std.zig.Ast // const min_zig = std.SemanticVersion.parse("0.11.0-dev.1254+1f8f79cd5") catch return; // add helper functions to std.zig.Ast
@ -31,7 +31,10 @@ pub fn build(b: *std.build.Builder) !void {
.target = target, .target = target,
.optimize = optimize, .optimize = optimize,
}); });
i2cdriver.addCSourceFile("lib/i2cdriver/i2cdriver.c", &[_][]const u8{ "-Wall", "-Wpointer-sign", "-Werror" }); i2cdriver.addCSourceFile(.{
.file = b.path("lib/i2cdriver/i2cdriver.c"),
.flags = &[_][]const u8{ "-Wall", "-Wpointer-sign", "-Werror" },
});
i2cdriver.linkLibC(); i2cdriver.linkLibC();
const exe = b.addExecutable(.{ const exe = b.addExecutable(.{
@ -43,8 +46,8 @@ pub fn build(b: *std.build.Builder) !void {
exe.linkLibrary(im_dep.artifact("MagickWand")); exe.linkLibrary(im_dep.artifact("MagickWand"));
exe.linkLibrary(z_dep.artifact("z")); exe.linkLibrary(z_dep.artifact("z"));
exe.linkLibrary(i2cdriver); exe.linkLibrary(i2cdriver);
exe.addIncludePath("lib/i2cdriver"); exe.addIncludePath(b.path("lib/i2cdriver"));
exe.install(); b.installArtifact(exe);
const exe_fontgen = b.addExecutable(.{ const exe_fontgen = b.addExecutable(.{
.name = "fontgen", .name = "fontgen",
@ -54,11 +57,11 @@ pub fn build(b: *std.build.Builder) !void {
}); });
exe_fontgen.linkLibrary(im_dep.artifact("MagickWand")); exe_fontgen.linkLibrary(im_dep.artifact("MagickWand"));
exe_fontgen.linkLibrary(z_dep.artifact("z")); exe_fontgen.linkLibrary(z_dep.artifact("z"));
exe.step.dependOn(&exe_fontgen.run().step); exe.step.dependOn(&b.addRunArtifact(exe_fontgen).step);
// If image based characters are needed, uncomment this // If image based characters are needed, uncomment this
// exe.step.dependOn(&AsciiPrintableStep.create(b, .{ .path = "src/images" }).step); // exe.step.dependOn(&AsciiPrintableStep.create(b, .{ .path = "src/images" }).step);
const run_cmd = exe.run(); const run_cmd = b.addRunArtifact(exe);
run_cmd.step.dependOn(b.getInstallStep()); run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| { if (b.args) |args| {
run_cmd.addArgs(args); run_cmd.addArgs(args);
@ -75,10 +78,10 @@ pub fn build(b: *std.build.Builder) !void {
exe_tests.linkLibrary(im_dep.artifact("MagickWand")); exe_tests.linkLibrary(im_dep.artifact("MagickWand"));
exe_tests.linkLibrary(z_dep.artifact("z")); exe_tests.linkLibrary(z_dep.artifact("z"));
exe_tests.linkLibrary(i2cdriver); exe_tests.linkLibrary(i2cdriver);
exe_tests.addIncludePath("lib/i2cdriver"); exe_tests.addIncludePath(b.path("lib/i2cdriver"));
const test_step = b.step("test", "Run unit tests"); const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&exe_tests.run().step); test_step.dependOn(&b.addRunArtifact(exe_tests).step);
} }
// Should be able to remove this // Should be able to remove this

View File

@ -1,15 +1,18 @@
.{ .{
.name = "i2c", .name = "i2c",
.version = "0.0.1", .version = "0.0.1",
.paths = .{
"",
},
.dependencies = .{ .dependencies = .{
.ImageMagick = .{ .ImageMagick = .{
.url = "https://github.com/elerch/ImageMagick/archive/0c78c43ba348fe2d764593b074b4f53d087a3a26.tar.gz", .url = "https://github.com/elerch/ImageMagick/archive/91d7290d02188139486fd5078446ddd88e57aebe.tar.gz",
.hash = "12208162dcc0b1f2e5fb6376136fe5266b2b493a38ca8f30eff94b735f7da6ada462", .hash = "1220a49c78df0938f80aca90d23ac694a1550d5329fe0594918c000fbcf0c9354822",
}, },
.libz = .{ .libz = .{
.url="https://github.com/andrewrk/libz/archive/9e71b746b83d2b5bf5eb247663eb65a52cf0f68f.tar.gz", .url = "https://github.com/elerch/libz/archive/1632972f211c6876d6dd8fcfdc13414a26b55c65.tar.gz",
.hash = "12204ea3490e5bdf379f56aa11784d906aed6d4c553c724fa5427169915f2cf4a651", .hash = "12200d3858388c9f74ef769cab3762cfddb4aee33133a5e08c96ee68130b2664f13a",
}, },
}, },
} }

View File

@ -37,10 +37,9 @@ pub fn main() !void {
const generated_file = try proj_path.createFile("src/fonts/fonts.zig", .{ const generated_file = try proj_path.createFile("src/fonts/fonts.zig", .{
.read = false, .read = false,
.truncate = true, .truncate = true,
.lock = .Exclusive, .lock = .exclusive,
.lock_nonblocking = false, .lock_nonblocking = false,
.mode = 0o666, .mode = 0o666,
.intended_io_mode = .blocking,
}); });
defer generated_file.close(); defer generated_file.close();
@ -74,7 +73,7 @@ pub fn main() !void {
// try writer.print(" \"\",\n", .{}); // try writer.print(" \"\",\n", .{});
// continue; // continue;
// } // }
const char_str = [_]u8{@intCast(u8, i)}; const char_str = [_]u8{@intCast(i)};
// Need to escape the following chars: 32 (' ') 92 ('\') // Need to escape the following chars: 32 (' ') 92 ('\')
const label_param = parm: { const label_param = parm: {
switch (i) { switch (i) {
@ -155,11 +154,11 @@ fn run(allocator: std.mem.Allocator, argv: []const []const u8) !void {
} }
std.log.debug("[RUN] {s}", .{msg.items}); std.log.debug("[RUN] {s}", .{msg.items});
} }
std.os.exit(0xff); std.posix.exit(0xff);
}, },
else => { else => {
std.log.err("command failed with: {}", .{result}); std.log.err("command failed with: {}", .{result});
std.os.exit(0xff); std.posix.exit(0xff);
}, },
} }
} }
@ -172,8 +171,8 @@ pub fn unpackBits(pixels: *[GLYPH_WIDTH * GLYPH_HEIGHT]u8) void {
// overwrites // overwrites
var i: isize = (GLYPH_WIDTH * GLYPH_HEIGHT / 8 - 1); var i: isize = (GLYPH_WIDTH * GLYPH_HEIGHT / 8 - 1);
while (i >= 0) { while (i >= 0) {
const start = @intCast(usize, i) * 8; const start = @as(usize, @intCast(i)) * 8;
const packed_byte = pixels[@intCast(usize, i)]; const packed_byte = pixels[@intCast(i)];
pixels[start + 7] = ((packed_byte & 0b10000000) >> 7) * 0xFF; pixels[start + 7] = ((packed_byte & 0b10000000) >> 7) * 0xFF;
pixels[start + 6] = ((packed_byte & 0b01000000) >> 6) * 0xFF; pixels[start + 6] = ((packed_byte & 0b01000000) >> 6) * 0xFF;
pixels[start + 5] = ((packed_byte & 0b00100000) >> 5) * 0xFF; pixels[start + 5] = ((packed_byte & 0b00100000) >> 5) * 0xFF;
@ -235,7 +234,7 @@ fn convertImage(filename: [:0]u8, pixels: *[GLYPH_WIDTH * GLYPH_HEIGHT]u8) !void
if (status == c.MagickFalse) if (status == c.MagickFalse)
return error.CouldNotQuantizeImage; return error.CouldNotQuantizeImage;
status = c.MagickExportImagePixels(mw, 0, 0, GLYPH_WIDTH, GLYPH_HEIGHT, "I", c.CharPixel, @ptrCast(*anyopaque, pixels)); status = c.MagickExportImagePixels(mw, 0, 0, GLYPH_WIDTH, GLYPH_HEIGHT, "I", c.CharPixel, @as(*anyopaque, @ptrCast(pixels)));
if (status == c.MagickFalse) if (status == c.MagickFalse)
return error.CouldNotExportImage; return error.CouldNotExportImage;

View File

@ -1,6 +1,6 @@
const std = @import("std"); const std = @import("std");
pub fn ioctl(handle: std.os.fd_t, request: u32, arg: usize) !void { pub fn ioctl(handle: std.posix.fd_t, request: u32, arg: usize) !void {
const rc = std.os.linux.ioctl(handle, request, arg); const rc = std.os.linux.ioctl(handle, request, arg);
try throwReturnCodeError(rc); try throwReturnCodeError(rc);
return; return;
@ -8,7 +8,7 @@ pub fn ioctl(handle: std.os.fd_t, request: u32, arg: usize) !void {
pub fn throwReturnCodeError(return_code: usize) LinuxGenericError!void { pub fn throwReturnCodeError(return_code: usize) LinuxGenericError!void {
// zig fmt: off // zig fmt: off
switch (std.os.errno(return_code)) { switch (std.posix.errno(return_code)) {
.SUCCESS => return, .SUCCESS => return,
.PERM => return LinuxGenericError.OperationNotPermittedError, .PERM => return LinuxGenericError.OperationNotPermittedError,
.NOENT => return LinuxGenericError.NoSuchFileOrDirectoryError, .NOENT => return LinuxGenericError.NoSuchFileOrDirectoryError,

View File

@ -34,7 +34,7 @@ fn usage(args: [][]u8) !void {
try writer.print("usage: {s} <device> [-bg <image file>] [-<num> text]...\n", .{args[0]}); try writer.print("usage: {s} <device> [-bg <image file>] [-<num> text]...\n", .{args[0]});
try writer.print("\t-<num> text: line number and text to display\n", .{}); try writer.print("\t-<num> text: line number and text to display\n", .{});
try writer.print("\te.g. \"-1 'hello world'\" will display \"hello world\" on line 1\n", .{}); try writer.print("\te.g. \"-1 'hello world'\" will display \"hello world\" on line 1\n", .{});
std.os.exit(1); std.posix.exit(1);
} }
const Options = struct { const Options = struct {
background_filename: [:0]u8, background_filename: [:0]u8,
@ -76,7 +76,7 @@ pub fn main() !void {
try std.io.getStdErr().writer().print("ERROR: data provided exceeds what can be sent to device!\n", .{}); try std.io.getStdErr().writer().print("ERROR: data provided exceeds what can be sent to device!\n", .{});
try usage(args); try usage(args);
} }
var read_data = stdin_data[0..read]; const read_data = stdin_data[0..read];
var it = std.mem.split(u8, read_data, "\n"); var it = std.mem.split(u8, read_data, "\n");
while (it.next()) |line| { while (it.next()) |line| {
if (line.len == 0) continue; if (line.len == 0) continue;
@ -153,7 +153,7 @@ fn processArgs(args: [][:0]u8, line_array: *[display.LINES]*const [:0]u8) !Optio
"ERROR: text for line {d} has {d} chars, exceeding maximum length {d}\n", "ERROR: text for line {d} has {d} chars, exceeding maximum length {d}\n",
.{ line, arg.len, display.CHARS_PER_LINE }, .{ line, arg.len, display.CHARS_PER_LINE },
); );
std.os.exit(1); std.posix.exit(1);
} }
std.log.debug("line {d} text: \"{s}\"\n", .{ line, arg }); std.log.debug("line {d} text: \"{s}\"\n", .{ line, arg });
line_array.*[line] = &args[i]; line_array.*[line] = &args[i];
@ -181,7 +181,7 @@ fn flipImage(pixels: *[display.WIDTH * display.HEIGHT]u8) void {
} }
fn addTextToImage(allocator: std.mem.Allocator, pixels: *[display.WIDTH * display.HEIGHT]u8, data: []*[]u8) !void { fn addTextToImage(allocator: std.mem.Allocator, pixels: *[display.WIDTH * display.HEIGHT]u8, data: []*[]u8) !void {
var maybe_font_data = try getFontData(allocator, DEFAULT_FONT); const maybe_font_data = try getFontData(allocator, DEFAULT_FONT);
if (maybe_font_data == null) return error.FontNotFound; if (maybe_font_data == null) return error.FontNotFound;
var font_data = maybe_font_data.?; var font_data = maybe_font_data.?;
@ -220,7 +220,7 @@ fn getFontData(allocator: std.mem.Allocator, font_name: []const u8) !?FontInnerH
if (font_arena == null) { if (font_arena == null) {
font_arena = std.heap.ArenaAllocator.init(allocator); font_arena = std.heap.ArenaAllocator.init(allocator);
} }
var alloc = font_arena.?.allocator(); const alloc = font_arena.?.allocator();
// The bit lookup will be a bit tricky because we have runtime value to look up // The bit lookup will be a bit tricky because we have runtime value to look up
// We can use an inline for but compute complexity is a bit crazy. Best to use a // We can use an inline for but compute complexity is a bit crazy. Best to use a
// hashmap here // hashmap here
@ -277,7 +277,7 @@ fn getFontMap(allocator: std.mem.Allocator, comptime font_name: []const u8) !*Fo
.{fmtSliceHexLower(@field(font_struct, point.name))}, .{fmtSliceHexLower(@field(font_struct, point.name))},
); );
} }
var key_ptr = try allocator.create(u21); const key_ptr = try allocator.create(u21);
key_ptr.* = std.fmt.parseInt(u21, point.name, 10) catch unreachable; key_ptr.* = std.fmt.parseInt(u21, point.name, 10) catch unreachable;
map.putAssumeCapacity( map.putAssumeCapacity(
key_ptr.*, key_ptr.*,
@ -344,7 +344,7 @@ fn sendPixelsThroughI2CDriver(pixels: []const u8, file: [*:0]const u8, device_id
.ccitt_crc = 0, .ccitt_crc = 0,
.e_ccitt_crc = 0, .e_ccitt_crc = 0,
}; };
const c_file = @ptrCast([*c]const u8, file); const c_file: [*c]const u8 = @ptrCast(file);
const stdout_file = std.io.getStdOut().writer(); const stdout_file = std.io.getStdOut().writer();
var bw = std.io.bufferedWriter(stdout_file); var bw = std.io.bufferedWriter(stdout_file);
const stdout = bw.writer(); const stdout = bw.writer();
@ -382,7 +382,7 @@ fn sendPixelsThroughI2CDriver(pixels: []const u8, file: [*:0]const u8, device_id
} }
fn i2cWrite(i2c: *c.I2CDriver, bytes: []const u8) !void { fn i2cWrite(i2c: *c.I2CDriver, bytes: []const u8) !void {
var rc = c.i2c_write(i2c, @ptrCast([*c]const u8, bytes), bytes.len); // nn is size of array const rc = c.i2c_write(i2c, @ptrCast(bytes), bytes.len); // nn is size of array
if (rc != 1) if (rc != 1)
return error.BadWrite; return error.BadWrite;
} }
@ -439,7 +439,7 @@ fn formatSliceGreyscaleImage(
fn reportMagickError(mw: ?*c.MagickWand) !void { fn reportMagickError(mw: ?*c.MagickWand) !void {
var severity: c.ExceptionType = undefined; var severity: c.ExceptionType = undefined;
var description = c.MagickGetException(mw, &severity); var description = c.MagickGetException(mw, &severity);
defer description = @ptrCast([*c]u8, c.MagickRelinquishMemory(description)); defer description = @ptrCast(c.MagickRelinquishMemory(description));
try std.io.getStdErr().writer().print("{s}\n", .{description}); try std.io.getStdErr().writer().print("{s}\n", .{description});
} }
fn textForLine(line: usize) []u8 { fn textForLine(line: usize) []u8 {
@ -514,8 +514,8 @@ fn convertImage(filename: [:0]u8, pixels: *[display.WIDTH * display.HEIGHT]u8, t
mw, mw,
display.WIDTH, display.WIDTH,
display.HEIGHT, display.HEIGHT,
-@intCast(isize, (display.WIDTH - resize_dimensions.width) / 2), -@as(isize, @intCast((display.WIDTH - resize_dimensions.width) / 2)),
-@intCast(isize, (display.HEIGHT - resize_dimensions.height) / 2), -@as(isize, @intCast((display.HEIGHT - resize_dimensions.height) / 2)),
); );
if (status == c.MagickFalse) if (status == c.MagickFalse)
@ -525,7 +525,7 @@ fn convertImage(filename: [:0]u8, pixels: *[display.WIDTH * display.HEIGHT]u8, t
const text = text_fn(i); const text = text_fn(i);
if (text.len == 0) continue; if (text.len == 0) continue;
// We have text! // We have text!
const y: isize = display.FONT_HEIGHT * @intCast(isize, i); const y: isize = display.FONT_HEIGHT * @as(isize, @intCast(i));
var x: isize = display.BORDER_LEFT; var x: isize = display.BORDER_LEFT;
var left_spaces: isize = 0; var left_spaces: isize = 0;
for (text) |ch| { for (text) |ch| {
@ -536,7 +536,7 @@ fn convertImage(filename: [:0]u8, pixels: *[display.WIDTH * display.HEIGHT]u8, t
break; break;
} }
x += (display.FONT_WIDTH * left_spaces); x += (display.FONT_WIDTH * left_spaces);
mw = try drawString(mw, text[@intCast(usize, left_spaces)..], x, y); mw = try drawString(mw, text[@intCast(left_spaces)..], x, y);
} }
// We make the image monochrome by quantizing the image with 2 colors in the // We make the image monochrome by quantizing the image with 2 colors in the
@ -558,7 +558,7 @@ fn convertImage(filename: [:0]u8, pixels: *[display.WIDTH * display.HEIGHT]u8, t
if (status == c.MagickFalse) if (status == c.MagickFalse)
return error.CouldNotQuantizeImage; return error.CouldNotQuantizeImage;
status = c.MagickExportImagePixels(mw, 0, 0, display.WIDTH, display.HEIGHT, "I", c.CharPixel, @ptrCast(*anyopaque, pixels)); status = c.MagickExportImagePixels(mw, 0, 0, display.WIDTH, display.HEIGHT, "I", c.CharPixel, @as(*anyopaque, @ptrCast(pixels)));
if (status == c.MagickFalse) if (status == c.MagickFalse)
return error.CouldNotExportImage; return error.CouldNotExportImage;
@ -577,7 +577,7 @@ fn drawString(mw: ?*c.MagickWand, str: []const u8, x: isize, y: isize) !?*c.Magi
rc = try drawCharacter( rc = try drawCharacter(
rc, rc,
ch, ch,
-(x + @intCast(isize, display.FONT_WIDTH * i)), -(x + @as(isize, @intCast(display.FONT_WIDTH * i))),
-y, -y,
); );
} }
@ -596,7 +596,7 @@ fn drawCharacter(mw: ?*c.MagickWand, char: u8, x: isize, y: isize) !?*c.MagickWa
} }
const image_char = chars[char]; const image_char = chars[char];
if (image_char.len == 0) return error.CharacterNotSupported; if (image_char.len == 0) return error.CharacterNotSupported;
var status = c.MagickReadImageBlob(cw, @ptrCast(?*const anyopaque, image_char), image_char.len); var status = c.MagickReadImageBlob(cw, @ptrCast(image_char), image_char.len);
if (status == c.MagickFalse) unreachable; // Something is terribly wrong if this fails if (status == c.MagickFalse) unreachable; // Something is terribly wrong if this fails
// For character placement, we need to set the image to the correct // For character placement, we need to set the image to the correct
@ -650,20 +650,20 @@ const Dimensions = struct {
fn getNewDimensions(width: usize, height: usize, desired_width: usize, desired_height: usize) Dimensions { fn getNewDimensions(width: usize, height: usize, desired_width: usize, desired_height: usize) Dimensions {
// assuming we're shrinking for now. // assuming we're shrinking for now.
// TODO: Handle expansion // TODO: Handle expansion
const width_ratio = @intToFloat(f64, width) / @intToFloat(f64, desired_width); const width_ratio = @as(f64, @floatFromInt(width)) / @as(f64, @floatFromInt(desired_width));
const height_ratio = @intToFloat(f64, height) / @intToFloat(f64, desired_height); const height_ratio = @as(f64, @floatFromInt(height)) / @as(f64, @floatFromInt(desired_height));
const resize_ratio = if (width_ratio > height_ratio) width_ratio else height_ratio; const resize_ratio = if (width_ratio > height_ratio) width_ratio else height_ratio;
return .{ return .{
.width = @floatToInt(usize, @intToFloat(f64, width) / resize_ratio), // 48, .width = @intFromFloat(@as(f64, @floatFromInt(width)) / resize_ratio), // 48,
.height = @floatToInt(usize, @intToFloat(f64, height) / resize_ratio), // 64, .height = @intFromFloat(@as(f64, @floatFromInt(height)) / resize_ratio), // 64,
}; };
} }
test "gets proper font data" { test "gets proper font data" {
// std.testing.log_level = .debug; // std.testing.log_level = .debug;
std.log.debug("\n", .{}); std.log.debug("\n", .{});
defer deinit(); defer deinit();
var maybe_font_data = try getFontData(std.testing.allocator, DEFAULT_FONT); const maybe_font_data = try getFontData(std.testing.allocator, DEFAULT_FONT);
try std.testing.expect(maybe_font_data != null); try std.testing.expect(maybe_font_data != null);
var font_data = maybe_font_data.?; var font_data = maybe_font_data.?;