xfermodeimagefilter.cpp revision 1a4fb70c8a04db2d92ec821555f91218a989031d
186fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org/*
286fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org * Copyright 2013 Google Inc.
386fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org *
486fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org * Use of this source code is governed by a BSD-style license that can be
586fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org * found in the LICENSE file.
686fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org */
786fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org
886fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org#include "gm.h"
986fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org#include "SkArithmeticMode.h"
107b320703d47ff2b242ae74faba5e4b0af3560d71commit-bot@chromium.org#include "SkOffsetImageFilter.h"
1186fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org#include "SkXfermodeImageFilter.h"
1286fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org#include "SkBitmapSource.h"
1386fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org
1486fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org#define WIDTH 600
1586fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org#define HEIGHT 600
1686fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org#define MARGIN 12
1786fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org
1886fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.orgnamespace skiagm {
1986fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org
2086fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.orgclass XfermodeImageFilterGM : public GM {
2186fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.orgpublic:
2286fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org    XfermodeImageFilterGM() : fInitialized(false) {
2386fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        this->setBGColor(0xFF000000);
2486fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org    }
2586fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org
2686fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.orgprotected:
2786fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org    virtual SkString onShortName() {
2886fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        return SkString("xfermodeimagefilter");
2986fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org    }
3086fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org
3186fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org    void make_bitmap() {
3286fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        fBitmap.setConfig(SkBitmap::kARGB_8888_Config, 80, 80);
3386fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        fBitmap.allocPixels();
341f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com        SkBitmapDevice device(fBitmap);
3586fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        SkCanvas canvas(&device);
3686fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        canvas.clear(0x00000000);
3786fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        SkPaint paint;
3886fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        paint.setAntiAlias(true);
3986fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        paint.setColor(0xD000D000);
4086fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        paint.setTextSize(SkIntToScalar(96));
4186fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        const char* str = "e";
4286fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        canvas.drawText(str, strlen(str), SkIntToScalar(15), SkIntToScalar(65), paint);
4386fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org    }
4486fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org
4586fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org    void make_checkerboard() {
4686fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        fCheckerboard.setConfig(SkBitmap::kARGB_8888_Config, 80, 80);
4786fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        fCheckerboard.allocPixels();
481f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com        SkBitmapDevice device(fCheckerboard);
4986fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        SkCanvas canvas(&device);
5086fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        canvas.clear(0x00000000);
5186fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        SkPaint darkPaint;
5286fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        darkPaint.setColor(0xFF404040);
5386fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        SkPaint lightPaint;
5486fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        lightPaint.setColor(0xFFA0A0A0);
5586fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        for (int y = 0; y < 80; y += 16) {
5686fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org          for (int x = 0; x < 80; x += 16) {
5786fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            canvas.save();
5886fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            canvas.translate(SkIntToScalar(x), SkIntToScalar(y));
5986fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            canvas.drawRect(SkRect::MakeXYWH(0, 0, 8, 8), darkPaint);
6086fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            canvas.drawRect(SkRect::MakeXYWH(8, 0, 8, 8), lightPaint);
6186fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            canvas.drawRect(SkRect::MakeXYWH(0, 8, 8, 8), lightPaint);
6286fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            canvas.drawRect(SkRect::MakeXYWH(8, 8, 8, 8), darkPaint);
6386fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            canvas.restore();
6486fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org          }
6586fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        }
6686fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org    }
6786fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org
6886fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org    virtual SkISize onISize() {
6986fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        return make_isize(WIDTH, HEIGHT);
7086fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org    }
7186fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org
727b320703d47ff2b242ae74faba5e4b0af3560d71commit-bot@chromium.org    void drawClippedBitmap(SkCanvas* canvas, const SkBitmap& bitmap, const SkPaint& paint,
737b320703d47ff2b242ae74faba5e4b0af3560d71commit-bot@chromium.org                           SkScalar x, SkScalar y) {
7486fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        canvas->save();
7586fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        canvas->clipRect(SkRect::MakeXYWH(x, y,
7686fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            SkIntToScalar(bitmap.width()), SkIntToScalar(bitmap.height())));
7786fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        canvas->drawBitmap(bitmap, x, y, &paint);
7886fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        canvas->restore();
7986fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org    }
8086fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org
8186fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org    virtual void onDraw(SkCanvas* canvas) {
8286fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        if (!fInitialized) {
8386fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            make_bitmap();
8486fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            make_checkerboard();
8586fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            fInitialized = true;
8686fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        }
8786fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        canvas->clear(0x00000000);
8886fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        SkPaint paint;
8986fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org
9086fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        const struct {
9186fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            SkXfermode::Mode  fMode;
9286fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            const char*         fLabel;
9386fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        } gModes[] = {
9486fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            { SkXfermode::kClear_Mode,    "Clear"     },
9586fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            { SkXfermode::kSrc_Mode,      "Src"       },
9686fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            { SkXfermode::kDst_Mode,      "Dst"       },
9786fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            { SkXfermode::kSrcOver_Mode,  "SrcOver"   },
9886fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            { SkXfermode::kDstOver_Mode,  "DstOver"   },
9986fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            { SkXfermode::kSrcIn_Mode,    "SrcIn"     },
10086fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            { SkXfermode::kDstIn_Mode,    "DstIn"     },
10186fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            { SkXfermode::kSrcOut_Mode,   "SrcOut"    },
10286fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            { SkXfermode::kDstOut_Mode,   "DstOut"    },
10386fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            { SkXfermode::kSrcATop_Mode,  "SrcATop"   },
10486fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            { SkXfermode::kDstATop_Mode,  "DstATop"   },
10586fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            { SkXfermode::kXor_Mode,      "Xor"       },
10686fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org
10786fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            { SkXfermode::kPlus_Mode,         "Plus"          },
10886fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            { SkXfermode::kModulate_Mode,     "Modulate"      },
10986fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            { SkXfermode::kScreen_Mode,       "Screen"        },
11086fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            { SkXfermode::kOverlay_Mode,      "Overlay"       },
11186fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            { SkXfermode::kDarken_Mode,       "Darken"        },
11286fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            { SkXfermode::kLighten_Mode,      "Lighten"       },
11386fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            { SkXfermode::kColorDodge_Mode,   "ColorDodge"    },
11486fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            { SkXfermode::kColorBurn_Mode,    "ColorBurn"     },
11586fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            { SkXfermode::kHardLight_Mode,    "HardLight"     },
11686fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            { SkXfermode::kSoftLight_Mode,    "SoftLight"     },
11786fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            { SkXfermode::kDifference_Mode,   "Difference"    },
11886fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            { SkXfermode::kExclusion_Mode,    "Exclusion"     },
11986fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            { SkXfermode::kMultiply_Mode,     "Multiply"      },
12086fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            { SkXfermode::kHue_Mode,          "Hue"           },
12186fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            { SkXfermode::kSaturation_Mode,   "Saturation"    },
12286fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            { SkXfermode::kColor_Mode,        "Color"         },
12386fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            { SkXfermode::kLuminosity_Mode,   "Luminosity"    },
12486fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        };
12586fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org
12686fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        int x = 0, y = 0;
12786fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        SkAutoTUnref<SkImageFilter> background(SkNEW_ARGS(SkBitmapSource, (fCheckerboard)));
12886fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        for (size_t i = 0; i < SK_ARRAY_COUNT(gModes); i++) {
12986fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            SkAutoTUnref<SkXfermode> mode(SkXfermode::Create(gModes[i].fMode));
1307b320703d47ff2b242ae74faba5e4b0af3560d71commit-bot@chromium.org            SkAutoTUnref<SkImageFilter> filter(SkNEW_ARGS(
1317b320703d47ff2b242ae74faba5e4b0af3560d71commit-bot@chromium.org                SkXfermodeImageFilter, (mode, background)));
13286fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            paint.setImageFilter(filter);
13386fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            drawClippedBitmap(canvas, fBitmap, paint, SkIntToScalar(x), SkIntToScalar(y));
13486fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            x += fBitmap.width() + MARGIN;
13586fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            if (x + fBitmap.width() > WIDTH) {
13686fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org                x = 0;
13786fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org                y += fBitmap.height() + MARGIN;
13886fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            }
13986fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        }
14086fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        // Test arithmetic mode as image filter
14186fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        SkAutoTUnref<SkXfermode> mode(SkArithmeticMode::Create(0, SK_Scalar1, SK_Scalar1, 0));
14286fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        SkAutoTUnref<SkImageFilter> filter(SkNEW_ARGS(SkXfermodeImageFilter, (mode, background)));
14386fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        paint.setImageFilter(filter);
14486fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        drawClippedBitmap(canvas, fBitmap, paint, SkIntToScalar(x), SkIntToScalar(y));
14586fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        x += fBitmap.width() + MARGIN;
14686fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        if (x + fBitmap.width() > WIDTH) {
14786fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            x = 0;
14886fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org            y += fBitmap.height() + MARGIN;
14986fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        }
15086fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        // Test NULL mode
15186fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        filter.reset(SkNEW_ARGS(SkXfermodeImageFilter, (NULL, background)));
15286fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        paint.setImageFilter(filter);
15386fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org        drawClippedBitmap(canvas, fBitmap, paint, SkIntToScalar(x), SkIntToScalar(y));
1547b320703d47ff2b242ae74faba5e4b0af3560d71commit-bot@chromium.org        x += fBitmap.width() + MARGIN;
1557b320703d47ff2b242ae74faba5e4b0af3560d71commit-bot@chromium.org        if (x + fBitmap.width() > WIDTH) {
1567b320703d47ff2b242ae74faba5e4b0af3560d71commit-bot@chromium.org            x = 0;
1577b320703d47ff2b242ae74faba5e4b0af3560d71commit-bot@chromium.org            y += fBitmap.height() + MARGIN;
1587b320703d47ff2b242ae74faba5e4b0af3560d71commit-bot@chromium.org        }
1597b320703d47ff2b242ae74faba5e4b0af3560d71commit-bot@chromium.org        // Test offsets on SrcMode (uses fixed-function blend)
1607b320703d47ff2b242ae74faba5e4b0af3560d71commit-bot@chromium.org        SkAutoTUnref<SkImageFilter> foreground(SkNEW_ARGS(SkBitmapSource, (fBitmap)));
1617b320703d47ff2b242ae74faba5e4b0af3560d71commit-bot@chromium.org        SkAutoTUnref<SkImageFilter> offsetForeground(SkNEW_ARGS(SkOffsetImageFilter,
1627b320703d47ff2b242ae74faba5e4b0af3560d71commit-bot@chromium.org            (SkIntToScalar(4), SkIntToScalar(-4), foreground)));
1637b320703d47ff2b242ae74faba5e4b0af3560d71commit-bot@chromium.org        SkAutoTUnref<SkImageFilter> offsetBackground(SkNEW_ARGS(SkOffsetImageFilter,
1647b320703d47ff2b242ae74faba5e4b0af3560d71commit-bot@chromium.org            (SkIntToScalar(4), SkIntToScalar(4), background)));
1657b320703d47ff2b242ae74faba5e4b0af3560d71commit-bot@chromium.org        mode.reset(SkXfermode::Create(SkXfermode::kSrcOver_Mode));
1667b320703d47ff2b242ae74faba5e4b0af3560d71commit-bot@chromium.org        filter.reset(SkNEW_ARGS(SkXfermodeImageFilter,
1677b320703d47ff2b242ae74faba5e4b0af3560d71commit-bot@chromium.org            (mode, offsetBackground, offsetForeground)));
1687b320703d47ff2b242ae74faba5e4b0af3560d71commit-bot@chromium.org        paint.setImageFilter(filter);
1697b320703d47ff2b242ae74faba5e4b0af3560d71commit-bot@chromium.org        canvas->save();
170de2e4e8a6422c7d8b5847f038f5c6360b187f7a2skia.committer@gmail.com        canvas->clipRect(SkRect::MakeXYWH(SkIntToScalar(x),
17131a40ef58b8eda59fd12b5e172683d8882acdc60robertphillips@google.com                                          SkIntToScalar(y),
172de2e4e8a6422c7d8b5847f038f5c6360b187f7a2skia.committer@gmail.com                                          SkIntToScalar(fBitmap.width() + 4),
17331a40ef58b8eda59fd12b5e172683d8882acdc60robertphillips@google.com                                          SkIntToScalar(fBitmap.height() + 4)));
1747b320703d47ff2b242ae74faba5e4b0af3560d71commit-bot@chromium.org        canvas->drawPaint(paint);
1757b320703d47ff2b242ae74faba5e4b0af3560d71commit-bot@chromium.org        canvas->restore();
1767b320703d47ff2b242ae74faba5e4b0af3560d71commit-bot@chromium.org        x += fBitmap.width() + MARGIN;
1777b320703d47ff2b242ae74faba5e4b0af3560d71commit-bot@chromium.org        if (x + fBitmap.width() > WIDTH) {
1787b320703d47ff2b242ae74faba5e4b0af3560d71commit-bot@chromium.org            x = 0;
1797b320703d47ff2b242ae74faba5e4b0af3560d71commit-bot@chromium.org            y += fBitmap.height() + MARGIN;
1807b320703d47ff2b242ae74faba5e4b0af3560d71commit-bot@chromium.org        }
1817b320703d47ff2b242ae74faba5e4b0af3560d71commit-bot@chromium.org        // Test offsets on Darken (uses shader blend)
1827b320703d47ff2b242ae74faba5e4b0af3560d71commit-bot@chromium.org        mode.reset(SkXfermode::Create(SkXfermode::kDarken_Mode));
1837b320703d47ff2b242ae74faba5e4b0af3560d71commit-bot@chromium.org        filter.reset(SkNEW_ARGS(SkXfermodeImageFilter, (mode, offsetBackground, offsetForeground)));
1847b320703d47ff2b242ae74faba5e4b0af3560d71commit-bot@chromium.org        paint.setImageFilter(filter);
1857b320703d47ff2b242ae74faba5e4b0af3560d71commit-bot@chromium.org        canvas->save();
186de2e4e8a6422c7d8b5847f038f5c6360b187f7a2skia.committer@gmail.com        canvas->clipRect(SkRect::MakeXYWH(SkIntToScalar(x),
18731a40ef58b8eda59fd12b5e172683d8882acdc60robertphillips@google.com                                          SkIntToScalar(y),
188de2e4e8a6422c7d8b5847f038f5c6360b187f7a2skia.committer@gmail.com                                          SkIntToScalar(fBitmap.width() + 4),
18931a40ef58b8eda59fd12b5e172683d8882acdc60robertphillips@google.com                                          SkIntToScalar(fBitmap.height() + 4)));
1907b320703d47ff2b242ae74faba5e4b0af3560d71commit-bot@chromium.org        canvas->drawPaint(paint);
1917b320703d47ff2b242ae74faba5e4b0af3560d71commit-bot@chromium.org        canvas->restore();
1921a4fb70c8a04db2d92ec821555f91218a989031dcommit-bot@chromium.org        x += fBitmap.width() + MARGIN;
1931a4fb70c8a04db2d92ec821555f91218a989031dcommit-bot@chromium.org        if (x + fBitmap.width() > WIDTH) {
1941a4fb70c8a04db2d92ec821555f91218a989031dcommit-bot@chromium.org            x = 0;
1951a4fb70c8a04db2d92ec821555f91218a989031dcommit-bot@chromium.org            y += fBitmap.height() + MARGIN;
1961a4fb70c8a04db2d92ec821555f91218a989031dcommit-bot@chromium.org        }
1971a4fb70c8a04db2d92ec821555f91218a989031dcommit-bot@chromium.org        // Test cropping
1981a4fb70c8a04db2d92ec821555f91218a989031dcommit-bot@chromium.org        static const size_t nbSamples = 3;
1991a4fb70c8a04db2d92ec821555f91218a989031dcommit-bot@chromium.org        SkXfermode::Mode sampledModes[nbSamples] = {SkXfermode::kOverlay_Mode,
2001a4fb70c8a04db2d92ec821555f91218a989031dcommit-bot@chromium.org                                                    SkXfermode::kSrcOver_Mode,
2011a4fb70c8a04db2d92ec821555f91218a989031dcommit-bot@chromium.org                                                    SkXfermode::kPlus_Mode};
2021a4fb70c8a04db2d92ec821555f91218a989031dcommit-bot@chromium.org        int offsets[nbSamples][4] = {{ 10,  10, -16, -16},
2031a4fb70c8a04db2d92ec821555f91218a989031dcommit-bot@chromium.org                                     { 10,  10,  10,  10},
2041a4fb70c8a04db2d92ec821555f91218a989031dcommit-bot@chromium.org                                     {-10, -10,  -6,  -6}};
2051a4fb70c8a04db2d92ec821555f91218a989031dcommit-bot@chromium.org        for (size_t i = 0; i < nbSamples; ++i) {
2061a4fb70c8a04db2d92ec821555f91218a989031dcommit-bot@chromium.org            SkIRect cropRect = SkIRect::MakeXYWH(x + offsets[i][0],
2071a4fb70c8a04db2d92ec821555f91218a989031dcommit-bot@chromium.org                                                 y + offsets[i][1],
2081a4fb70c8a04db2d92ec821555f91218a989031dcommit-bot@chromium.org                                                 fBitmap.width()  + offsets[i][2],
2091a4fb70c8a04db2d92ec821555f91218a989031dcommit-bot@chromium.org                                                 fBitmap.height() + offsets[i][3]);
2101a4fb70c8a04db2d92ec821555f91218a989031dcommit-bot@chromium.org            mode.reset(SkXfermode::Create(sampledModes[i]));
2111a4fb70c8a04db2d92ec821555f91218a989031dcommit-bot@chromium.org            filter.reset(SkNEW_ARGS(SkXfermodeImageFilter,
2121a4fb70c8a04db2d92ec821555f91218a989031dcommit-bot@chromium.org                                    (mode, offsetBackground, offsetForeground, &cropRect)));
2131a4fb70c8a04db2d92ec821555f91218a989031dcommit-bot@chromium.org            paint.setImageFilter(filter);
2141a4fb70c8a04db2d92ec821555f91218a989031dcommit-bot@chromium.org            canvas->save();
2151a4fb70c8a04db2d92ec821555f91218a989031dcommit-bot@chromium.org            canvas->clipRect(SkRect::MakeXYWH(SkIntToScalar(x),
2161a4fb70c8a04db2d92ec821555f91218a989031dcommit-bot@chromium.org                                              SkIntToScalar(y),
2171a4fb70c8a04db2d92ec821555f91218a989031dcommit-bot@chromium.org                                              SkIntToScalar(fBitmap.width() + 4),
2181a4fb70c8a04db2d92ec821555f91218a989031dcommit-bot@chromium.org                                              SkIntToScalar(fBitmap.height() + 4)));
2191a4fb70c8a04db2d92ec821555f91218a989031dcommit-bot@chromium.org            canvas->drawPaint(paint);
2201a4fb70c8a04db2d92ec821555f91218a989031dcommit-bot@chromium.org            canvas->restore();
2211a4fb70c8a04db2d92ec821555f91218a989031dcommit-bot@chromium.org            x += fBitmap.width() + MARGIN;
2221a4fb70c8a04db2d92ec821555f91218a989031dcommit-bot@chromium.org            if (x + fBitmap.width() > WIDTH) {
2231a4fb70c8a04db2d92ec821555f91218a989031dcommit-bot@chromium.org                x = 0;
2241a4fb70c8a04db2d92ec821555f91218a989031dcommit-bot@chromium.org                y += fBitmap.height() + MARGIN;
2251a4fb70c8a04db2d92ec821555f91218a989031dcommit-bot@chromium.org            }
2261a4fb70c8a04db2d92ec821555f91218a989031dcommit-bot@chromium.org        }
22786fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org    }
22886fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.orgprivate:
22986fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org    typedef GM INHERITED;
23086fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org    SkBitmap fBitmap, fCheckerboard;
23186fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org    bool fInitialized;
23286fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org};
23386fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org
23486fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org//////////////////////////////////////////////////////////////////////////////
23586fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org
23686fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.orgstatic GM* MyFactory(void*) { return new XfermodeImageFilterGM; }
23786fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.orgstatic GMRegistry reg(MyFactory);
23886fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org
23986fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org}
240