Skip to content

Commit

Permalink
Minor documentation and cleanup to zero-length tangent detection
Browse files Browse the repository at this point in the history
  • Loading branch information
armansito committed Nov 8, 2023
1 parent 1f5a93d commit 24681fa
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 10 deletions.
24 changes: 15 additions & 9 deletions crates/encoding/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -525,9 +525,11 @@ impl<'a> PathEncoder<'a> {
if self.state == PathState::MoveTo {
let x0 = self.first_point[0];
let y0 = self.first_point[1];
// TODO: should this be an exact match?
if (x - x0).abs() < 1e-12 && (y - y0).abs() < 1e-12 {
// Ensure that we don't end up with a zero-length start tangent.
const EPS: f32 = 1e-12;
if (x - x0).abs() < EPS && (y - y0).abs() < EPS {
// Drop the segment if its length is zero
// TODO: do this for all not segments, not just start?
return;
}
self.first_start_tangent_end = [x, y];
Expand All @@ -552,13 +554,15 @@ impl<'a> PathEncoder<'a> {
if self.state == PathState::MoveTo {
let x0 = self.first_point[0];
let y0 = self.first_point[1];
// TODO clean this up
let (x, y) = if (x1 - x0).abs() > 1e-12 || (y1 - y0).abs() > 1e-12 {
// Ensure that we don't end up with a zero-length start tangent.
const EPS: f32 = 1e-12;
let (x, y) = if (x1 - x0).abs() > EPS || (y1 - y0).abs() > EPS {
(x1, y1)
} else if (x2 - x0).abs() > 1e-12 || (y2 - y0).abs() > 1e-12 {
} else if (x2 - x0).abs() > EPS || (y2 - y0).abs() > EPS {
(x2, y2)
} else {
// Drop the segment if its length is zero
// TODO: do this for all not segments, not just start?
return;
};
self.first_start_tangent_end = [x, y];
Expand All @@ -583,15 +587,17 @@ impl<'a> PathEncoder<'a> {
if self.state == PathState::MoveTo {
let x0 = self.first_point[0];
let y0 = self.first_point[1];
// TODO clean this up
let (x, y) = if (x1 - x0).abs() > 1e-12 || (y1 - y0).abs() > 1e-12 {
// Ensure that we don't end up with a zero-length start tangent.
const EPS: f32 = 1e-12;
let (x, y) = if (x1 - x0).abs() > EPS || (y1 - y0).abs() > EPS {
(x1, y1)
} else if (x2 - x0).abs() > 1e-12 || (y2 - y0).abs() > 1e-12 {
} else if (x2 - x0).abs() > EPS || (y2 - y0).abs() > EPS {
(x2, y2)
} else if (x3 - x0).abs() > 1e-12 || (y3 - y0).abs() > 1e-12 {
} else if (x3 - x0).abs() > EPS || (y3 - y0).abs() > EPS {
(x3, y3)
} else {
// Drop the segment if its length is zero
// TODO: do this for all not segments, not just start?
return;
};
self.first_start_tangent_end = [x, y];
Expand Down
8 changes: 7 additions & 1 deletion shader/flatten.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,13 @@ fn read_path_segment(tag: PathTagData, transform: Transform, is_stroke: bool) ->
}

if is_stroke_cap_marker && is_open {
// TODO: document
// The stroke cap marker for an open path is encoded as a quadto where the p1 and p2 store
// the start control point of the subpath and together with p2 forms the start tangent. p0
// is ignored.
//
// This is encoded this way because encoding this as a lineto would require adding a moveto,
// which would terminate the subpath too early (by setting the SUBPATH_END_BIT on the
// segment preceding the cap marker). This scheme is only used for strokes.
p0 = transform_apply(transform, p1);
p1 = transform_apply(transform, p2);
seg_type = PATH_TAG_LINETO;
Expand Down

0 comments on commit 24681fa

Please sign in to comment.