Implement SkColorFilter::asColorMatrix() virtual, and override in

SkColorMatrixFilter.  Implement missing SkColorMatrixFilter::setMatrix() and
setArray() functions (were in .h, just not implemented).  Add a gm for color
matrix filters.

Review URL:  http://codereview.appspot.com/5500044/



git-svn-id: http://skia.googlecode.com/svn/trunk@2909 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
senorblanco@chromium.org 2011-12-20 20:58:18 +00:00
parent 9d0c6ecb84
commit e5ff3cefe0
6 changed files with 141 additions and 0 deletions

104
gm/colormatrix.cpp Normal file
View File

@ -0,0 +1,104 @@
/*
* 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 "gm.h"
#include "SkColorMatrixFilter.h"
#define WIDTH 500
#define HEIGHT 500
namespace skiagm {
class ColorMatrixGM : public GM {
public:
ColorMatrixGM() {
this->setBGColor(0xFF808080);
fBitmap = createBitmap(64, 64);
}
protected:
virtual SkString onShortName() {
return SkString("colormatrix");
}
virtual SkISize onISize() {
return make_isize(WIDTH, HEIGHT);
}
SkBitmap createBitmap(int width, int height) {
SkBitmap bm;
bm.setConfig(SkBitmap::kARGB_8888_Config, width, height);
bm.allocPixels();
SkCanvas canvas(bm);
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
SkPaint paint;
paint.setColor(SkColorSetARGB(255, x * 255 / width, y * 255 / height, 0));
canvas.drawRect(SkRect::MakeXYWH(x, y, 1, 1), paint);
}
}
return bm;
}
virtual void onDraw(SkCanvas* canvas) {
SkPaint paint;
SkColorMatrix matrix;
SkColorMatrixFilter* filter = new SkColorMatrixFilter();
paint.setColorFilter(filter)->unref();
matrix.setIdentity();
filter->setMatrix(matrix);
canvas->drawBitmap(fBitmap, 0, 0, &paint);
matrix.setRotate(SkColorMatrix::kR_Axis, 90);
filter->setMatrix(matrix);
canvas->drawBitmap(fBitmap, 80, 0, &paint);
matrix.setRotate(SkColorMatrix::kG_Axis, 90);
filter->setMatrix(matrix);
canvas->drawBitmap(fBitmap, 160, 0, &paint);
matrix.setRotate(SkColorMatrix::kB_Axis, 90);
filter->setMatrix(matrix);
canvas->drawBitmap(fBitmap, 240, 0, &paint);
matrix.setSaturation(SkFloatToScalar(0.0f));
filter->setMatrix(matrix);
canvas->drawBitmap(fBitmap, 0, 80, &paint);
matrix.setSaturation(SkFloatToScalar(0.5f));
filter->setMatrix(matrix);
canvas->drawBitmap(fBitmap, 80, 80, &paint);
matrix.setSaturation(SkFloatToScalar(1.0f));
filter->setMatrix(matrix);
canvas->drawBitmap(fBitmap, 160, 80, &paint);
matrix.setSaturation(SkFloatToScalar(2.0f));
filter->setMatrix(matrix);
canvas->drawBitmap(fBitmap, 240, 80, &paint);
matrix.setRGB2YUV();
filter->setMatrix(matrix);
canvas->drawBitmap(fBitmap, 0, 160, &paint);
matrix.setYUV2RGB();
filter->setMatrix(matrix);
canvas->drawBitmap(fBitmap, 80, 160, &paint);
}
private:
SkBitmap fBitmap;
typedef GM INHERITED;
};
//////////////////////////////////////////////////////////////////////////////
static GM* MyFactory(void*) { return new ColorMatrixGM; }
static GMRegistry reg(MyFactory);
}

View File

@ -7,6 +7,7 @@
'../gm/bitmapfilters.cpp',
'../gm/bitmapscroll.cpp',
'../gm/blurs.cpp',
'../gm/colormatrix.cpp',
'../gm/complexclip.cpp',
'../gm/complexclip2.cpp',
'../gm/cubicpaths.cpp',

View File

@ -23,6 +23,13 @@ public:
*/
virtual bool asColorMode(SkColor* color, SkXfermode::Mode* mode);
/**
* If the filter can be represented by a 5x4 matrix, this
* returns true, and sets the matrix appropriately.
* If not, this returns false and ignores the parameter.
*/
virtual bool asColorMatrix(SkScalar matrix[20]);
/** Called with a scanline of colors, as if there was a shader installed.
The implementation writes out its filtered version into result[].
Note: shader and result may be the same buffer.

View File

@ -26,6 +26,7 @@ public:
virtual void filterSpan(const SkPMColor src[], int count, SkPMColor[]);
virtual void filterSpan16(const uint16_t src[], int count, uint16_t[]);
virtual uint32_t getFlags();
virtual bool asColorMatrix(SkScalar matrix[20]) SK_OVERRIDE;
// overrides for SkFlattenable
virtual void flatten(SkFlattenableWriteBuffer& buffer);

View File

@ -15,6 +15,10 @@ bool SkColorFilter::asColorMode(SkColor* color, SkXfermode::Mode* mode) {
return false;
}
bool SkColorFilter::asColorMatrix(SkScalar matrix[20]) {
return false;
}
void SkColorFilter::filterSpan16(const uint16_t s[], int count, uint16_t d[]) {
SkASSERT(this->getFlags() & SkColorFilter::kHasFilter16_Flag);
SkASSERT(!"missing implementation of SkColorFilter::filterSpan16");

View File

@ -333,8 +333,32 @@ SkColorMatrixFilter::SkColorMatrixFilter(SkFlattenableReadBuffer& buffer)
fFlags = buffer.readU32();
}
bool SkColorMatrixFilter::asColorMatrix(SkScalar matrix[20]) {
int32_t* SK_RESTRICT array = fState.fArray;
for (int i = 0; i < 20; i++) {
matrix[i] = SkFixedToScalar(array[i]);
}
if (NULL != fProc) {
// Undo the offset applied to the constant column in setup().
SkScalar offset = SkFixedToScalar(1 << (fState.fShift - 1));
matrix[4] -= offset;
matrix[9] -= offset;
matrix[14] -= offset;
matrix[19] -= offset;
}
return true;
}
SkFlattenable* SkColorMatrixFilter::CreateProc(SkFlattenableReadBuffer& buf) {
return SkNEW_ARGS(SkColorMatrixFilter, (buf));
}
void SkColorMatrixFilter::setMatrix(const SkColorMatrix& matrix) {
setup(matrix.fMat);
}
void SkColorMatrixFilter::setArray(const SkScalar array[20]) {
setup(array);
}
SK_DEFINE_FLATTENABLE_REGISTRAR(SkColorMatrixFilter)