1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/*
2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2013 Google Inc.
3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *
4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be
5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file.
6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */
7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "gm.h"
9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkBitmap.h"
10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkCanvas.h"
11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkColor.h"
12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkShader.h"
13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotnamespace skiagm {
15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// This GM draws a 3x3 grid (with the center element excluded) of rectangles
17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// filled with a bitmap shader. The bitmap shader is transformed so that the
18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// pattern cell is at the center (excluded) region.
19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot//
20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// In Repeat and Mirror mode, this tests that the bitmap shader still draws
21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// even though the pattern cell is outside the clip.
22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot//
23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// In Clamp mode, this tests that the clamp is handled properly. For PDF,
24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// (and possibly other exported formats) this also "tests" that the image itself
25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// is not stored (well, you'll need to open it up with an external tool to
26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// verify that).
27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic SkBitmap create_bitmap() {
29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkBitmap bmp;
30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bmp.allocN32Pixels(2, 2);
31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    uint32_t* pixels = reinterpret_cast<uint32_t*>(bmp.getPixels());
32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    pixels[0] = SkPreMultiplyColor(SK_ColorRED);
33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    pixels[1] = SkPreMultiplyColor(SK_ColorGREEN);
34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    pixels[2] = SkPreMultiplyColor(SK_ColorBLACK);
35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    pixels[3] = SkPreMultiplyColor(SK_ColorBLUE);
36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return bmp;
38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotconstexpr SkScalar RECT_SIZE = 64;
41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotconstexpr SkScalar SLIDE_SIZE = 300;
42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass ClippedBitmapShadersGM : public GM {
44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    ClippedBitmapShadersGM(SkShader::TileMode mode, bool hq=false)
46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    : fMode(mode), fHQ(hq) {
47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprotected:
50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkShader::TileMode fMode;
51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fHQ;
52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    virtual SkString onShortName() {
54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkString descriptor;
55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        switch (fMode) {
56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case SkShader::kRepeat_TileMode:
57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                descriptor = "tile";
58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            break;
59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case SkShader::kMirror_TileMode:
60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                descriptor = "mirror";
61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            break;
62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case SkShader::kClamp_TileMode:
63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                descriptor = "clamp";
64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            break;
65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            default:
66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkASSERT(false);
67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        descriptor.prepend("clipped-bitmap-shaders-");
69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fHQ) {
70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            descriptor.append("-hq");
71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return descriptor;
73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    virtual SkISize onISize() {
76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return SkISize::Make(300, 300);
77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    virtual void onDraw(SkCanvas* canvas) {
80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkBitmap bmp = create_bitmap();
81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkMatrix s;
82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        s.reset();
83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        s.setScale(8, 8);
84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        s.postTranslate(SLIDE_SIZE / 2, SLIDE_SIZE / 2);
85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPaint paint;
86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint.setShader(SkShader::MakeBitmapShader(bmp, fMode, fMode, &s));
87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fHQ) {
89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            paint.setFilterQuality(kHigh_SkFilterQuality);
90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkScalar margin = (SLIDE_SIZE / 3 - RECT_SIZE) / 2;
93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (int i = 0; i < 3; i++) {
94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkScalar yOrigin = SLIDE_SIZE / 3 * i + margin;
95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            for (int j = 0; j < 3; j++) {
96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkScalar xOrigin = SLIDE_SIZE / 3 * j + margin;
97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (i == 1 && j == 1) {
98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    continue;   // skip center element
99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkRect rect = SkRect::MakeXYWH(xOrigin, yOrigin,
101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                               RECT_SIZE, RECT_SIZE);
102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                canvas->save();
103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                canvas->clipRect(rect);
104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                canvas->drawRect(rect, paint);
105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                canvas->restore();
106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef GM INHERITED;
112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot//////////////////////////////////////////////////////////////////////////////
115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_GM( return new ClippedBitmapShadersGM(SkShader::kRepeat_TileMode); )
117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_GM( return new ClippedBitmapShadersGM(SkShader::kMirror_TileMode); )
118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_GM( return new ClippedBitmapShadersGM(SkShader::kClamp_TileMode); )
119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_GM( return new ClippedBitmapShadersGM(SkShader::kRepeat_TileMode, true); )
121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_GM( return new ClippedBitmapShadersGM(SkShader::kMirror_TileMode, true); )
122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_GM( return new ClippedBitmapShadersGM(SkShader::kClamp_TileMode, true); )
123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
126