Skip to content

Commit

Permalink
Merge pull request #49 from vancluever/transformations
Browse files Browse the repository at this point in the history
Transformation support
  • Loading branch information
vancluever authored Oct 17, 2024
2 parents 285a796 + 0405c7f commit f0012cf
Show file tree
Hide file tree
Showing 61 changed files with 1,594 additions and 109 deletions.
1 change: 0 additions & 1 deletion spec/003_fill_triangle.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Copyright © 2024 Chris Marchesi

//! Case: Renders and fills a triangle on a 300x300 surface.
const debug = @import("std").debug;
const mem = @import("std").mem;

const z2d = @import("z2d");
Expand Down
1 change: 0 additions & 1 deletion spec/004_fill_square.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Copyright © 2024 Chris Marchesi

//! Case: Renders and fills a square on a 300x300 surface.
const debug = @import("std").debug;
const mem = @import("std").mem;

const z2d = @import("z2d");
Expand Down
1 change: 0 additions & 1 deletion spec/005_fill_trapezoid.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Copyright © 2024 Chris Marchesi

//! Case: Renders and fills a trapezoid on a 300x300 surface.
const debug = @import("std").debug;
const mem = @import("std").mem;

const z2d = @import("z2d");
Expand Down
1 change: 0 additions & 1 deletion spec/006_fill_star_even_odd.zig
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
//!
//! NOTE: This star fills with even-odd rule, so it's expected for there to be
//! a gap in the middle.
const debug = @import("std").debug;
const mem = @import("std").mem;

const z2d = @import("z2d");
Expand Down
1 change: 0 additions & 1 deletion spec/007_fill_bezier.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Copyright © 2024 Chris Marchesi

//! Case: Renders and fills a bezier curve on a 300x300 surface.
const debug = @import("std").debug;
const mem = @import("std").mem;

const z2d = @import("z2d");
Expand Down
1 change: 0 additions & 1 deletion spec/008_stroke_triangle.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Copyright © 2024 Chris Marchesi

//! Case: Renders and strokes a triangle on a 300x300 surface.
const debug = @import("std").debug;
const mem = @import("std").mem;

const z2d = @import("z2d");
Expand Down
1 change: 0 additions & 1 deletion spec/009_stroke_square.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Copyright © 2024 Chris Marchesi

//! Case: Renders and strokes a square on a 300x300 surface.
const debug = @import("std").debug;
const mem = @import("std").mem;

const z2d = @import("z2d");
Expand Down
1 change: 0 additions & 1 deletion spec/010_stroke_trapezoid.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Copyright © 2024 Chris Marchesi

//! Case: Renders and strokes a trapezoid on a 300x300 surface.
const debug = @import("std").debug;
const mem = @import("std").mem;

const z2d = @import("z2d");
Expand Down
1 change: 0 additions & 1 deletion spec/011_stroke_star.zig
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
//! Note that this test also validates that we always fill strokes using the
//! non-zero rule, since drawing a star means tracing a path that overlaps as
//! you move from point to point.
const debug = @import("std").debug;
const mem = @import("std").mem;

const z2d = @import("z2d");
Expand Down
1 change: 0 additions & 1 deletion spec/012_stroke_bezier.zig
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
//! surface.
//!
//! The beziers are not closed.
const debug = @import("std").debug;
const mem = @import("std").mem;

const z2d = @import("z2d");
Expand Down
1 change: 0 additions & 1 deletion spec/013_fill_combined.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

//! Case: Renders and fills multiple shapes using a single path operation, used
//! to ensure we can do this without having to fill each polygon individually.
const debug = @import("std").debug;
const mem = @import("std").mem;

const z2d = @import("z2d");
Expand Down
1 change: 0 additions & 1 deletion spec/014_stroke_lines.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

//! Case: Renders multiple lines with the default thickness in different
//! directions, unclosed.
const debug = @import("std").debug;
const mem = @import("std").mem;

const z2d = @import("z2d");
Expand Down
1 change: 0 additions & 1 deletion spec/015_stroke_miter.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Copyright © 2024 Chris Marchesi

//! Case: Renders unclosed lines with miters.
const debug = @import("std").debug;
const mem = @import("std").mem;

const z2d = @import("z2d");
Expand Down
1 change: 0 additions & 1 deletion spec/016_fill_star_non_zero.zig
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
//!
//! NOTE: This star explicitly fills with non-zero rule, so it's expected for
//! there to NOT be a gap in the middle.
const debug = @import("std").debug;
const mem = @import("std").mem;

const z2d = @import("z2d");
Expand Down
1 change: 0 additions & 1 deletion spec/017_stroke_star_round.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Copyright © 2024 Chris Marchesi

//! Case: Renders and strokes a star on a 300x300 surface with rounded corners.
const debug = @import("std").debug;
const mem = @import("std").mem;

const z2d = @import("z2d");
Expand Down
1 change: 0 additions & 1 deletion spec/018_stroke_square_spiral_round.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Copyright © 2024 Chris Marchesi

//! Case: Renders unclosed lines with rounded joins.
const debug = @import("std").debug;
const mem = @import("std").mem;

