| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
| 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 #include "SkLinearGradient.h" | 8 #include "SkLinearGradient.h" |
| 9 | 9 |
| 10 static inline int repeat_bits(int x, const int bits) { | 10 static inline int repeat_bits(int x, const int bits) { |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 // only claim this if we do have a 16bit mode (i.e. none of our | 97 // only claim this if we do have a 16bit mode (i.e. none of our |
| 98 // colors have alpha), and if we are not dithering (which obviously | 98 // colors have alpha), and if we are not dithering (which obviously |
| 99 // is not const in Y). | 99 // is not const in Y). |
| 100 fFlags |= SkShader::kConstInY16_Flag; | 100 fFlags |= SkShader::kConstInY16_Flag; |
| 101 } | 101 } |
| 102 } | 102 } |
| 103 } | 103 } |
| 104 | 104 |
| 105 #define NO_CHECK_ITER \ | 105 #define NO_CHECK_ITER \ |
| 106 do { \ | 106 do { \ |
| 107 unsigned fi = fx >> SkGradientShaderBase::kCache32Shift; \ | 107 unsigned fi = SkGradFixedToFixed(fx) >> SkGradientShaderBase::kCache32Shift;
\ |
| 108 SkASSERT(fi <= 0xFF); \ | 108 SkASSERT(fi <= 0xFF); \ |
| 109 fx += dx; \ | 109 fx += dx; \ |
| 110 *dstC++ = cache[toggle + fi]; \ | 110 *dstC++ = cache[toggle + fi]; \ |
| 111 toggle = next_dither_toggle(toggle); \ | 111 toggle = next_dither_toggle(toggle); \ |
| 112 } while (0) | 112 } while (0) |
| 113 | 113 |
| 114 namespace { | 114 namespace { |
| 115 | 115 |
| 116 typedef void (*LinearShadeProc)(TileProc proc, SkFixed dx, SkFixed fx, | 116 typedef void (*LinearShadeProc)(TileProc proc, SkGradFixed dx, SkGradFixed fx, |
| 117 SkPMColor* dstC, const SkPMColor* cache, | 117 SkPMColor* dstC, const SkPMColor* cache, |
| 118 int toggle, int count); | 118 int toggle, int count); |
| 119 | 119 |
| 120 // Linear interpolation (lerp) is unnecessary if there are no sharp | 120 // Linear interpolation (lerp) is unnecessary if there are no sharp |
| 121 // discontinuities in the gradient - which must be true if there are | 121 // discontinuities in the gradient - which must be true if there are |
| 122 // only 2 colors - but it's cheap. | 122 // only 2 colors - but it's cheap. |
| 123 void shadeSpan_linear_vertical_lerp(TileProc proc, SkFixed dx, SkFixed fx, | 123 void shadeSpan_linear_vertical_lerp(TileProc proc, SkGradFixed dx, SkGradFixed f
x, |
| 124 SkPMColor* SK_RESTRICT dstC, | 124 SkPMColor* SK_RESTRICT dstC, |
| 125 const SkPMColor* SK_RESTRICT cache, | 125 const SkPMColor* SK_RESTRICT cache, |
| 126 int toggle, int count) { | 126 int toggle, int count) { |
| 127 // We're a vertical gradient, so no change in a span. | 127 // We're a vertical gradient, so no change in a span. |
| 128 // If colors change sharply across the gradient, dithering is | 128 // If colors change sharply across the gradient, dithering is |
| 129 // insufficient (it subsamples the color space) and we need to lerp. | 129 // insufficient (it subsamples the color space) and we need to lerp. |
| 130 unsigned fullIndex = proc(fx); | 130 unsigned fullIndex = proc(SkGradFixedToFixed(fx)); |
| 131 unsigned fi = fullIndex >> SkGradientShaderBase::kCache32Shift; | 131 unsigned fi = fullIndex >> SkGradientShaderBase::kCache32Shift; |
| 132 unsigned remainder = fullIndex & ((1 << SkGradientShaderBase::kCache32Shift)
- 1); | 132 unsigned remainder = fullIndex & ((1 << SkGradientShaderBase::kCache32Shift)
- 1); |
| 133 | 133 |
| 134 int index0 = fi + toggle; | 134 int index0 = fi + toggle; |
| 135 int index1 = index0; | 135 int index1 = index0; |
| 136 if (fi < SkGradientShaderBase::kCache32Count - 1) { | 136 if (fi < SkGradientShaderBase::kCache32Count - 1) { |
| 137 index1 += 1; | 137 index1 += 1; |
| 138 } | 138 } |
| 139 SkPMColor lerp = SkFastFourByteInterp(cache[index1], cache[index0], remainde
r); | 139 SkPMColor lerp = SkFastFourByteInterp(cache[index1], cache[index0], remainde
r); |
| 140 index0 ^= SkGradientShaderBase::kDitherStride32; | 140 index0 ^= SkGradientShaderBase::kDitherStride32; |
| 141 index1 ^= SkGradientShaderBase::kDitherStride32; | 141 index1 ^= SkGradientShaderBase::kDitherStride32; |
| 142 SkPMColor dlerp = SkFastFourByteInterp(cache[index1], cache[index0], remaind
er); | 142 SkPMColor dlerp = SkFastFourByteInterp(cache[index1], cache[index0], remaind
er); |
| 143 sk_memset32_dither(dstC, lerp, dlerp, count); | 143 sk_memset32_dither(dstC, lerp, dlerp, count); |
| 144 } | 144 } |
| 145 | 145 |
| 146 void shadeSpan_linear_clamp(TileProc proc, SkFixed dx, SkFixed fx, | 146 void shadeSpan_linear_clamp(TileProc proc, SkGradFixed dx, SkGradFixed fx, |
| 147 SkPMColor* SK_RESTRICT dstC, | 147 SkPMColor* SK_RESTRICT dstC, |
| 148 const SkPMColor* SK_RESTRICT cache, | 148 const SkPMColor* SK_RESTRICT cache, |
| 149 int toggle, int count) { | 149 int toggle, int count) { |
| 150 SkClampRange range; | 150 SkClampRange range; |
| 151 range.init(fx, dx, count, 0, SkGradientShaderBase::kCache32Count - 1); | 151 range.init(fx, dx, count, 0, SkGradientShaderBase::kCache32Count - 1); |
| 152 | 152 |
| 153 if ((count = range.fCount0) > 0) { | 153 if ((count = range.fCount0) > 0) { |
| 154 sk_memset32_dither(dstC, | 154 sk_memset32_dither(dstC, |
| 155 cache[toggle + range.fV0], | 155 cache[toggle + range.fV0], |
| 156 cache[next_dither_toggle(toggle) + range.fV0], | 156 cache[next_dither_toggle(toggle) + range.fV0], |
| (...skipping 16 matching lines...) Expand all Loading... |
| 173 } | 173 } |
| 174 } | 174 } |
| 175 if ((count = range.fCount2) > 0) { | 175 if ((count = range.fCount2) > 0) { |
| 176 sk_memset32_dither(dstC, | 176 sk_memset32_dither(dstC, |
| 177 cache[toggle + range.fV1], | 177 cache[toggle + range.fV1], |
| 178 cache[next_dither_toggle(toggle) + range.fV1], | 178 cache[next_dither_toggle(toggle) + range.fV1], |
| 179 count); | 179 count); |
| 180 } | 180 } |
| 181 } | 181 } |
| 182 | 182 |
| 183 void shadeSpan_linear_mirror(TileProc proc, SkFixed dx, SkFixed fx, | 183 void shadeSpan_linear_mirror(TileProc proc, SkGradFixed dx, SkGradFixed fx, |
| 184 SkPMColor* SK_RESTRICT dstC, | 184 SkPMColor* SK_RESTRICT dstC, |
| 185 const SkPMColor* SK_RESTRICT cache, | 185 const SkPMColor* SK_RESTRICT cache, |
| 186 int toggle, int count) { | 186 int toggle, int count) { |
| 187 do { | 187 do { |
| 188 unsigned fi = mirror_8bits(fx >> 8); | 188 unsigned fi = mirror_8bits(SkGradFixedToFixed(fx) >> 8); |
| 189 SkASSERT(fi <= 0xFF); | 189 SkASSERT(fi <= 0xFF); |
| 190 fx += dx; | 190 fx += dx; |
| 191 *dstC++ = cache[toggle + fi]; | 191 *dstC++ = cache[toggle + fi]; |
| 192 toggle = next_dither_toggle(toggle); | 192 toggle = next_dither_toggle(toggle); |
| 193 } while (--count != 0); | 193 } while (--count != 0); |
| 194 } | 194 } |
| 195 | 195 |
| 196 void shadeSpan_linear_repeat(TileProc proc, SkFixed dx, SkFixed fx, | 196 void shadeSpan_linear_repeat(TileProc proc, SkGradFixed dx, SkGradFixed fx, |
| 197 SkPMColor* SK_RESTRICT dstC, | 197 SkPMColor* SK_RESTRICT dstC, |
| 198 const SkPMColor* SK_RESTRICT cache, | 198 const SkPMColor* SK_RESTRICT cache, |
| 199 int toggle, int count) { | 199 int toggle, int count) { |
| 200 do { | 200 do { |
| 201 unsigned fi = repeat_8bits(fx >> 8); | 201 unsigned fi = repeat_8bits(SkGradFixedToFixed(fx) >> 8); |
| 202 SkASSERT(fi <= 0xFF); | 202 SkASSERT(fi <= 0xFF); |
| 203 fx += dx; | 203 fx += dx; |
| 204 *dstC++ = cache[toggle + fi]; | 204 *dstC++ = cache[toggle + fi]; |
| 205 toggle = next_dither_toggle(toggle); | 205 toggle = next_dither_toggle(toggle); |
| 206 } while (--count != 0); | 206 } while (--count != 0); |
| 207 } | 207 } |
| 208 | 208 |
| 209 } | 209 } |
| 210 | 210 |
| 211 void SkLinearGradient::LinearGradientContext::shadeSpan(int x, int y, SkPMColor*
SK_RESTRICT dstC, | 211 void SkLinearGradient::LinearGradientContext::shadeSpan(int x, int y, SkPMColor*
SK_RESTRICT dstC, |
| 212 int count) { | 212 int count) { |
| 213 SkASSERT(count > 0); | 213 SkASSERT(count > 0); |
| 214 | 214 |
| 215 const SkLinearGradient& linearGradient = static_cast<const SkLinearGradient&
>(fShader); | 215 const SkLinearGradient& linearGradient = static_cast<const SkLinearGradient&
>(fShader); |
| 216 | 216 |
| 217 SkPoint srcPt; | 217 SkPoint srcPt; |
| 218 SkMatrix::MapXYProc dstProc = fDstToIndexProc; | 218 SkMatrix::MapXYProc dstProc = fDstToIndexProc; |
| 219 TileProc proc = linearGradient.fTileProc; | 219 TileProc proc = linearGradient.fTileProc; |
| 220 const SkPMColor* SK_RESTRICT cache = fCache->getCache32(); | 220 const SkPMColor* SK_RESTRICT cache = fCache->getCache32(); |
| 221 int toggle = init_dither_toggle(x, y); | 221 int toggle = init_dither_toggle(x, y); |
| 222 | 222 |
| 223 if (fDstToIndexClass != kPerspective_MatrixClass) { | 223 if (fDstToIndexClass != kPerspective_MatrixClass) { |
| 224 dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf, | 224 dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf, |
| 225 SkIntToScalar(y) + SK_ScalarHalf, &srcPt); | 225 SkIntToScalar(y) + SK_ScalarHalf, &srcPt); |
| 226 SkFixed dx, fx = SkScalarToFixed(srcPt.fX); | 226 SkGradFixed dx, fx = SkScalarToGradFixed(srcPt.fX); |
| 227 | 227 |
| 228 if (fDstToIndexClass == kFixedStepInX_MatrixClass) { | 228 if (fDstToIndexClass == kFixedStepInX_MatrixClass) { |
| 229 SkFixed dxStorage[1]; | 229 SkFixed dxStorage[1]; |
| 230 (void)fDstToIndex.fixedStepInX(SkIntToScalar(y), dxStorage, NULL); | 230 (void)fDstToIndex.fixedStepInX(SkIntToScalar(y), dxStorage, NULL); |
| 231 dx = dxStorage[0]; | 231 // todo: do we need a real/high-precision value for dx here? |
| 232 dx = SkFixedToGradFixed(dxStorage[0]); |
| 232 } else { | 233 } else { |
| 233 SkASSERT(fDstToIndexClass == kLinear_MatrixClass); | 234 SkASSERT(fDstToIndexClass == kLinear_MatrixClass); |
| 234 dx = SkScalarToFixed(fDstToIndex.getScaleX()); | 235 dx = SkScalarToGradFixed(fDstToIndex.getScaleX()); |
| 235 } | 236 } |
| 236 | 237 |
| 237 LinearShadeProc shadeProc = shadeSpan_linear_repeat; | 238 LinearShadeProc shadeProc = shadeSpan_linear_repeat; |
| 238 if (0 == dx) { | 239 if (0 == dx) { |
| 239 shadeProc = shadeSpan_linear_vertical_lerp; | 240 shadeProc = shadeSpan_linear_vertical_lerp; |
| 240 } else if (SkShader::kClamp_TileMode == linearGradient.fTileMode) { | 241 } else if (SkShader::kClamp_TileMode == linearGradient.fTileMode) { |
| 241 shadeProc = shadeSpan_linear_clamp; | 242 shadeProc = shadeSpan_linear_clamp; |
| 242 } else if (SkShader::kMirror_TileMode == linearGradient.fTileMode) { | 243 } else if (SkShader::kMirror_TileMode == linearGradient.fTileMode) { |
| 243 shadeProc = shadeSpan_linear_mirror; | 244 shadeProc = shadeSpan_linear_mirror; |
| 244 } else { | 245 } else { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 | 295 |
| 295 sk_memset32((uint32_t*)dst, (value << 16) | other, count >> 1); | 296 sk_memset32((uint32_t*)dst, (value << 16) | other, count >> 1); |
| 296 | 297 |
| 297 if (count & 1) { | 298 if (count & 1) { |
| 298 dst[count - 1] = value; | 299 dst[count - 1] = value; |
| 299 } | 300 } |
| 300 } | 301 } |
| 301 | 302 |
| 302 #define NO_CHECK_ITER_16 \ | 303 #define NO_CHECK_ITER_16 \ |
| 303 do { \ | 304 do { \ |
| 304 unsigned fi = fx >> SkGradientShaderBase::kCache16Shift; \ | 305 unsigned fi = SkGradFixedToFixed(fx) >> SkGradientShaderBase::kCache16Shift;
\ |
| 305 SkASSERT(fi < SkGradientShaderBase::kCache16Count); \ | 306 SkASSERT(fi < SkGradientShaderBase::kCache16Count); \ |
| 306 fx += dx; \ | 307 fx += dx; \ |
| 307 *dstC++ = cache[toggle + fi]; \ | 308 *dstC++ = cache[toggle + fi]; \ |
| 308 toggle = next_dither_toggle16(toggle); \ | 309 toggle = next_dither_toggle16(toggle); \ |
| 309 } while (0) | 310 } while (0) |
| 310 | 311 |
| 311 namespace { | 312 namespace { |
| 312 | 313 |
| 313 typedef void (*LinearShade16Proc)(TileProc proc, SkFixed dx, SkFixed fx, | 314 typedef void (*LinearShade16Proc)(TileProc proc, SkGradFixed dx, SkGradFixed fx, |
| 314 uint16_t* dstC, const uint16_t* cache, | 315 uint16_t* dstC, const uint16_t* cache, |
| 315 int toggle, int count); | 316 int toggle, int count); |
| 316 | 317 |
| 317 void shadeSpan16_linear_vertical(TileProc proc, SkFixed dx, SkFixed fx, | 318 void shadeSpan16_linear_vertical(TileProc proc, SkGradFixed dx, SkGradFixed fx, |
| 318 uint16_t* SK_RESTRICT dstC, | 319 uint16_t* SK_RESTRICT dstC, |
| 319 const uint16_t* SK_RESTRICT cache, | 320 const uint16_t* SK_RESTRICT cache, |
| 320 int toggle, int count) { | 321 int toggle, int count) { |
| 321 // we're a vertical gradient, so no change in a span | 322 // we're a vertical gradient, so no change in a span |
| 322 unsigned fi = proc(fx) >> SkGradientShaderBase::kCache16Shift; | 323 unsigned fi = proc(SkGradFixedToFixed(fx)) >> SkGradientShaderBase::kCache16
Shift; |
| 323 SkASSERT(fi < SkGradientShaderBase::kCache16Count); | 324 SkASSERT(fi < SkGradientShaderBase::kCache16Count); |
| 324 dither_memset16(dstC, cache[toggle + fi], | 325 dither_memset16(dstC, cache[toggle + fi], |
| 325 cache[next_dither_toggle16(toggle) + fi], count); | 326 cache[next_dither_toggle16(toggle) + fi], count); |
| 326 } | 327 } |
| 327 | 328 |
| 328 void shadeSpan16_linear_clamp(TileProc proc, SkFixed dx, SkFixed fx, | 329 void shadeSpan16_linear_clamp(TileProc proc, SkGradFixed dx, SkGradFixed fx, |
| 329 uint16_t* SK_RESTRICT dstC, | 330 uint16_t* SK_RESTRICT dstC, |
| 330 const uint16_t* SK_RESTRICT cache, | 331 const uint16_t* SK_RESTRICT cache, |
| 331 int toggle, int count) { | 332 int toggle, int count) { |
| 332 SkClampRange range; | 333 SkClampRange range; |
| 333 range.init(fx, dx, count, 0, SkGradientShaderBase::kCache32Count - 1); | 334 range.init(fx, dx, count, 0, SkGradientShaderBase::kCache32Count - 1); |
| 334 | 335 |
| 335 if ((count = range.fCount0) > 0) { | 336 if ((count = range.fCount0) > 0) { |
| 336 dither_memset16(dstC, | 337 dither_memset16(dstC, |
| 337 cache[toggle + range.fV0], | 338 cache[toggle + range.fV0], |
| 338 cache[next_dither_toggle16(toggle) + range.fV0], | 339 cache[next_dither_toggle16(toggle) + range.fV0], |
| (...skipping 16 matching lines...) Expand all Loading... |
| 355 } | 356 } |
| 356 } | 357 } |
| 357 if ((count = range.fCount2) > 0) { | 358 if ((count = range.fCount2) > 0) { |
| 358 dither_memset16(dstC, | 359 dither_memset16(dstC, |
| 359 cache[toggle + range.fV1], | 360 cache[toggle + range.fV1], |
| 360 cache[next_dither_toggle16(toggle) + range.fV1], | 361 cache[next_dither_toggle16(toggle) + range.fV1], |
| 361 count); | 362 count); |
| 362 } | 363 } |
| 363 } | 364 } |
| 364 | 365 |
| 365 void shadeSpan16_linear_mirror(TileProc proc, SkFixed dx, SkFixed fx, | 366 void shadeSpan16_linear_mirror(TileProc proc, SkGradFixed dx, SkGradFixed fx, |
| 366 uint16_t* SK_RESTRICT dstC, | 367 uint16_t* SK_RESTRICT dstC, |
| 367 const uint16_t* SK_RESTRICT cache, | 368 const uint16_t* SK_RESTRICT cache, |
| 368 int toggle, int count) { | 369 int toggle, int count) { |
| 369 do { | 370 do { |
| 370 unsigned fi = mirror_bits(fx >> SkGradientShaderBase::kCache16Shift, | 371 unsigned fi = mirror_bits(SkGradFixedToFixed(fx) >> SkGradientShaderBase
::kCache16Shift, |
| 371 SkGradientShaderBase::kCache16Bits); | 372 SkGradientShaderBase::kCache16Bits); |
| 372 SkASSERT(fi < SkGradientShaderBase::kCache16Count); | 373 SkASSERT(fi < SkGradientShaderBase::kCache16Count); |
| 373 fx += dx; | 374 fx += dx; |
| 374 *dstC++ = cache[toggle + fi]; | 375 *dstC++ = cache[toggle + fi]; |
| 375 toggle = next_dither_toggle16(toggle); | 376 toggle = next_dither_toggle16(toggle); |
| 376 } while (--count != 0); | 377 } while (--count != 0); |
| 377 } | 378 } |
| 378 | 379 |
| 379 void shadeSpan16_linear_repeat(TileProc proc, SkFixed dx, SkFixed fx, | 380 void shadeSpan16_linear_repeat(TileProc proc, SkGradFixed dx, SkGradFixed fx, |
| 380 uint16_t* SK_RESTRICT dstC, | 381 uint16_t* SK_RESTRICT dstC, |
| 381 const uint16_t* SK_RESTRICT cache, | 382 const uint16_t* SK_RESTRICT cache, |
| 382 int toggle, int count) { | 383 int toggle, int count) { |
| 383 do { | 384 do { |
| 384 unsigned fi = repeat_bits(fx >> SkGradientShaderBase::kCache16Shift, | 385 unsigned fi = repeat_bits(SkGradFixedToFixed(fx) >> SkGradientShaderBase
::kCache16Shift, |
| 385 SkGradientShaderBase::kCache16Bits); | 386 SkGradientShaderBase::kCache16Bits); |
| 386 SkASSERT(fi < SkGradientShaderBase::kCache16Count); | 387 SkASSERT(fi < SkGradientShaderBase::kCache16Count); |
| 387 fx += dx; | 388 fx += dx; |
| 388 *dstC++ = cache[toggle + fi]; | 389 *dstC++ = cache[toggle + fi]; |
| 389 toggle = next_dither_toggle16(toggle); | 390 toggle = next_dither_toggle16(toggle); |
| 390 } while (--count != 0); | 391 } while (--count != 0); |
| 391 } | 392 } |
| 392 } | 393 } |
| 393 | 394 |
| 394 static bool fixed_nearly_zero(SkFixed x) { | 395 static bool fixed_nearly_zero(SkFixed x) { |
| 395 return SkAbs32(x) < (SK_Fixed1 >> 12); | 396 return SkAbs32(x) < (SK_Fixed1 >> 12); |
| 396 } | 397 } |
| 397 | 398 |
| 398 void SkLinearGradient::LinearGradientContext::shadeSpan16(int x, int y, | 399 void SkLinearGradient::LinearGradientContext::shadeSpan16(int x, int y, |
| 399 uint16_t* SK_RESTRICT
dstC, int count) { | 400 uint16_t* SK_RESTRICT
dstC, int count) { |
| 400 SkASSERT(count > 0); | 401 SkASSERT(count > 0); |
| 401 | 402 |
| 402 const SkLinearGradient& linearGradient = static_cast<const SkLinearGradient&
>(fShader); | 403 const SkLinearGradient& linearGradient = static_cast<const SkLinearGradient&
>(fShader); |
| 403 | 404 |
| 404 SkPoint srcPt; | 405 SkPoint srcPt; |
| 405 SkMatrix::MapXYProc dstProc = fDstToIndexProc; | 406 SkMatrix::MapXYProc dstProc = fDstToIndexProc; |
| 406 TileProc proc = linearGradient.fTileProc; | 407 TileProc proc = linearGradient.fTileProc; |
| 407 const uint16_t* SK_RESTRICT cache = fCache->getCache16(); | 408 const uint16_t* SK_RESTRICT cache = fCache->getCache16(); |
| 408 int toggle = init_dither_toggle16(x, y); | 409 int toggle = init_dither_toggle16(x, y); |
| 409 | 410 |
| 410 if (fDstToIndexClass != kPerspective_MatrixClass) { | 411 if (fDstToIndexClass != kPerspective_MatrixClass) { |
| 411 dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf, | 412 dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf, |
| 412 SkIntToScalar(y) + SK_ScalarHalf, &srcPt); | 413 SkIntToScalar(y) + SK_ScalarHalf, &srcPt); |
| 413 SkFixed dx, fx = SkScalarToFixed(srcPt.fX); | 414 SkGradFixed dx, fx = SkScalarToGradFixed(srcPt.fX); |
| 414 | 415 |
| 415 if (fDstToIndexClass == kFixedStepInX_MatrixClass) { | 416 if (fDstToIndexClass == kFixedStepInX_MatrixClass) { |
| 416 SkFixed dxStorage[1]; | 417 SkFixed dxStorage[1]; |
| 417 (void)fDstToIndex.fixedStepInX(SkIntToScalar(y), dxStorage, NULL); | 418 (void)fDstToIndex.fixedStepInX(SkIntToScalar(y), dxStorage, NULL); |
| 418 dx = dxStorage[0]; | 419 // todo: do we need a real/high-precision value for dx here? |
| 420 dx = SkFixedToGradFixed(dxStorage[0]); |
| 419 } else { | 421 } else { |
| 420 SkASSERT(fDstToIndexClass == kLinear_MatrixClass); | 422 SkASSERT(fDstToIndexClass == kLinear_MatrixClass); |
| 421 dx = SkScalarToFixed(fDstToIndex.getScaleX()); | 423 dx = SkScalarToGradFixed(fDstToIndex.getScaleX()); |
| 422 } | 424 } |
| 423 | 425 |
| 424 LinearShade16Proc shadeProc = shadeSpan16_linear_repeat; | 426 LinearShade16Proc shadeProc = shadeSpan16_linear_repeat; |
| 425 if (fixed_nearly_zero(dx)) { | 427 if (fixed_nearly_zero(SkGradFixedToFixed(dx))) { |
| 426 shadeProc = shadeSpan16_linear_vertical; | 428 shadeProc = shadeSpan16_linear_vertical; |
| 427 } else if (SkShader::kClamp_TileMode == linearGradient.fTileMode) { | 429 } else if (SkShader::kClamp_TileMode == linearGradient.fTileMode) { |
| 428 shadeProc = shadeSpan16_linear_clamp; | 430 shadeProc = shadeSpan16_linear_clamp; |
| 429 } else if (SkShader::kMirror_TileMode == linearGradient.fTileMode) { | 431 } else if (SkShader::kMirror_TileMode == linearGradient.fTileMode) { |
| 430 shadeProc = shadeSpan16_linear_mirror; | 432 shadeProc = shadeSpan16_linear_mirror; |
| 431 } else { | 433 } else { |
| 432 SkASSERT(SkShader::kRepeat_TileMode == linearGradient.fTileMode); | 434 SkASSERT(SkShader::kRepeat_TileMode == linearGradient.fTileMode); |
| 433 } | 435 } |
| 434 (*shadeProc)(proc, dx, fx, dstC, cache, toggle, count); | 436 (*shadeProc)(proc, dx, fx, dstC, cache, toggle, count); |
| 435 } else { | 437 } else { |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 602 str->append("SkLinearGradient ("); | 604 str->append("SkLinearGradient ("); |
| 603 | 605 |
| 604 str->appendf("start: (%f, %f)", fStart.fX, fStart.fY); | 606 str->appendf("start: (%f, %f)", fStart.fX, fStart.fY); |
| 605 str->appendf(" end: (%f, %f) ", fEnd.fX, fEnd.fY); | 607 str->appendf(" end: (%f, %f) ", fEnd.fX, fEnd.fY); |
| 606 | 608 |
| 607 this->INHERITED::toString(str); | 609 this->INHERITED::toString(str); |
| 608 | 610 |
| 609 str->append(")"); | 611 str->append(")"); |
| 610 } | 612 } |
| 611 #endif | 613 #endif |
| OLD | NEW |