add compose-colorfilter
now with serialization registration
This reverts commit 5bd055c038
.
BUG=skia:
TBR=
Review URL: https://codereview.chromium.org/970753002
This commit is contained in:
parent
5bd055c038
commit
db873d8677
@ -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)} };
|
||||
SkColor colors[] = {
|
||||
SK_ColorBLACK, SK_ColorGREEN, SK_ColorCYAN,
|
||||
SK_ColorRED, 0, SK_ColorBLUE, SK_ColorWHITE
|
||||
};
|
||||
SkShader* s = SkGradientShader::CreateLinear(pts, colors, NULL, SK_ARRAY_COUNT(colors),
|
||||
SkShader::kClamp_TileMode);
|
||||
paint.setShader(s)->unref();
|
||||
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_ColorRED, SK_ColorGREEN, SK_ColorBLUE,
|
||||
};
|
||||
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; )
|
||||
|
||||
|
@ -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.
|
||||
*/
|
||||
|
63
include/effects/SkModeColorFilter.h
Normal file
63
include/effects/SkModeColorFilter.h
Normal file
@ -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
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
bool SkModeColorFilter::asColorMode(SkColor* color, SkXfermode::Mode* mode) const {
|
||||
if (color) {
|
||||
*color = fColor;
|
||||
}
|
||||
|
||||
uint32_t getFlags() const SK_OVERRIDE {
|
||||
return fProc16 ? (kAlphaUnchanged_Flag | kHasFilter16_Flag) : 0;
|
||||
if (mode) {
|
||||
*mode = fMode;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void filterSpan(const SkPMColor shader[], int count,
|
||||
SkPMColor result[]) const SK_OVERRIDE {
|
||||
SkPMColor color = fPMColor;
|
||||
SkXfermodeProc proc = fProc;
|
||||
uint32_t SkModeColorFilter::getFlags() const {
|
||||
return fProc16 ? (kAlphaUnchanged_Flag | kHasFilter16_Flag) : 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
result[i] = proc(color, shader[i]);
|
||||
}
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
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]);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
#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& buffer) const SK_OVERRIDE {
|
||||
buffer.writeColor(fColor);
|
||||
buffer.writeUInt(fMode);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user