//! DrawCommand - Rendering commands for the software rasterizer //! //! The immediate mode UI generates a list of DrawCommands each frame. //! The software rasterizer then processes these commands to produce pixels. //! //! This is the "command list" approach (like microui), not vertex buffers. const Style = @import("style.zig"); /// A single draw command pub const DrawCommand = union(enum) { /// Draw a filled rectangle rect: RectCommand, /// Draw text text: TextCommand, /// Draw a line line: LineCommand, /// Draw a rectangle outline (border) rect_outline: RectOutlineCommand, /// Begin clipping to a rectangle clip: ClipCommand, /// End clipping clip_end, /// No operation (placeholder) nop, }; /// Draw a filled rectangle pub const RectCommand = struct { x: i32, y: i32, w: u32, h: u32, color: Style.Color, }; /// Draw text at a position pub const TextCommand = struct { x: i32, y: i32, text: []const u8, color: Style.Color, /// null means default font font: ?*anyopaque = null, }; /// Draw a line between two points pub const LineCommand = struct { x1: i32, y1: i32, x2: i32, y2: i32, color: Style.Color, }; /// Draw a rectangle outline pub const RectOutlineCommand = struct { x: i32, y: i32, w: u32, h: u32, color: Style.Color, thickness: u32 = 1, }; /// Begin clipping to a rectangle pub const ClipCommand = struct { x: i32, y: i32, w: u32, h: u32, }; // ============================================================================= // Helper constructors // ============================================================================= /// Create a rect command pub fn rect(x: i32, y: i32, w: u32, h: u32, color: Style.Color) DrawCommand { return .{ .rect = .{ .x = x, .y = y, .w = w, .h = h, .color = color, } }; } /// Create a text command pub fn text(x: i32, y: i32, str: []const u8, color: Style.Color) DrawCommand { return .{ .text = .{ .x = x, .y = y, .text = str, .color = color, } }; } /// Create a line command pub fn line(x1: i32, y1: i32, x2: i32, y2: i32, color: Style.Color) DrawCommand { return .{ .line = .{ .x1 = x1, .y1 = y1, .x2 = x2, .y2 = y2, .color = color, } }; } /// Create a rect outline command pub fn rectOutline(x: i32, y: i32, w: u32, h: u32, color: Style.Color) DrawCommand { return .{ .rect_outline = .{ .x = x, .y = y, .w = w, .h = h, .color = color, } }; } /// Create a clip command pub fn clip(x: i32, y: i32, w: u32, h: u32) DrawCommand { return .{ .clip = .{ .x = x, .y = y, .w = w, .h = h, } }; } /// Create a clip end command pub fn clipEnd() DrawCommand { return .clip_end; } // ============================================================================= // Tests // ============================================================================= const std = @import("std"); test "DrawCommand creation" { const cmd = rect(10, 20, 100, 50, Style.Color.red); switch (cmd) { .rect => |r| { try std.testing.expectEqual(@as(i32, 10), r.x); try std.testing.expectEqual(@as(i32, 20), r.y); try std.testing.expectEqual(@as(u32, 100), r.w); try std.testing.expectEqual(@as(u32, 50), r.h); }, else => unreachable, } }