diff options
Diffstat (limited to 'src/estd/graphics/root.zig')
| -rw-r--r-- | src/estd/graphics/root.zig | 202 |
1 files changed, 5 insertions, 197 deletions
diff --git a/src/estd/graphics/root.zig b/src/estd/graphics/root.zig index da09450..533d518 100644 --- a/src/estd/graphics/root.zig +++ b/src/estd/graphics/root.zig @@ -1,197 +1,5 @@ -const std = @import("std"); - -pub const Pixel = packed struct(u32) { - blue: u8, - green: u8, - red: u8, - _padding: u8 = 0x0, -}; - -pub const Canvas = struct { - const Self = @This(); - - width: u32, - height: u32, - buffer: []volatile Pixel, - - pub fn fill(self: *const Canvas, pixel: Pixel) void { - @memset(self.buffer, pixel); - } - - fn gaussian_mean(values: [9]u32) u32 { - return (values[0] + values[1] * 2 + values[2] + - values[3] * 2 + values[4] * 8 + values[5] * 2 + - values[6] + values[7] * 2 + values[8]) / 20; - } - - pub fn set_with_anti_aliasing(self: *const Canvas, x: u32, y: u32) void { - var neighbors_red: [9]u32 = undefined; - var neighbors_green: [9]u32 = undefined; - var neighbors_blue: [9]u32 = undefined; - - for (0..3) |h| { - for (0..3) |w| { - const pixel = self.buffer[(y + 1 - h) * self.width + x + 1 - w]; - neighbors_red[w + 3 * h] = pixel.red; - neighbors_green[w + 3 * h] = pixel.green; - neighbors_blue[w + 3 * h] = pixel.blue; - } - } - - self.buffer[x + (y * self.width)] = .{ - .red = @intCast(Self.gaussian_mean(neighbors_red)), - .green = @intCast(Self.gaussian_mean(neighbors_green)), - .blue = @intCast(Self.gaussian_mean(neighbors_blue)), - }; - } -}; - -pub const Box = struct { - const Self = @This(); - - x: u32, - y: u32, - width: u32, - height: u32, - color: Pixel, - radius: u32 = 0, - - fn render_rect( - self: *const Self, - x: u32, - y: u32, - width: u32, - height: u32, - canvas: *const Canvas - ) void { - if (x >= canvas.width or y >= canvas.height) { - return; - } - - const x_end = @min(x + width, canvas.width); - const y_end = @min(y + height, canvas.height); - - for (y..y_end) |yp| { - const offset = yp * canvas.width; - @memset( - canvas.buffer[(offset + x)..(offset + x_end)], - self.color - ); - } - } - - pub fn render(self: *const Self, canvas: *const Canvas) void { - if (self.radius == 0) { - self.render_rect(self.x, self.y, self.width, self.height, canvas); - return; - } - - const radius = @min(self.radius, self.width / 2, self.height / 2); - const core_width = self.width - 2 * radius; - const core_height = self.height - 2 * radius; - - self.render_rect( - self.x + radius, - self.y, - core_width, - radius, - canvas - ); - - self.render_rect( - self.x + radius, - self.y + radius + core_height, - core_width, - radius, - canvas - ); - - self.render_rect( - self.x, - self.y + radius, - self.width, - core_height, - canvas - ); - - for (0..radius) |yp| { - const width: u32 = @intFromFloat(std.math.round( - @as(f64, @floatFromInt(radius)) * - @cos(std.math.asin( - @as(f64, @floatFromInt(yp)) / @as(f64, @floatFromInt(radius)) - )) - )); - const spacing = radius - width; - - var offset = ((radius - yp) + self.y) * canvas.width + self.x + spacing; - @memset( - canvas.buffer[offset..offset + width], - self.color - ); - - offset = ((radius - yp) + self.y) * canvas.width + self.x + core_width + radius; - @memset( - canvas.buffer[offset..offset + width], - self.color - ); - - offset = (yp + self.y + radius + core_height) * canvas.width + self.x + spacing; - @memset( - canvas.buffer[offset..offset + width], - self.color - ); - - offset = (yp + self.y + radius + core_height) * canvas.width + self.x + core_width + radius; - @memset( - canvas.buffer[offset..offset + width], - self.color - ); - } - - for (0..radius) |yp| { - const width: u32 = @intFromFloat(std.math.round( - @as(f64, @floatFromInt(radius)) * - @cos(std.math.asin( - @as(f64, @floatFromInt(yp)) / @as(f64, @floatFromInt(radius)) - )) - )); - - const spacing = radius - width; - - canvas.set_with_anti_aliasing( - self.x + spacing, - @intCast(self.y + radius - yp), - ); - - canvas.set_with_anti_aliasing( - self.x + spacing - 1, - @intCast(self.y + radius - yp), - ); - - canvas.set_with_anti_aliasing( - self.x + core_width + radius + width, - @intCast(self.y + radius - yp), - ); - - canvas.set_with_anti_aliasing( - self.x + spacing, - @intCast(self.y + yp + radius + core_height), - ); - - canvas.set_with_anti_aliasing( - self.x + core_width + radius + width, - @intCast(self.y + yp + radius + core_height), - ); - } - - for (0..core_width) |w| { - canvas.set_with_anti_aliasing(@intCast(self.x + radius + w), self.y); - canvas.set_with_anti_aliasing(@intCast(self.x + radius + w), self.y + self.height); - } - - for (0..core_height) |h| { - canvas.set_with_anti_aliasing(self.x, @intCast(self.y + radius + h)); - canvas.set_with_anti_aliasing(self.x + self.width, @intCast(self.y + radius + h)); - } - } -}; +pub const Canvas = @import("canvas.zig").Canvas; +pub const Box = @import("box.zig").Box; +pub const Color = @import("color.zig").Color; +pub const Line = @import("line.zig").Line; +pub const Curve = @import("curve.zig").Curve; |