Implement SkColorFilter::asColorMatrix() virtual, and override in
authorsenorblanco@chromium.org <senorblanco@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 20 Dec 2011 20:58:18 +0000 (20:58 +0000)
committersenorblanco@chromium.org <senorblanco@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 20 Dec 2011 20:58:18 +0000 (20:58 +0000)
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

gm/colormatrix.cpp [new file with mode: 0644]
gyp/gmslides.gypi
include/core/SkColorFilter.h
include/effects/SkColorMatrixFilter.h
src/core/SkColorFilter.cpp
src/effects/SkColorMatrixFilter.cpp

diff --git a/gm/colormatrix.cpp b/gm/colormatrix.cpp
new file mode 100644 (file)
index 0000000..2c6e44c
--- /dev/null
@@ -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);
+
+}
index 9e86b0f..9d4a664 100644 (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',
index e346996..6328e70 100644 (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.
index 32ae7df..d5f87d0 100644 (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);
index d3f5faa..e91488b 100644 (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");
index a58e06d..5ed8698 100644 (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)