const z2d = @import("z2d");
Expand Down
1 change: 0 additions & 1 deletion spec/019_stroke_bevel_miterlimit.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

//! Case: Renders multiple cornered lines with bevels and miters, the latter
//! with varying miter limits.
const debug = @import("std").debug;
const mem = @import("std").mem;

const z2d = @import("z2d");
Expand Down
1 change: 0 additions & 1 deletion spec/020_stroke_lines_round_caps.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Copyright © 2024 Chris Marchesi

//! Case: Renders multiple lines, round-capped, in various directions.
const debug = @import("std").debug;
const mem = @import("std").mem;

const z2d = @import("z2d");
Expand Down
1 change: 0 additions & 1 deletion spec/021_stroke_lines_square_caps.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Copyright © 2024 Chris Marchesi

//! Case: Renders multiple lines, square-capped, in various directions.
const debug = @import("std").debug;
const mem = @import("std").mem;

const z2d = @import("z2d");
Expand Down
1 change: 0 additions & 1 deletion spec/022_stroke_lines_butt_caps.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Copyright © 2024 Chris Marchesi

//! Case: Renders multiple lines, butt-capped, in various directions.
const debug = @import("std").debug;
const mem = @import("std").mem;

const z2d = @import("z2d");
Expand Down
1 change: 0 additions & 1 deletion spec/024_fill_triangle_direct_cross_format.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
//! Case: Renders and fills a triangle on a 300x300 surface, but with different
//! pixel types (RGBA on RGB surface) We expect compositing to work on both
//! main AA modes (no AA, default AA).
const debug = @import("std").debug;
const mem = @import("std").mem;

const z2d = @import("z2d");
Expand Down
1 change: 0 additions & 1 deletion spec/025_fill_diamond_clipped.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Copyright © 2024 Chris Marchesi

//! Case: Renders and fills a diamond clipped on a 300x300 surface.
const debug = @import("std").debug;
const mem = @import("std").mem;

const z2d = @import("z2d");
Expand Down
1 change: 0 additions & 1 deletion spec/026_fill_triangle_full.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

//! Case: Renders and fills a triangle on a 300x300 surface, extended to the
//! full canvas.
const debug = @import("std").debug;
const mem = @import("std").mem;

const z2d = @import("z2d");
Expand Down
1 change: 0 additions & 1 deletion spec/027_stroke_bezier_tolerance.zig
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
//! surface, at varying levels of error tolerance.
//!
//! The beziers are not closed.
const debug = @import("std").debug;
const mem = @import("std").mem;

const z2d = @import("z2d");
Expand Down
1 change: 0 additions & 1 deletion spec/029_stroke_lines_round_caps_tolerance.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Copyright © 2024 Chris Marchesi

//! Case: Renders multiple lines, round-capped at varying levels of tolerance.
const debug = @import("std").debug;
const mem = @import("std").mem;

const z2d = @import("z2d");
Expand Down
1 change: 0 additions & 1 deletion spec/030_stroke_star_round_tolerance.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

//! Case: Renders and strokes stars on a 900x300 surface with rounded corners,
//! and varying tolerance.
const debug = @import("std").debug;
const mem = @import("std").mem;

const z2d = @import("z2d");
Expand Down
1 change: 0 additions & 1 deletion spec/031_fill_quad_bezier.zig
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
//! the one that you'd set with moveTo) and the final point are technically the
//! start and end points. Thus, to get a proper quadratic to what you'd expect,
//! you need the *control* points (so (x1, y1), (x2, y2)) to be equal.
const debug = @import("std").debug;
const mem = @import("std").mem;

const z2d = @import("z2d");
Expand Down
1 change: 0 additions & 1 deletion spec/032_fill_arc.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

//! Case: Renders arcs as a demonstration of how this can be done with bezier
//! primitives.
const debug = @import("std").debug;
const mem = @import("std").mem;

const z2d = @import("z2d");
Expand Down
1 change: 0 additions & 1 deletion spec/033_fill_zig_mark.zig
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
//!
//! The [Zig logo](https://github.com/ziglang/logo) and logomark are licensed
//! CC-BY-SA 4.0.
const debug = @import("std").debug;
const mem = @import("std").mem;

const z2d = @import("z2d");
Expand Down
1 change: 0 additions & 1 deletion spec/034_stroke_cross.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

//! Case: Renders a stroked cross (used to validate correct join direction for
//! strokes when changing direction (clockwise -> counter-clockwise and vice versa).
const debug = @import("std").debug;
const mem = @import("std").mem;

const z2d = @import("z2d");
Expand Down
1 change: 0 additions & 1 deletion spec/035_arc_command.zig
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
//! https://www.w3.org/TR/SVG11/paths.html#PathDataEllipticalArcCommands.
//! Copyright © 2011 World Wide Web Consortium.
//! https://www.w3.org/copyright/software-license-2023/
const debug = @import("std").debug;
const math = @import("std").math;
const mem = @import("std").mem;

