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 ); } } };