diff options
author | Derek Sollenberger <djsollen@google.com> | 2011-03-14 11:20:24 -0400 |
---|---|---|
committer | Derek Sollenberger <djsollen@google.com> | 2011-03-14 16:33:36 -0400 |
commit | 05b6b4d746867a9fb02e14edfe1bf3685abeb813 (patch) | |
tree | 34b121f598d1693c014df48ee70bffa382b0cc23 /src/effects/SkGradientShader.cpp | |
parent | 6210a7c68844602ee390bcce61dbb637910a3c6b (diff) | |
download | external_skia-05b6b4d746867a9fb02e14edfe1bf3685abeb813.zip external_skia-05b6b4d746867a9fb02e14edfe1bf3685abeb813.tar.gz external_skia-05b6b4d746867a9fb02e14edfe1bf3685abeb813.tar.bz2 |
Skia Merge (revision 922)
Change-Id: I7ed57d10905d8bad6486a4d7410165eec1cc2b4f
Diffstat (limited to 'src/effects/SkGradientShader.cpp')
-rw-r--r-- | src/effects/SkGradientShader.cpp | 212 |
1 files changed, 161 insertions, 51 deletions
diff --git a/src/effects/SkGradientShader.cpp b/src/effects/SkGradientShader.cpp index 64a78c7..3452212 100644 --- a/src/effects/SkGradientShader.cpp +++ b/src/effects/SkGradientShader.cpp @@ -123,12 +123,11 @@ protected: kCache32Count = 1 << kCache32Bits }; virtual void flatten(SkFlattenableWriteBuffer& ); - const uint16_t* getCache16(); - const SkPMColor* getCache32(); + const uint16_t* getCache16() const; + const SkPMColor* getCache32() const; - SkMallocPixelRef* fCache32PixelRef; - - void commonAsABitmap(SkBitmap*); + void commonAsABitmap(SkBitmap*) const; + void commonAsAGradient(GradientInfo*) const; private: enum { @@ -139,10 +138,11 @@ private: SkColor fStorage[(kStorageSize + 3) >> 2]; SkColor* fOrigColors; - uint16_t* fCache16; // working ptr. If this is NULL, we need to recompute the cache values - SkPMColor* fCache32; // working ptr. If this is NULL, we need to recompute the cache values + mutable uint16_t* fCache16; // working ptr. If this is NULL, we need to recompute the cache values + mutable SkPMColor* fCache32; // working ptr. If this is NULL, we need to recompute the cache values - uint16_t* fCache16Storage; // storage for fCache16, allocated on demand + mutable uint16_t* fCache16Storage; // storage for fCache16, allocated on demand + mutable SkMallocPixelRef* fCache32PixelRef; unsigned fCacheAlpha; // the alpha value we used when we computed the cache. larger than 8bits so we can store uninitialized value static void Build16bitCache(uint16_t[], SkColor c0, SkColor c1, int count); @@ -535,7 +535,7 @@ static inline U16CPU bitsTo16(unsigned x, const unsigned bits) { return 0; } -const uint16_t* Gradient_Shader::getCache16() { +const uint16_t* Gradient_Shader::getCache16() const { if (fCache16 == NULL) { // double the count for dither entries const int entryCount = kCache16Count * 2; @@ -578,7 +578,7 @@ const uint16_t* Gradient_Shader::getCache16() { return fCache16; } -const SkPMColor* Gradient_Shader::getCache32() { +const SkPMColor* Gradient_Shader::getCache32() const { if (fCache32 == NULL) { // double the count for dither entries const int entryCount = kCache32Count * 2; @@ -635,7 +635,7 @@ const SkPMColor* Gradient_Shader::getCache32() { * colors and positions. Note: we don't try to flatten the fMapper, so if one * is present, we skip the cache for now. */ -void Gradient_Shader::commonAsABitmap(SkBitmap* bitmap) { +void Gradient_Shader::commonAsABitmap(SkBitmap* bitmap) const { // don't have a way to put the mapper into our cache-key yet if (fMapper) { // force our cahce32pixelref to be built @@ -687,6 +687,28 @@ void Gradient_Shader::commonAsABitmap(SkBitmap* bitmap) { } } +void Gradient_Shader::commonAsAGradient(GradientInfo* info) const { + if (info) { + if (info->fColorCount >= fColorCount) { + if (info->fColors) { + memcpy(info->fColors, fOrigColors, + fColorCount * sizeof(SkColor)); + } + if (info->fColorOffsets) { + if (fColorCount == 2) { + info->fColorOffsets[0] = 0; + info->fColorOffsets[1] = SK_Scalar1; + } else if (fColorCount > 2) { + for (int i = 0; i < fColorCount; i++) + info->fColorOffsets[i] = SkFixedToScalar(fRecs[i].fPos); + } + } + } + info->fColorCount = fColorCount; + info->fTileMode = fTileMode; + } +} + /////////////////////////////////////////////////////////////////////////// static void pts_to_unit_matrix(const SkPoint pts[2], SkMatrix* matrix) { @@ -707,7 +729,9 @@ public: Linear_Gradient(const SkPoint pts[2], const SkColor colors[], const SkScalar pos[], int colorCount, SkShader::TileMode mode, SkUnitMapper* mapper) - : Gradient_Shader(colors, pos, colorCount, mode, mapper) + : Gradient_Shader(colors, pos, colorCount, mode, mapper), + fStart(pts[0]), + fEnd(pts[1]) { pts_to_unit_matrix(pts, &fPtsToUnit); } @@ -716,18 +740,33 @@ public: virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count); virtual void shadeSpan16(int x, int y, uint16_t dstC[], int count); virtual BitmapType asABitmap(SkBitmap*, SkMatrix*, - TileMode*, SkScalar* twoPointRadialParams); + TileMode*, SkScalar* twoPointRadialParams) const; + virtual GradientType asAGradient(GradientInfo* info) const; static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { return SkNEW_ARGS(Linear_Gradient, (buffer)); } + virtual void flatten(SkFlattenableWriteBuffer& buffer) { + this->INHERITED::flatten(buffer); + buffer.writeScalar(fStart.fX); + buffer.writeScalar(fStart.fY); + buffer.writeScalar(fEnd.fX); + buffer.writeScalar(fEnd.fY); + } + protected: - Linear_Gradient(SkFlattenableReadBuffer& buffer) : Gradient_Shader(buffer) {} + Linear_Gradient(SkFlattenableReadBuffer& buffer) + : Gradient_Shader(buffer), + fStart(SkPoint::Make(buffer.readScalar(), buffer.readScalar())), + fEnd(SkPoint::Make(buffer.readScalar(), buffer.readScalar())) { + } virtual Factory getFactory() { return CreateProc; } private: typedef Gradient_Shader INHERITED; + const SkPoint fStart; + const SkPoint fEnd; }; bool Linear_Gradient::setContext(const SkBitmap& device, const SkPaint& paint, @@ -835,7 +874,7 @@ void Linear_Gradient::shadeSpan(int x, int y, SkPMColor dstC[], int count) SkShader::BitmapType Linear_Gradient::asABitmap(SkBitmap* bitmap, SkMatrix* matrix, TileMode xy[], - SkScalar* twoPointRadialParams) { + SkScalar* twoPointRadialParams) const { if (bitmap) { this->commonAsABitmap(bitmap); } @@ -850,6 +889,15 @@ SkShader::BitmapType Linear_Gradient::asABitmap(SkBitmap* bitmap, return kDefault_BitmapType; } +SkShader::GradientType Linear_Gradient::asAGradient(GradientInfo* info) const { + if (info) { + commonAsAGradient(info); + info->fPoint[0] = fStart; + info->fPoint[1] = fEnd; + } + return kLinear_GradientType; +} + static void dither_memset16(uint16_t dst[], uint16_t value, uint16_t other, int count) { if (reinterpret_cast<uintptr_t>(dst) & 2) { @@ -989,7 +1037,9 @@ public: Radial_Gradient(const SkPoint& center, SkScalar radius, const SkColor colors[], const SkScalar pos[], int colorCount, SkShader::TileMode mode, SkUnitMapper* mapper) - : Gradient_Shader(colors, pos, colorCount, mode, mapper) + : Gradient_Shader(colors, pos, colorCount, mode, mapper), + fCenter(center), + fRadius(radius) { // make sure our table is insync with our current #define for kSQRT_TABLE_SIZE SkASSERT(sizeof(gSqrt8Table) == kSQRT_TABLE_SIZE); @@ -1185,7 +1235,7 @@ public: virtual BitmapType asABitmap(SkBitmap* bitmap, SkMatrix* matrix, TileMode* xy, - SkScalar* twoPointRadialParams) { + SkScalar* twoPointRadialParams) const { if (bitmap) { this->commonAsABitmap(bitmap); } @@ -1199,17 +1249,38 @@ public: } return kRadial_BitmapType; } + virtual GradientType asAGradient(GradientInfo* info) const { + if (info) { + commonAsAGradient(info); + info->fPoint[0] = fCenter; + info->fRadius[0] = fRadius; + } + return kRadial_GradientType; + } static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { return SkNEW_ARGS(Radial_Gradient, (buffer)); } + virtual void flatten(SkFlattenableWriteBuffer& buffer) { + this->INHERITED::flatten(buffer); + buffer.writeScalar(fCenter.fX); + buffer.writeScalar(fCenter.fY); + buffer.writeScalar(fRadius); + } + protected: - Radial_Gradient(SkFlattenableReadBuffer& buffer) : Gradient_Shader(buffer) {}; + Radial_Gradient(SkFlattenableReadBuffer& buffer) + : Gradient_Shader(buffer), + fCenter(SkPoint::Make(buffer.readScalar(), buffer.readScalar())), + fRadius(buffer.readScalar()) { + } virtual Factory getFactory() { return CreateProc; } private: typedef Gradient_Shader INHERITED; + const SkPoint fCenter; + const SkScalar fRadius; }; /* Two-point radial gradients are specified by two circles, each with a center @@ -1305,26 +1376,18 @@ public: const SkColor colors[], const SkScalar pos[], int colorCount, SkShader::TileMode mode, SkUnitMapper* mapper) - : Gradient_Shader(colors, pos, colorCount, mode, mapper) - { - fDiff = start - end; - fDiffRadius = endRadius - startRadius; - SkScalar inv = SkScalarInvert(fDiffRadius); - fDiff.fX = SkScalarMul(fDiff.fX, inv); - fDiff.fY = SkScalarMul(fDiff.fY, inv); - fStartRadius = SkScalarMul(startRadius, inv); - fSr2D2 = SkScalarSquare(fStartRadius); - fA = SkScalarSquare(fDiff.fX) + SkScalarSquare(fDiff.fY) - SK_Scalar1; - fOneOverTwoA = SkScalarInvert(fA * 2); - - fPtsToUnit.setTranslate(-start.fX, -start.fY); - fPtsToUnit.postScale(inv, inv); + : Gradient_Shader(colors, pos, colorCount, mode, mapper), + fCenter1(start), + fCenter2(end), + fRadius1(startRadius), + fRadius2(endRadius) { + init(); } virtual BitmapType asABitmap(SkBitmap* bitmap, SkMatrix* matrix, TileMode* xy, - SkScalar* twoPointRadialParams) { + SkScalar* twoPointRadialParams) const { if (bitmap) { this->commonAsABitmap(bitmap); } @@ -1351,6 +1414,17 @@ public: return kTwoPointRadial_BitmapType; } + virtual GradientType asAGradient(GradientInfo* info) const { + if (info) { + commonAsAGradient(info); + info->fPoint[0] = fCenter1; + info->fPoint[1] = fCenter2; + info->fRadius[0] = fRadius1; + info->fRadius[1] = fRadius2; + } + return kRadial2_GradientType; + } + virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count) { SkASSERT(count > 0); @@ -1468,32 +1542,48 @@ public: virtual void flatten(SkFlattenableWriteBuffer& buffer) { this->INHERITED::flatten(buffer); - buffer.writeScalar(fDiff.fX); - buffer.writeScalar(fDiff.fY); - buffer.writeScalar(fStartRadius); - buffer.writeScalar(fDiffRadius); - buffer.writeScalar(fSr2D2); - buffer.writeScalar(fA); - buffer.writeScalar(fOneOverTwoA); + buffer.writeScalar(fCenter1.fX); + buffer.writeScalar(fCenter1.fY); + buffer.writeScalar(fCenter2.fX); + buffer.writeScalar(fCenter2.fY); + buffer.writeScalar(fRadius1); + buffer.writeScalar(fRadius2); } protected: Two_Point_Radial_Gradient(SkFlattenableReadBuffer& buffer) - : Gradient_Shader(buffer) { - fDiff.fX = buffer.readScalar(); - fDiff.fY = buffer.readScalar(); - fStartRadius = buffer.readScalar(); - fDiffRadius = buffer.readScalar(); - fSr2D2 = buffer.readScalar(); - fA = buffer.readScalar(); - fOneOverTwoA = buffer.readScalar(); + : Gradient_Shader(buffer), + fCenter1(SkPoint::Make(buffer.readScalar(), buffer.readScalar())), + fCenter2(SkPoint::Make(buffer.readScalar(), buffer.readScalar())), + fRadius1(buffer.readScalar()), + fRadius2(buffer.readScalar()) { + init(); }; virtual Factory getFactory() { return CreateProc; } private: typedef Gradient_Shader INHERITED; + const SkPoint fCenter1; + const SkPoint fCenter2; + const SkScalar fRadius1; + const SkScalar fRadius2; SkPoint fDiff; SkScalar fStartRadius, fDiffRadius, fSr2D2, fA, fOneOverTwoA; + + void init() { + fDiff = fCenter1 - fCenter2; + fDiffRadius = fRadius2 - fRadius1; + SkScalar inv = SkScalarInvert(fDiffRadius); + fDiff.fX = SkScalarMul(fDiff.fX, inv); + fDiff.fY = SkScalarMul(fDiff.fY, inv); + fStartRadius = SkScalarMul(fRadius1, inv); + fSr2D2 = SkScalarSquare(fStartRadius); + fA = SkScalarSquare(fDiff.fX) + SkScalarSquare(fDiff.fY) - SK_Scalar1; + fOneOverTwoA = SkScalarInvert(fA * 2); + + fPtsToUnit.setTranslate(-fCenter1.fX, -fCenter1.fY); + fPtsToUnit.postScale(inv, inv); + } }; /////////////////////////////////////////////////////////////////////////////// @@ -1502,7 +1592,8 @@ class Sweep_Gradient : public Gradient_Shader { public: Sweep_Gradient(SkScalar cx, SkScalar cy, const SkColor colors[], const SkScalar pos[], int count, SkUnitMapper* mapper) - : Gradient_Shader(colors, pos, count, SkShader::kClamp_TileMode, mapper) + : Gradient_Shader(colors, pos, count, SkShader::kClamp_TileMode, mapper), + fCenter(SkPoint::Make(cx, cy)) { fPtsToUnit.setTranslate(-cx, -cy); } @@ -1512,7 +1603,7 @@ public: virtual BitmapType asABitmap(SkBitmap* bitmap, SkMatrix* matrix, TileMode* xy, - SkScalar* twoPointRadialParams) { + SkScalar* twoPointRadialParams) const { if (bitmap) { this->commonAsABitmap(bitmap); } @@ -1526,16 +1617,35 @@ public: return kSweep_BitmapType; } + virtual GradientType asAGradient(GradientInfo* info) const { + if (info) { + commonAsAGradient(info); + info->fPoint[0] = fCenter; + } + return kSweep_GradientType; + } + static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { return SkNEW_ARGS(Sweep_Gradient, (buffer)); } + virtual void flatten(SkFlattenableWriteBuffer& buffer) { + this->INHERITED::flatten(buffer); + buffer.writeScalar(fCenter.fX); + buffer.writeScalar(fCenter.fY); + } + protected: - Sweep_Gradient(SkFlattenableReadBuffer& buffer) : Gradient_Shader(buffer) {} + Sweep_Gradient(SkFlattenableReadBuffer& buffer) + : Gradient_Shader(buffer), + fCenter(SkPoint::Make(buffer.readScalar(), buffer.readScalar())) { + } + virtual Factory getFactory() { return CreateProc; } private: typedef Gradient_Shader INHERITED; + const SkPoint fCenter; }; #ifdef COMPUTE_SWEEP_TABLE |