summaryrefslogtreecommitdiff
path: root/src/estd/graphics/box.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/estd/graphics/box.zig')
-rw-r--r--src/estd/graphics/box.zig101
1 files changed, 101 insertions, 0 deletions
diff --git a/src/estd/graphics/box.zig b/src/estd/graphics/box.zig
new file mode 100644
index 0000000..83868aa
--- /dev/null
+++ b/src/estd/graphics/box.zig
@@ -0,0 +1,101 @@
+const std = @import("std");
+const graphics = @import("root.zig");
+
+pub const Box = struct {
+ const Self = @This();
+
+ x: u32,
+ y: u32,
+ width: u32,
+ height: u32,
+ color: graphics.Color,
+ radius: u32 = 0,
+
+ fn render_rect(
+ self: *const Self,
+ x: u32,
+ y: u32,
+ width: u32,
+ height: u32,
+ canvas: *const graphics.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 graphics.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(@round(std.math.sqrt(@as(f64, @floatFromInt(radius * radius - yp * yp)))));
+ 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
+ );
+ }
+ }
+};