Microkernel thing OS experiment (Zig ⚡)
1const std = @import("std");
2
3pub const Font = struct {
4 const Self = @This();
5 pub const PsfHeader = extern struct {
6 magic: u32 = 0x864ab572,
7 version: u32,
8 header_size: u32,
9 flags: u32,
10 numglyph: u32,
11 bytes_per_glyph: u32,
12 height: u32,
13 width: u32,
14
15 pub fn bytesPerLine(self: *const PsfHeader) u32 {
16 return (self.width + 7) / 8;
17 }
18 };
19
20 fontdata: []const u8,
21 hdr: PsfHeader,
22
23 pub fn new(fontdata: []const u8) !Self {
24 var ret: Self = undefined;
25 ret.fontdata = fontdata;
26
27 // fill the header properly
28 const hdr_size = @sizeOf(PsfHeader);
29 if (fontdata.len < hdr_size) return error.TooSmall;
30 const hdr_ptr: [*]u8 = @ptrCast(&ret.hdr);
31 @memcpy(hdr_ptr[0..hdr_size], fontdata[0..hdr_size]);
32
33 return ret;
34 }
35
36 pub fn getGlyph(self: *const Self, ch: u8) ![]const u8 {
37 const startpos: u64 = self.hdr.header_size + ch * self.hdr.bytes_per_glyph;
38 const endpos: u64 = startpos + self.hdr.bytes_per_glyph;
39
40 if (self.fontdata.len < endpos) return error.InvalidCharacter;
41 return self.fontdata[startpos..endpos];
42 }
43};
44pub fn readIntTo32(buffer: []const u8) u32 {
45 const readInt = std.mem.readInt;
46 return switch (buffer.len) {
47 0 => 0,
48 1 => @intCast(readInt(u8, buffer[0..1], .big)),
49 2 => @intCast(readInt(u16, buffer[0..2], .big)),
50 3 => @intCast(readInt(u24, buffer[0..3], .big)),
51 else => @intCast(readInt(u32, buffer[0..4], .big)),
52 };
53}