aboutsummaryrefslogtreecommitdiffstats
path: root/src/effects/SkGradientShader.cpp
diff options
context:
space:
mode:
authorDerek Sollenberger <djsollen@google.com>2011-03-14 11:20:24 -0400
committerDerek Sollenberger <djsollen@google.com>2011-03-14 16:33:36 -0400
commit05b6b4d746867a9fb02e14edfe1bf3685abeb813 (patch)
tree34b121f598d1693c014df48ee70bffa382b0cc23 /src/effects/SkGradientShader.cpp
parent6210a7c68844602ee390bcce61dbb637910a3c6b (diff)
downloadexternal_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.cpp212
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