mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-20 02:36:22 +03:00
Fix z2d StaticPath
usage (#3084)
There was an accidental use of `undefined` which I believe is the source of crashes people are experiencing when drawing Powerline chevrons (#3083). I've resolved this by using the slice from the path's internal `ArrayList` instead of the backing array (`z2d` should probably introduce a `getNodes()` method or similar to `StaticPath`), and also annotated all `StaticPath` uses counting the maximum number of nodes that may be required. (**Edit**: confirmed, fixes #3083)
This commit is contained in:
@ -2515,19 +2515,19 @@ fn draw_smooth_mosaic(
|
||||
const right: f64 = @floatFromInt(self.metrics.cell_width);
|
||||
|
||||
var path: z2d.StaticPath(12) = .{};
|
||||
path.init();
|
||||
path.init(); // nodes.len = 0
|
||||
|
||||
if (mosaic.tl) path.lineTo(left, top);
|
||||
if (mosaic.ul) path.lineTo(left, upper);
|
||||
if (mosaic.ll) path.lineTo(left, lower);
|
||||
if (mosaic.bl) path.lineTo(left, bottom);
|
||||
if (mosaic.bc) path.lineTo(center, bottom);
|
||||
if (mosaic.br) path.lineTo(right, bottom);
|
||||
if (mosaic.lr) path.lineTo(right, lower);
|
||||
if (mosaic.ur) path.lineTo(right, upper);
|
||||
if (mosaic.tr) path.lineTo(right, top);
|
||||
if (mosaic.tc) path.lineTo(center, top);
|
||||
path.close();
|
||||
if (mosaic.tl) path.lineTo(left, top); // +1, nodes.len = 1
|
||||
if (mosaic.ul) path.lineTo(left, upper); // +1, nodes.len = 2
|
||||
if (mosaic.ll) path.lineTo(left, lower); // +1, nodes.len = 3
|
||||
if (mosaic.bl) path.lineTo(left, bottom); // +1, nodes.len = 4
|
||||
if (mosaic.bc) path.lineTo(center, bottom); // +1, nodes.len = 5
|
||||
if (mosaic.br) path.lineTo(right, bottom); // +1, nodes.len = 6
|
||||
if (mosaic.lr) path.lineTo(right, lower); // +1, nodes.len = 7
|
||||
if (mosaic.ur) path.lineTo(right, upper); // +1, nodes.len = 8
|
||||
if (mosaic.tr) path.lineTo(right, top); // +1, nodes.len = 9
|
||||
if (mosaic.tc) path.lineTo(center, top); // +1, nodes.len = 10
|
||||
path.close(); // +2, nodes.len = 12
|
||||
|
||||
try z2d.painter.fill(
|
||||
canvas.alloc,
|
||||
@ -2535,7 +2535,7 @@ fn draw_smooth_mosaic(
|
||||
&.{ .opaque_pattern = .{
|
||||
.pixel = .{ .alpha8 = .{ .a = @intFromEnum(Shade.on) } },
|
||||
} },
|
||||
&path.nodes,
|
||||
path.wrapped_path.nodes.items,
|
||||
.{},
|
||||
);
|
||||
}
|
||||
@ -2560,12 +2560,12 @@ fn draw_edge_triangle(
|
||||
};
|
||||
|
||||
var path: z2d.StaticPath(5) = .{};
|
||||
path.init();
|
||||
path.init(); // nodes.len = 0
|
||||
|
||||
path.moveTo(center, middle);
|
||||
path.lineTo(x0, y0);
|
||||
path.lineTo(x1, y1);
|
||||
path.close();
|
||||
path.moveTo(center, middle); // +1, nodes.len = 1
|
||||
path.lineTo(x0, y0); // +1, nodes.len = 2
|
||||
path.lineTo(x1, y1); // +1, nodes.len = 3
|
||||
path.close(); // +2, nodes.len = 5
|
||||
|
||||
try z2d.painter.fill(
|
||||
canvas.alloc,
|
||||
@ -2573,7 +2573,7 @@ fn draw_edge_triangle(
|
||||
&.{ .opaque_pattern = .{
|
||||
.pixel = .{ .alpha8 = .{ .a = @intFromEnum(Shade.on) } },
|
||||
} },
|
||||
&path.nodes,
|
||||
path.wrapped_path.nodes.items,
|
||||
.{},
|
||||
);
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ fn draw(self: Powerline, alloc: Allocator, canvas: *font.sprite.Canvas, cp: u32)
|
||||
fn draw_chevron(self: Powerline, canvas: *font.sprite.Canvas, cp: u32) !void {
|
||||
const width = self.width;
|
||||
const height = self.height;
|
||||
|
||||
|
||||
var p1_x: u32 = 0;
|
||||
var p1_y: u32 = 0;
|
||||
var p2_x: u32 = 0;
|
||||
@ -123,7 +123,6 @@ fn draw_chevron(self: Powerline, canvas: *font.sprite.Canvas, cp: u32) !void {
|
||||
var p3_x: u32 = 0;
|
||||
var p3_y: u32 = 0;
|
||||
|
||||
|
||||
switch (cp) {
|
||||
0xE0B1 => {
|
||||
p1_x = 0;
|
||||
@ -141,19 +140,15 @@ fn draw_chevron(self: Powerline, canvas: *font.sprite.Canvas, cp: u32) !void {
|
||||
p3_x = width;
|
||||
p3_y = height;
|
||||
},
|
||||
|
||||
else => unreachable,
|
||||
|
||||
else => unreachable,
|
||||
}
|
||||
|
||||
try canvas.triangle_outline(.{
|
||||
.p0 = .{ .x = @floatFromInt(p1_x), .y = @floatFromInt(p1_y) },
|
||||
.p1 = .{ .x = @floatFromInt(p2_x), .y = @floatFromInt(p2_y) },
|
||||
.p2 = .{ .x = @floatFromInt(p3_x), .y = @floatFromInt(p3_y) },
|
||||
},
|
||||
@floatFromInt(Thickness.light.height(self.thickness)),
|
||||
.on);
|
||||
|
||||
}, @floatFromInt(Thickness.light.height(self.thickness)), .on);
|
||||
}
|
||||
|
||||
fn draw_wedge_triangle(self: Powerline, canvas: *font.sprite.Canvas, cp: u32) !void {
|
||||
|
@ -184,13 +184,13 @@ pub const Canvas = struct {
|
||||
/// Draw and fill a quad.
|
||||
pub fn quad(self: *Canvas, q: Quad(f64), color: Color) !void {
|
||||
var path: z2d.StaticPath(6) = .{};
|
||||
path.init();
|
||||
path.init(); // nodes.len = 0
|
||||
|
||||
path.moveTo(q.p0.x, q.p0.y);
|
||||
path.lineTo(q.p1.x, q.p1.y);
|
||||
path.lineTo(q.p2.x, q.p2.y);
|
||||
path.lineTo(q.p3.x, q.p3.y);
|
||||
path.close();
|
||||
path.moveTo(q.p0.x, q.p0.y); // +1, nodes.len = 1
|
||||
path.lineTo(q.p1.x, q.p1.y); // +1, nodes.len = 2
|
||||
path.lineTo(q.p2.x, q.p2.y); // +1, nodes.len = 3
|
||||
path.lineTo(q.p3.x, q.p3.y); // +1, nodes.len = 4
|
||||
path.close(); // +2, nodes.len = 6
|
||||
|
||||
try z2d.painter.fill(
|
||||
self.alloc,
|
||||
@ -198,7 +198,7 @@ pub const Canvas = struct {
|
||||
&.{ .opaque_pattern = .{
|
||||
.pixel = .{ .alpha8 = .{ .a = @intFromEnum(color) } },
|
||||
} },
|
||||
&path.nodes,
|
||||
path.wrapped_path.nodes.items,
|
||||
.{},
|
||||
);
|
||||
}
|
||||
@ -206,12 +206,12 @@ pub const Canvas = struct {
|
||||
/// Draw and fill a triangle.
|
||||
pub fn triangle(self: *Canvas, t: Triangle(f64), color: Color) !void {
|
||||
var path: z2d.StaticPath(5) = .{};
|
||||
path.init();
|
||||
path.init(); // nodes.len = 0
|
||||
|
||||
path.moveTo(t.p0.x, t.p0.y);
|
||||
path.lineTo(t.p1.x, t.p1.y);
|
||||
path.lineTo(t.p2.x, t.p2.y);
|
||||
path.close();
|
||||
path.moveTo(t.p0.x, t.p0.y); // +1, nodes.len = 1
|
||||
path.lineTo(t.p1.x, t.p1.y); // +1, nodes.len = 2
|
||||
path.lineTo(t.p2.x, t.p2.y); // +1, nodes.len = 3
|
||||
path.close(); // +2, nodes.len = 5
|
||||
|
||||
try z2d.painter.fill(
|
||||
self.alloc,
|
||||
@ -219,18 +219,18 @@ pub const Canvas = struct {
|
||||
&.{ .opaque_pattern = .{
|
||||
.pixel = .{ .alpha8 = .{ .a = @intFromEnum(color) } },
|
||||
} },
|
||||
&path.nodes,
|
||||
path.wrapped_path.nodes.items,
|
||||
.{},
|
||||
);
|
||||
}
|
||||
|
||||
pub fn triangle_outline(self: *Canvas, t: Triangle(f64), thickness: f64, color: Color) !void {
|
||||
var path: z2d.StaticPath(5) = .{};
|
||||
path.init();
|
||||
var path: z2d.StaticPath(3) = .{};
|
||||
path.init(); // nodes.len = 0
|
||||
|
||||
path.moveTo(t.p0.x, t.p0.y);
|
||||
path.lineTo(t.p1.x, t.p1.y);
|
||||
path.lineTo(t.p2.x, t.p2.y);
|
||||
path.moveTo(t.p0.x, t.p0.y); // +1, nodes.len = 1
|
||||
path.lineTo(t.p1.x, t.p1.y); // +1, nodes.len = 2
|
||||
path.lineTo(t.p2.x, t.p2.y); // +1, nodes.len = 3
|
||||
|
||||
try z2d.painter.stroke(
|
||||
self.alloc,
|
||||
@ -238,7 +238,7 @@ pub const Canvas = struct {
|
||||
&.{ .opaque_pattern = .{
|
||||
.pixel = .{ .alpha8 = .{ .a = @intFromEnum(color) } },
|
||||
} },
|
||||
&path.nodes,
|
||||
path.wrapped_path.nodes.items,
|
||||
.{
|
||||
.line_cap_mode = .round,
|
||||
.line_width = thickness,
|
||||
@ -248,11 +248,11 @@ pub const Canvas = struct {
|
||||
|
||||
/// Stroke a line.
|
||||
pub fn line(self: *Canvas, l: Line(f64), thickness: f64, color: Color) !void {
|
||||
var path: z2d.StaticPath(3) = .{};
|
||||
path.init();
|
||||
var path: z2d.StaticPath(2) = .{};
|
||||
path.init(); // nodes.len = 0
|
||||
|
||||
path.moveTo(l.p0.x, l.p0.y);
|
||||
path.lineTo(l.p1.x, l.p1.y);
|
||||
path.moveTo(l.p0.x, l.p0.y); // +1, nodes.len = 1
|
||||
path.lineTo(l.p1.x, l.p1.y); // +1, nodes.len = 2
|
||||
|
||||
try z2d.painter.stroke(
|
||||
self.alloc,
|
||||
@ -260,7 +260,7 @@ pub const Canvas = struct {
|
||||
&.{ .opaque_pattern = .{
|
||||
.pixel = .{ .alpha8 = .{ .a = @intFromEnum(color) } },
|
||||
} },
|
||||
&path.nodes,
|
||||
path.wrapped_path.nodes.items,
|
||||
.{
|
||||
.line_cap_mode = .round,
|
||||
.line_width = thickness,
|
||||
|
Reference in New Issue
Block a user