diff options
author | Cary Clark <caryclark@skia.org> | 2017-04-18 12:08:58 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-04-18 16:40:48 +0000 |
commit | 73e597d0eddeaaa466101d5bb7da537c0066166a (patch) | |
tree | 4d6196ac7f074c96ccaee75beaffa196d27fe1fe /src/pathops/SkAddIntersections.cpp | |
parent | 4304d11ada22ebfb6b64d87247ad24cde89c3a74 (diff) |
keep integral rectangle intersections integral
A pair of coincident lines can generate multiple intersection
points. Path ops is more stable when the intersection T value
is used to recompute the intersection point, but this has
the side-effect of making integral edges intersect at non-integral
values.
While it's worthwhile to fix this, for the moment it is less
disruptive to only worry about keeping intersection values
integral if the original intersection point is integral in
both axes.
Also, fix some debugging code that bit-rotted.
R=msarett@google.com
Change-Id: Iefd27b25d1d21c22b224c174bd59bc6c105033c4
Reviewed-on: https://skia-review.googlesource.com/13721
Reviewed-by: Matt Sarett <msarett@google.com>
Commit-Queue: Cary Clark <caryclark@google.com>
Diffstat (limited to 'src/pathops/SkAddIntersections.cpp')
-rw-r--r-- | src/pathops/SkAddIntersections.cpp | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/src/pathops/SkAddIntersections.cpp b/src/pathops/SkAddIntersections.cpp index b47e7df599..b9f2d8dee2 100644 --- a/src/pathops/SkAddIntersections.cpp +++ b/src/pathops/SkAddIntersections.cpp @@ -509,9 +509,17 @@ bool AddIntersectTs(SkOpContour* test, SkOpContour* next, SkOpCoincidence* coinc SkASSERT(ts[0][pt] >= 0 && ts[0][pt] <= 1); SkASSERT(ts[1][pt] >= 0 && ts[1][pt] <= 1); wt.segment()->debugValidate(); - SkOpPtT* testTAt = wt.segment()->addT(ts[swap][pt]); + // if t value is used to compute pt in addT, error may creep in and + // rect intersections may result in non-rects. if pt value from intersection + // is passed in, current tests break. As a workaround, pass in pt + // value from intersection only if pt.x and pt.y is integral + SkPoint iPt = ts.pt(pt).asSkPoint(); + bool iPtIsIntegral = iPt.fX == floor(iPt.fX) && iPt.fY == floor(iPt.fY); + SkOpPtT* testTAt = iPtIsIntegral ? wt.segment()->addT(ts[swap][pt], iPt) + : wt.segment()->addT(ts[swap][pt]); wn.segment()->debugValidate(); - SkOpPtT* nextTAt = wn.segment()->addT(ts[!swap][pt]); + SkOpPtT* nextTAt = iPtIsIntegral ? wn.segment()->addT(ts[!swap][pt], iPt) + : wn.segment()->addT(ts[!swap][pt]); if (!testTAt->contains(nextTAt)) { SkOpPtT* oppPrev = testTAt->oppPrev(nextTAt); // Returns nullptr if pair if (oppPrev) { // already share a pt-t loop. |