1ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com/*
2ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com * Copyright 2011 Google Inc.
3ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com *
4ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com * Use of this source code is governed by a BSD-style license that can be
5ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com * found in the LICENSE file.
6ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com */
7ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com
8ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com#include "gm.h"
9ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com#include "SkCanvas.h"
10ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com#include "SkColorPriv.h"
11ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com#include "SkShader.h"
12ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com
13d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osmanconstexpr SkBlendMode gModes[] = {
14d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman    SkBlendMode::kClear,
15d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman    SkBlendMode::kSrc,
16d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman    SkBlendMode::kDst,
17d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman    SkBlendMode::kSrcOver,
18d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman    SkBlendMode::kDstOver,
19d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman    SkBlendMode::kSrcIn,
20d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman    SkBlendMode::kDstIn,
21d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman    SkBlendMode::kSrcOut,
22d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman    SkBlendMode::kDstOut,
23d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman    SkBlendMode::kSrcATop,
24d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman    SkBlendMode::kDstATop,
25d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman    SkBlendMode::kXor,
26ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com};
27ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com
28ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.comconst int gWidth = 64;
29ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.comconst int gHeight = 64;
30ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.comconst SkScalar W = SkIntToScalar(gWidth);
31ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.comconst SkScalar H = SkIntToScalar(gHeight);
32ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com
33374772bd61951f01bf84fe17bf53d8867681c9aereedstatic SkScalar drawCell(SkCanvas* canvas, SkBlendMode mode, SkAlpha a0, SkAlpha a1) {
34ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com
35ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    SkPaint paint;
36ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    paint.setAntiAlias(true);
37ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com
38ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    SkRect r = SkRect::MakeWH(W, H);
39ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    r.inset(W/10, H/10);
40ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com
41ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    paint.setColor(SK_ColorBLUE);
42ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    paint.setAlpha(a0);
43ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    canvas->drawOval(r, paint);
44ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com
45ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    paint.setColor(SK_ColorRED);
46ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    paint.setAlpha(a1);
47374772bd61951f01bf84fe17bf53d8867681c9aereed    paint.setBlendMode(mode);
48ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    for (int angle = 0; angle < 24; ++angle) {
49ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com        SkScalar x = SkScalarCos(SkIntToScalar(angle) * (SK_ScalarPI * 2) / 24) * gWidth;
50ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com        SkScalar y = SkScalarSin(SkIntToScalar(angle) * (SK_ScalarPI * 2) / 24) * gHeight;
51ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com        paint.setStrokeWidth(SK_Scalar1 * angle * 2 / 24);
52ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com        canvas->drawLine(W/2, H/2, W/2 + x, H/2 + y, paint);
53ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    }
54ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
55ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    return H;
56ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com}
57ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com
581a9b9640843a64af8d9d90337ec3b3fea663196areedstatic sk_sp<SkShader> make_bg_shader() {
59ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    SkBitmap bm;
60eb9a46cbbb475e862a084aa2224ec18d4ac5e95breed@google.com    bm.allocN32Pixels(2, 2);
61ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    *bm.getAddr32(0, 0) = *bm.getAddr32(1, 1) = 0xFFFFFFFF;
62125960152dfd7f2aba4c2239131bdf75d9ac2705caryclark    *bm.getAddr32(1, 0) = *bm.getAddr32(0, 1) = SkPackARGB32(0xFF, 0xCE, 0xCF, 0xCE);
63ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com
64ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    SkMatrix m;
65ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    m.setScale(SkIntToScalar(6), SkIntToScalar(6));
661a9b9640843a64af8d9d90337ec3b3fea663196areed    return SkShader::MakeBitmapShader(bm,
671a9b9640843a64af8d9d90337ec3b3fea663196areed                                      SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, &m);
68ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com}
69ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com
70ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.comnamespace skiagm {
71ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
72ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    class HairModesGM : public GM {
73ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com        SkPaint fBGPaint;
74ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
75ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    protected:
7636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein        SkString onShortName() override {
77ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com            return SkString("hairmodes");
78ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com        }
79ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
8036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein        virtual SkISize onISize() override { return SkISize::Make(640, 480); }
81ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
8236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein        void onOnceBeforeDraw() override {
831a9b9640843a64af8d9d90337ec3b3fea663196areed            fBGPaint.setShader(make_bg_shader());
847775d66aa0e5958c9ea55ddb8317af4d9b019220reed@google.com        }
857775d66aa0e5958c9ea55ddb8317af4d9b019220reed@google.com
8636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein        void onDraw(SkCanvas* canvas) override {
87ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com            const SkRect bounds = SkRect::MakeWH(W, H);
88dbfd7ab10883f173f5c1b653a233e18dc6142002mtklein            constexpr SkAlpha gAlphaValue[] = { 0xFF, 0x88, 0x88 };
89ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
90ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com            canvas->translate(SkIntToScalar(4), SkIntToScalar(4));
91ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
92ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com            for (int alpha = 0; alpha < 4; ++alpha) {
93ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com                canvas->save();
94ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com                canvas->save();
95ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com                for (size_t i = 0; i < SK_ARRAY_COUNT(gModes); ++i) {
96ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com                    if (6 == i) {
97ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com                        canvas->restore();
98ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com                        canvas->translate(W * 5, 0);
99ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com                        canvas->save();
100ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com                    }
101ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
102ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com                    canvas->drawRect(bounds, fBGPaint);
10396fcdcc219d2a0d3579719b84b28bede76efba64halcanary                    canvas->saveLayer(&bounds, nullptr);
104d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman                    SkScalar dy = drawCell(canvas, gModes[i],
105ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com                                           gAlphaValue[alpha & 1],
106ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com                                           gAlphaValue[alpha & 2]);
107ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com                    canvas->restore();
108ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
109ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com                    canvas->translate(0, dy * 5 / 4);
110ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com                }
111ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com                canvas->restore();
112ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com                canvas->restore();
113ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com                canvas->translate(W * 5 / 4, 0);
114ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com            }
115ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com        }
116fbc21172885fe1f028594bc9b181246c71eb106creed@google.com
117ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    private:
118ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com        typedef GM INHERITED;
119ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    };
120ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
121ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    //////////////////////////////////////////////////////////////////////////////
122ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
123ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    static GM* MyFactory(void*) { return new HairModesGM; }
124ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    static GMRegistry reg(MyFactory);
125ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
126ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com}
127