Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(226)

Unified Diff: src/core/SkEdge.h

Issue 2221103002: Analytic AntiAlias for Convex Shapes (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix alpha computation Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/core/SkEdge.h
diff --git a/src/core/SkEdge.h b/src/core/SkEdge.h
index 11669b4f7fb4056f0309022294a0bc8dc625fd1b..eedec5e33d806acb23a22070dcb49bf50b204534 100644
--- a/src/core/SkEdge.h
+++ b/src/core/SkEdge.h
@@ -130,5 +130,150 @@ int SkEdge::setLine(const SkPoint& p0, const SkPoint& p1, int shift) {
return 1;
}
+//////////////Analytic Edges////////////////////////////////
+
+struct SkAnalyticEdge {
+ // Similar to SkEdge, the conic edges will be converted to quadratic edges
+ enum Type {
+ kLine_Type,
+ kQuad_Type,
+ kCubic_Type
+ };
+
+ SkAnalyticEdge* fNext;
+ SkAnalyticEdge* fPrev;
+
+ SkFixed fX;
+ SkFixed fDX;
+ SkFixed fUpperX; // The x value when y = fUpperY
+ SkFixed fY; // The current y
+ SkFixed fUpperY; // The upper bound of y (our edge is from y = fUpperY to y = fLowerY)
+ SkFixed fLowerY; // The lower bound of y (our edge is from y = fUpperY to y = fLowerY)
+ SkFixed fDY; // abs(1/fDX); may be SK_MaxS32 when fDX is close to 0.
+ // fDY is only used for blitting trapezoids.
+
+ int8_t fCurveCount; // only used by kQuad(+) and kCubic(-)
+ uint8_t fCurveShift; // appled to all Dx/DDx/DDDx except for fCubicDShift exception
+ uint8_t fCubicDShift; // applied to fCDx and fCDy only in cubic
+ int8_t fWinding; // 1 or -1
+
+ static const int kDefaultAccuracy = 4; // default accuracy for snapping
+
+ static inline SkFixed snapY(SkFixed y, int accuracy = kDefaultAccuracy) {
+ // We do ceiling to ensure that y is increasing
+ return SkFixedCeilToFixed(y << accuracy) >> accuracy;
+ }
+
+ // Update fX, fY of this edge so fY = y
+ inline void goY(SkFixed y) {
+ if (y == fY + SK_Fixed1) {
+ fX = fX + fDX;
+ fY = y;
+ } else if (y != fY) {
+ // Drop lower digits as our alpha only has 8 bits
+ // (fDX and y - fUpperY may be greater than SK_Fixed1)
+ fX = fUpperX + SkFixedMul_lowprec(fDX, y - fUpperY);
+ fY = y;
+ }
+ }
+
+ inline bool setLine(const SkPoint& p0, const SkPoint& p1, const SkIRect* clip = nullptr);
+ inline bool updateLine(SkFixed ax, SkFixed ay, SkFixed bx, SkFixed by, SkFixed slope);
+ void chopLineWithClip(const SkIRect& clip);
+
+ inline bool intersectsClip(const SkIRect& clip) const {
+ SkASSERT(SkFixedFloorToInt(fUpperY) < clip.fBottom);
+ return SkFixedCeilToInt(fLowerY) > clip.fTop;
+ }
+
+#ifdef SK_DEBUG
+ void dump() const {
+ SkDebugf("edge: upperY:%d lowerY:%d y:%g x:%g dx:%g w:%d\n",
+ fUpperY, fLowerY, SkFixedToFloat(fY), SkFixedToFloat(fX),
+ SkFixedToFloat(fDX), fWinding);
+ }
+
+ void validate() const {
+ SkASSERT(fPrev && fNext);
+ SkASSERT(fPrev->fNext == this);
+ SkASSERT(fNext->fPrev == this);
+
+ SkASSERT(fUpperY < fLowerY);
+ SkASSERT(SkAbs32(fWinding) == 1);
+ }
+#endif
+};
+
+struct SkAnalyticQuadraticEdge : public SkAnalyticEdge {
+ SkFixed fQx, fQy;
+ SkFixed fQDx, fQDy;
+ SkFixed fQDDx, fQDDy;
+ SkFixed fQLastX, fQLastY;
+
+ // snap y to integer points in the middle of the curve to accelerate AAA path filling
+ SkFixed fSnappedX, fSnappedY;
+
+ int setQuadratic(const SkPoint pts[3]);
+ int updateQuadratic();
+};
+
+struct SkAnalyticCubicEdge : public SkAnalyticEdge {
+ SkFixed fCx, fCy;
+ SkFixed fCDx, fCDy;
+ SkFixed fCDDx, fCDDy;
+ SkFixed fCDDDx, fCDDDy;
+ SkFixed fCLastX, fCLastY;
+
+ int setCubic(const SkPoint pts[4]);
+ int updateCubic();
+};
+
+bool SkAnalyticEdge::setLine(const SkPoint& p0, const SkPoint& p1, const SkIRect* clip) {
+ SkFixed x0 = SkScalarToFixed(p0.fX);
+ SkFixed y0 = snapY(SkScalarToFixed(p0.fY));
+ SkFixed x1 = SkScalarToFixed(p1.fX);
+ SkFixed y1 = snapY(SkScalarToFixed(p1.fY));
+
+ // are we a zero-height line?
+ if (y0 == y1) {
+ return false;
+ }
+
+ int top = SkFixedFloorToInt(y0);
+ int bot = SkFixedCeilToInt(y1);
+
+ // are we completely above or below the clip?
+ if (clip && (top >= clip->fBottom || bot <= clip->fTop)) {
+ return false;
+ }
+
+ int winding = 1;
+
+ if (y0 > y1) {
+ SkTSwap(x0, x1);
+ SkTSwap(y0, y1);
+ winding = -1;
+ }
+
+ SkFixed slope = SkFixedDiv(x1 - x0, y1 - y0);
+
+ fX = x0;
+ fDX = slope;
+ fUpperX = x0;
+ fY = y0;
+ fUpperY = y0;
+ fLowerY = y1;
+ fDY = x1 != x0 ? SkAbs32(SkFixedDiv(y1 - y0, x1 - x0)) : SK_MaxS32;
+ fCurveCount = 0;
+ fWinding = SkToS8(winding);
+ fCurveShift = 0;
+
+ if (clip) {
+ this->chopLineWithClip(*clip);
+ }
+ return true;
+}
+
+////////////////////////////////////////////////////////////
#endif

Powered by Google App Engine
This is Rietveld 408576698