aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gm/tablecolorfilter.cpp103
-rw-r--r--include/core/SkColorFilter.h6
-rw-r--r--include/effects/SkModeColorFilter.h63
-rw-r--r--src/core/SkColorFilter.cpp83
-rw-r--r--src/effects/SkColorFilters.cpp118
-rw-r--r--src/ports/SkGlobalInitialization_chromium.cpp2
-rw-r--r--src/ports/SkGlobalInitialization_default.cpp2
7 files changed, 272 insertions, 105 deletions
diff --git a/gm/tablecolorfilter.cpp b/gm/tablecolorfilter.cpp
index a49859bf8f..2acb15c677 100644
--- a/gm/tablecolorfilter.cpp
+++ b/gm/tablecolorfilter.cpp
@@ -11,6 +11,15 @@
#include "SkGradientShader.h"
#include "SkTableColorFilter.h"
+static SkShader* make_shader0(int w, int h) {
+ SkPoint pts[] = { {0, 0}, {SkIntToScalar(w), SkIntToScalar(h)} };
+ SkColor colors[] = {
+ SK_ColorBLACK, SK_ColorGREEN, SK_ColorCYAN,
+ SK_ColorRED, 0, SK_ColorBLUE, SK_ColorWHITE
+ };
+ return SkGradientShader::CreateLinear(pts, colors, NULL, SK_ARRAY_COUNT(colors),
+ SkShader::kClamp_TileMode);
+}
static void make_bm0(SkBitmap* bm) {
int W = 120;
int H = 120;
@@ -19,34 +28,29 @@ static void make_bm0(SkBitmap* bm) {
SkCanvas canvas(*bm);
SkPaint paint;
- SkPoint pts[] = { {0, 0}, {SkIntToScalar(W), SkIntToScalar(H)} };
+ paint.setShader(make_shader0(W, H))->unref();
+ canvas.drawPaint(paint);
+}
+static SkShader* make_shader1(int w, int h) {
+ SkScalar cx = SkIntToScalar(w)/2;
+ SkScalar cy = SkIntToScalar(h)/2;
SkColor colors[] = {
- SK_ColorBLACK, SK_ColorGREEN, SK_ColorCYAN,
- SK_ColorRED, 0, SK_ColorBLUE, SK_ColorWHITE
+ SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE,
};
- SkShader* s = SkGradientShader::CreateLinear(pts, colors, NULL, SK_ARRAY_COUNT(colors),
- SkShader::kClamp_TileMode);
- paint.setShader(s)->unref();
- canvas.drawPaint(paint);
+ return SkGradientShader::CreateRadial(SkPoint::Make(cx, cy), cx, colors, NULL,
+ SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode);
}
static void make_bm1(SkBitmap* bm) {
int W = 120;
int H = 120;
+ SkScalar cx = SkIntToScalar(W)/2;
+ SkScalar cy = SkIntToScalar(H)/2;
bm->allocN32Pixels(W, H);
bm->eraseColor(SK_ColorTRANSPARENT);
SkCanvas canvas(*bm);
SkPaint paint;
- SkScalar cx = SkIntToScalar(W)/2;
- SkScalar cy = SkIntToScalar(H)/2;
- SkColor colors[] = {
- SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE,
- };
- SkShader* s = SkGradientShader::CreateRadial(SkPoint::Make(SkIntToScalar(W)/2,
- SkIntToScalar(H)/2),
- SkIntToScalar(W)/2, colors, NULL, SK_ARRAY_COUNT(colors),
- SkShader::kClamp_TileMode);
- paint.setShader(s)->unref();
+ paint.setShader(make_shader1(W, H))->unref();
paint.setAntiAlias(true);
canvas.drawCircle(cx, cy, cx, paint);
}
@@ -184,8 +188,69 @@ protected:
private:
typedef GM INHERITED;
};
+DEF_GM( return new TableColorFilterGM; )
//////////////////////////////////////////////////////////////////////////////
-static skiagm::GM* MyFactory(void*) { return new TableColorFilterGM; }
-static skiagm::GMRegistry reg(MyFactory);
+class ComposeColorFilterGM : public skiagm::GM {
+public:
+ ComposeColorFilterGM() {}
+
+protected:
+ virtual SkString onShortName() {
+ return SkString("composecolorfilter");
+ }
+
+ virtual SkISize onISize() {
+ return SkISize::Make(730, 730);
+ }
+
+ virtual void onDraw(SkCanvas* canvas) {
+ SkBitmap bm;
+ make_bm1(&bm);
+
+ canvas->drawColor(0xFFDDDDDD);
+
+ SkColor colors[] = { SK_ColorCYAN, SK_ColorMAGENTA, SK_ColorYELLOW };
+ SkXfermode::Mode modes[] = {
+ SkXfermode::kOverlay_Mode,
+ SkXfermode::kDarken_Mode,
+ SkXfermode::kColorBurn_Mode,
+ SkXfermode::kExclusion_Mode,
+ };
+
+ const int MODES = SK_ARRAY_COUNT(modes) * SK_ARRAY_COUNT(colors);
+ SkAutoTUnref<SkColorFilter> filters[MODES];
+ int index = 0;
+ for (size_t i = 0; i < SK_ARRAY_COUNT(modes); ++i) {
+ for (size_t j = 0; j < SK_ARRAY_COUNT(colors); ++j) {
+ filters[index++].reset(SkColorFilter::CreateModeFilter(colors[j], modes[i]));
+ }
+ }
+
+ SkPaint paint;
+ paint.setShader(make_shader1(50, 50))->unref();
+ SkRect r = SkRect::MakeWH(50, 50);
+ const SkScalar spacer = 10;
+
+ canvas->translate(spacer, spacer);
+
+ for (size_t y = 0; y < MODES; ++y) {
+ canvas->save();
+ for (size_t x = 0; x < MODES; ++x) {
+ SkAutoTUnref<SkColorFilter> compose(SkColorFilter::CreateComposeFilter(filters[y],
+ filters[x]));
+ paint.setColorFilter(compose);
+ canvas->drawRect(r, paint);
+ canvas->translate(r.width() + spacer, 0);
+ }
+ canvas->restore();
+ canvas->translate(0, r.height() + spacer);
+ }
+ }
+
+private:
+ typedef GM INHERITED;
+};
+DEF_GM( return new ComposeColorFilterGM; )
+
diff --git a/include/core/SkColorFilter.h b/include/core/SkColorFilter.h
index 929607a398..bb628053a6 100644
--- a/include/core/SkColorFilter.h
+++ b/include/core/SkColorFilter.h
@@ -123,6 +123,12 @@ public:
*/
static SkColorFilter* CreateLightingFilter(SkColor mul, SkColor add);
+ /** Construct a colorfilter whose effect is to first apply the inner filter and then apply
+ * the outer filter to the result of the inner's.
+ * The reference counts for outer and inner are incremented.
+ */
+ static SkColorFilter* CreateComposeFilter(SkColorFilter* outer, SkColorFilter* inner);
+
/** A subclass may implement this factory function to work with the GPU backend. If the return
is non-NULL then the caller owns a ref on the returned object.
*/
diff --git a/include/effects/SkModeColorFilter.h b/include/effects/SkModeColorFilter.h
new file mode 100644
index 0000000000..16c6e13359
--- /dev/null
+++ b/include/effects/SkModeColorFilter.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkModeColorFilter_DEFINED
+#define SkModeColorFilter_DEFINED
+
+#include "SkColorFilter.h"
+#include "SkColorPriv.h"
+#include "SkString.h"
+#include "SkXfermode.h"
+
+class SkModeColorFilter : public SkColorFilter {
+public:
+ SkModeColorFilter(SkColor color, SkXfermode::Mode mode) {
+ fColor = color;
+ fMode = mode;
+ this->updateCache();
+ };
+
+ SkColor getColor() const { return fColor; }
+ SkXfermode::Mode getMode() const { return fMode; }
+ SkPMColor getPMColor() const { return fPMColor; }
+
+ bool asColorMode(SkColor*, SkXfermode::Mode*) const SK_OVERRIDE;
+ uint32_t getFlags() const SK_OVERRIDE;
+ void filterSpan(const SkPMColor shader[], int count, SkPMColor result[]) const SK_OVERRIDE;
+ void filterSpan16(const uint16_t shader[], int count, uint16_t result[]) const SK_OVERRIDE;
+
+#ifndef SK_IGNORE_TO_STRING
+ void toString(SkString* str) const SK_OVERRIDE {
+ str->append("SkModeColorFilter: color: 0x");
+ str->appendHex(fColor);
+ str->append(" mode: ");
+ str->append(SkXfermode::ModeName(fMode));
+ }
+#endif
+
+#if SK_SUPPORT_GPU
+ GrFragmentProcessor* asFragmentProcessor(GrContext*) const SK_OVERRIDE;
+#endif
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkModeColorFilter)
+
+protected:
+ void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+
+private:
+ SkColor fColor;
+ SkXfermode::Mode fMode;
+ // cache
+ SkPMColor fPMColor;
+ SkXfermodeProc fProc;
+ SkXfermodeProc16 fProc16;
+
+ void updateCache();
+
+ typedef SkColorFilter INHERITED;
+};
+
+#endif
diff --git a/src/core/SkColorFilter.cpp b/src/core/SkColorFilter.cpp
index aadb29cb2d..d49fc52fa1 100644
--- a/src/core/SkColorFilter.cpp
+++ b/src/core/SkColorFilter.cpp
@@ -6,12 +6,9 @@
*/
#include "SkColorFilter.h"
-
#include "SkReadBuffer.h"
-#include "SkWriteBuffer.h"
-#include "SkShader.h"
-#include "SkUnPreMultiply.h"
#include "SkString.h"
+#include "SkWriteBuffer.h"
bool SkColorFilter::asColorMode(SkColor* color, SkXfermode::Mode* mode) const {
return false;
@@ -43,3 +40,81 @@ SkColor SkColorFilter::filterColor(SkColor c) const {
GrFragmentProcessor* SkColorFilter::asFragmentProcessor(GrContext*) const {
return NULL;
}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SkComposeColorFilter : public SkColorFilter {
+public:
+ SkComposeColorFilter(SkColorFilter* outer, SkColorFilter* inner)
+ : fOuter(SkRef(outer))
+ , fInner(SkRef(inner))
+ {}
+
+ uint32_t getFlags() const SK_OVERRIDE {
+ // Can only claim alphaunchanged and 16bit support if both our proxys do.
+ return fOuter->getFlags() & fInner->getFlags();
+ }
+
+ void filterSpan(const SkPMColor shader[], int count, SkPMColor result[]) const SK_OVERRIDE {
+ fInner->filterSpan(shader, count, result);
+ fOuter->filterSpan(result, count, result);
+ }
+
+ void filterSpan16(const uint16_t shader[], int count, uint16_t result[]) const SK_OVERRIDE {
+ SkASSERT(this->getFlags() & kHasFilter16_Flag);
+ fInner->filterSpan16(shader, count, result);
+ fOuter->filterSpan16(result, count, result);
+ }
+
+#ifndef SK_IGNORE_TO_STRING
+ void toString(SkString* str) const SK_OVERRIDE {
+ SkString outerS, innerS;
+ fOuter->toString(&outerS);
+ fInner->toString(&innerS);
+ str->appendf("SkComposeColorFilter: outer(%s) inner(%s)", outerS.c_str(), innerS.c_str());
+ }
+#endif
+
+#if 0 // TODO: should we support composing the fragments?
+#if SK_SUPPORT_GPU
+ GrFragmentProcessor* asFragmentProcessor(GrContext*) const SK_OVERRIDE;
+#endif
+#endif
+
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposeColorFilter)
+
+protected:
+ void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE {
+ buffer.writeFlattenable(fOuter);
+ buffer.writeFlattenable(fInner);
+ }
+
+private:
+ SkAutoTUnref<SkColorFilter> fOuter;
+ SkAutoTUnref<SkColorFilter> fInner;
+
+ friend class SkColorFilter;
+
+ typedef SkColorFilter INHERITED;
+};
+
+SkFlattenable* SkComposeColorFilter::CreateProc(SkReadBuffer& buffer) {
+ SkAutoTUnref<SkColorFilter> outer(buffer.readColorFilter());
+ SkAutoTUnref<SkColorFilter> inner(buffer.readColorFilter());
+ return CreateComposeFilter(outer, inner);
+}
+
+SkColorFilter* SkColorFilter::CreateComposeFilter(SkColorFilter* outer, SkColorFilter* inner) {
+ if (!outer) {
+ return SkSafeRef(inner);
+ }
+ if (!inner) {
+ return SkSafeRef(outer);
+ }
+ return SkNEW_ARGS(SkComposeColorFilter, (outer, inner));
+}
+
+SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkColorFilter)
+SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposeColorFilter)
+SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
+
diff --git a/src/effects/SkColorFilters.cpp b/src/effects/SkColorFilters.cpp
index 95041b5b57..10e6958570 100644
--- a/src/effects/SkColorFilters.cpp
+++ b/src/effects/SkColorFilters.cpp
@@ -8,6 +8,7 @@
#include "SkBlitRow.h"
#include "SkColorFilter.h"
#include "SkColorPriv.h"
+#include "SkModeColorFilter.h"
#include "SkReadBuffer.h"
#include "SkWriteBuffer.h"
#include "SkUtils.h"
@@ -15,93 +16,49 @@
#include "SkValidationUtils.h"
#include "SkColorMatrixFilter.h"
-// baseclass for filters that store a color and mode
-class SkModeColorFilter : public SkColorFilter {
-public:
- SkModeColorFilter(SkColor color, SkXfermode::Mode mode) {
- fColor = color;
- fMode = mode;
- this->updateCache();
- };
-
- SkColor getColor() const { return fColor; }
- SkXfermode::Mode getMode() const { return fMode; }
- SkPMColor getPMColor() const { return fPMColor; }
-
- bool asColorMode(SkColor* color, SkXfermode::Mode* mode) const SK_OVERRIDE {
- if (color) {
- *color = fColor;
- }
- if (mode) {
- *mode = fMode;
- }
- return true;
- }
-
- uint32_t getFlags() const SK_OVERRIDE {
- return fProc16 ? (kAlphaUnchanged_Flag | kHasFilter16_Flag) : 0;
- }
-
- virtual void filterSpan(const SkPMColor shader[], int count,
- SkPMColor result[]) const SK_OVERRIDE {
- SkPMColor color = fPMColor;
- SkXfermodeProc proc = fProc;
-
- for (int i = 0; i < count; i++) {
- result[i] = proc(color, shader[i]);
- }
- }
-
- virtual void filterSpan16(const uint16_t shader[], int count,
- uint16_t result[]) const SK_OVERRIDE {
- SkASSERT(this->getFlags() & kHasFilter16_Flag);
-
- SkPMColor color = fPMColor;
- SkXfermodeProc16 proc16 = fProc16;
-
- for (int i = 0; i < count; i++) {
- result[i] = proc16(color, shader[i]);
- }
+bool SkModeColorFilter::asColorMode(SkColor* color, SkXfermode::Mode* mode) const {
+ if (color) {
+ *color = fColor;
}
-
-#ifndef SK_IGNORE_TO_STRING
- void toString(SkString* str) const SK_OVERRIDE {
- str->append("SkModeColorFilter: color: 0x");
- str->appendHex(fColor);
- str->append(" mode: ");
- str->append(SkXfermode::ModeName(fMode));
+ if (mode) {
+ *mode = fMode;
}
-#endif
+ return true;
+}
-#if SK_SUPPORT_GPU
- GrFragmentProcessor* asFragmentProcessor(GrContext*) const SK_OVERRIDE;
-#endif
- SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkModeColorFilter)
+uint32_t SkModeColorFilter::getFlags() const {
+ return fProc16 ? (kAlphaUnchanged_Flag | kHasFilter16_Flag) : 0;
+}
-protected:
- void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE {
- buffer.writeColor(fColor);
- buffer.writeUInt(fMode);
+void SkModeColorFilter::filterSpan(const SkPMColor shader[], int count, SkPMColor result[]) const {
+ SkPMColor color = fPMColor;
+ SkXfermodeProc proc = fProc;
+
+ for (int i = 0; i < count; i++) {
+ result[i] = proc(color, shader[i]);
}
+}
-private:
- SkColor fColor;
- SkXfermode::Mode fMode;
- // cache
- SkPMColor fPMColor;
- SkXfermodeProc fProc;
- SkXfermodeProc16 fProc16;
-
- void updateCache() {
- fPMColor = SkPreMultiplyColor(fColor);
- fProc = SkXfermode::GetProc(fMode);
- fProc16 = SkXfermode::GetProc16(fMode, fColor);
+void SkModeColorFilter::filterSpan16(const uint16_t shader[], int count, uint16_t result[]) const {
+ SkASSERT(this->getFlags() & kHasFilter16_Flag);
+
+ SkPMColor color = fPMColor;
+ SkXfermodeProc16 proc16 = fProc16;
+
+ for (int i = 0; i < count; i++) {
+ result[i] = proc16(color, shader[i]);
}
+}
+void SkModeColorFilter::flatten(SkWriteBuffer& buffer) const {
+ buffer.writeColor(fColor);
+ buffer.writeUInt(fMode);
+}
- friend class SkColorFilter;
-
- typedef SkColorFilter INHERITED;
-};
+void SkModeColorFilter::updateCache() {
+ fPMColor = SkPreMultiplyColor(fColor);
+ fProc = SkXfermode::GetProc(fMode);
+ fProc16 = SkXfermode::GetProc16(fMode, fColor);
+}
SkFlattenable* SkModeColorFilter::CreateProc(SkReadBuffer& buffer) {
SkColor color = buffer.readColor();
@@ -549,6 +506,3 @@ SkColorFilter* SkColorFilter::CreateLightingFilter(SkColor mul, SkColor add) {
return SkColorMatrixFilter::Create(matrix);
}
-SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkColorFilter)
- SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkModeColorFilter)
-SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
diff --git a/src/ports/SkGlobalInitialization_chromium.cpp b/src/ports/SkGlobalInitialization_chromium.cpp
index f3e16db12c..0f7d71b207 100644
--- a/src/ports/SkGlobalInitialization_chromium.cpp
+++ b/src/ports/SkGlobalInitialization_chromium.cpp
@@ -46,6 +46,7 @@
#include "SkMagnifierImageFilter.h"
#include "SkMatrixConvolutionImageFilter.h"
#include "SkMergeImageFilter.h"
+#include "SkModeColorFilter.h"
#include "SkMorphologyImageFilter.h"
#include "SkOffsetImageFilter.h"
#include "SkOnce.h"
@@ -89,6 +90,7 @@ public:
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLumaColorFilter)
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPath1DPathEffect)
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLine2DPathEffect)
+ SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkModeColorFilter)
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPath2DPathEffect)
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPerlinNoiseShader)
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPictureImageFilter)
diff --git a/src/ports/SkGlobalInitialization_default.cpp b/src/ports/SkGlobalInitialization_default.cpp
index f3e16db12c..0f7d71b207 100644
--- a/src/ports/SkGlobalInitialization_default.cpp
+++ b/src/ports/SkGlobalInitialization_default.cpp
@@ -46,6 +46,7 @@
#include "SkMagnifierImageFilter.h"
#include "SkMatrixConvolutionImageFilter.h"
#include "SkMergeImageFilter.h"
+#include "SkModeColorFilter.h"
#include "SkMorphologyImageFilter.h"
#include "SkOffsetImageFilter.h"
#include "SkOnce.h"
@@ -89,6 +90,7 @@ public:
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLumaColorFilter)
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPath1DPathEffect)
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLine2DPathEffect)
+ SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkModeColorFilter)
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPath2DPathEffect)
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPerlinNoiseShader)
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPictureImageFilter)