feat: add renderText and renderGradient functions
parent
fcd58ad7e6
commit
dad4b23cf5
|
@ -5,6 +5,8 @@ const font8x8 = @cImport({
|
||||||
@cInclude("font8x8.h");
|
@cInclude("font8x8.h");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const Pixel = [4]u8;
|
||||||
|
|
||||||
pub fn main() !void {
|
pub fn main() !void {
|
||||||
var general_allocator = std.heap.GeneralPurposeAllocator(.{}){};
|
var general_allocator = std.heap.GeneralPurposeAllocator(.{}){};
|
||||||
defer _ = general_allocator.deinit();
|
defer _ = general_allocator.deinit();
|
||||||
|
@ -176,8 +178,7 @@ pub fn main() !void {
|
||||||
const wl_keyboard_id = wl_keyboard_id_opt orelse return error.MissingKeyboard;
|
const wl_keyboard_id = wl_keyboard_id_opt orelse return error.MissingKeyboard;
|
||||||
|
|
||||||
// allocate a shared memory file for display purposes
|
// allocate a shared memory file for display purposes
|
||||||
const Pixel = [4]u8;
|
const framebuffer_size = [2]u32{ 128, 128 };
|
||||||
const framebuffer_size = [2]usize{ 128, 128 };
|
|
||||||
const pool_file_len = 1024 * framebuffer_size[0] * framebuffer_size[1] * @sizeOf(Pixel);
|
const pool_file_len = 1024 * framebuffer_size[0] * framebuffer_size[1] * @sizeOf(Pixel);
|
||||||
|
|
||||||
const pool_fd = try std.os.memfd_create("my-wayland-framebuffer", 0);
|
const pool_fd = try std.os.memfd_create("my-wayland-framebuffer", 0);
|
||||||
|
@ -190,17 +191,7 @@ pub fn main() !void {
|
||||||
const framebuffer = try pool_alloc.alloc(Pixel, framebuffer_size[0] * framebuffer_size[1]);
|
const framebuffer = try pool_alloc.alloc(Pixel, framebuffer_size[0] * framebuffer_size[1]);
|
||||||
|
|
||||||
// put some interesting colors into the framebuffer
|
// put some interesting colors into the framebuffer
|
||||||
for (0..framebuffer_size[1]) |y| {
|
renderGradient(framebuffer, framebuffer_size);
|
||||||
const row = framebuffer[y * framebuffer_size[0] .. (y + 1) * framebuffer_size[0]];
|
|
||||||
for (row, 0..framebuffer_size[0]) |*pixel, x| {
|
|
||||||
pixel.* = .{
|
|
||||||
@truncate(x),
|
|
||||||
@truncate(y),
|
|
||||||
0x00,
|
|
||||||
0xFF,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const wl_shm_pool_id = id_pool.create();
|
const wl_shm_pool_id = id_pool.create();
|
||||||
{
|
{
|
||||||
|
@ -295,43 +286,10 @@ pub fn main() !void {
|
||||||
try framebuffers.put(new_buffer_id, new_framebuffer);
|
try framebuffers.put(new_buffer_id, new_framebuffer);
|
||||||
|
|
||||||
// put some interesting colors into the new_framebuffer
|
// put some interesting colors into the new_framebuffer
|
||||||
for (0..window_size[1]) |y| {
|
renderGradient(new_framebuffer, window_size);
|
||||||
const row = new_framebuffer[y * window_size[0] .. (y + 1) * window_size[0]];
|
|
||||||
for (row, 0..window_size[0]) |*pixel, x| {
|
|
||||||
pixel.* = .{
|
|
||||||
@truncate(x),
|
|
||||||
@truncate(y),
|
|
||||||
0x00,
|
|
||||||
0xFF,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// blit some characters
|
// blit some characters
|
||||||
for (0..window_size[1]) |y| {
|
renderText(new_framebuffer, window_size, .{ 10, 10 }, "Hello, World!");
|
||||||
const row = new_framebuffer[y * window_size[0] .. (y + 1) * window_size[0]];
|
|
||||||
for (row, 0..window_size[0]) |*pixel, x| {
|
|
||||||
const which_char = '!' + (x / 8) + ((y / 8) * (window_size[0] / 8));
|
|
||||||
if (which_char >= 128) continue;
|
|
||||||
const char = font8x8.font8x8_basic[which_char];
|
|
||||||
const line = char[y % 8];
|
|
||||||
if ((line >> @intCast(x % 8)) & 0x1 != 0) {
|
|
||||||
pixel.* = .{
|
|
||||||
0xFF,
|
|
||||||
0xFF,
|
|
||||||
0xFF,
|
|
||||||
0xFF,
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
pixel.* = .{
|
|
||||||
0x00,
|
|
||||||
0x00,
|
|
||||||
0x00,
|
|
||||||
0xFF,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try conn.send(
|
try conn.send(
|
||||||
wayland.core.ShmPool.Request,
|
wayland.core.ShmPool.Request,
|
||||||
|
@ -481,3 +439,53 @@ fn cmsg(comptime T: type) type {
|
||||||
_padding: [padding_size]u8 align(1) = [_]u8{0} ** padding_size,
|
_padding: [padding_size]u8 align(1) = [_]u8{0} ** padding_size,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn renderGradient(framebuffer: []Pixel, fb_size: [2]u32) void {
|
||||||
|
for (0..fb_size[1]) |y| {
|
||||||
|
const row = framebuffer[y * fb_size[0] .. (y + 1) * fb_size[0]];
|
||||||
|
for (row, 0..fb_size[0]) |*pixel, x| {
|
||||||
|
pixel.* = .{
|
||||||
|
@truncate(x),
|
||||||
|
@truncate(y),
|
||||||
|
0x00,
|
||||||
|
0xFF,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn textWidth(str: []const u8) usize {
|
||||||
|
return std.unicode.utf8CountCodepoints(str) catch 0; // incorrect, but I'm going with it
|
||||||
|
}
|
||||||
|
|
||||||
|
fn renderText(framebuffer: []Pixel, fb_size: [2]u32, pos: [2]usize, str: []const u8) void {
|
||||||
|
const top, const left = pos;
|
||||||
|
const bot = @min(top + 8, fb_size[1]);
|
||||||
|
const right = @min(left + textWidth(str) * 8, fb_size[0]);
|
||||||
|
|
||||||
|
for (top..bot) |y| {
|
||||||
|
const row = framebuffer[y * fb_size[0] .. (y + 1) * fb_size[0]];
|
||||||
|
for (row[left..right], left..right) |*pixel, x| {
|
||||||
|
const col = ((x - left) / 8);
|
||||||
|
const which_char = str[col];
|
||||||
|
if (!std.ascii.isPrint(which_char)) continue;
|
||||||
|
const char = font8x8.font8x8_basic[which_char];
|
||||||
|
const line = char[(y - top) % 8];
|
||||||
|
if ((line >> @intCast((x - left) % 8)) & 0x1 != 0) {
|
||||||
|
pixel.* = .{
|
||||||
|
0xFF,
|
||||||
|
0xFF,
|
||||||
|
0xFF,
|
||||||
|
0xFF,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
pixel.* = .{
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0xFF,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue