New SkRectShaderImageFilter image filter
This new changelist also introduces a new image filter called SkRectShaderImageFilter which is make to simply apply a shader on a region without using any inputs. TEST=Added ShaderImageFilter test Review URL: https://codereview.appspot.com/7300046 git-svn-id: http://skia.googlecode.com/svn/trunk@7808 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
ee3bc3b267
commit
a1c511b870
@ -43,6 +43,7 @@
|
||||
'<(skia_src_path)/effects/SkPaintFlagsDrawFilter.cpp',
|
||||
'<(skia_src_path)/effects/SkPixelXorXfermode.cpp',
|
||||
'<(skia_src_path)/effects/SkPorterDuff.cpp',
|
||||
'<(skia_src_path)/effects/SkRectShaderImageFilter.cpp',
|
||||
'<(skia_src_path)/effects/SkStippleMaskFilter.cpp',
|
||||
'<(skia_src_path)/effects/SkTableColorFilter.cpp',
|
||||
'<(skia_src_path)/effects/SkTableMaskFilter.cpp',
|
||||
@ -97,6 +98,7 @@
|
||||
'<(skia_include_path)/effects/SkPaintFlagsDrawFilter.h',
|
||||
'<(skia_include_path)/effects/SkPixelXorXfermode.h',
|
||||
'<(skia_include_path)/effects/SkPorterDuff.h',
|
||||
'<(skia_include_path)/effects/SkRectShaderImageFilter.h',
|
||||
'<(skia_include_path)/effects/SkStippleMaskFilter.h',
|
||||
'<(skia_include_path)/effects/SkTableColorFilter.h',
|
||||
'<(skia_include_path)/effects/SkTableMaskFilter.h',
|
||||
|
@ -88,6 +88,7 @@
|
||||
'../tests/RTreeTest.cpp',
|
||||
'../tests/SHA1Test.cpp',
|
||||
'../tests/ScalarTest.cpp',
|
||||
'../tests/ShaderImageFilterTest.cpp',
|
||||
'../tests/ShaderOpacityTest.cpp',
|
||||
'../tests/Sk64Test.cpp',
|
||||
'../tests/skia_test.cpp',
|
||||
|
@ -16,6 +16,7 @@ class SkDevice;
|
||||
class SkMatrix;
|
||||
struct SkIPoint;
|
||||
struct SkIRect;
|
||||
class SkShader;
|
||||
class GrEffectRef;
|
||||
class GrTexture;
|
||||
|
||||
@ -112,10 +113,12 @@ public:
|
||||
virtual bool filterImageGPU(Proxy*, const SkBitmap& src, SkBitmap* result);
|
||||
|
||||
/**
|
||||
* Returns this image filter as a color filter if possible,
|
||||
* NULL otherwise.
|
||||
* Returns whether this image filter is a color filter and puts the color filter into the
|
||||
* "filter" parameter if it can. Does nothing otherwise.
|
||||
* If this function returns a non NULL *filter value, then the SkColorFilter object has been
|
||||
* refed within this function and the caller will need to call unref() later on.
|
||||
*/
|
||||
virtual SkColorFilter* asColorFilter() const;
|
||||
virtual bool asColorFilter(SkColorFilter** filter) const;
|
||||
|
||||
/**
|
||||
* Returns the number of inputs this filter will accept (some inputs can
|
||||
|
@ -26,7 +26,7 @@ protected:
|
||||
virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&,
|
||||
SkBitmap* result, SkIPoint* loc) SK_OVERRIDE;
|
||||
|
||||
virtual SkColorFilter* asColorFilter() const SK_OVERRIDE;
|
||||
virtual bool asColorFilter(SkColorFilter**) const SK_OVERRIDE;
|
||||
|
||||
private:
|
||||
SkColorFilterImageFilter(SkColorFilter* cf, SkImageFilter* input);
|
||||
|
43
include/effects/SkRectShaderImageFilter.h
Normal file
43
include/effects/SkRectShaderImageFilter.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2013 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkRectShaderImageFilter_DEFINED
|
||||
#define SkRectShaderImageFilter_DEFINED
|
||||
|
||||
#include "SkImageFilter.h"
|
||||
#include "SkRect.h"
|
||||
|
||||
class SkShader;
|
||||
|
||||
class SK_API SkRectShaderImageFilter : public SkImageFilter {
|
||||
public:
|
||||
/**
|
||||
* The SkShader object will have its refcnt increased as it becomes a member of the
|
||||
* SkRectShaderImageFilter object returned by this function. It cannot be NULL.
|
||||
* The region parameter is used to specify on which region the shader is applied.
|
||||
*/
|
||||
static SkRectShaderImageFilter* Create(SkShader* s, SkRect region);
|
||||
virtual ~SkRectShaderImageFilter();
|
||||
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkRectShaderImageFilter)
|
||||
|
||||
protected:
|
||||
SkRectShaderImageFilter(SkFlattenableReadBuffer& buffer);
|
||||
virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
|
||||
|
||||
virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&,
|
||||
SkBitmap* result, SkIPoint* loc) SK_OVERRIDE;
|
||||
|
||||
private:
|
||||
SkRectShaderImageFilter(SkShader* s, SkRect region);
|
||||
SkShader* fShader;
|
||||
SkRect fRegion;
|
||||
|
||||
typedef SkImageFilter INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
@ -122,6 +122,6 @@ bool SkImageFilter::asNewEffect(GrEffectRef**, GrTexture*) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
SkColorFilter* SkImageFilter::asColorFilter() const {
|
||||
return NULL;
|
||||
bool SkImageFilter::asColorFilter(SkColorFilter**) const {
|
||||
return false;
|
||||
}
|
||||
|
@ -62,16 +62,17 @@ SkColorFilterImageFilter* SkColorFilterImageFilter::Create(SkColorFilter* cf,
|
||||
SkScalar colorMatrix[20], inputMatrix[20];
|
||||
SkColorFilter* inputColorFilter;
|
||||
if (input && cf->asColorMatrix(colorMatrix)
|
||||
&& (inputColorFilter = input->asColorFilter())
|
||||
&& inputColorFilter->asColorMatrix(inputMatrix)
|
||||
&& !matrix_needs_clamping(inputMatrix)) {
|
||||
SkScalar combinedMatrix[20];
|
||||
mult_color_matrix(inputMatrix, colorMatrix, combinedMatrix);
|
||||
SkAutoTUnref<SkColorFilter> newCF(SkNEW_ARGS(SkColorMatrixFilter, (combinedMatrix)));
|
||||
return SkNEW_ARGS(SkColorFilterImageFilter, (newCF, input->getInput(0)));
|
||||
} else {
|
||||
return SkNEW_ARGS(SkColorFilterImageFilter, (cf, input));
|
||||
&& input->asColorFilter(&inputColorFilter)
|
||||
&& (NULL != inputColorFilter)) {
|
||||
SkAutoUnref autoUnref(inputColorFilter);
|
||||
if (inputColorFilter->asColorMatrix(inputMatrix) && !matrix_needs_clamping(inputMatrix)) {
|
||||
SkScalar combinedMatrix[20];
|
||||
mult_color_matrix(inputMatrix, colorMatrix, combinedMatrix);
|
||||
SkAutoTUnref<SkColorFilter> newCF(SkNEW_ARGS(SkColorMatrixFilter, (combinedMatrix)));
|
||||
return SkNEW_ARGS(SkColorFilterImageFilter, (newCF, input->getInput(0)));
|
||||
}
|
||||
}
|
||||
return SkNEW_ARGS(SkColorFilterImageFilter, (cf, input));
|
||||
}
|
||||
|
||||
SkColorFilterImageFilter::SkColorFilterImageFilter(SkColorFilter* cf, SkImageFilter* input) : INHERITED(input), fColorFilter(cf) {
|
||||
@ -110,6 +111,10 @@ bool SkColorFilterImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& sourc
|
||||
return true;
|
||||
}
|
||||
|
||||
SkColorFilter* SkColorFilterImageFilter::asColorFilter() const {
|
||||
return fColorFilter;
|
||||
bool SkColorFilterImageFilter::asColorFilter(SkColorFilter** filter) const {
|
||||
if (filter) {
|
||||
*filter = fColorFilter;
|
||||
fColorFilter->ref();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
58
src/effects/SkRectShaderImageFilter.cpp
Normal file
58
src/effects/SkRectShaderImageFilter.cpp
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2013 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "SkRectShaderImageFilter.h"
|
||||
#include "SkBitmap.h"
|
||||
#include "SkCanvas.h"
|
||||
#include "SkDevice.h"
|
||||
#include "SkFlattenableBuffers.h"
|
||||
#include "SkShader.h"
|
||||
|
||||
SkRectShaderImageFilter* SkRectShaderImageFilter::Create(SkShader* s, SkRect region) {
|
||||
SkASSERT(s);
|
||||
return SkNEW_ARGS(SkRectShaderImageFilter, (s, region));
|
||||
}
|
||||
|
||||
SkRectShaderImageFilter::SkRectShaderImageFilter(SkShader* s, SkRect region)
|
||||
: INHERITED(NULL)
|
||||
, fShader(s)
|
||||
, fRegion(region) {
|
||||
SkASSERT(s);
|
||||
SkSafeRef(s);
|
||||
}
|
||||
|
||||
SkRectShaderImageFilter::SkRectShaderImageFilter(SkFlattenableReadBuffer& buffer)
|
||||
: INHERITED(buffer) {
|
||||
fShader = buffer.readFlattenableT<SkShader>();
|
||||
buffer.readRect(&fRegion);
|
||||
}
|
||||
|
||||
void SkRectShaderImageFilter::flatten(SkFlattenableWriteBuffer& buffer) const {
|
||||
this->INHERITED::flatten(buffer);
|
||||
|
||||
buffer.writeFlattenable(fShader);
|
||||
buffer.writeRect(fRegion);
|
||||
}
|
||||
|
||||
SkRectShaderImageFilter::~SkRectShaderImageFilter() {
|
||||
SkSafeUnref(fShader);
|
||||
}
|
||||
|
||||
bool SkRectShaderImageFilter::onFilterImage(Proxy* proxy,
|
||||
const SkBitmap& source,
|
||||
const SkMatrix& matrix,
|
||||
SkBitmap* result,
|
||||
SkIPoint* loc) {
|
||||
SkAutoTUnref<SkDevice> device(proxy->createDevice(fRegion.width(), fRegion.height()));
|
||||
SkCanvas canvas(device.get());
|
||||
SkPaint paint;
|
||||
paint.setShader(fShader);
|
||||
canvas.drawRect(fRegion, paint);
|
||||
*result = device.get()->accessBitmap(false);
|
||||
return true;
|
||||
}
|
||||
|
64
tests/ShaderImageFilterTest.cpp
Normal file
64
tests/ShaderImageFilterTest.cpp
Normal file
@ -0,0 +1,64 @@
|
||||
|
||||
/*
|
||||
* Copyright 2011 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
#include "Test.h"
|
||||
#include "SkCanvas.h"
|
||||
#include "SkShader.h"
|
||||
#include "SkRectShaderImageFilter.h"
|
||||
#include "SkGradientShader.h"
|
||||
|
||||
static void test_asShaderMode(skiatest::Reporter* reporter) {
|
||||
SkRect r = SkRect::MakeWH(10, 10); // Make small 10x10 gradient
|
||||
|
||||
SkBitmap filterResult, shaderResult;
|
||||
|
||||
filterResult.setConfig(SkBitmap::kARGB_8888_Config, r.width(), r.height());
|
||||
filterResult.allocPixels();
|
||||
SkCanvas canvasFilter(filterResult);
|
||||
canvasFilter.clear(0x00000000);
|
||||
|
||||
shaderResult.setConfig(SkBitmap::kARGB_8888_Config, r.width(), r.height());
|
||||
shaderResult.allocPixels();
|
||||
SkCanvas canvasShader(shaderResult);
|
||||
canvasShader.clear(0x00000000);
|
||||
|
||||
SkPoint center = SkPoint::Make(SkIntToScalar(5), SkIntToScalar(5));
|
||||
SkColor colors[] = {SK_ColorBLUE, SK_ColorRED, SK_ColorGREEN};
|
||||
SkScalar pos[] = {0, SK_ScalarHalf, SK_Scalar1};
|
||||
SkScalar radius = SkIntToScalar(5);
|
||||
|
||||
// Test using the image filter
|
||||
{
|
||||
SkShader* s = SkGradientShader::CreateRadial(
|
||||
center, radius, colors, pos, SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode);
|
||||
SkPaint paint;
|
||||
paint.setImageFilter(SkRectShaderImageFilter::Create(s, r))->unref();
|
||||
canvasFilter.drawRect(r, paint);
|
||||
s->unref();
|
||||
}
|
||||
|
||||
// Test using the shader directly
|
||||
{
|
||||
SkShader* s = SkGradientShader::CreateRadial(
|
||||
center, radius, colors, pos, SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode);
|
||||
SkPaint paint;
|
||||
paint.setShader(s)->unref();
|
||||
canvasShader.drawRect(r, paint);
|
||||
}
|
||||
|
||||
// Assert that both paths yielded the same result
|
||||
for (int y = 0; y < r.height(); ++y) {
|
||||
const SkPMColor* filterPtr = filterResult.getAddr32(0, y);
|
||||
const SkPMColor* shaderPtr = shaderResult.getAddr32(0, y);
|
||||
for (int x = 0; x < r.width(); ++x, ++filterPtr, ++shaderPtr) {
|
||||
REPORTER_ASSERT(reporter, *filterPtr == *shaderPtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#include "TestClassDef.h"
|
||||
DEFINE_TESTCLASS("ShaderImageFilter", ShaderImageFilterTestClass, test_asShaderMode)
|
Loading…
Reference in New Issue
Block a user