32451cf9bc
1 Commits
Author | SHA1 | Message | Date | |
---|---|---|---|---|
Michael Ludwig
|
6c8e2e832e |
Fix winding when splitting edges at out-of-bounds vertices
Add GM repros and up triangulation verb count to match chromium's define The GMs draw incorrectly in (base->p2) with the updated verb count, but would draw fine w/o the increased verb count because a different path renderer would be chosen. This fixes a latent bug that was in the edge splitting code of the triangulator that was exposed by https://skia-review.googlesource.com/c/skia/+/432196 Before that CL, intersections of two lines would be clamped to one of the 4 vertices of the 2 segments. In the CL linked, the clamping was adjusted to clamp X and Y axes separately, so it increased the chance that a clamped intersection would have its X or Y coord equal to line's vertex but differ along the other coord (when they both equaled, they were considered coincident and splitting that edge did nothing). Splitting an edge at its intersection was intended to split (p0 to p1) into new lines (p0 to v) and (v to p1) where p0 < v < p1 according to the vertical or horizontal sorting that was imposed on the mesh. For a given line segment and a clamped vertex, there are 8 ways the intersection could be clamped (4 edges and 4 corners). If the edge has a positive non-zero slope, a zero slope, or an infinite slope, in all cases the clamped intersection will be sorted correctly and satisfy p0 < v < p1. However, if the edge has negative slope vertical: p0.y<p1.y and p0.x>p1.x, horizontal: p0.x<p1.x and p0.y<p1.y then intersections snapped to the primary sorting axis will be out of order and produce a split such that v < p0 < p1 or p0 < p1 < v. This was already detected, but it didn't update the winding of the new edge to preserve the original winding from p0 to p1. In these out-of-order cases, the intersection point is the top of both the new and old edge, or the bottom of both the new and old edge. This means that winding "top to bottom" on the new edge would go in the opposite direction as the original winding from p0 to p1. Flipping the winding on the new edge preserves the intended winding of the contour while still allowing the edges/vertices to be sorted consistently. This showed up as large gradients in the AA triangulator because w/o the winding adjustment, the winding flip at the new edge would confuse the border extractor that was used to compute insets and outsets for the 1px coverage ramp. It would then use edges that were normally unrelated to each and declare their line intersections as the "interior" with full coverage. Obviously these could be anywhere so the 1px coverage ramp would get smeared across that shape. Bug: chromium:1257515 Change-Id: I015d6b4767db352e3eecfc53047958e74320268d Reviewed-on: https://skia-review.googlesource.com/c/skia/+/458057 Reviewed-by: Robert Phillips <robertphillips@google.com> Commit-Queue: Michael Ludwig <michaelludwig@google.com> |