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

Side by Side Diff: src/core/SkAnalyticEdge.h

Issue 2221103002: Analytic AntiAlias for Convex Shapes (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Declare flag in SkCommonFlags.h for iOS build Created 4 years, 2 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 unified diff | Download patch
« no previous file with comments | « src/core/SkAAAConstants.h ('k') | src/core/SkAnalyticEdge.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2006 The Android Open Source Project
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #ifndef SkAnalyticEdge_DEFINED
9 #define SkAnalyticEdge_DEFINED
10
11 #include "SkEdge.h"
12
13 inline SkFixed SkFixedMul_lowprec(SkFixed a, SkFixed b) {
14 SkASSERT(((int64_t)a >> 8) * (b >> 8) <= SK_MaxS32);
15 return (a >> 8) * (b >> 8);
16 }
17
18 struct SkAnalyticEdge {
19 // Similar to SkEdge, the conic edges will be converted to quadratic edges
20 enum Type {
21 kLine_Type,
22 kQuad_Type,
23 kCubic_Type
24 };
25
26 SkAnalyticEdge* fNext;
27 SkAnalyticEdge* fPrev;
28
29 SkFixed fX;
30 SkFixed fDX;
31 SkFixed fUpperX; // The x value when y = fUpperY
32 SkFixed fY; // The current y
33 SkFixed fUpperY; // The upper bound of y (our edge is from y = fUpper Y to y = fLowerY)
34 SkFixed fLowerY; // The lower bound of y (our edge is from y = fUpper Y to y = fLowerY)
35 SkFixed fDY; // abs(1/fDX); may be SK_MaxS32 when fDX is close to 0.
36 // fDY is only used for blitting trapezoids.
37
38 int8_t fCurveCount; // only used by kQuad(+) and kCubic(-)
39 uint8_t fCurveShift; // appled to all Dx/DDx/DDDx except for fCubicDShift exception
40 uint8_t fCubicDShift; // applied to fCDx and fCDy only in cubic
41 int8_t fWinding; // 1 or -1
42
43 static const int kDefaultAccuracy = 2; // default accuracy for snapping
44
45 static inline SkFixed snapY(SkFixed y, int accuracy = kDefaultAccuracy) {
46 return SkFixedRoundToFixed(y << accuracy) >> accuracy;
47 }
48
49 // Update fX, fY of this edge so fY = y
50 inline void goY(SkFixed y) {
51 if (y == fY + SK_Fixed1) {
52 fX = fX + fDX;
53 fY = y;
54 } else if (y != fY) {
55 // Drop lower digits as our alpha only has 8 bits
56 // (fDX and y - fUpperY may be greater than SK_Fixed1)
57 fX = fUpperX + SkFixedMul_lowprec(fDX, y - fUpperY);
58 fY = y;
59 }
60 }
61
62 inline bool setLine(const SkPoint& p0, const SkPoint& p1, const SkIRect* cli p = nullptr);
63 inline bool updateLine(SkFixed ax, SkFixed ay, SkFixed bx, SkFixed by, SkFix ed slope);
64 void chopLineWithClip(const SkIRect& clip);
65
66 inline bool intersectsClip(const SkIRect& clip) const {
67 SkASSERT(SkFixedFloorToInt(fUpperY) < clip.fBottom);
68 return SkFixedCeilToInt(fLowerY) > clip.fTop;
69 }
70
71 #ifdef SK_DEBUG
72 void dump() const {
73 SkDebugf("edge: upperY:%d lowerY:%d y:%g x:%g dx:%g w:%d\n",
74 fUpperY, fLowerY, SkFixedToFloat(fY), SkFixedToFloat(fX),
75 SkFixedToFloat(fDX), fWinding);
76 }
77
78 void validate() const {
79 SkASSERT(fPrev && fNext);
80 SkASSERT(fPrev->fNext == this);
81 SkASSERT(fNext->fPrev == this);
82
83 SkASSERT(fUpperY < fLowerY);
84 SkASSERT(SkAbs32(fWinding) == 1);
85 }
86 #endif
87 };
88
89 struct SkAnalyticQuadraticEdge : public SkAnalyticEdge {
90 SkQuadraticEdge fQEdge;
91
92 // snap y to integer points in the middle of the curve to accelerate AAA pat h filling
93 SkFixed fSnappedX, fSnappedY;
94
95 bool setQuadratic(const SkPoint pts[3]);
96 bool updateQuadratic();
97 };
98
99 struct SkAnalyticCubicEdge : public SkAnalyticEdge {
100 SkCubicEdge fCEdge;
101
102 bool setCubic(const SkPoint pts[4]);
103 bool updateCubic();
104 };
105
106 bool SkAnalyticEdge::setLine(const SkPoint& p0, const SkPoint& p1, const SkIRect * clip) {
107 // We must set X/Y using the same way (times 4, to FDot6, then to Fixed) as Quads/Cubics.
108 // Otherwise the order of the edge might be wrong due to precision limit.
109 SkFixed x0 = SkFDot6ToFixed(SkScalarToFDot6(p0.fX * 4)) >> 2;
110 SkFixed y0 = snapY(SkFDot6ToFixed(SkScalarToFDot6(p0.fY * 4)) >> 2);
111 SkFixed x1 = SkFDot6ToFixed(SkScalarToFDot6(p1.fX * 4)) >> 2;
112 SkFixed y1 = snapY(SkFDot6ToFixed(SkScalarToFDot6(p1.fY * 4)) >> 2);
113
114 // are we a zero-height line?
115 if (y0 == y1) {
116 return false;
117 }
118
119 int top = SkFixedFloorToInt(y0);
120 int bot = SkFixedCeilToInt(y1);
121
122 // are we completely above or below the clip?
123 if (clip && (top >= clip->fBottom || bot <= clip->fTop)) {
124 return false;
125 }
126
127 int winding = 1;
128
129 if (y0 > y1) {
130 SkTSwap(x0, x1);
131 SkTSwap(y0, y1);
132 winding = -1;
133 }
134
135 SkFixed slope = SkFixedDiv(x1 - x0, y1 - y0);
136
137 fX = x0;
138 fDX = slope;
139 fUpperX = x0;
140 fY = y0;
141 fUpperY = y0;
142 fLowerY = y1;
143 fDY = x1 != x0 ? SkAbs32(SkFixedDiv(y1 - y0, x1 - x0)) : SK_MaxS32;
144 fCurveCount = 0;
145 fWinding = SkToS8(winding);
146 fCurveShift = 0;
147
148 if (clip) {
149 this->chopLineWithClip(*clip);
150 }
151 return true;
152 }
153
154 #endif
OLDNEW
« no previous file with comments | « src/core/SkAAAConstants.h ('k') | src/core/SkAnalyticEdge.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698