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