~andreafeletto/levee

ref: ae55230ec4895a224104a266195278ff23a8d44b levee/src/clock.zig -rw-r--r-- 1.9 KiB
ae55230eAndrea Feletto correct rendering of clock 3 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
const std = @import("std");
const os = std.os;

const datetime = @import("datetime").datetime;
const pixman = @import("pixman");
const fcft = @import("fcft");

const Wayland = @import("wayland.zig").Wayland;
const State = @import("main.zig").State;

pub const Clock = struct {
    thread: ?*std.Thread = null,
    stop: bool = false,

    pub fn render(self: *const Clock, pix: *pixman.Image, state: *State) !void {
        var now = datetime.Datetime.now();
        const str = try now.formatHttp(state.allocator);

        const cint = try state.allocator.alloc(c_int, str.len);
        for (str) |char, i| cint[i] = char;

        const run = try fcft.TextRun.rasterize(state.font, cint, .default);
        defer run.destroy();

        var i: usize = 0;
        var text_width: u32 = 0;
        while (i < run.count) : (i += 1) {
            text_width += @intCast(u32, run.glyphs[i].advance.x);
        }

        var x_offset = @intCast(i32, @divFloor(state.wayland.width - text_width, 2));
        var y_offset = @intCast(i32, @divFloor(state.wayland.height - @intCast(u32, state.font.height), 2));

        i = 0;
        var color = pixman.Image.createSolidFill(state.foreground).?;
        while (i < run.count) : (i += 1) {
            const glyph = run.glyphs[i];
            const x = x_offset + @intCast(i32, glyph.x);
            const y = y_offset + state.font.ascent - @intCast(i32, glyph.y);
            pixman.Image.composite32(.over, color, glyph.pix, pix, 0, 0, 0, 0, x, y, glyph.width, glyph.height);
            x_offset += glyph.advance.x;
        }
    }

    pub fn start(self: *Clock, state: *State) !void {
        // self.thread = try std.Thread.spawn(repeatDraw, state);
        if ((try os.fork()) == 0) {
            repeatDraw(state);
        }
    }
};

fn repeatDraw(state: *State) void {
    while (!state.clock.stop) {
        std.time.sleep(1 * std.time.ns_per_s);
        state.draw(state);
    }
}