OLD | NEW |
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 Loading... |
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 |
OLD | NEW |