Expand Down
1 change: 0 additions & 1 deletion spec/036_stroke_colinear.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Copyright © 2024 Chris Marchesi

//! Case: Asserts correctness in colinear stroke operations.
const debug = @import("std").debug;
const mem = @import("std").mem;

const z2d = @import("z2d");
Expand Down
1 change: 0 additions & 1 deletion spec/037_stroke_join_overlap.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

//! Case: Draws overlapping strokes in different directions to test that joins
//! with extremely acute angles overlap properly.
const debug = @import("std").debug;
const mem = @import("std").mem;

const z2d = @import("z2d");
Expand Down
1 change: 0 additions & 1 deletion spec/038_stroke_zero_length.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Copyright © 2024 Chris Marchesi

//! Case: Renders and fills a triangle on a 300x300 surface.
const debug = @import("std").debug;
const mem = @import("std").mem;

const z2d = @import("z2d");
Expand Down
1 change: 0 additions & 1 deletion spec/039_stroke_paint_extent_dontclip.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

//! Case: Ensures that certain extents don't get clipped on the larger
//! y-boundary.
const debug = @import("std").debug;
const mem = @import("std").mem;

const z2d = @import("z2d");
Expand Down
1 change: 0 additions & 1 deletion spec/040_stroke_corner_symmetrical.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
//! Case: ensures proper alignment of a line spanning the whole box diagonally.
//! The line should be symmetrical on both the upper left and bottom right
//! corners of the box.
const debug = @import("std").debug;
const mem = @import("std").mem;

const z2d = @import("z2d");
Expand Down
1 change: 0 additions & 1 deletion spec/041_stroke_noop_lineto.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

//! Case: Ensure no-op (degenerate) lineto operations are accounted for
//! properly and do not break strokes.
const debug = @import("std").debug;
const mem = @import("std").mem;

const z2d = @import("z2d");
Expand Down
92 changes: 92 additions & 0 deletions spec/042_arc_ellipses.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// SPDX-License-Identifier: 0BSD
// Copyright © 2024 Chris Marchesi

//! Case: Renders ellipses (fill and stroke) using arc commands and
//! transformation matrices.
const math = @import("std").math;
const mem = @import("std").mem;

const z2d = @import("z2d");

pub const filename = "042_arc_ellipses";

pub fn render(alloc: mem.Allocator, aa_mode: z2d.options.AntiAliasMode) !z2d.Surface {
const width = 400;
const height = 400;
const sfc = try z2d.Surface.init(.image_surface_rgb, alloc, width, height);

var context: z2d.Context = .{
.surface = sfc,
.pattern = .{
.opaque_pattern = .{
.pixel = .{ .rgb = .{ .r = 0xFF, .g = 0xFF, .b = 0xFF } }, // White on black
},
},
.anti_aliasing_mode = aa_mode,
.line_width = 5,
};

var path = z2d.Path.init(alloc);
defer path.deinit();
// Add a margin of (10, 10) by translation
path.transformation = path.transformation.translate(10, 10);
// first ellipse at 0, 0 rx = 50, ry=100
_ = try ellipse(&path, 0, 0, 50, 100);
try context.fill(alloc, path);

// second as the first, but stroked, at 100, 0)
_ = try ellipse(&path, 100, 0, 50, 100);
try context.stroke(alloc, path);

// as the second, but we capture the CTM to test stroke warping (at 200, 0)
var saved_ctm = context.transformation;
var saved_line_width = context.line_width;
context.transformation = try ellipse(&path, 200, 0, 50, 100);
context.line_width = lw: {
var ux = saved_line_width;
var uy = saved_line_width;
try context.transformation.deviceToUserDistance(&ux, &uy);
if (ux < uy) {
break :lw uy;
}
break :lw ux;
};
try context.stroke(alloc, path);
context.transformation = saved_ctm;
context.line_width = saved_line_width;

// as the third, but first rotate 45 degrees (at 300, 0)
const saved_path_ctm = path.transformation;
saved_ctm = context.transformation;
saved_line_width = context.line_width;
path.transformation = path.transformation.rotate(math.pi / 4.0);
context.transformation = try ellipse(&path, 300, 0, 50, 100);
context.line_width = lw: {
var ux = saved_line_width;
var uy = saved_line_width;
try context.transformation.deviceToUserDistance(&ux, &uy);
if (ux < uy) {
break :lw uy;
}
break :lw ux;
};
try context.stroke(alloc, path);
path.transformation = saved_path_ctm;
context.transformation = saved_ctm;
context.line_width = saved_line_width;

return sfc;
}

fn ellipse(path: *z2d.Path, x: f64, y: f64, rx: f64, ry: f64) !z2d.Transformation {
const saved_ctm = path.transformation;
path.reset();
path.transformation = path.transformation
.translate(x + rx / 2, y + ry / 2)
.scale(rx / 2, ry / 2);
try path.arc(0, 0, 1, 0, 2 * math.pi, false, null);
const effective_ctm = path.transformation;
path.transformation = saved_ctm;
try path.close();
return effective_ctm;
}
Loading

0 comments on commit f0012cf

Please sign in to comment.