split_tree: fix bugs for 0/1 sized ratios

pull/8215/head
Mitchell Hashimoto 2025-08-12 10:46:36 -07:00
parent 2bcc2fa4bd
commit 4afd3445c4
No known key found for this signature in database
GPG Key ID: 523D5DC389D273BC
1 changed files with 142 additions and 3 deletions

View File

@ -888,7 +888,7 @@ pub fn SplitTree(comptime V: type) type {
slots: []Spatial.Slot,
current: Node.Handle,
) void {
assert(slots[current].width > 0 and slots[current].height > 0);
assert(slots[current].width >= 0 and slots[current].height >= 0);
switch (self.nodes[current]) {
// Leaf node, current slot is already filled by caller.
@ -1040,8 +1040,8 @@ pub fn SplitTree(comptime V: type) type {
var min_w: f16 = 1;
var min_h: f16 = 1;
for (sp.slots) |slot| {
min_w = @min(min_w, slot.width);
min_h = @min(min_h, slot.height);
if (slot.width > 0) min_w = @min(min_w, slot.width);
if (slot.height > 0) min_h = @min(min_h, slot.height);
}
const ratio_w: f16 = 1 / min_w;
@ -1121,6 +1121,9 @@ pub fn SplitTree(comptime V: type) type {
.split => continue,
}
// If our width/height is zero then we skip this.
if (slot.width == 0 or slot.height == 0) continue;
var x: usize = @intFromFloat(@floor(slot.x));
var y: usize = @intFromFloat(@floor(slot.y));
var width: usize = @intFromFloat(@max(@floor(slot.width), 1));
@ -1492,6 +1495,142 @@ test "SplitTree: split vertical" {
);
}
test "SplitTree: split horizontal with zero ratio" {
const testing = std.testing;
const alloc = testing.allocator;
var v1: TestTree.View = .{ .label = "A" };
var t1: TestTree = try .init(alloc, &v1);
defer t1.deinit();
var v2: TestTree.View = .{ .label = "B" };
var t2: TestTree = try .init(alloc, &v2);
defer t2.deinit();
// A | B horizontal
var splitAB = try t1.split(
alloc,
0, // at root
.right, // split right
0,
&t2, // insert t2
);
defer splitAB.deinit();
const split = splitAB;
{
const str = try std.fmt.allocPrint(alloc, "{diagram}", .{split});
defer alloc.free(str);
try testing.expectEqualStrings(str,
\\+---+
\\| B |
\\+---+
\\
);
}
}
test "SplitTree: split vertical with zero ratio" {
const testing = std.testing;
const alloc = testing.allocator;
var v1: TestTree.View = .{ .label = "A" };
var t1: TestTree = try .init(alloc, &v1);
defer t1.deinit();
var v2: TestTree.View = .{ .label = "B" };
var t2: TestTree = try .init(alloc, &v2);
defer t2.deinit();
// A | B horizontal
var splitAB = try t1.split(
alloc,
0, // at root
.down, // split right
0,
&t2, // insert t2
);
defer splitAB.deinit();
const split = splitAB;
{
const str = try std.fmt.allocPrint(alloc, "{diagram}", .{split});
defer alloc.free(str);
try testing.expectEqualStrings(str,
\\+---+
\\| B |
\\+---+
\\
);
}
}
test "SplitTree: split horizontal with full width" {
const testing = std.testing;
const alloc = testing.allocator;
var v1: TestTree.View = .{ .label = "A" };
var t1: TestTree = try .init(alloc, &v1);
defer t1.deinit();
var v2: TestTree.View = .{ .label = "B" };
var t2: TestTree = try .init(alloc, &v2);
defer t2.deinit();
// A | B horizontal
var splitAB = try t1.split(
alloc,
0, // at root
.right, // split right
1,
&t2, // insert t2
);
defer splitAB.deinit();
const split = splitAB;
{
const str = try std.fmt.allocPrint(alloc, "{diagram}", .{split});
defer alloc.free(str);
try testing.expectEqualStrings(str,
\\+---+
\\| A |
\\+---+
\\
);
}
}
test "SplitTree: split vertical with full width" {
const testing = std.testing;
const alloc = testing.allocator;
var v1: TestTree.View = .{ .label = "A" };
var t1: TestTree = try .init(alloc, &v1);
defer t1.deinit();
var v2: TestTree.View = .{ .label = "B" };
var t2: TestTree = try .init(alloc, &v2);
defer t2.deinit();
// A | B horizontal
var splitAB = try t1.split(
alloc,
0, // at root
.down, // split right
1,
&t2, // insert t2
);
defer splitAB.deinit();
const split = splitAB;
{
const str = try std.fmt.allocPrint(alloc, "{diagram}", .{split});
defer alloc.free(str);
try testing.expectEqualStrings(str,
\\+---+
\\| A |
\\+---+
\\
);
}
}
test "SplitTree: remove leaf" {
const testing = std.testing;
const alloc = testing.allocator;