aboutsummaryrefslogtreecommitdiffhomepage
path: root/gm/imagefilterscropped.cpp
diff options
context:
space:
mode:
authorGravatar senorblanco@chromium.org <senorblanco@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-07-22 20:03:22 +0000
committerGravatar senorblanco@chromium.org <senorblanco@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-07-22 20:03:22 +0000
commitccf225cebb68f9dbd8e353ba0ded247f7e8915ec (patch)
tree1c92c05d4ff012766ca266d90496301772267553 /gm/imagefilterscropped.cpp
parent49a07ad0977fb118fe91f5c908b6703e2d89dec6 (diff)
This patch implements a crop rect for SkImageFilter. It has been implemented for SkColorFilterImageFilter and SkBlurImageFilter as examples.
In order to preserve the immutability of SkImageFilters, the crop rect is passed as a constructor parameter. If NULL (the default), the bounds of the input image are used, as before. This also tightens up the boundary handling for SkImageBlurFilter on the GPU backend. Where we were previously using clamping semantics, we now respect decal semantics (so we don't oversaturate the edges). This brings the GPU and raster backends into closer alignment, but will require some new baselines for the GPU tests. At a minimum, the following tests will need new baselines: imageblur, imagefiltersbase, imagefilterscropped, spritebitmap. R=reed@google.com Review URL: https://codereview.chromium.org/19775006 git-svn-id: http://skia.googlecode.com/svn/trunk@10251 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'gm/imagefilterscropped.cpp')
-rw-r--r--gm/imagefilterscropped.cpp176
1 files changed, 176 insertions, 0 deletions
diff --git a/gm/imagefilterscropped.cpp b/gm/imagefilterscropped.cpp
new file mode 100644
index 0000000000..f1ede2fefd
--- /dev/null
+++ b/gm/imagefilterscropped.cpp
@@ -0,0 +1,176 @@
+/*
+ * 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 "SkCanvas.h"
+#include "SkColorFilter.h"
+#include "SkColorPriv.h"
+#include "SkShader.h"
+
+#include "SkBlurImageFilter.h"
+#include "SkColorFilterImageFilter.h"
+#include "SkTestImageFilters.h"
+
+///////////////////////////////////////////////////////////////////////////////
+
+static void draw_paint(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
+ SkPaint paint;
+ paint.setImageFilter(imf);
+ paint.setColor(SK_ColorBLACK);
+ canvas->save();
+ canvas->clipRect(r);
+ canvas->drawPaint(paint);
+ canvas->restore();
+}
+
+static void draw_path(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
+ SkPaint paint;
+ paint.setColor(SK_ColorMAGENTA);
+ paint.setImageFilter(imf);
+ paint.setAntiAlias(true);
+ canvas->save();
+ canvas->clipRect(r);
+ canvas->drawCircle(r.centerX(), r.centerY(), r.width()*2/5, paint);
+ canvas->restore();
+}
+
+static void draw_text(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
+ SkPaint paint;
+ paint.setImageFilter(imf);
+ paint.setColor(SK_ColorGREEN);
+ paint.setAntiAlias(true);
+ paint.setTextSize(r.height()/2);
+ paint.setTextAlign(SkPaint::kCenter_Align);
+ canvas->save();
+ canvas->clipRect(r);
+ canvas->drawText("Text", 4, r.centerX(), r.centerY(), paint);
+ canvas->restore();
+}
+
+static void draw_bitmap(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
+ SkPaint paint;
+
+ SkIRect bounds;
+ r.roundOut(&bounds);
+
+ SkBitmap bm;
+ bm.setConfig(SkBitmap::kARGB_8888_Config, bounds.width(), bounds.height());
+ bm.allocPixels();
+ bm.eraseColor(SK_ColorTRANSPARENT);
+ SkCanvas c(bm);
+ draw_path(&c, r, NULL);
+
+ paint.setImageFilter(imf);
+ canvas->save();
+ canvas->clipRect(r);
+ canvas->drawBitmap(bm, 0, 0, &paint);
+ canvas->restore();
+}
+
+static void draw_sprite(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
+ SkPaint paint;
+
+ SkIRect bounds;
+ r.roundOut(&bounds);
+
+ SkBitmap bm;
+ bm.setConfig(SkBitmap::kARGB_8888_Config, bounds.width(), bounds.height());
+ bm.allocPixels();
+ bm.eraseColor(SK_ColorRED);
+ SkCanvas c(bm);
+
+ SkIRect cropRect = SkIRect::MakeXYWH(10, 10, 44, 44);
+ paint.setColor(SK_ColorGREEN);
+ c.drawRect(SkRect::Make(cropRect), paint);
+
+ paint.setImageFilter(imf);
+ SkPoint loc = { r.fLeft, r.fTop };
+ canvas->getTotalMatrix().mapPoints(&loc, 1);
+ canvas->drawSprite(bm,
+ SkScalarRoundToInt(loc.fX), SkScalarRoundToInt(loc.fY),
+ &paint);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+class ImageFiltersCroppedGM : public skiagm::GM {
+public:
+ ImageFiltersCroppedGM () {}
+
+protected:
+
+ virtual SkString onShortName() {
+ return SkString("imagefilterscropped");
+ }
+
+ virtual SkISize onISize() { return SkISize::Make(700, 460); }
+
+ void draw_frame(SkCanvas* canvas, const SkRect& r) {
+ SkPaint paint;
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setColor(SK_ColorRED);
+ canvas->drawRect(r, paint);
+ }
+
+ virtual uint32_t onGetFlags() const {
+ // Because of the use of drawSprite, this test is excluded
+ // from scaled replay tests because drawSprite ignores the
+ // reciprocal scale that is applied at record time, which is
+ // the intended behavior of drawSprite.
+ return kSkipScaledReplay_Flag;
+ }
+
+ virtual void onDraw(SkCanvas* canvas) {
+ void (*drawProc[])(SkCanvas*, const SkRect&, SkImageFilter*) = {
+ draw_sprite, draw_bitmap, draw_path, draw_paint, draw_text
+ };
+
+ SkColorFilter* cf = SkColorFilter::CreateModeFilter(SK_ColorRED,
+ SkXfermode::kSrcIn_Mode);
+ SkIRect cropRect = SkIRect::MakeXYWH(10, 10, 44, 44);
+ SkIRect bogusRect = SkIRect::MakeXYWH(-100, -100, 10, 10);
+
+ SkImageFilter* filters[] = {
+ NULL,
+ SkColorFilterImageFilter::Create(cf, NULL, &cropRect),
+ new SkBlurImageFilter(8.0f, 0.0f, NULL, &cropRect),
+ new SkBlurImageFilter(0.0f, 8.0f, NULL, &cropRect),
+ new SkBlurImageFilter(8.0f, 8.0f, NULL, &cropRect),
+ new SkBlurImageFilter(8.0f, 8.0f, NULL, &bogusRect),
+ SkColorFilterImageFilter::Create(cf, NULL, &bogusRect),
+ };
+ cf->unref();
+
+ SkRect r = SkRect::MakeWH(SkIntToScalar(64), SkIntToScalar(64));
+ SkScalar MARGIN = SkIntToScalar(16);
+ SkScalar DX = r.width() + MARGIN;
+ SkScalar DY = r.height() + MARGIN;
+
+ canvas->translate(MARGIN, MARGIN);
+ for (size_t i = 0; i < SK_ARRAY_COUNT(filters); ++i) {
+ canvas->save();
+ for (size_t j = 0; j < SK_ARRAY_COUNT(drawProc); ++j) {
+ drawProc[j](canvas, r, filters[i]);
+ canvas->translate(0, DY);
+ }
+ canvas->restore();
+ canvas->translate(DX, 0);
+ }
+
+ for(size_t j = 0; j < SK_ARRAY_COUNT(filters); ++j) {
+ SkSafeUnref(filters[j]);
+ }
+ }
+
+private:
+ typedef GM INHERITED;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+static skiagm::GM* MyFactory(void*) { return new ImageFiltersCroppedGM; }
+static skiagm::GMRegistry reg(MyFactory);