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

Side by Side 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2006 The Android Open Source Project 2 * Copyright 2006 The Android Open Source Project
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 8
9 #ifndef SkEdge_DEFINED 9 #ifndef SkEdge_DEFINED
10 #define SkEdge_DEFINED 10 #define SkEdge_DEFINED
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 fX = SkFDot6ToFixed(x0 + SkFixedMul(slope, dy)); // + SK_Fixed1/2 123 fX = SkFDot6ToFixed(x0 + SkFixedMul(slope, dy)); // + SK_Fixed1/2
124 fDX = slope; 124 fDX = slope;
125 fFirstY = top; 125 fFirstY = top;
126 fLastY = bot - 1; 126 fLastY = bot - 1;
127 fCurveCount = 0; 127 fCurveCount = 0;
128 fWinding = SkToS8(winding); 128 fWinding = SkToS8(winding);
129 fCurveShift = 0; 129 fCurveShift = 0;
130 return 1; 130 return 1;
131 } 131 }
132 132
133 //////////////Analytic Edges////////////////////////////////
134
135 struct SkAnalyticEdge {
136 // Similar to SkEdge, the conic edges will be converted to quadratic edges
137 enum Type {
138 kLine_Type,
139 kQuad_Type,
140 kCubic_Type
141 };
142
143 SkAnalyticEdge* fNext;
144 SkAnalyticEdge* fPrev;
145
146 SkFixed fX;
147 SkFixed fDX;
148 SkFixed fUpperX; // The x value when y = fUpperY
149 SkFixed fY; // The current y
150 SkFixed fUpperY; // The upper bound of y (our edge is from y = fUpper Y to y = fLowerY)
151 SkFixed fLowerY; // The lower bound of y (our edge is from y = fUpper Y to y = fLowerY)
152 SkFixed fDY; // abs(1/fDX); may be SK_MaxS32 when fDX is close to 0.
153 // fDY is only used for blitting trapezoids.
154
155 int8_t fCurveCount; // only used by kQuad(+) and kCubic(-)
156 uint8_t fCurveShift; // appled to all Dx/DDx/DDDx except for fCubicDShift exception
157 uint8_t fCubicDShift; // applied to fCDx and fCDy only in cubic
158 int8_t fWinding; // 1 or -1
159
160 static const int kDefaultAccuracy = 4; // default accuracy for snapping
161
162 static inline SkFixed snapY(SkFixed y, int accuracy = kDefaultAccuracy) {
163 // We do ceiling to ensure that y is increasing
164 return SkFixedCeilToFixed(y << accuracy) >> accuracy;
165 }
166
167 // Update fX, fY of this edge so fY = y
168 inline void goY(SkFixed y) {
169 if (y == fY + SK_Fixed1) {
170 fX = fX + fDX;
171 fY = y;
172 } else if (y != fY) {
173 // Drop lower digits as our alpha only has 8 bits
174 // (fDX and y - fUpperY may be greater than SK_Fixed1)
175 fX = fUpperX + SkFixedMul_lowprec(fDX, y - fUpperY);
176 fY = y;
177 }
178 }
179
180 inline bool setLine(const SkPoint& p0, const SkPoint& p1, const SkIRect* cli p = nullptr);
181 inline bool updateLine(SkFixed ax, SkFixed ay, SkFixed bx, SkFixed by, SkFix ed slope);
182 void chopLineWithClip(const SkIRect& clip);
183
184 inline bool intersectsClip(const SkIRect& clip) const {
185 SkASSERT(SkFixedFloorToInt(fUpperY) < clip.fBottom);
186 return SkFixedCeilToInt(fLowerY) > clip.fTop;
187 }
188
189 #ifdef SK_DEBUG
190 void dump() const {
191 SkDebugf("edge: upperY:%d lowerY:%d y:%g x:%g dx:%g w:%d\n",
192 fUpperY, fLowerY, SkFixedToFloat(fY), SkFixedToFloat(fX),
193 SkFixedToFloat(fDX), fWinding);
194 }
195
196 void validate() const {
197 SkASSERT(fPrev && fNext);
198 SkASSERT(fPrev->fNext == this);
199 SkASSERT(fNext->fPrev == this);
200
201 SkASSERT(fUpperY < fLowerY);
202 SkASSERT(SkAbs32(fWinding) == 1);
203 }
204 #endif
205 };
206
207 struct SkAnalyticQuadraticEdge : public SkAnalyticEdge {
208 SkFixed fQx, fQy;
209 SkFixed fQDx, fQDy;
210 SkFixed fQDDx, fQDDy;
211 SkFixed fQLastX, fQLastY;
212
213 // snap y to integer points in the middle of the curve to accelerate AAA pat h filling
214 SkFixed fSnappedX, fSnappedY;
215
216 int setQuadratic(const SkPoint pts[3]);
217 int updateQuadratic();
218 };
219
220 struct SkAnalyticCubicEdge : public SkAnalyticEdge {
221 SkFixed fCx, fCy;
222 SkFixed fCDx, fCDy;
223 SkFixed fCDDx, fCDDy;
224 SkFixed fCDDDx, fCDDDy;
225 SkFixed fCLastX, fCLastY;
226
227 int setCubic(const SkPoint pts[4]);
228 int updateCubic();
229 };
230
231 bool SkAnalyticEdge::setLine(const SkPoint& p0, const SkPoint& p1, const SkIRect * clip) {
232 SkFixed x0 = SkScalarToFixed(p0.fX);
233 SkFixed y0 = snapY(SkScalarToFixed(p0.fY));
234 SkFixed x1 = SkScalarToFixed(p1.fX);
235 SkFixed y1 = snapY(SkScalarToFixed(p1.fY));
236
237 // are we a zero-height line?
238 if (y0 == y1) {
239 return false;
240 }
241
242 int top = SkFixedFloorToInt(y0);
243 int bot = SkFixedCeilToInt(y1);
244
245 // are we completely above or below the clip?
246 if (clip && (top >= clip->fBottom || bot <= clip->fTop)) {
247 return false;
248 }
249
250 int winding = 1;
251
252 if (y0 > y1) {
253 SkTSwap(x0, x1);
254 SkTSwap(y0, y1);
255 winding = -1;
256 }
257
258 SkFixed slope = SkFixedDiv(x1 - x0, y1 - y0);
259
260 fX = x0;
261 fDX = slope;
262 fUpperX = x0;
263 fY = y0;
264 fUpperY = y0;
265 fLowerY = y1;
266 fDY = x1 != x0 ? SkAbs32(SkFixedDiv(y1 - y0, x1 - x0)) : SK_MaxS32;
267 fCurveCount = 0;
268 fWinding = SkToS8(winding);
269 fCurveShift = 0;
270
271 if (clip) {
272 this->chopLineWithClip(*clip);
273 }
274 return true;
275 }
276
277 ////////////////////////////////////////////////////////////
133 278
134 #endif 279 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698