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 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 , fStart(buffer.readPoint()) | 64 , fStart(buffer.readPoint()) |
65 , fEnd(buffer.readPoint()) { | 65 , fEnd(buffer.readPoint()) { |
66 } | 66 } |
67 | 67 |
68 void SkLinearGradient::flatten(SkWriteBuffer& buffer) const { | 68 void SkLinearGradient::flatten(SkWriteBuffer& buffer) const { |
69 this->INHERITED::flatten(buffer); | 69 this->INHERITED::flatten(buffer); |
70 buffer.writePoint(fStart); | 70 buffer.writePoint(fStart); |
71 buffer.writePoint(fEnd); | 71 buffer.writePoint(fEnd); |
72 } | 72 } |
73 | 73 |
74 size_t SkLinearGradient::contextSize() const { | 74 bool SkLinearGradient::setContext(const SkBitmap& device, const SkPaint& paint, |
75 return sizeof(LinearGradientContext); | 75 const SkMatrix& matrix) { |
76 } | 76 if (!this->INHERITED::setContext(device, paint, matrix)) { |
77 | 77 return false; |
78 SkShader::Context* SkLinearGradient::createContext(const SkBitmap& device, const
SkPaint& paint, | |
79 const SkMatrix& matrix, void*
storage) const { | |
80 if (!this->validContext(device, paint, matrix)) { | |
81 return NULL; | |
82 } | 78 } |
83 | 79 |
84 return SkNEW_PLACEMENT_ARGS(storage, LinearGradientContext, (*this, device,
paint, matrix)); | |
85 } | |
86 | |
87 SkLinearGradient::LinearGradientContext::LinearGradientContext( | |
88 const SkLinearGradient& shader, const SkBitmap& device, | |
89 const SkPaint& paint, const SkMatrix& matrix) | |
90 : INHERITED(shader, device, paint, matrix) | |
91 { | |
92 unsigned mask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask; | 80 unsigned mask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask; |
93 if ((fDstToIndex.getType() & ~mask) == 0) { | 81 if ((fDstToIndex.getType() & ~mask) == 0) { |
94 // when we dither, we are (usually) not const-in-Y | 82 // when we dither, we are (usually) not const-in-Y |
95 if ((fFlags & SkShader::kHasSpan16_Flag) && !paint.isDither()) { | 83 if ((fFlags & SkShader::kHasSpan16_Flag) && !paint.isDither()) { |
96 // only claim this if we do have a 16bit mode (i.e. none of our | 84 // only claim this if we do have a 16bit mode (i.e. none of our |
97 // colors have alpha), and if we are not dithering (which obviously | 85 // colors have alpha), and if we are not dithering (which obviously |
98 // is not const in Y). | 86 // is not const in Y). |
99 fFlags |= SkShader::kConstInY16_Flag; | 87 fFlags |= SkShader::kConstInY16_Flag; |
100 } | 88 } |
101 } | 89 } |
| 90 return true; |
102 } | 91 } |
103 | 92 |
104 #define NO_CHECK_ITER \ | 93 #define NO_CHECK_ITER \ |
105 do { \ | 94 do { \ |
106 unsigned fi = fx >> SkGradientShaderBase::kCache32Shift; \ | 95 unsigned fi = fx >> SkGradientShaderBase::kCache32Shift; \ |
107 SkASSERT(fi <= 0xFF); \ | 96 SkASSERT(fi <= 0xFF); \ |
108 fx += dx; \ | 97 fx += dx; \ |
109 *dstC++ = cache[toggle + fi]; \ | 98 *dstC++ = cache[toggle + fi]; \ |
110 toggle = next_dither_toggle(toggle); \ | 99 toggle = next_dither_toggle(toggle); \ |
111 } while (0) | 100 } while (0) |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 unsigned fi = repeat_8bits(fx >> 8); | 189 unsigned fi = repeat_8bits(fx >> 8); |
201 SkASSERT(fi <= 0xFF); | 190 SkASSERT(fi <= 0xFF); |
202 fx += dx; | 191 fx += dx; |
203 *dstC++ = cache[toggle + fi]; | 192 *dstC++ = cache[toggle + fi]; |
204 toggle = next_dither_toggle(toggle); | 193 toggle = next_dither_toggle(toggle); |
205 } while (--count != 0); | 194 } while (--count != 0); |
206 } | 195 } |
207 | 196 |
208 } | 197 } |
209 | 198 |
210 void SkLinearGradient::LinearGradientContext::shadeSpan(int x, int y, SkPMColor*
SK_RESTRICT dstC, | 199 void SkLinearGradient::shadeSpan(int x, int y, SkPMColor* SK_RESTRICT dstC, |
211 int count) { | 200 int count) { |
212 SkASSERT(count > 0); | 201 SkASSERT(count > 0); |
213 | 202 |
214 const SkLinearGradient& linearGradient = static_cast<const SkLinearGradient&
>(fShader); | |
215 | |
216 SkPoint srcPt; | 203 SkPoint srcPt; |
217 SkMatrix::MapXYProc dstProc = fDstToIndexProc; | 204 SkMatrix::MapXYProc dstProc = fDstToIndexProc; |
218 TileProc proc = linearGradient.fTileProc; | 205 TileProc proc = fTileProc; |
219 const SkPMColor* SK_RESTRICT cache = fCache->getCache32(); | 206 const SkPMColor* SK_RESTRICT cache = this->getCache32(); |
220 int toggle = init_dither_toggle(x, y); | 207 int toggle = init_dither_toggle(x, y); |
221 | 208 |
222 if (fDstToIndexClass != kPerspective_MatrixClass) { | 209 if (fDstToIndexClass != kPerspective_MatrixClass) { |
223 dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf, | 210 dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf, |
224 SkIntToScalar(y) + SK_ScalarHalf, &srcPt); | 211 SkIntToScalar(y) + SK_ScalarHalf, &srcPt); |
225 SkFixed dx, fx = SkScalarToFixed(srcPt.fX); | 212 SkFixed dx, fx = SkScalarToFixed(srcPt.fX); |
226 | 213 |
227 if (fDstToIndexClass == kFixedStepInX_MatrixClass) { | 214 if (fDstToIndexClass == kFixedStepInX_MatrixClass) { |
228 SkFixed dxStorage[1]; | 215 SkFixed dxStorage[1]; |
229 (void)fDstToIndex.fixedStepInX(SkIntToScalar(y), dxStorage, NULL); | 216 (void)fDstToIndex.fixedStepInX(SkIntToScalar(y), dxStorage, NULL); |
230 dx = dxStorage[0]; | 217 dx = dxStorage[0]; |
231 } else { | 218 } else { |
232 SkASSERT(fDstToIndexClass == kLinear_MatrixClass); | 219 SkASSERT(fDstToIndexClass == kLinear_MatrixClass); |
233 dx = SkScalarToFixed(fDstToIndex.getScaleX()); | 220 dx = SkScalarToFixed(fDstToIndex.getScaleX()); |
234 } | 221 } |
235 | 222 |
236 LinearShadeProc shadeProc = shadeSpan_linear_repeat; | 223 LinearShadeProc shadeProc = shadeSpan_linear_repeat; |
237 if (0 == dx) { | 224 if (0 == dx) { |
238 shadeProc = shadeSpan_linear_vertical_lerp; | 225 shadeProc = shadeSpan_linear_vertical_lerp; |
239 } else if (SkShader::kClamp_TileMode == linearGradient.fTileMode) { | 226 } else if (SkShader::kClamp_TileMode == fTileMode) { |
240 shadeProc = shadeSpan_linear_clamp; | 227 shadeProc = shadeSpan_linear_clamp; |
241 } else if (SkShader::kMirror_TileMode == linearGradient.fTileMode) { | 228 } else if (SkShader::kMirror_TileMode == fTileMode) { |
242 shadeProc = shadeSpan_linear_mirror; | 229 shadeProc = shadeSpan_linear_mirror; |
243 } else { | 230 } else { |
244 SkASSERT(SkShader::kRepeat_TileMode == linearGradient.fTileMode); | 231 SkASSERT(SkShader::kRepeat_TileMode == fTileMode); |
245 } | 232 } |
246 (*shadeProc)(proc, dx, fx, dstC, cache, toggle, count); | 233 (*shadeProc)(proc, dx, fx, dstC, cache, toggle, count); |
247 } else { | 234 } else { |
248 SkScalar dstX = SkIntToScalar(x); | 235 SkScalar dstX = SkIntToScalar(x); |
249 SkScalar dstY = SkIntToScalar(y); | 236 SkScalar dstY = SkIntToScalar(y); |
250 do { | 237 do { |
251 dstProc(fDstToIndex, dstX, dstY, &srcPt); | 238 dstProc(fDstToIndex, dstX, dstY, &srcPt); |
252 unsigned fi = proc(SkScalarToFixed(srcPt.fX)); | 239 unsigned fi = proc(SkScalarToFixed(srcPt.fX)); |
253 SkASSERT(fi <= 0xFFFF); | 240 SkASSERT(fi <= 0xFFFF); |
254 *dstC++ = cache[toggle + (fi >> kCache32Shift)]; | 241 *dstC++ = cache[toggle + (fi >> kCache32Shift)]; |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
387 *dstC++ = cache[toggle + fi]; | 374 *dstC++ = cache[toggle + fi]; |
388 toggle = next_dither_toggle16(toggle); | 375 toggle = next_dither_toggle16(toggle); |
389 } while (--count != 0); | 376 } while (--count != 0); |
390 } | 377 } |
391 } | 378 } |
392 | 379 |
393 static bool fixed_nearly_zero(SkFixed x) { | 380 static bool fixed_nearly_zero(SkFixed x) { |
394 return SkAbs32(x) < (SK_Fixed1 >> 12); | 381 return SkAbs32(x) < (SK_Fixed1 >> 12); |
395 } | 382 } |
396 | 383 |
397 void SkLinearGradient::LinearGradientContext::shadeSpan16(int x, int y, | 384 void SkLinearGradient::shadeSpan16(int x, int y, |
398 uint16_t* SK_RESTRICT
dstC, int count) { | 385 uint16_t* SK_RESTRICT dstC, int count) { |
399 SkASSERT(count > 0); | 386 SkASSERT(count > 0); |
400 | 387 |
401 const SkLinearGradient& linearGradient = static_cast<const SkLinearGradient&
>(fShader); | |
402 | |
403 SkPoint srcPt; | 388 SkPoint srcPt; |
404 SkMatrix::MapXYProc dstProc = fDstToIndexProc; | 389 SkMatrix::MapXYProc dstProc = fDstToIndexProc; |
405 TileProc proc = linearGradient.fTileProc; | 390 TileProc proc = fTileProc; |
406 const uint16_t* SK_RESTRICT cache = fCache->getCache16(); | 391 const uint16_t* SK_RESTRICT cache = this->getCache16(); |
407 int toggle = init_dither_toggle16(x, y); | 392 int toggle = init_dither_toggle16(x, y); |
408 | 393 |
409 if (fDstToIndexClass != kPerspective_MatrixClass) { | 394 if (fDstToIndexClass != kPerspective_MatrixClass) { |
410 dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf, | 395 dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf, |
411 SkIntToScalar(y) + SK_ScalarHalf, &srcPt); | 396 SkIntToScalar(y) + SK_ScalarHalf, &srcPt); |
412 SkFixed dx, fx = SkScalarToFixed(srcPt.fX); | 397 SkFixed dx, fx = SkScalarToFixed(srcPt.fX); |
413 | 398 |
414 if (fDstToIndexClass == kFixedStepInX_MatrixClass) { | 399 if (fDstToIndexClass == kFixedStepInX_MatrixClass) { |
415 SkFixed dxStorage[1]; | 400 SkFixed dxStorage[1]; |
416 (void)fDstToIndex.fixedStepInX(SkIntToScalar(y), dxStorage, NULL); | 401 (void)fDstToIndex.fixedStepInX(SkIntToScalar(y), dxStorage, NULL); |
417 dx = dxStorage[0]; | 402 dx = dxStorage[0]; |
418 } else { | 403 } else { |
419 SkASSERT(fDstToIndexClass == kLinear_MatrixClass); | 404 SkASSERT(fDstToIndexClass == kLinear_MatrixClass); |
420 dx = SkScalarToFixed(fDstToIndex.getScaleX()); | 405 dx = SkScalarToFixed(fDstToIndex.getScaleX()); |
421 } | 406 } |
422 | 407 |
423 LinearShade16Proc shadeProc = shadeSpan16_linear_repeat; | 408 LinearShade16Proc shadeProc = shadeSpan16_linear_repeat; |
424 if (fixed_nearly_zero(dx)) { | 409 if (fixed_nearly_zero(dx)) { |
425 shadeProc = shadeSpan16_linear_vertical; | 410 shadeProc = shadeSpan16_linear_vertical; |
426 } else if (SkShader::kClamp_TileMode == linearGradient.fTileMode) { | 411 } else if (SkShader::kClamp_TileMode == fTileMode) { |
427 shadeProc = shadeSpan16_linear_clamp; | 412 shadeProc = shadeSpan16_linear_clamp; |
428 } else if (SkShader::kMirror_TileMode == linearGradient.fTileMode) { | 413 } else if (SkShader::kMirror_TileMode == fTileMode) { |
429 shadeProc = shadeSpan16_linear_mirror; | 414 shadeProc = shadeSpan16_linear_mirror; |
430 } else { | 415 } else { |
431 SkASSERT(SkShader::kRepeat_TileMode == linearGradient.fTileMode); | 416 SkASSERT(SkShader::kRepeat_TileMode == fTileMode); |
432 } | 417 } |
433 (*shadeProc)(proc, dx, fx, dstC, cache, toggle, count); | 418 (*shadeProc)(proc, dx, fx, dstC, cache, toggle, count); |
434 } else { | 419 } else { |
435 SkScalar dstX = SkIntToScalar(x); | 420 SkScalar dstX = SkIntToScalar(x); |
436 SkScalar dstY = SkIntToScalar(y); | 421 SkScalar dstY = SkIntToScalar(y); |
437 do { | 422 do { |
438 dstProc(fDstToIndex, dstX, dstY, &srcPt); | 423 dstProc(fDstToIndex, dstX, dstY, &srcPt); |
439 unsigned fi = proc(SkScalarToFixed(srcPt.fX)); | 424 unsigned fi = proc(SkScalarToFixed(srcPt.fX)); |
440 SkASSERT(fi <= 0xFFFF); | 425 SkASSERT(fi <= 0xFFFF); |
441 | 426 |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
576 str->append("SkLinearGradient ("); | 561 str->append("SkLinearGradient ("); |
577 | 562 |
578 str->appendf("start: (%f, %f)", fStart.fX, fStart.fY); | 563 str->appendf("start: (%f, %f)", fStart.fX, fStart.fY); |
579 str->appendf(" end: (%f, %f) ", fEnd.fX, fEnd.fY); | 564 str->appendf(" end: (%f, %f) ", fEnd.fX, fEnd.fY); |
580 | 565 |
581 this->INHERITED::toString(str); | 566 this->INHERITED::toString(str); |
582 | 567 |
583 str->append(")"); | 568 str->append(")"); |
584 } | 569 } |
585 #endif | 570 #endif |
OLD | NEW |