aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gm/aaa.cpp16
-rw-r--r--src/core/SkScan_AAAPath.cpp16
2 files changed, 30 insertions, 2 deletions
diff --git a/gm/aaa.cpp b/gm/aaa.cpp
index 614ff84258..4f81fc9a2c 100644
--- a/gm/aaa.cpp
+++ b/gm/aaa.cpp
@@ -123,6 +123,22 @@ protected:
p.setStrokeWidth(5);
canvas->drawPath(path, p);
canvas->restore();
+
+
+ // The following two paths test if we correctly cumulates the alpha on the middle pixel
+ // column where the left rect and the right rect abut.
+ p.setStyle(SkPaint::kFill_Style);
+ canvas->translate(0, 300);
+ path.reset();
+ path.addRect({20, 20, 100.4999f, 100});
+ path.addRect({100.5001f, 20, 200, 100});
+ canvas->drawPath(path, p);
+
+ canvas->translate(300, 0);
+ path.reset();
+ path.addRect({20, 20, 100.1f, 100});
+ path.addRect({100.9f, 20, 200, 100});
+ canvas->drawPath(path, p);
}
private:
diff --git a/src/core/SkScan_AAAPath.cpp b/src/core/SkScan_AAAPath.cpp
index f9445d24f2..6362d2f1e0 100644
--- a/src/core/SkScan_AAAPath.cpp
+++ b/src/core/SkScan_AAAPath.cpp
@@ -1282,15 +1282,27 @@ static void validate_edges_for_y(const SkAnalyticEdge* edge, SkFixed y) {
// Return true if prev->fX, next->fX are too close in the current pixel row.
static inline bool edges_too_close(SkAnalyticEdge* prev, SkAnalyticEdge* next, SkFixed lowerY) {
+ // When next->fDX == 0, prev->fX >= next->fX - SkAbs32(next->fDX) would be false
+ // even if prev->fX and next->fX are close and within one pixel (e.g., prev->fX == 0.1,
+ // next->fX == 0.9). Adding SLACK = 1 to the formula would guarantee it to be true if two
+ // edges prev and next are within one pixel.
+ constexpr SkFixed SLACK =
+#ifdef SK_SUPPORT_LEGACY_AA_BEHAVIOR
+ 0;
+#else
+ SK_Fixed1;
+#endif
+
// Note that even if the following test failed, the edges might still be very close to each
// other at some point within the current pixel row because of prev->fDX and next->fDX.
// However, to handle that case, we have to sacrafice more performance.
// I think the current quality is good enough (mainly by looking at Nebraska-StateSeal.svg)
// so I'll ignore fDX for performance tradeoff.
- return next && prev && next->fUpperY < lowerY && prev->fX >= next->fX - SkAbs32(next->fDX);
+ return next && prev && next->fUpperY < lowerY && prev->fX + SLACK >=
+ next->fX - SkAbs32(next->fDX);
// The following is more accurate but also slower.
// return (prev && prev->fPrev && next && next->fNext != nullptr && next->fUpperY < lowerY &&
- // prev->fX + SkAbs32(prev->fDX) >= next->fX - SkAbs32(next->fDX));
+ // prev->fX + SkAbs32(prev->fDX) + SLACK >= next->fX - SkAbs32(next->fDX));
}
// This function exists for the case where the previous rite edge is removed because