tiny.gui.paint.command
Defined in paint.
API (31)
Actions
Public operations.
CommandBuffer.appendCommandBuffer.appendFrameCommandBuffer.commitFragmentCommandBuffer.deinitCommandBuffer.ensureCapacityCommandBuffer.ensureFragmentCapacityCommandBuffer.fragmentItemsCommandBuffer.fragmentsCompleteCommandBuffer.initCommandBuffer.itemsCommandBuffer.resetCommandBuffer.rollbackassignOrdersboundsemptyintersectvisibleBoundsvisuallyEqual
Types and contracts
Public types and contracts.
Values and defaults
Public values and defaults.
Source
Source: lib/gui/src/paint/command.zig
zig
const std = @import("std");const gui = @import("../root.zig");const Allocator = std.mem.Allocator;const Color = gui.model.UiColor;const Gradient = gui.model.UiLinearGradient;pub const Image = gui.model.UiImage;pub const ImageSet = gui.model.UiImageSet;const Point = gui.model.UiPoint;const Rect = gui.layout.Rect;pub const Kind = enum(u32) { fill = 1, stroke = 2, image = 3, shadow = 4, glyph = 5, linear_gradient = 6,};pub const Options = struct { visual: gui.visual.Options = .{}, scale: f32 = 1,};pub const fragment_namespace_widget: u32 = 1;pub const fragment_namespace_layer: u32 = 2;pub const fragment_part_chrome: u32 = 1;pub const fragment_part_text: u32 = 2;pub const FragmentId = struct { root_id: u64, element_id: u64, namespace: u32, part: u32,};pub const Fragment = struct { id: FragmentId, command_start: u32, command_count: u32, bounds: Rect,};pub const Command = struct { kind: Kind, rect: Rect, clip: Rect, source: Rect = .{}, color: Color, color_end: Color = .{}, gradient_start: Point = .{}, gradient_end: Point = .{}, radius: f32 = 0, width: f32 = 0, image_index: u32 = 0, order: u32 = 0,};pub const CommandBuffer = struct { pub const Error = Allocator.Error || error{ InvalidFragmentStart, TooManyCommands, }; allocator: Allocator, commands: std.ArrayListUnmanaged(Command) = .empty, fragments: std.ArrayListUnmanaged(Fragment) = .empty, pub fn init(allocator: Allocator) CommandBuffer { return .{ .allocator = allocator }; } pub fn deinit(self: *CommandBuffer) void { self.commands.deinit(self.allocator); self.fragments.deinit(self.allocator); self.* = undefined; } pub fn reset(self: *CommandBuffer) void { self.commands.clearRetainingCapacity(); self.fragments.clearRetainingCapacity(); } pub fn ensureCapacity(self: *CommandBuffer, capacity: usize) Allocator.Error!void { try self.commands.ensureTotalCapacity(self.allocator, capacity); } pub fn ensureFragmentCapacity( self: *CommandBuffer, capacity: usize, ) Allocator.Error!void { try self.fragments.ensureTotalCapacity(self.allocator, capacity); } pub fn items(self: *const CommandBuffer) []const Command { return self.commands.items; } pub fn fragmentItems(self: *const CommandBuffer) []const Fragment { return self.fragments.items; } pub fn fragmentsComplete(self: *const CommandBuffer) bool { return self.coveredCommandCount() == self.commands.items.len; } pub fn commitFragment( self: *CommandBuffer, id: FragmentId, command_start: usize, ) Error!void { if (command_start != self.coveredCommandCount()) { return error.InvalidFragmentStart; } if (command_start > self.commands.items.len) { return error.InvalidFragmentStart; } const command_count = self.commands.items.len - command_start; if (command_count == 0) return; const start = std.math.cast(u32, command_start) orelse return error.TooManyCommands; const count = std.math.cast(u32, command_count) orelse return error.TooManyCommands; try self.fragments.append(self.allocator, .{ .id = id, .command_start = start, .command_count = count, .bounds = fragmentBounds(self.commands.items[command_start..]), }); } pub fn appendFrame( self: *CommandBuffer, frame: gui.model.UiFrame, root_id: u64, target_width: u32, target_height: u32, options: Options, ) Error!void { const command_start = self.commands.items.len; const fragment_start = self.fragments.items.len; errdefer { self.commands.shrinkRetainingCapacity(command_start); self.fragments.shrinkRetainingCapacity(fragment_start); } var recorder = Recorder.init(self, .{ .x = 0, .y = 0, .width = @floatFromInt(target_width), .height = @floatFromInt(target_height), }, options.scale); gui.visual.drawFrame(&recorder, frame, root_id, options.visual); std.debug.assert(recorder.fragment_start == null); if (recorder.failure) |failure| return failure; } pub fn append(self: *CommandBuffer, raw: Command) Allocator.Error!void { if (raw.kind == .linear_gradient) { if (raw.color.a == 0 and raw.color_end.a == 0) return; } else if (raw.color.a == 0) return; if (empty(raw.rect) or empty(raw.clip)) return; var paint = raw; paint.order = @intCast(self.commands.items.len); try self.commands.append(self.allocator, paint); } pub fn rollback(self: *CommandBuffer, len: usize) void { std.debug.assert(self.coveredCommandCount() <= len); self.commands.shrinkRetainingCapacity(len); } fn coveredCommandCount(self: *const CommandBuffer) usize { const last = if (self.fragments.items.len == 0) return 0 else self.fragments.items[self.fragments.items.len - 1]; return @as(usize, last.command_start) + last.command_count; }};pub fn assignOrders(commands: []Command) void { for (commands, 0..) |*paint, index| { paint.order = @intCast(index); }}pub fn bounds(paint: Command) Rect { return switch (paint.kind) { .shadow => inset(paint.rect, -@max(paint.width, 0)), else => paint.rect, };}pub fn visibleBounds(paint: Command) Rect { return intersect(bounds(paint), paint.clip);}pub fn visuallyEqual(left: Command, right: Command) bool { return left.kind == right.kind and std.meta.eql(left.rect, right.rect) and std.meta.eql(left.clip, right.clip) and std.meta.eql(left.source, right.source) and std.meta.eql(left.color, right.color) and std.meta.eql(left.color_end, right.color_end) and std.meta.eql(left.gradient_start, right.gradient_start) and std.meta.eql(left.gradient_end, right.gradient_end) and left.radius == right.radius and left.width == right.width and left.image_index == right.image_index;}const Recorder = struct { buffer: *CommandBuffer, clips: [2]Rect, clip_depth: u8 = 1, scale: f32 = 1, failure: ?CommandBuffer.Error = null, fragment_start: ?usize = null, fragment_id: FragmentId = undefined, fn init(buffer: *CommandBuffer, target: Rect, scale: f32) Recorder { return .{ .buffer = buffer, .clips = .{ target, undefined }, .scale = scale, }; } fn scaledRect(self: *const Recorder, rect: Rect) Rect { return .{ .x = rect.x * self.scale, .y = rect.y * self.scale, .width = rect.width * self.scale, .height = rect.height * self.scale, }; } fn scaledGradientPoint(self: *const Recorder, rect: Rect, point: Point, fallback: Point) Point { const x_unit = finiteOr(point.x, fallback.x); const y_unit = finiteOr(point.y, fallback.y); const fallback_x = rect.x + rect.width * fallback.x; const fallback_y = rect.y + rect.height * fallback.y; return .{ .x = finiteOr(rect.x + rect.width * x_unit, fallback_x) * self.scale, .y = finiteOr(rect.y + rect.height * y_unit, fallback_y) * self.scale, }; } pub fn beginClip(self: *Recorder, rect: Rect) void { std.debug.assert(self.clip_depth < self.clips.len); self.clips[self.clip_depth] = intersect(self.activeClip(), self.scaledRect(rect)); self.clip_depth += 1; } pub fn endClip(self: *Recorder) void { if (self.clip_depth > 1) self.clip_depth -= 1; } pub fn beginWidgetFragment( self: *Recorder, root_id: u64, widget_id: u64, ) void { if (self.failure != null) return; std.debug.assert(self.fragment_start == null); self.fragment_start = self.buffer.commands.items.len; self.fragment_id = .{ .root_id = root_id, .element_id = widget_id, .namespace = fragment_namespace_widget, .part = fragment_part_chrome, }; } pub fn endFragment(self: *Recorder) void { if (self.failure != null) { self.fragment_start = null; return; } const start = self.fragment_start orelse unreachable; self.fragment_start = null; self.buffer.commitFragment(self.fragment_id, start) catch |failure| { self.failure = failure; }; } pub fn fillRect(self: *Recorder, rect: Rect, color: Color) void { self.append(.{ .kind = .fill, .rect = self.scaledRect(rect), .clip = self.activeClip(), .color = color, }); } pub fn fillRoundedRect(self: *Recorder, rect: Rect, radius: f32, segments: u32, color: Color) void { _ = segments; self.append(.{ .kind = .fill, .rect = self.scaledRect(rect), .clip = self.activeClip(), .color = color, .radius = radius * self.scale, }); } pub fn fillLinearGradient(self: *Recorder, rect: Rect, radius: f32, segments: u32, gradient: Gradient) void { _ = segments; self.append(.{ .kind = .linear_gradient, .rect = self.scaledRect(rect), .clip = self.activeClip(), .color = gradient.start_color, .color_end = gradient.end_color, .gradient_start = self.scaledGradientPoint(rect, gradient.start, .{}), .gradient_end = self.scaledGradientPoint(rect, gradient.end, .{ .x = 1 }), .radius = @max(radius, 0) * self.scale, }); } pub fn strokeRect(self: *Recorder, rect: Rect, width: f32, color: Color) void { self.append(.{ .kind = .stroke, .rect = self.scaledRect(rect), .clip = self.activeClip(), .color = color, .width = width * self.scale, }); } pub fn strokeRoundedRect(self: *Recorder, rect: Rect, radius: f32, segments: u32, width: f32, color: Color) void { _ = segments; self.append(.{ .kind = .stroke, .rect = self.scaledRect(rect), .clip = self.activeClip(), .color = color, .radius = radius * self.scale, .width = width * self.scale, }); } pub fn drawImage(self: *Recorder, rect: Rect, image_index: u32, source: Rect, opacity: u8) void { self.append(.{ .kind = .image, .rect = self.scaledRect(rect), .clip = self.activeClip(), .source = source, .color = .{ .r = 255, .g = 255, .b = 255, .a = opacity }, .image_index = image_index, }); } pub fn drawGlyph(self: *Recorder, rect: Rect, image_index: u32, source: Rect, color: Color) void { self.append(.{ .kind = .glyph, .rect = self.scaledRect(rect), .clip = self.activeClip(), .source = source, .color = color, .image_index = image_index, }); } pub fn shadowRoundedRect(self: *Recorder, rect: Rect, radius: f32, blur_radius: f32, spread: f32, offset_x: f32, offset_y: f32, color: Color) void { const expanded = @max(spread, 0); self.append(.{ .kind = .shadow, .rect = self.scaledRect(.{ .x = rect.x + offset_x - expanded, .y = rect.y + offset_y - expanded, .width = rect.width + expanded * 2, .height = rect.height + expanded * 2, }), .clip = self.activeClip(), .color = color, .radius = @max(radius + expanded, 0) * self.scale, .width = @max(blur_radius, 0) * self.scale, }); } fn append(self: *Recorder, raw: Command) void { if (self.failure != null) return; self.buffer.append(raw) catch |failure| { self.failure = failure; }; } fn activeClip(self: *const Recorder) Rect { return self.clips[self.clip_depth - 1]; }};fn finiteOr(value: f32, fallback: f32) f32 { return if (std.math.isFinite(value)) value else fallback;}fn fragmentBounds(commands: []const Command) Rect { std.debug.assert(commands.len != 0); var result = visibleBounds(commands[0]); for (commands[1..]) |paint| { result = unionRect(result, visibleBounds(paint)); } return result;}pub fn intersect(left: Rect, right: Rect) Rect { const x0 = @max(left.x, right.x); const y0 = @max(left.y, right.y); const x1 = @min(left.x + left.width, right.x + right.width); const y1 = @min(left.y + left.height, right.y + right.height); return .{ .x = x0, .y = y0, .width = @max(x1 - x0, 0), .height = @max(y1 - y0, 0), };}fn unionRect(left: Rect, right: Rect) Rect { if (empty(left)) return right; if (empty(right)) return left; const x0 = @min(left.x, right.x); const y0 = @min(left.y, right.y); const x1 = @max(left.x + left.width, right.x + right.width); const y1 = @max(left.y + left.height, right.y + right.height); return .{ .x = x0, .y = y0, .width = x1 - x0, .height = y1 - y0, };}pub fn empty(rect: Rect) bool { return rect.width <= 0 or rect.height <= 0;}fn inset(rect: Rect, value: f32) Rect { return .{ .x = rect.x + value, .y = rect.y + value, .width = @max(rect.width - value * 2, 0), .height = @max(rect.height - value * 2, 0), };}test "CommandBuffer captures visual widget chrome commands" { const allocator = std.testing.allocator; const child = [_]gui.model.UiNode{.{ .widget_id = 2, .kind = .button, .paint = .{ .background = .{ .r = 200, .g = 10, .b = 20, .a = 255 }, .border = .{ .r = 0, .g = 0, .b = 0, .a = 255 }, .border_width = 1, .shadow = .{ .color = .{ .r = 0, .g = 0, .b = 0, .a = 80 }, .offset_y = 1, .blur_radius = 2, }, }, .size = .{ .width = 12, .height = 8 }, }}; const surface = gui.model.UiSurfaceTree{ .available_size = .{ .width = 32, .height = 16 }, .root = .{ .widget_id = 1, .children = child[0..], }, }; var frame_workspace = gui.frame.Workspace.init(allocator); defer frame_workspace.deinit(); const frame = try frame_workspace.buildSurface(&surface, .{}); var commands = CommandBuffer.init(allocator); defer commands.deinit(); try commands.appendFrame(frame, 1, 32, 16, .{}); try std.testing.expect(commands.items().len >= 3); try std.testing.expectEqual(Kind.shadow, commands.items()[0].kind); try std.testing.expectEqual(Kind.fill, commands.items()[1].kind); try std.testing.expectEqual(@as(u32, 0), commands.items()[0].order); try std.testing.expectEqual(@as(u32, 1), commands.items()[1].order); try std.testing.expect(commands.fragmentsComplete()); try std.testing.expectEqual(@as(usize, 1), commands.fragmentItems().len); const fragment = commands.fragmentItems()[0]; try std.testing.expectEqual(FragmentId{ .root_id = 1, .element_id = 2, .namespace = fragment_namespace_widget, .part = fragment_part_chrome, }, fragment.id); try std.testing.expectEqual( Rect{ .width = 14, .height = 11 }, fragment.bounds, );}test "CommandBuffer scales chrome geometry to device pixels" { const allocator = std.testing.allocator; const child = [_]gui.model.UiNode{.{ .widget_id = 2, .kind = .button, .paint = .{ .background = .{ .r = 200, .g = 10, .b = 20, .a = 255 }, .border = .{ .r = 0, .g = 0, .b = 0, .a = 255 }, .border_width = 1, .corner_roundness = 3, }, .size = .{ .width = 12, .height = 8 }, }}; const surface = gui.model.UiSurfaceTree{ .available_size = .{ .width = 32, .height = 16 }, .root = .{ .widget_id = 1, .children = child[0..], }, }; var frame_workspace = gui.frame.Workspace.init(allocator); defer frame_workspace.deinit(); const frame = try frame_workspace.buildSurface(&surface, .{}); var logical = CommandBuffer.init(allocator); defer logical.deinit(); try logical.appendFrame(frame, 1, 32, 16, .{}); var device = CommandBuffer.init(allocator); defer device.deinit(); try device.appendFrame(frame, 1, 64, 32, .{ .scale = 2 }); try std.testing.expectEqual(logical.items().len, device.items().len); for (logical.items(), device.items()) |one, two| { try std.testing.expectEqual(one.kind, two.kind); try std.testing.expectEqual(one.rect.x * 2, two.rect.x); try std.testing.expectEqual(one.rect.y * 2, two.rect.y); try std.testing.expectEqual(one.rect.width * 2, two.rect.width); try std.testing.expectEqual(one.rect.height * 2, two.rect.height); try std.testing.expectEqual(one.radius * 2, two.radius); try std.testing.expectEqual(one.width * 2, two.width); try std.testing.expectEqual(one.source.x, two.source.x); try std.testing.expectEqual(one.source.width, two.source.width); }}test "CommandBuffer records normalized linear gradient endpoints in device pixels" { const gradient = gui.model.UiLinearGradient{ .start = .{ .x = 0.25, .y = 0.5 }, .end = .{ .x = 0.75, .y = 1 }, .start_color = .{ .r = 12, .g = 24, .b = 48, .a = 220 }, .end_color = .{ .r = 80, .g = 120, .b = 220, .a = 160 }, }; const child = [_]gui.model.UiNode{.{ .widget_id = 2, .kind = .container, .paint = .{ .linear_gradient = gradient, .corner_roundness = 3, }, .size = .{ .width = 12, .height = 8 }, }}; const surface = gui.model.UiSurfaceTree{ .available_size = .{ .width = 32, .height = 16 }, .root = .{ .widget_id = 1, .children = &child }, }; var frame_workspace = gui.frame.Workspace.init(std.testing.allocator); defer frame_workspace.deinit(); const frame = try frame_workspace.buildSurface(&surface, .{}); var logical = CommandBuffer.init(std.testing.allocator); defer logical.deinit(); try logical.appendFrame(frame, 1, 32, 16, .{}); var device = CommandBuffer.init(std.testing.allocator); defer device.deinit(); try device.appendFrame(frame, 1, 64, 32, .{ .scale = 2 }); try std.testing.expectEqual(@as(usize, 1), logical.items().len); const one = logical.items()[0]; const two = device.items()[0]; try std.testing.expectEqual(Kind.linear_gradient, one.kind); try std.testing.expectEqual(gradient.start_color, one.color); try std.testing.expectEqual(gradient.end_color, one.color_end); try std.testing.expectEqual(Point{ .x = 3, .y = 4 }, one.gradient_start); try std.testing.expectEqual(Point{ .x = 9, .y = 8 }, one.gradient_end); try std.testing.expectEqual(Point{ .x = 6, .y = 8 }, two.gradient_start); try std.testing.expectEqual(Point{ .x = 18, .y = 16 }, two.gradient_end); try std.testing.expectEqual(@as(f32, 6), two.radius);}test "CommandBuffer keeps a linear gradient with transparent start color" { var commands = CommandBuffer.init(std.testing.allocator); defer commands.deinit(); try commands.append(.{ .kind = .linear_gradient, .rect = .{ .width = 8, .height = 8 }, .clip = .{ .width = 8, .height = 8 }, .color = .{ .a = 0 }, .color_end = .{ .r = 40, .g = 80, .b = 120, .a = 255 }, .gradient_end = .{ .x = 8 }, }); try std.testing.expectEqual(@as(usize, 1), commands.items().len);}test "assignOrders preserves painter order" { var commands = [_]Command{ .{ .kind = .fill, .rect = .{ .x = 0, .y = 0, .width = 8, .height = 8 }, .clip = .{ .x = 0, .y = 0, .width = 20, .height = 20 }, .color = .{ .a = 255 }, }, .{ .kind = .fill, .rect = .{ .x = 10, .y = 0, .width = 4, .height = 4 }, .clip = .{ .x = 0, .y = 0, .width = 20, .height = 20 }, .color = .{ .a = 255 }, }, .{ .kind = .fill, .rect = .{ .x = 1, .y = 1, .width = 3, .height = 3 }, .clip = .{ .x = 0, .y = 0, .width = 20, .height = 20 }, .color = .{ .a = 255 }, }, .{ .kind = .shadow, .rect = .{ .x = 12, .y = 1, .width = 2, .height = 2 }, .clip = .{ .x = 0, .y = 0, .width = 20, .height = 20 }, .color = .{ .a = 255 }, .width = 2, }, }; assignOrders(commands[0..]); try std.testing.expectEqual(@as(u32, 0), commands[0].order); try std.testing.expectEqual(@as(u32, 1), commands[1].order); try std.testing.expectEqual(@as(u32, 2), commands[2].order); try std.testing.expectEqual(@as(u32, 3), commands[3].order);}test "CommandBuffer warmed frames need no backing allocation" { const child = [_]gui.model.UiNode{.{ .widget_id = 2, .size = .{ .width = 8, .height = 8 }, .paint = .{ .linear_gradient = .{ .start = .{ .x = 0.125, .y = 0.25 }, .end = .{ .x = 0.875, .y = 0.75 }, .start_color = .{ .r = 20, .g = 30, .b = 40, .a = 255 }, .end_color = .{ .r = 70, .g = 90, .b = 120, .a = 255 }, } }, }}; const surface = gui.model.UiSurfaceTree{ .available_size = .{ .width = 16, .height = 16 }, .root = .{ .widget_id = 1, .children = child[0..] }, }; var frame_workspace = gui.frame.Workspace.init(std.testing.allocator); defer frame_workspace.deinit(); const frame = try frame_workspace.buildSurface(&surface, .{}); var failing = std.testing.FailingAllocator.init(std.testing.allocator, .{}); var commands = CommandBuffer.init(failing.allocator()); defer commands.deinit(); try commands.appendFrame(frame, 1, 16, 16, .{}); const storage = commands.items().ptr; const fragment_storage = commands.fragmentItems().ptr; failing.fail_index = failing.alloc_index; failing.resize_fail_index = failing.resize_index; for (0..8) |_| { commands.reset(); try commands.appendFrame(frame, 1, 16, 16, .{}); try std.testing.expectEqual(@as(usize, 1), commands.items().len); try std.testing.expectEqual(@as(usize, 1), commands.fragmentItems().len); try std.testing.expectEqual(storage, commands.items().ptr); try std.testing.expectEqual(fragment_storage, commands.fragmentItems().ptr); } try std.testing.expect(!failing.has_induced_failure);}test "CommandBuffer reports allocation failure and rolls back" { const child = [_]gui.model.UiNode{.{ .widget_id = 2, .size = .{ .width = 8, .height = 8 }, .paint = .{ .background = .{ .r = 20, .g = 30, .b = 40, .a = 255 } }, }}; const surface = gui.model.UiSurfaceTree{ .available_size = .{ .width = 16, .height = 16 }, .root = .{ .widget_id = 1, .children = child[0..] }, }; var frame_workspace = gui.frame.Workspace.init(std.testing.allocator); defer frame_workspace.deinit(); const frame = try frame_workspace.buildSurface(&surface, .{}); var failing = std.testing.FailingAllocator.init(std.testing.allocator, .{ .fail_index = 0 }); var commands = CommandBuffer.init(failing.allocator()); defer commands.deinit(); try std.testing.expectError(error.OutOfMemory, commands.appendFrame(frame, 1, 16, 16, .{})); try std.testing.expectEqual(@as(usize, 0), commands.items().len); try std.testing.expectEqual(@as(usize, 0), commands.fragmentItems().len); failing.fail_index = std.math.maxInt(usize); try commands.appendFrame(frame, 1, 16, 16, .{}); try std.testing.expectEqual(@as(usize, 1), commands.items().len); try std.testing.expectEqual(@as(usize, 1), commands.fragmentItems().len);}Source: lib/gui/src/paint/root.zig:2
zig
pub const command = @import("command.zig");Complete caller list for paint.CommandBuffer.items
23 direct callers.
lib.gui.src.paint.accy.test_Accy_compositor_matches_recorded_frame_rasterization[function] — test source atlib/gui/src/paint/accy.zig:2960in nearest public ownertiny.gui.paint.accylib.gui.src.paint.command.test_CommandBuffer_captures_visual_widget_chrome_commands[function] — test source atlib/gui/src/paint/command.zig:450in nearest public ownertiny.gui.paint.commandlib.gui.src.paint.command.test_CommandBuffer_keeps_a_linear_gradient_with_transparent_start_color[function] — test source atlib/gui/src/paint/command.zig:590in nearest public ownertiny.gui.paint.commandlib.gui.src.paint.command.test_CommandBuffer_records_normalized_linear_gradient_endpoints_in_device_pixels[function] — test source atlib/gui/src/paint/command.zig:547in nearest public ownertiny.gui.paint.commandlib.gui.src.paint.command.test_CommandBuffer_reports_allocation_failure_and_rolls_back[function] — test source atlib/gui/src/paint/command.zig:679in nearest public ownertiny.gui.paint.commandlib.gui.src.paint.command.test_CommandBuffer_scales_chrome_geometry_to_device_pixels[function] — test source atlib/gui/src/paint/command.zig:502in nearest public ownertiny.gui.paint.commandlib.gui.src.paint.command.test_CommandBuffer_warmed_frames_need_no_backing_allocation[function] — test source atlib/gui/src/paint/command.zig:641in nearest public ownertiny.gui.paint.commandlib.gui.src.paint.retained.test_retained_semantic_damage_repaints_changed_image_content[function] — test source atlib/gui/src/paint/retained.zig:729in nearest public ownertiny.gui.paint.retainedlib.gui.src.paint.text.test_Atlas_shapes_fixture_bytes_and_appends_frame_glyph_commands[function] — test source atlib/gui/src/paint/text.zig:7119in nearest public ownertiny.gui.paint.textlib.gui.src.paint.text.test_appendFrameCommands_draws_cursor_for_empty_text_input[function] — test source atlib/gui/src/paint/text.zig:6371in nearest public ownertiny.gui.paint.textlib.gui.src.paint.text.test_appendFrameCommands_draws_text_selection_fills_before_glyph_commands[function] — test source atlib/gui/src/paint/text.zig:5482in nearest public ownertiny.gui.paint.textlib.gui.src.paint.text.test_appendFrameCommands_keeps_glyph_runs_inside_their_line_box[function] — test source atlib/gui/src/paint/text.zig:5265in nearest public ownertiny.gui.paint.textlib.gui.src.paint.text.test_appendFrameCommands_paints_the_glyph_under_a_block_cursor_in_the_background_color[function] — test source atlib/gui/src/paint/text.zig:5322in nearest public ownertiny.gui.paint.textlib.gui.src.paint.text.test_appendFrameCommands_scales_glyph_commands_to_text_point_size[function] — test source atlib/gui/src/paint/text.zig:5386in nearest public ownertiny.gui.paint.textlib.gui.src.paint.text.test_appendFrameCommands_scales_glyph_geometry_by_device_scale_and_keeps_atlas_sources[function] — test source atlib/gui/src/paint/text.zig:5428in nearest public ownertiny.gui.paint.textlib.gui.src.paint.text.test_bitmap_atlas_measures_and_paints_Unicode_wrapped_text_with_one_line_plan[function] — test source atlib/gui/src/paint/text.zig:4139in nearest public ownertiny.gui.paint.textlib.gui.src.paint.text.test_fallback_face_segments_preserve_primary_runs_and_paint_final_notdef[function] — test source atlib/gui/src/paint/text.zig:5017in nearest public ownertiny.gui.paint.textlib.gui.src.paint.text.test_measure_and_paint_reject_malformed_text_runs[function] — test source atlib/gui/src/paint/text.zig:6336in nearest public ownertiny.gui.paint.textlib.gui.src.paint.text.test_missing_terminal_glyphs_synthesize_fills_instead_of_blank_advances[function] — test source atlib/gui/src/paint/text.zig:7164in nearest public ownertiny.gui.paint.textlib.gui.src.paint.text.test_mixed_metric_runs_share_a_baseline_and_retain_per_glyph_atlas_identity[function] — test source atlib/gui/src/paint/text.zig:5833in nearest public ownertiny.gui.paint.textlib.gui.src.paint.text.test_multiline_query_geometry_matches_painted_caret_at_device_scales[function] — test source atlib/gui/src/paint/text.zig:4538in nearest public ownertiny.gui.paint.textlib.gui.src.paint.text.test_styled_text_runs_rasterize_fixed_colors_gaps_decorations_and_wrapped_partitions[function] — test source atlib/gui/src/paint/text.zig:5975in nearest public ownertiny.gui.paint.textlib.gui.src.paint.text.test_warmed_identical_styled_text_measure_emission_and_retained_diff_need_no_allocation_or_damage[function] — test source atlib/gui/src/paint/text.zig:6167in nearest public ownertiny.gui.paint.text
Audit
| Definitions | 32 |
|---|---|
| Public names | 52 |
| Members | 31 |
| Version | 26.7.0 |
| Revision | daab053ee433 |