|
1 diff --git a/gfx/skia/src/effects/SkGradientShader.cpp b/gfx/skia/src/effects/SkGradientShader.cpp |
|
2 --- a/gfx/skia/src/effects/SkGradientShader.cpp |
|
3 +++ b/gfx/skia/src/effects/SkGradientShader.cpp |
|
4 @@ -1184,116 +1184,17 @@ public: |
|
5 { |
|
6 // make sure our table is insync with our current #define for kSQRT_TABLE_SIZE |
|
7 SkASSERT(sizeof(gSqrt8Table) == kSQRT_TABLE_SIZE); |
|
8 |
|
9 rad_to_unit_matrix(center, radius, &fPtsToUnit); |
|
10 } |
|
11 |
|
12 virtual void shadeSpan(int x, int y, SkPMColor* dstC, int count) SK_OVERRIDE; |
|
13 - virtual void shadeSpan16(int x, int y, uint16_t* SK_RESTRICT dstC, int count) SK_OVERRIDE { |
|
14 - SkASSERT(count > 0); |
|
15 - |
|
16 - SkPoint srcPt; |
|
17 - SkMatrix::MapXYProc dstProc = fDstToIndexProc; |
|
18 - TileProc proc = fTileProc; |
|
19 - const uint16_t* SK_RESTRICT cache = this->getCache16(); |
|
20 - int toggle = ((x ^ y) & 1) << kCache16Bits; |
|
21 - |
|
22 - if (fDstToIndexClass != kPerspective_MatrixClass) { |
|
23 - dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf, |
|
24 - SkIntToScalar(y) + SK_ScalarHalf, &srcPt); |
|
25 - SkFixed dx, fx = SkScalarToFixed(srcPt.fX); |
|
26 - SkFixed dy, fy = SkScalarToFixed(srcPt.fY); |
|
27 - |
|
28 - if (fDstToIndexClass == kFixedStepInX_MatrixClass) { |
|
29 - SkFixed storage[2]; |
|
30 - (void)fDstToIndex.fixedStepInX(SkIntToScalar(y), &storage[0], &storage[1]); |
|
31 - dx = storage[0]; |
|
32 - dy = storage[1]; |
|
33 - } else { |
|
34 - SkASSERT(fDstToIndexClass == kLinear_MatrixClass); |
|
35 - dx = SkScalarToFixed(fDstToIndex.getScaleX()); |
|
36 - dy = SkScalarToFixed(fDstToIndex.getSkewY()); |
|
37 - } |
|
38 - |
|
39 - if (proc == clamp_tileproc) { |
|
40 - const uint8_t* SK_RESTRICT sqrt_table = gSqrt8Table; |
|
41 - |
|
42 - /* knock these down so we can pin against +- 0x7FFF, which is an immediate load, |
|
43 - rather than 0xFFFF which is slower. This is a compromise, since it reduces our |
|
44 - precision, but that appears to be visually OK. If we decide this is OK for |
|
45 - all of our cases, we could (it seems) put this scale-down into fDstToIndex, |
|
46 - to avoid having to do these extra shifts each time. |
|
47 - */ |
|
48 - fx >>= 1; |
|
49 - dx >>= 1; |
|
50 - fy >>= 1; |
|
51 - dy >>= 1; |
|
52 - if (dy == 0) { // might perform this check for the other modes, but the win will be a smaller % of the total |
|
53 - fy = SkPin32(fy, -0xFFFF >> 1, 0xFFFF >> 1); |
|
54 - fy *= fy; |
|
55 - do { |
|
56 - unsigned xx = SkPin32(fx, -0xFFFF >> 1, 0xFFFF >> 1); |
|
57 - unsigned fi = (xx * xx + fy) >> (14 + 16 - kSQRT_TABLE_BITS); |
|
58 - fi = SkFastMin32(fi, 0xFFFF >> (16 - kSQRT_TABLE_BITS)); |
|
59 - fx += dx; |
|
60 - *dstC++ = cache[toggle + (sqrt_table[fi] >> (8 - kCache16Bits))]; |
|
61 - toggle ^= (1 << kCache16Bits); |
|
62 - } while (--count != 0); |
|
63 - } else { |
|
64 - do { |
|
65 - unsigned xx = SkPin32(fx, -0xFFFF >> 1, 0xFFFF >> 1); |
|
66 - unsigned fi = SkPin32(fy, -0xFFFF >> 1, 0xFFFF >> 1); |
|
67 - fi = (xx * xx + fi * fi) >> (14 + 16 - kSQRT_TABLE_BITS); |
|
68 - fi = SkFastMin32(fi, 0xFFFF >> (16 - kSQRT_TABLE_BITS)); |
|
69 - fx += dx; |
|
70 - fy += dy; |
|
71 - *dstC++ = cache[toggle + (sqrt_table[fi] >> (8 - kCache16Bits))]; |
|
72 - toggle ^= (1 << kCache16Bits); |
|
73 - } while (--count != 0); |
|
74 - } |
|
75 - } else if (proc == mirror_tileproc) { |
|
76 - do { |
|
77 - SkFixed dist = SkFixedSqrt(SkFixedSquare(fx) + SkFixedSquare(fy)); |
|
78 - unsigned fi = mirror_tileproc(dist); |
|
79 - SkASSERT(fi <= 0xFFFF); |
|
80 - fx += dx; |
|
81 - fy += dy; |
|
82 - *dstC++ = cache[toggle + (fi >> (16 - kCache16Bits))]; |
|
83 - toggle ^= (1 << kCache16Bits); |
|
84 - } while (--count != 0); |
|
85 - } else { |
|
86 - SkASSERT(proc == repeat_tileproc); |
|
87 - do { |
|
88 - SkFixed dist = SkFixedSqrt(SkFixedSquare(fx) + SkFixedSquare(fy)); |
|
89 - unsigned fi = repeat_tileproc(dist); |
|
90 - SkASSERT(fi <= 0xFFFF); |
|
91 - fx += dx; |
|
92 - fy += dy; |
|
93 - *dstC++ = cache[toggle + (fi >> (16 - kCache16Bits))]; |
|
94 - toggle ^= (1 << kCache16Bits); |
|
95 - } while (--count != 0); |
|
96 - } |
|
97 - } else { // perspective case |
|
98 - SkScalar dstX = SkIntToScalar(x); |
|
99 - SkScalar dstY = SkIntToScalar(y); |
|
100 - do { |
|
101 - dstProc(fDstToIndex, dstX, dstY, &srcPt); |
|
102 - unsigned fi = proc(SkScalarToFixed(srcPt.length())); |
|
103 - SkASSERT(fi <= 0xFFFF); |
|
104 - |
|
105 - int index = fi >> (16 - kCache16Bits); |
|
106 - *dstC++ = cache[toggle + index]; |
|
107 - toggle ^= (1 << kCache16Bits); |
|
108 - |
|
109 - dstX += SK_Scalar1; |
|
110 - } while (--count != 0); |
|
111 - } |
|
112 - } |
|
113 + virtual void shadeSpan16(int x, int y, uint16_t* dstC, int count) SK_OVERRIDE; |
|
114 |
|
115 virtual BitmapType asABitmap(SkBitmap* bitmap, |
|
116 SkMatrix* matrix, |
|
117 TileMode* xy, |
|
118 SkScalar* twoPointRadialParams) const SK_OVERRIDE { |
|
119 if (bitmap) { |
|
120 this->commonAsABitmap(bitmap); |
|
121 } |
|
122 @@ -1507,16 +1408,117 @@ void Radial_Gradient::shadeSpan(int x, i |
|
123 unsigned fi = proc(SkScalarToFixed(srcPt.length())); |
|
124 SkASSERT(fi <= 0xFFFF); |
|
125 *dstC++ = cache[fi >> (16 - kCache32Bits)]; |
|
126 dstX += SK_Scalar1; |
|
127 } while (--count != 0); |
|
128 } |
|
129 } |
|
130 |
|
131 +void Radial_Gradient::shadeSpan16(int x, int y, uint16_t* SK_RESTRICT dstC, int count) { |
|
132 + SkASSERT(count > 0); |
|
133 + |
|
134 + SkPoint srcPt; |
|
135 + SkMatrix::MapXYProc dstProc = fDstToIndexProc; |
|
136 + TileProc proc = fTileProc; |
|
137 + const uint16_t* SK_RESTRICT cache = this->getCache16(); |
|
138 + int toggle = ((x ^ y) & 1) << kCache16Bits; |
|
139 + |
|
140 + if (fDstToIndexClass != kPerspective_MatrixClass) { |
|
141 + dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf, |
|
142 + SkIntToScalar(y) + SK_ScalarHalf, &srcPt); |
|
143 + SkFixed dx, fx = SkScalarToFixed(srcPt.fX); |
|
144 + SkFixed dy, fy = SkScalarToFixed(srcPt.fY); |
|
145 + |
|
146 + if (fDstToIndexClass == kFixedStepInX_MatrixClass) { |
|
147 + SkFixed storage[2]; |
|
148 + (void)fDstToIndex.fixedStepInX(SkIntToScalar(y), &storage[0], &storage[1]); |
|
149 + dx = storage[0]; |
|
150 + dy = storage[1]; |
|
151 + } else { |
|
152 + SkASSERT(fDstToIndexClass == kLinear_MatrixClass); |
|
153 + dx = SkScalarToFixed(fDstToIndex.getScaleX()); |
|
154 + dy = SkScalarToFixed(fDstToIndex.getSkewY()); |
|
155 + } |
|
156 + |
|
157 + if (proc == clamp_tileproc) { |
|
158 + const uint8_t* SK_RESTRICT sqrt_table = gSqrt8Table; |
|
159 + |
|
160 + /* knock these down so we can pin against +- 0x7FFF, which is an immediate load, |
|
161 + rather than 0xFFFF which is slower. This is a compromise, since it reduces our |
|
162 + precision, but that appears to be visually OK. If we decide this is OK for |
|
163 + all of our cases, we could (it seems) put this scale-down into fDstToIndex, |
|
164 + to avoid having to do these extra shifts each time. |
|
165 + */ |
|
166 + fx >>= 1; |
|
167 + dx >>= 1; |
|
168 + fy >>= 1; |
|
169 + dy >>= 1; |
|
170 + if (dy == 0) { // might perform this check for the other modes, but the win will be a smaller % of the total |
|
171 + fy = SkPin32(fy, -0xFFFF >> 1, 0xFFFF >> 1); |
|
172 + fy *= fy; |
|
173 + do { |
|
174 + unsigned xx = SkPin32(fx, -0xFFFF >> 1, 0xFFFF >> 1); |
|
175 + unsigned fi = (xx * xx + fy) >> (14 + 16 - kSQRT_TABLE_BITS); |
|
176 + fi = SkFastMin32(fi, 0xFFFF >> (16 - kSQRT_TABLE_BITS)); |
|
177 + fx += dx; |
|
178 + *dstC++ = cache[toggle + (sqrt_table[fi] >> (8 - kCache16Bits))]; |
|
179 + toggle ^= (1 << kCache16Bits); |
|
180 + } while (--count != 0); |
|
181 + } else { |
|
182 + do { |
|
183 + unsigned xx = SkPin32(fx, -0xFFFF >> 1, 0xFFFF >> 1); |
|
184 + unsigned fi = SkPin32(fy, -0xFFFF >> 1, 0xFFFF >> 1); |
|
185 + fi = (xx * xx + fi * fi) >> (14 + 16 - kSQRT_TABLE_BITS); |
|
186 + fi = SkFastMin32(fi, 0xFFFF >> (16 - kSQRT_TABLE_BITS)); |
|
187 + fx += dx; |
|
188 + fy += dy; |
|
189 + *dstC++ = cache[toggle + (sqrt_table[fi] >> (8 - kCache16Bits))]; |
|
190 + toggle ^= (1 << kCache16Bits); |
|
191 + } while (--count != 0); |
|
192 + } |
|
193 + } else if (proc == mirror_tileproc) { |
|
194 + do { |
|
195 + SkFixed dist = SkFixedSqrt(SkFixedSquare(fx) + SkFixedSquare(fy)); |
|
196 + unsigned fi = mirror_tileproc(dist); |
|
197 + SkASSERT(fi <= 0xFFFF); |
|
198 + fx += dx; |
|
199 + fy += dy; |
|
200 + *dstC++ = cache[toggle + (fi >> (16 - kCache16Bits))]; |
|
201 + toggle ^= (1 << kCache16Bits); |
|
202 + } while (--count != 0); |
|
203 + } else { |
|
204 + SkASSERT(proc == repeat_tileproc); |
|
205 + do { |
|
206 + SkFixed dist = SkFixedSqrt(SkFixedSquare(fx) + SkFixedSquare(fy)); |
|
207 + unsigned fi = repeat_tileproc(dist); |
|
208 + SkASSERT(fi <= 0xFFFF); |
|
209 + fx += dx; |
|
210 + fy += dy; |
|
211 + *dstC++ = cache[toggle + (fi >> (16 - kCache16Bits))]; |
|
212 + toggle ^= (1 << kCache16Bits); |
|
213 + } while (--count != 0); |
|
214 + } |
|
215 + } else { // perspective case |
|
216 + SkScalar dstX = SkIntToScalar(x); |
|
217 + SkScalar dstY = SkIntToScalar(y); |
|
218 + do { |
|
219 + dstProc(fDstToIndex, dstX, dstY, &srcPt); |
|
220 + unsigned fi = proc(SkScalarToFixed(srcPt.length())); |
|
221 + SkASSERT(fi <= 0xFFFF); |
|
222 + |
|
223 + int index = fi >> (16 - kCache16Bits); |
|
224 + *dstC++ = cache[toggle + index]; |
|
225 + toggle ^= (1 << kCache16Bits); |
|
226 + |
|
227 + dstX += SK_Scalar1; |
|
228 + } while (--count != 0); |
|
229 + } |
|
230 +} |
|
231 + |
|
232 /* Two-point radial gradients are specified by two circles, each with a center |
|
233 point and radius. The gradient can be considered to be a series of |
|
234 concentric circles, with the color interpolated from the start circle |
|
235 (at t=0) to the end circle (at t=1). |
|
236 |
|
237 For each point (x, y) in the span, we want to find the |
|
238 interpolated circle that intersects that point. The center |
|
239 of the desired circle (Cx, Cy) falls at some distance t |
|
240 @@ -1661,109 +1663,17 @@ public: |
|
241 info->fPoint[0] = fCenter1; |
|
242 info->fPoint[1] = fCenter2; |
|
243 info->fRadius[0] = fRadius1; |
|
244 info->fRadius[1] = fRadius2; |
|
245 } |
|
246 return kRadial2_GradientType; |
|
247 } |
|
248 |
|
249 - virtual void shadeSpan(int x, int y, SkPMColor* SK_RESTRICT dstC, int count) SK_OVERRIDE { |
|
250 - SkASSERT(count > 0); |
|
251 - |
|
252 - // Zero difference between radii: fill with transparent black. |
|
253 - // TODO: Is removing this actually correct? Two circles with the |
|
254 - // same radius, but different centers doesn't sound like it |
|
255 - // should be cleared |
|
256 - if (fDiffRadius == 0 && fCenter1 == fCenter2) { |
|
257 - sk_bzero(dstC, count * sizeof(*dstC)); |
|
258 - return; |
|
259 - } |
|
260 - SkMatrix::MapXYProc dstProc = fDstToIndexProc; |
|
261 - TileProc proc = fTileProc; |
|
262 - const SkPMColor* SK_RESTRICT cache = this->getCache32(); |
|
263 - |
|
264 - SkScalar foura = fA * 4; |
|
265 - bool posRoot = fDiffRadius < 0; |
|
266 - if (fDstToIndexClass != kPerspective_MatrixClass) { |
|
267 - SkPoint srcPt; |
|
268 - dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf, |
|
269 - SkIntToScalar(y) + SK_ScalarHalf, &srcPt); |
|
270 - SkScalar dx, fx = srcPt.fX; |
|
271 - SkScalar dy, fy = srcPt.fY; |
|
272 - |
|
273 - if (fDstToIndexClass == kFixedStepInX_MatrixClass) { |
|
274 - SkFixed fixedX, fixedY; |
|
275 - (void)fDstToIndex.fixedStepInX(SkIntToScalar(y), &fixedX, &fixedY); |
|
276 - dx = SkFixedToScalar(fixedX); |
|
277 - dy = SkFixedToScalar(fixedY); |
|
278 - } else { |
|
279 - SkASSERT(fDstToIndexClass == kLinear_MatrixClass); |
|
280 - dx = fDstToIndex.getScaleX(); |
|
281 - dy = fDstToIndex.getSkewY(); |
|
282 - } |
|
283 - SkScalar b = (SkScalarMul(fDiff.fX, fx) + |
|
284 - SkScalarMul(fDiff.fY, fy) - fStartRadius) * 2; |
|
285 - SkScalar db = (SkScalarMul(fDiff.fX, dx) + |
|
286 - SkScalarMul(fDiff.fY, dy)) * 2; |
|
287 - if (proc == clamp_tileproc) { |
|
288 - for (; count > 0; --count) { |
|
289 - SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot); |
|
290 - if (t < 0) { |
|
291 - *dstC++ = cache[-1]; |
|
292 - } else if (t > 0xFFFF) { |
|
293 - *dstC++ = cache[kCache32Count * 2]; |
|
294 - } else { |
|
295 - SkASSERT(t <= 0xFFFF); |
|
296 - *dstC++ = cache[t >> (16 - kCache32Bits)]; |
|
297 - } |
|
298 - fx += dx; |
|
299 - fy += dy; |
|
300 - b += db; |
|
301 - } |
|
302 - } else if (proc == mirror_tileproc) { |
|
303 - for (; count > 0; --count) { |
|
304 - SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot); |
|
305 - SkFixed index = mirror_tileproc(t); |
|
306 - SkASSERT(index <= 0xFFFF); |
|
307 - *dstC++ = cache[index >> (16 - kCache32Bits)]; |
|
308 - fx += dx; |
|
309 - fy += dy; |
|
310 - b += db; |
|
311 - } |
|
312 - } else { |
|
313 - SkASSERT(proc == repeat_tileproc); |
|
314 - for (; count > 0; --count) { |
|
315 - SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot); |
|
316 - SkFixed index = repeat_tileproc(t); |
|
317 - SkASSERT(index <= 0xFFFF); |
|
318 - *dstC++ = cache[index >> (16 - kCache32Bits)]; |
|
319 - fx += dx; |
|
320 - fy += dy; |
|
321 - b += db; |
|
322 - } |
|
323 - } |
|
324 - } else { // perspective case |
|
325 - SkScalar dstX = SkIntToScalar(x); |
|
326 - SkScalar dstY = SkIntToScalar(y); |
|
327 - for (; count > 0; --count) { |
|
328 - SkPoint srcPt; |
|
329 - dstProc(fDstToIndex, dstX, dstY, &srcPt); |
|
330 - SkScalar fx = srcPt.fX; |
|
331 - SkScalar fy = srcPt.fY; |
|
332 - SkScalar b = (SkScalarMul(fDiff.fX, fx) + |
|
333 - SkScalarMul(fDiff.fY, fy) - fStartRadius) * 2; |
|
334 - SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot); |
|
335 - SkFixed index = proc(t); |
|
336 - SkASSERT(index <= 0xFFFF); |
|
337 - *dstC++ = cache[index >> (16 - kCache32Bits)]; |
|
338 - dstX += SK_Scalar1; |
|
339 - } |
|
340 - } |
|
341 - } |
|
342 + virtual void shadeSpan(int x, int y, SkPMColor* dstC, int count) SK_OVERRIDE; |
|
343 |
|
344 virtual bool setContext(const SkBitmap& device, |
|
345 const SkPaint& paint, |
|
346 const SkMatrix& matrix) SK_OVERRIDE { |
|
347 if (!this->INHERITED::setContext(device, paint, matrix)) { |
|
348 return false; |
|
349 } |
|
350 |
|
351 @@ -1817,16 +1727,110 @@ private: |
|
352 fA = SkScalarSquare(fDiff.fX) + SkScalarSquare(fDiff.fY) - SK_Scalar1; |
|
353 fOneOverTwoA = fA ? SkScalarInvert(fA * 2) : 0; |
|
354 |
|
355 fPtsToUnit.setTranslate(-fCenter1.fX, -fCenter1.fY); |
|
356 fPtsToUnit.postScale(inv, inv); |
|
357 } |
|
358 }; |
|
359 |
|
360 +void Two_Point_Radial_Gradient::shadeSpan(int x, int y, SkPMColor* SK_RESTRICT dstC, int count) { |
|
361 + SkASSERT(count > 0); |
|
362 + |
|
363 + // Zero difference between radii: fill with transparent black. |
|
364 + // TODO: Is removing this actually correct? Two circles with the |
|
365 + // same radius, but different centers doesn't sound like it |
|
366 + // should be cleared |
|
367 + if (fDiffRadius == 0 && fCenter1 == fCenter2) { |
|
368 + sk_bzero(dstC, count * sizeof(*dstC)); |
|
369 + return; |
|
370 + } |
|
371 + SkMatrix::MapXYProc dstProc = fDstToIndexProc; |
|
372 + TileProc proc = fTileProc; |
|
373 + const SkPMColor* SK_RESTRICT cache = this->getCache32(); |
|
374 + |
|
375 + SkScalar foura = fA * 4; |
|
376 + bool posRoot = fDiffRadius < 0; |
|
377 + if (fDstToIndexClass != kPerspective_MatrixClass) { |
|
378 + SkPoint srcPt; |
|
379 + dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf, |
|
380 + SkIntToScalar(y) + SK_ScalarHalf, &srcPt); |
|
381 + SkScalar dx, fx = srcPt.fX; |
|
382 + SkScalar dy, fy = srcPt.fY; |
|
383 + |
|
384 + if (fDstToIndexClass == kFixedStepInX_MatrixClass) { |
|
385 + SkFixed fixedX, fixedY; |
|
386 + (void)fDstToIndex.fixedStepInX(SkIntToScalar(y), &fixedX, &fixedY); |
|
387 + dx = SkFixedToScalar(fixedX); |
|
388 + dy = SkFixedToScalar(fixedY); |
|
389 + } else { |
|
390 + SkASSERT(fDstToIndexClass == kLinear_MatrixClass); |
|
391 + dx = fDstToIndex.getScaleX(); |
|
392 + dy = fDstToIndex.getSkewY(); |
|
393 + } |
|
394 + SkScalar b = (SkScalarMul(fDiff.fX, fx) + |
|
395 + SkScalarMul(fDiff.fY, fy) - fStartRadius) * 2; |
|
396 + SkScalar db = (SkScalarMul(fDiff.fX, dx) + |
|
397 + SkScalarMul(fDiff.fY, dy)) * 2; |
|
398 + if (proc == clamp_tileproc) { |
|
399 + for (; count > 0; --count) { |
|
400 + SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot); |
|
401 + if (t < 0) { |
|
402 + *dstC++ = cache[-1]; |
|
403 + } else if (t > 0xFFFF) { |
|
404 + *dstC++ = cache[kCache32Count * 2]; |
|
405 + } else { |
|
406 + SkASSERT(t <= 0xFFFF); |
|
407 + *dstC++ = cache[t >> (16 - kCache32Bits)]; |
|
408 + } |
|
409 + fx += dx; |
|
410 + fy += dy; |
|
411 + b += db; |
|
412 + } |
|
413 + } else if (proc == mirror_tileproc) { |
|
414 + for (; count > 0; --count) { |
|
415 + SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot); |
|
416 + SkFixed index = mirror_tileproc(t); |
|
417 + SkASSERT(index <= 0xFFFF); |
|
418 + *dstC++ = cache[index >> (16 - kCache32Bits)]; |
|
419 + fx += dx; |
|
420 + fy += dy; |
|
421 + b += db; |
|
422 + } |
|
423 + } else { |
|
424 + SkASSERT(proc == repeat_tileproc); |
|
425 + for (; count > 0; --count) { |
|
426 + SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot); |
|
427 + SkFixed index = repeat_tileproc(t); |
|
428 + SkASSERT(index <= 0xFFFF); |
|
429 + *dstC++ = cache[index >> (16 - kCache32Bits)]; |
|
430 + fx += dx; |
|
431 + fy += dy; |
|
432 + b += db; |
|
433 + } |
|
434 + } |
|
435 + } else { // perspective case |
|
436 + SkScalar dstX = SkIntToScalar(x); |
|
437 + SkScalar dstY = SkIntToScalar(y); |
|
438 + for (; count > 0; --count) { |
|
439 + SkPoint srcPt; |
|
440 + dstProc(fDstToIndex, dstX, dstY, &srcPt); |
|
441 + SkScalar fx = srcPt.fX; |
|
442 + SkScalar fy = srcPt.fY; |
|
443 + SkScalar b = (SkScalarMul(fDiff.fX, fx) + |
|
444 + SkScalarMul(fDiff.fY, fy) - fStartRadius) * 2; |
|
445 + SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot); |
|
446 + SkFixed index = proc(t); |
|
447 + SkASSERT(index <= 0xFFFF); |
|
448 + *dstC++ = cache[index >> (16 - kCache32Bits)]; |
|
449 + dstX += SK_Scalar1; |
|
450 + } |
|
451 + } |
|
452 +} |
|
453 + |
|
454 /////////////////////////////////////////////////////////////////////////////// |
|
455 |
|
456 class Sweep_Gradient : public Gradient_Shader { |
|
457 public: |
|
458 Sweep_Gradient(SkScalar cx, SkScalar cy, const SkColor colors[], |
|
459 const SkScalar pos[], int count, SkUnitMapper* mapper) |
|
460 : Gradient_Shader(colors, pos, count, SkShader::kClamp_TileMode, mapper), |
|
461 fCenter(SkPoint::Make(cx, cy)) |