mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 16:56:09 +03:00
deps: update z2d to v0.4.0 (#3075)
Introduces static path methods and a reworked context API that makes things generally cleaner. This update incidentally fixed a bug we had before where the corner triangle shade characters were drawn solid rather than medium shade. ### `Box_test_diff.ppm`: 
This commit is contained in:
@ -61,8 +61,8 @@
|
|||||||
.hash = "1220edc3b8d8bedbb50555947987e5e8e2f93871ca3c8e8d4cc8f1377c15b5dd35e8",
|
.hash = "1220edc3b8d8bedbb50555947987e5e8e2f93871ca3c8e8d4cc8f1377c15b5dd35e8",
|
||||||
},
|
},
|
||||||
.z2d = .{
|
.z2d = .{
|
||||||
.url = "git+https://github.com/vancluever/z2d?ref=main#285a796eb9c25a2389f087d008f0e60faf0b8eda",
|
.url = "git+https://github.com/vancluever/z2d?ref=v0.4.0#4638bb02a9dc41cc2fb811f092811f6a951c752a",
|
||||||
.hash = "12206445aa45bcf0170ace371905f705aec1d8d4f61e7dd77839c6621b8c407680a5",
|
.hash = "12201f0d542e7541cf492a001d4d0d0155c92f58212fbcb0d224e95edeba06b5416a",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
# This file is auto-generated! check build-support/check-zig-cache-hash.sh for
|
# This file is auto-generated! check build-support/check-zig-cache-hash.sh for
|
||||||
# more details.
|
# more details.
|
||||||
"sha256-vP8f8KQyM4CwKlw7Esmxv1q4ANu8pDXXsnVorgpWCr4="
|
"sha256-lS5v5VdFCLnIyCq9mp7fd2pXhQmkkDFHHVdg4pf37PA="
|
||||||
|
@ -220,7 +220,7 @@ pub fn renderGlyph(
|
|||||||
metrics.cell_width,
|
metrics.cell_width,
|
||||||
metrics.cell_height,
|
metrics.cell_height,
|
||||||
);
|
);
|
||||||
defer canvas.deinit(alloc);
|
defer canvas.deinit();
|
||||||
|
|
||||||
// Perform the actual drawing
|
// Perform the actual drawing
|
||||||
try self.draw(alloc, &canvas, cp);
|
try self.draw(alloc, &canvas, cp);
|
||||||
@ -2233,18 +2233,10 @@ fn draw_branch_node(
|
|||||||
@min(float_width - cx, float_height - cy),
|
@min(float_width - cx, float_height - cy),
|
||||||
);
|
);
|
||||||
|
|
||||||
var ctx: z2d.Context = .{
|
var ctx = canvas.getContext() catch return;
|
||||||
.surface = canvas.sfc,
|
defer ctx.deinit();
|
||||||
.pattern = .{
|
ctx.setSource(.{ .alpha8 = .{ .a = @intFromEnum(Shade.on) } });
|
||||||
.opaque_pattern = .{
|
ctx.setLineWidth(float_thick);
|
||||||
.pixel = .{ .alpha8 = .{ .a = @intFromEnum(Shade.on) } },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
.line_width = float_thick,
|
|
||||||
};
|
|
||||||
|
|
||||||
var path = z2d.Path.init(canvas.alloc);
|
|
||||||
defer path.deinit();
|
|
||||||
|
|
||||||
// These @intFromFloat casts shouldn't ever fail since r can never
|
// These @intFromFloat casts shouldn't ever fail since r can never
|
||||||
// be greater than cx or cy, so when subtracting it from them the
|
// be greater than cx or cy, so when subtracting it from them the
|
||||||
@ -2259,13 +2251,13 @@ fn draw_branch_node(
|
|||||||
self.rect(canvas, 0, h_top, @intFromFloat(@ceil(cx - r)), h_bottom);
|
self.rect(canvas, 0, h_top, @intFromFloat(@ceil(cx - r)), h_bottom);
|
||||||
|
|
||||||
if (node.filled) {
|
if (node.filled) {
|
||||||
path.arc(cx, cy, r, 0, std.math.pi * 2, false, null) catch return;
|
ctx.arc(cx, cy, r, 0, std.math.pi * 2) catch return;
|
||||||
path.close() catch return;
|
ctx.closePath() catch return;
|
||||||
ctx.fill(canvas.alloc, path) catch return;
|
ctx.fill() catch return;
|
||||||
} else {
|
} else {
|
||||||
path.arc(cx, cy, r - float_thick / 2, 0, std.math.pi * 2, false, null) catch return;
|
ctx.arc(cx, cy, r - float_thick / 2, 0, std.math.pi * 2) catch return;
|
||||||
path.close() catch return;
|
ctx.closePath() catch return;
|
||||||
ctx.stroke(canvas.alloc, path) catch return;
|
ctx.stroke() catch return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2290,27 +2282,21 @@ fn draw_circle(
|
|||||||
};
|
};
|
||||||
const r: f64 = 0.5 * @min(float_width, float_height);
|
const r: f64 = 0.5 * @min(float_width, float_height);
|
||||||
|
|
||||||
var ctx: z2d.Context = .{
|
var ctx = canvas.getContext() catch return;
|
||||||
.surface = canvas.sfc,
|
defer ctx.deinit();
|
||||||
.pattern = .{
|
ctx.setSource(.{ .alpha8 = .{ .a = @intFromEnum(Shade.on) } });
|
||||||
.opaque_pattern = .{
|
ctx.setLineWidth(
|
||||||
.pixel = .{ .alpha8 = .{ .a = @intFromEnum(Shade.on) } },
|
@floatFromInt(Thickness.light.height(self.metrics.box_thickness)),
|
||||||
},
|
);
|
||||||
},
|
|
||||||
.line_width = @floatFromInt(Thickness.light.height(self.metrics.box_thickness)),
|
|
||||||
};
|
|
||||||
|
|
||||||
var path = z2d.Path.init(canvas.alloc);
|
|
||||||
defer path.deinit();
|
|
||||||
|
|
||||||
if (filled) {
|
if (filled) {
|
||||||
path.arc(x, y, r, 0, std.math.pi * 2, false, null) catch return;
|
ctx.arc(x, y, r, 0, std.math.pi * 2) catch return;
|
||||||
path.close() catch return;
|
ctx.closePath() catch return;
|
||||||
ctx.fill(canvas.alloc, path) catch return;
|
ctx.fill() catch return;
|
||||||
} else {
|
} else {
|
||||||
path.arc(x, y, r - ctx.line_width / 2, 0, std.math.pi * 2, false, null) catch return;
|
ctx.arc(x, y, r - ctx.line_width / 2, 0, std.math.pi * 2) catch return;
|
||||||
path.close() catch return;
|
ctx.closePath() catch return;
|
||||||
ctx.stroke(canvas.alloc, path) catch return;
|
ctx.stroke() catch return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2528,31 +2514,30 @@ fn draw_smooth_mosaic(
|
|||||||
const center: f64 = @round(@as(f64, @floatFromInt(self.metrics.cell_width)) / 2);
|
const center: f64 = @round(@as(f64, @floatFromInt(self.metrics.cell_width)) / 2);
|
||||||
const right: f64 = @floatFromInt(self.metrics.cell_width);
|
const right: f64 = @floatFromInt(self.metrics.cell_width);
|
||||||
|
|
||||||
var path = z2d.Path.init(canvas.alloc);
|
var path: z2d.StaticPath(12) = .{};
|
||||||
defer path.deinit();
|
path.init();
|
||||||
|
|
||||||
if (mosaic.tl) try path.lineTo(left, top);
|
if (mosaic.tl) path.lineTo(left, top);
|
||||||
if (mosaic.ul) try path.lineTo(left, upper);
|
if (mosaic.ul) path.lineTo(left, upper);
|
||||||
if (mosaic.ll) try path.lineTo(left, lower);
|
if (mosaic.ll) path.lineTo(left, lower);
|
||||||
if (mosaic.bl) try path.lineTo(left, bottom);
|
if (mosaic.bl) path.lineTo(left, bottom);
|
||||||
if (mosaic.bc) try path.lineTo(center, bottom);
|
if (mosaic.bc) path.lineTo(center, bottom);
|
||||||
if (mosaic.br) try path.lineTo(right, bottom);
|
if (mosaic.br) path.lineTo(right, bottom);
|
||||||
if (mosaic.lr) try path.lineTo(right, lower);
|
if (mosaic.lr) path.lineTo(right, lower);
|
||||||
if (mosaic.ur) try path.lineTo(right, upper);
|
if (mosaic.ur) path.lineTo(right, upper);
|
||||||
if (mosaic.tr) try path.lineTo(right, top);
|
if (mosaic.tr) path.lineTo(right, top);
|
||||||
if (mosaic.tc) try path.lineTo(center, top);
|
if (mosaic.tc) path.lineTo(center, top);
|
||||||
try path.close();
|
path.close();
|
||||||
|
|
||||||
var ctx: z2d.Context = .{
|
try z2d.painter.fill(
|
||||||
.surface = canvas.sfc,
|
canvas.alloc,
|
||||||
.pattern = .{
|
&canvas.sfc,
|
||||||
.opaque_pattern = .{
|
&.{ .opaque_pattern = .{
|
||||||
.pixel = .{ .alpha8 = .{ .a = @intFromEnum(Shade.on) } },
|
.pixel = .{ .alpha8 = .{ .a = @intFromEnum(Shade.on) } },
|
||||||
},
|
} },
|
||||||
},
|
&path.nodes,
|
||||||
};
|
.{},
|
||||||
|
);
|
||||||
try ctx.fill(canvas.alloc, path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_edge_triangle(
|
fn draw_edge_triangle(
|
||||||
@ -2567,9 +2552,6 @@ fn draw_edge_triangle(
|
|||||||
const center: f64 = @round(@as(f64, @floatFromInt(self.metrics.cell_width)) / 2);
|
const center: f64 = @round(@as(f64, @floatFromInt(self.metrics.cell_width)) / 2);
|
||||||
const right: f64 = @floatFromInt(self.metrics.cell_width);
|
const right: f64 = @floatFromInt(self.metrics.cell_width);
|
||||||
|
|
||||||
var path = z2d.Path.init(canvas.alloc);
|
|
||||||
defer path.deinit();
|
|
||||||
|
|
||||||
const x0, const y0, const x1, const y1 = switch (edge) {
|
const x0, const y0, const x1, const y1 = switch (edge) {
|
||||||
.top => .{ right, upper, left, upper },
|
.top => .{ right, upper, left, upper },
|
||||||
.left => .{ left, upper, left, lower },
|
.left => .{ left, upper, left, lower },
|
||||||
@ -2577,21 +2559,23 @@ fn draw_edge_triangle(
|
|||||||
.right => .{ right, lower, right, upper },
|
.right => .{ right, lower, right, upper },
|
||||||
};
|
};
|
||||||
|
|
||||||
try path.moveTo(center, middle);
|
var path: z2d.StaticPath(5) = .{};
|
||||||
try path.lineTo(x0, y0);
|
path.init();
|
||||||
try path.lineTo(x1, y1);
|
|
||||||
try path.close();
|
|
||||||
|
|
||||||
var ctx: z2d.Context = .{
|
path.moveTo(center, middle);
|
||||||
.surface = canvas.sfc,
|
path.lineTo(x0, y0);
|
||||||
.pattern = .{
|
path.lineTo(x1, y1);
|
||||||
.opaque_pattern = .{
|
path.close();
|
||||||
|
|
||||||
|
try z2d.painter.fill(
|
||||||
|
canvas.alloc,
|
||||||
|
&canvas.sfc,
|
||||||
|
&.{ .opaque_pattern = .{
|
||||||
.pixel = .{ .alpha8 = .{ .a = @intFromEnum(Shade.on) } },
|
.pixel = .{ .alpha8 = .{ .a = @intFromEnum(Shade.on) } },
|
||||||
},
|
} },
|
||||||
},
|
&path.nodes,
|
||||||
};
|
.{},
|
||||||
|
);
|
||||||
try ctx.fill(canvas.alloc, path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_arc(
|
fn draw_arc(
|
||||||
@ -2612,25 +2596,17 @@ fn draw_arc(
|
|||||||
// Fraction away from the center to place the middle control points,
|
// Fraction away from the center to place the middle control points,
|
||||||
const s: f64 = 0.25;
|
const s: f64 = 0.25;
|
||||||
|
|
||||||
var ctx: z2d.Context = .{
|
var ctx = try canvas.getContext();
|
||||||
.surface = canvas.sfc,
|
defer ctx.deinit();
|
||||||
.pattern = .{
|
ctx.setSource(.{ .alpha8 = .{ .a = @intFromEnum(Shade.on) } });
|
||||||
.opaque_pattern = .{
|
ctx.setLineWidth(float_thick);
|
||||||
.pixel = .{ .alpha8 = .{ .a = @intFromEnum(Shade.on) } },
|
ctx.setLineCapMode(.round);
|
||||||
},
|
|
||||||
},
|
|
||||||
.line_width = float_thick,
|
|
||||||
.line_cap_mode = .round,
|
|
||||||
};
|
|
||||||
|
|
||||||
var path = z2d.Path.init(canvas.alloc);
|
|
||||||
defer path.deinit();
|
|
||||||
|
|
||||||
switch (corner) {
|
switch (corner) {
|
||||||
.tl => {
|
.tl => {
|
||||||
try path.moveTo(center_x, 0);
|
try ctx.moveTo(center_x, 0);
|
||||||
try path.lineTo(center_x, center_y - r);
|
try ctx.lineTo(center_x, center_y - r);
|
||||||
try path.curveTo(
|
try ctx.curveTo(
|
||||||
center_x,
|
center_x,
|
||||||
center_y - s * r,
|
center_y - s * r,
|
||||||
center_x - s * r,
|
center_x - s * r,
|
||||||
@ -2638,12 +2614,12 @@ fn draw_arc(
|
|||||||
center_x - r,
|
center_x - r,
|
||||||
center_y,
|
center_y,
|
||||||
);
|
);
|
||||||
try path.lineTo(0, center_y);
|
try ctx.lineTo(0, center_y);
|
||||||
},
|
},
|
||||||
.tr => {
|
.tr => {
|
||||||
try path.moveTo(center_x, 0);
|
try ctx.moveTo(center_x, 0);
|
||||||
try path.lineTo(center_x, center_y - r);
|
try ctx.lineTo(center_x, center_y - r);
|
||||||
try path.curveTo(
|
try ctx.curveTo(
|
||||||
center_x,
|
center_x,
|
||||||
center_y - s * r,
|
center_y - s * r,
|
||||||
center_x + s * r,
|
center_x + s * r,
|
||||||
@ -2651,12 +2627,12 @@ fn draw_arc(
|
|||||||
center_x + r,
|
center_x + r,
|
||||||
center_y,
|
center_y,
|
||||||
);
|
);
|
||||||
try path.lineTo(float_width, center_y);
|
try ctx.lineTo(float_width, center_y);
|
||||||
},
|
},
|
||||||
.bl => {
|
.bl => {
|
||||||
try path.moveTo(center_x, float_height);
|
try ctx.moveTo(center_x, float_height);
|
||||||
try path.lineTo(center_x, center_y + r);
|
try ctx.lineTo(center_x, center_y + r);
|
||||||
try path.curveTo(
|
try ctx.curveTo(
|
||||||
center_x,
|
center_x,
|
||||||
center_y + s * r,
|
center_y + s * r,
|
||||||
center_x - s * r,
|
center_x - s * r,
|
||||||
@ -2664,12 +2640,12 @@ fn draw_arc(
|
|||||||
center_x - r,
|
center_x - r,
|
||||||
center_y,
|
center_y,
|
||||||
);
|
);
|
||||||
try path.lineTo(0, center_y);
|
try ctx.lineTo(0, center_y);
|
||||||
},
|
},
|
||||||
.br => {
|
.br => {
|
||||||
try path.moveTo(center_x, float_height);
|
try ctx.moveTo(center_x, float_height);
|
||||||
try path.lineTo(center_x, center_y + r);
|
try ctx.lineTo(center_x, center_y + r);
|
||||||
try path.curveTo(
|
try ctx.curveTo(
|
||||||
center_x,
|
center_x,
|
||||||
center_y + s * r,
|
center_y + s * r,
|
||||||
center_x + s * r,
|
center_x + s * r,
|
||||||
@ -2677,10 +2653,10 @@ fn draw_arc(
|
|||||||
center_x + r,
|
center_x + r,
|
||||||
center_y,
|
center_y,
|
||||||
);
|
);
|
||||||
try path.lineTo(float_width, center_y);
|
try ctx.lineTo(float_width, center_y);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
try ctx.stroke(canvas.alloc, path);
|
try ctx.stroke();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_dash_horizontal(
|
fn draw_dash_horizontal(
|
||||||
@ -2912,14 +2888,9 @@ fn draw_separated_block_quadrant(self: Box, canvas: *font.sprite.Canvas, comptim
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var ctx: z2d.Context = .{
|
var ctx = try canvas.getContext();
|
||||||
.surface = canvas.sfc,
|
defer ctx.deinit();
|
||||||
.pattern = .{
|
ctx.setSource(.{ .alpha8 = .{ .a = @intFromEnum(Shade.on) } });
|
||||||
.opaque_pattern = .{
|
|
||||||
.pixel = .{ .alpha8 = .{ .a = @intFromEnum(Shade.on) } },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const gap: f64 = @max(1.0, @as(f64, @floatFromInt(self.metrics.cell_width)) * 0.10) / 2.0;
|
const gap: f64 = @max(1.0, @as(f64, @floatFromInt(self.metrics.cell_width)) * 0.10) / 2.0;
|
||||||
const left: f64 = gap;
|
const left: f64 = gap;
|
||||||
@ -2953,15 +2924,14 @@ fn draw_separated_block_quadrant(self: Box, canvas: *font.sprite.Canvas, comptim
|
|||||||
},
|
},
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
};
|
};
|
||||||
var path = z2d.Path.init(canvas.alloc);
|
try ctx.moveTo(x1, y1);
|
||||||
defer path.deinit();
|
try ctx.lineTo(x2, y1);
|
||||||
try path.moveTo(x1, y1);
|
try ctx.lineTo(x2, y2);
|
||||||
try path.lineTo(x2, y1);
|
try ctx.lineTo(x1, y2);
|
||||||
try path.lineTo(x2, y2);
|
try ctx.closePath();
|
||||||
try path.lineTo(x1, y2);
|
|
||||||
try path.close();
|
|
||||||
try ctx.fill(canvas.alloc, path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try ctx.fill();
|
||||||
}
|
}
|
||||||
|
|
||||||
test "all" {
|
test "all" {
|
||||||
|
@ -58,7 +58,7 @@ pub fn renderGlyph(
|
|||||||
) !font.Glyph {
|
) !font.Glyph {
|
||||||
// Create the canvas we'll use to draw
|
// Create the canvas we'll use to draw
|
||||||
var canvas = try font.sprite.Canvas.init(alloc, self.width, self.height);
|
var canvas = try font.sprite.Canvas.init(alloc, self.width, self.height);
|
||||||
defer canvas.deinit(alloc);
|
defer canvas.deinit();
|
||||||
|
|
||||||
// Perform the actual drawing
|
// Perform the actual drawing
|
||||||
try self.draw(alloc, &canvas, cp);
|
try self.draw(alloc, &canvas, cp);
|
||||||
|
@ -74,6 +74,9 @@ pub const Color = enum(u8) {
|
|||||||
_,
|
_,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// This is a managed struct, it keeps a reference to the allocator that is
|
||||||
|
/// used to initialize it, and the same allocator is used for any further
|
||||||
|
/// necessary allocations when drawing.
|
||||||
pub const Canvas = struct {
|
pub const Canvas = struct {
|
||||||
/// The underlying z2d surface.
|
/// The underlying z2d surface.
|
||||||
sfc: z2d.Surface,
|
sfc: z2d.Surface,
|
||||||
@ -88,16 +91,13 @@ pub const Canvas = struct {
|
|||||||
@intCast(width),
|
@intCast(width),
|
||||||
@intCast(height),
|
@intCast(height),
|
||||||
);
|
);
|
||||||
|
errdefer sfc.deinit(alloc);
|
||||||
|
|
||||||
return .{
|
return .{ .sfc = sfc, .alloc = alloc };
|
||||||
.sfc = sfc,
|
|
||||||
.alloc = alloc,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Canvas, alloc: Allocator) void {
|
pub fn deinit(self: *Canvas) void {
|
||||||
_ = alloc;
|
self.sfc.deinit(self.alloc);
|
||||||
self.sfc.deinit();
|
|
||||||
self.* = undefined;
|
self.* = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,27 +148,18 @@ pub const Canvas = struct {
|
|||||||
return region;
|
return region;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Acquires a z2d drawing context, caller MUST deinit context.
|
||||||
|
pub fn getContext(self: *Canvas) Allocator.Error!z2d.Context {
|
||||||
|
return try z2d.Context.init(self.alloc, &self.sfc);
|
||||||
|
}
|
||||||
|
|
||||||
/// Draw and fill a single pixel
|
/// Draw and fill a single pixel
|
||||||
pub fn pixel(self: *Canvas, x: u32, y: u32, color: Color) void {
|
pub fn pixel(self: *Canvas, x: u32, y: u32, color: Color) void {
|
||||||
self.sfc.putPixel(
|
self.sfc.putPixel(
|
||||||
@intCast(x),
|
@intCast(x),
|
||||||
@intCast(y),
|
@intCast(y),
|
||||||
.{ .alpha8 = .{ .a = @intFromEnum(color) } },
|
.{ .alpha8 = .{ .a = @intFromEnum(color) } },
|
||||||
) catch |e| switch (e) {
|
);
|
||||||
error.OutOfRange => {
|
|
||||||
// If we try to set out of range this will fail. We just silently
|
|
||||||
// ignore it, so that this method (and `rect` which uses it) have
|
|
||||||
// implicit bounds clipping.
|
|
||||||
},
|
|
||||||
|
|
||||||
error.InvalidHeight,
|
|
||||||
error.InvalidWidth,
|
|
||||||
error.InvalidPixelFormat,
|
|
||||||
=> {
|
|
||||||
std.log.err("unexpected (considered impossible) error err={}", .{e});
|
|
||||||
unreachable; // This shouldn't be possible.
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw and fill a rectangle. This is the main primitive for drawing
|
/// Draw and fill a rectangle. This is the main primitive for drawing
|
||||||
@ -192,94 +183,89 @@ pub const Canvas = struct {
|
|||||||
|
|
||||||
/// Draw and fill a quad.
|
/// Draw and fill a quad.
|
||||||
pub fn quad(self: *Canvas, q: Quad(f64), color: Color) !void {
|
pub fn quad(self: *Canvas, q: Quad(f64), color: Color) !void {
|
||||||
var ctx: z2d.Context = .{
|
var path: z2d.StaticPath(6) = .{};
|
||||||
.surface = self.sfc,
|
path.init();
|
||||||
.pattern = .{
|
|
||||||
.opaque_pattern = .{
|
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();
|
||||||
|
|
||||||
|
try z2d.painter.fill(
|
||||||
|
self.alloc,
|
||||||
|
&self.sfc,
|
||||||
|
&.{ .opaque_pattern = .{
|
||||||
.pixel = .{ .alpha8 = .{ .a = @intFromEnum(color) } },
|
.pixel = .{ .alpha8 = .{ .a = @intFromEnum(color) } },
|
||||||
},
|
} },
|
||||||
},
|
&path.nodes,
|
||||||
};
|
.{},
|
||||||
|
);
|
||||||
var path = z2d.Path.init(self.alloc);
|
|
||||||
defer path.deinit();
|
|
||||||
|
|
||||||
try path.moveTo(q.p0.x, q.p0.y);
|
|
||||||
try path.lineTo(q.p1.x, q.p1.y);
|
|
||||||
try path.lineTo(q.p2.x, q.p2.y);
|
|
||||||
try path.lineTo(q.p3.x, q.p3.y);
|
|
||||||
try path.close();
|
|
||||||
|
|
||||||
try ctx.fill(self.alloc, path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw and fill a triangle.
|
/// Draw and fill a triangle.
|
||||||
pub fn triangle(self: *Canvas, t: Triangle(f64), color: Color) !void {
|
pub fn triangle(self: *Canvas, t: Triangle(f64), color: Color) !void {
|
||||||
var ctx: z2d.Context = .{
|
var path: z2d.StaticPath(5) = .{};
|
||||||
.surface = self.sfc,
|
path.init();
|
||||||
.pattern = .{
|
|
||||||
.opaque_pattern = .{
|
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();
|
||||||
|
|
||||||
|
try z2d.painter.fill(
|
||||||
|
self.alloc,
|
||||||
|
&self.sfc,
|
||||||
|
&.{ .opaque_pattern = .{
|
||||||
.pixel = .{ .alpha8 = .{ .a = @intFromEnum(color) } },
|
.pixel = .{ .alpha8 = .{ .a = @intFromEnum(color) } },
|
||||||
},
|
} },
|
||||||
},
|
&path.nodes,
|
||||||
};
|
.{},
|
||||||
|
);
|
||||||
var path = z2d.Path.init(self.alloc);
|
|
||||||
defer path.deinit();
|
|
||||||
|
|
||||||
try path.moveTo(t.p0.x, t.p0.y);
|
|
||||||
try path.lineTo(t.p1.x, t.p1.y);
|
|
||||||
try path.lineTo(t.p2.x, t.p2.y);
|
|
||||||
try path.close();
|
|
||||||
|
|
||||||
try ctx.fill(self.alloc, path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn triangle_outline(self: *Canvas, t: Triangle(f64), thickness: f64, color: Color) !void {
|
pub fn triangle_outline(self: *Canvas, t: Triangle(f64), thickness: f64, color: Color) !void {
|
||||||
var ctx: z2d.Context = .{
|
var path: z2d.StaticPath(5) = .{};
|
||||||
.surface = self.sfc,
|
path.init();
|
||||||
.pattern = .{
|
|
||||||
.opaque_pattern = .{
|
path.moveTo(t.p0.x, t.p0.y);
|
||||||
|
path.lineTo(t.p1.x, t.p1.y);
|
||||||
|
path.lineTo(t.p2.x, t.p2.y);
|
||||||
|
|
||||||
|
try z2d.painter.stroke(
|
||||||
|
self.alloc,
|
||||||
|
&self.sfc,
|
||||||
|
&.{ .opaque_pattern = .{
|
||||||
.pixel = .{ .alpha8 = .{ .a = @intFromEnum(color) } },
|
.pixel = .{ .alpha8 = .{ .a = @intFromEnum(color) } },
|
||||||
},
|
} },
|
||||||
},
|
&path.nodes,
|
||||||
.line_width = thickness,
|
.{
|
||||||
.line_cap_mode = .round,
|
.line_cap_mode = .round,
|
||||||
};
|
.line_width = thickness,
|
||||||
|
},
|
||||||
var path = z2d.Path.init(self.alloc);
|
);
|
||||||
defer path.deinit();
|
|
||||||
|
|
||||||
try path.moveTo(t.p0.x, t.p0.y);
|
|
||||||
try path.lineTo(t.p1.x, t.p1.y);
|
|
||||||
try path.lineTo(t.p2.x, t.p2.y);
|
|
||||||
// try path.close();
|
|
||||||
|
|
||||||
try ctx.stroke(self.alloc, path);
|
|
||||||
// try ctx.fill(self.alloc, path);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Stroke a line.
|
/// Stroke a line.
|
||||||
pub fn line(self: *Canvas, l: Line(f64), thickness: f64, color: Color) !void {
|
pub fn line(self: *Canvas, l: Line(f64), thickness: f64, color: Color) !void {
|
||||||
var ctx: z2d.Context = .{
|
var path: z2d.StaticPath(3) = .{};
|
||||||
.surface = self.sfc,
|
path.init();
|
||||||
.pattern = .{
|
|
||||||
.opaque_pattern = .{
|
path.moveTo(l.p0.x, l.p0.y);
|
||||||
|
path.lineTo(l.p1.x, l.p1.y);
|
||||||
|
|
||||||
|
try z2d.painter.stroke(
|
||||||
|
self.alloc,
|
||||||
|
&self.sfc,
|
||||||
|
&.{ .opaque_pattern = .{
|
||||||
.pixel = .{ .alpha8 = .{ .a = @intFromEnum(color) } },
|
.pixel = .{ .alpha8 = .{ .a = @intFromEnum(color) } },
|
||||||
},
|
} },
|
||||||
},
|
&path.nodes,
|
||||||
.line_width = thickness,
|
.{
|
||||||
.line_cap_mode = .round,
|
.line_cap_mode = .round,
|
||||||
};
|
.line_width = thickness,
|
||||||
|
},
|
||||||
var path = z2d.Path.init(self.alloc);
|
);
|
||||||
defer path.deinit();
|
|
||||||
|
|
||||||
try path.moveTo(l.p0.x, l.p0.y);
|
|
||||||
try path.lineTo(l.p1.x, l.p1.y);
|
|
||||||
|
|
||||||
try ctx.stroke(self.alloc, path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn invert(self: *Canvas) void {
|
pub fn invert(self: *Canvas) void {
|
||||||
|
@ -17,7 +17,7 @@ pub fn renderGlyph(
|
|||||||
) !font.Glyph {
|
) !font.Glyph {
|
||||||
// Make a canvas of the desired size
|
// Make a canvas of the desired size
|
||||||
var canvas = try font.sprite.Canvas.init(alloc, width, height);
|
var canvas = try font.sprite.Canvas.init(alloc, width, height);
|
||||||
defer canvas.deinit(alloc);
|
defer canvas.deinit();
|
||||||
|
|
||||||
// Draw the appropriate sprite
|
// Draw the appropriate sprite
|
||||||
switch (sprite) {
|
switch (sprite) {
|
||||||
|
BIN
src/font/sprite/testdata/Box.ppm
vendored
BIN
src/font/sprite/testdata/Box.ppm
vendored
Binary file not shown.
@ -38,7 +38,7 @@ pub fn renderGlyph(
|
|||||||
.strikethrough => try drawSingle(alloc, width, line_thickness),
|
.strikethrough => try drawSingle(alloc, width, line_thickness),
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
};
|
};
|
||||||
defer canvas.deinit(alloc);
|
defer canvas.deinit();
|
||||||
|
|
||||||
// Write the drawing to the atlas
|
// Write the drawing to the atlas
|
||||||
const region = try canvas.writeAtlas(alloc, atlas);
|
const region = try canvas.writeAtlas(alloc, atlas);
|
||||||
|
Reference in New Issue
Block a user