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