1e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org/*
2e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org * Copyright 2011 Google Inc.
3e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org *
4e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org * Use of this source code is governed by a BSD-style license that can be
5e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org * found in the LICENSE file.
6e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org */
7e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org
8e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org#include "gm.h"
9e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org#include "SkCanvas.h"
10e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org#include "SkColorPriv.h"
11e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org#include "SkShader.h"
12e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org
13e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org#include "SkArithmeticMode.h"
14e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org#include "SkGradientShader.h"
15e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org#define WW  100
16e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org#define HH  32
17e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org
18e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.orgstatic SkBitmap make_bm() {
19e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org    SkBitmap bm;
20eb9a46cbbb475e862a084aa2224ec18d4ac5e95breed@google.com    bm.allocN32Pixels(WW, HH);
21dbfac8a72393eaf01670aeb3244de0e18d8faf98junov@google.com    bm.eraseColor(SK_ColorTRANSPARENT);
22e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org    return bm;
23e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org}
24e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org
25e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.orgstatic SkBitmap make_src() {
26e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org    SkBitmap bm = make_bm();
27e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org    SkCanvas canvas(bm);
28e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org    SkPaint paint;
29cadbcb8e536f89babb4e165bfdca18384e97d582bsalomon@google.com    SkPoint pts[] = { {0, 0}, {SkIntToScalar(WW), SkIntToScalar(HH)} };
30e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org    SkColor colors[] = {
3135c733cc9ce71c4513dfb6f39c4d9df5905e897csenorblanco@chromium.org        SK_ColorTRANSPARENT, SK_ColorGREEN, SK_ColorCYAN,
3235c733cc9ce71c4513dfb6f39c4d9df5905e897csenorblanco@chromium.org        SK_ColorRED, SK_ColorMAGENTA, SK_ColorWHITE,
33e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org    };
34e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org    SkShader* s = SkGradientShader::CreateLinear(pts, colors, NULL, SK_ARRAY_COUNT(colors),
35e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org                                                 SkShader::kClamp_TileMode);
36e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org    paint.setShader(s)->unref();
37e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org    canvas.drawPaint(paint);
38e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org    return bm;
39e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org}
40e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org
41e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.orgstatic SkBitmap make_dst() {
42e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org    SkBitmap bm = make_bm();
43e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org    SkCanvas canvas(bm);
44e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org    SkPaint paint;
45cadbcb8e536f89babb4e165bfdca18384e97d582bsalomon@google.com    SkPoint pts[] = { {0, SkIntToScalar(HH)}, {SkIntToScalar(WW), 0} };
46e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org    SkColor colors[] = {
47e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org        SK_ColorBLUE, SK_ColorYELLOW, SK_ColorBLACK, SK_ColorGREEN, SK_ColorGRAY
48e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org    };
49e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org    SkShader* s = SkGradientShader::CreateLinear(pts, colors, NULL, SK_ARRAY_COUNT(colors),
50e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org                                                 SkShader::kClamp_TileMode);
51e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org    paint.setShader(s)->unref();
52e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org    canvas.drawPaint(paint);
53e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org    return bm;
54e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org}
55e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org
56e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.orgstatic void show_k_text(SkCanvas* canvas, SkScalar x, SkScalar y, const SkScalar k[]) {
57e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org    SkPaint paint;
58eb0fa29fc468e3f02d5a3b6456effd10b984f6bareed@google.com    paint.setTextSize(SkIntToScalar(24));
59e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org    paint.setAntiAlias(true);
60e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org    for (int i = 0; i < 4; ++i) {
61e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org        SkString str;
62e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org        str.appendScalar(k[i]);
63e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org        SkScalar width = paint.measureText(str.c_str(), str.size());
64eb0fa29fc468e3f02d5a3b6456effd10b984f6bareed@google.com        canvas->drawText(str.c_str(), str.size(), x, y + paint.getTextSize(), paint);
65eb0fa29fc468e3f02d5a3b6456effd10b984f6bareed@google.com        x += width + SkIntToScalar(10);
66e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org    }
67e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org}
68e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org
69e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.orgclass ArithmodeGM : public skiagm::GM {
70e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.orgpublic:
71e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org    ArithmodeGM () {}
72e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org
73e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.orgprotected:
74e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org
75e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org    virtual SkString onShortName() {
76e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org        return SkString("arithmode");
77e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org    }
78e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org
79e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org    virtual SkISize onISize() { return SkISize::Make(640, 480); }
80e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org
81e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org    virtual void onDraw(SkCanvas* canvas) {
82e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org        SkBitmap src = make_src();
83e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org        SkBitmap dst = make_dst();
84ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
85eb0fa29fc468e3f02d5a3b6456effd10b984f6bareed@google.com        const SkScalar one = SK_Scalar1;
86e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org        static const SkScalar K[] = {
87e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org            0, 0, 0, 0,
88eb0fa29fc468e3f02d5a3b6456effd10b984f6bareed@google.com            0, 0, 0, one,
89eb0fa29fc468e3f02d5a3b6456effd10b984f6bareed@google.com            0, one, 0, 0,
90eb0fa29fc468e3f02d5a3b6456effd10b984f6bareed@google.com            0, 0, one, 0,
91eb0fa29fc468e3f02d5a3b6456effd10b984f6bareed@google.com            0, one, one, 0,
92eb0fa29fc468e3f02d5a3b6456effd10b984f6bareed@google.com            0, one, -one, 0,
93eb0fa29fc468e3f02d5a3b6456effd10b984f6bareed@google.com            0, one/2, one/2, 0,
94eb0fa29fc468e3f02d5a3b6456effd10b984f6bareed@google.com            0, one/2, one/2, one/4,
95eb0fa29fc468e3f02d5a3b6456effd10b984f6bareed@google.com            0, one/2, one/2, -one/4,
96eb0fa29fc468e3f02d5a3b6456effd10b984f6bareed@google.com            one/4, one/2, one/2, 0,
97eb0fa29fc468e3f02d5a3b6456effd10b984f6bareed@google.com            -one/4, one/2, one/2, 0,
98e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org        };
99ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
100e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org        const SkScalar* k = K;
101e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org        const SkScalar* stop = k + SK_ARRAY_COUNT(K);
102e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org        SkScalar y = 0;
103eb85630fd6105189df316bd3cde662a616ac1180reed@google.com        SkScalar gap = SkIntToScalar(src.width() + 20);
104e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org        while (k < stop) {
105e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org            SkScalar x = 0;
106e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org            canvas->drawBitmap(src, x, y, NULL);
107e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org            x += gap;
108e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org            canvas->drawBitmap(dst, x, y, NULL);
109e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org            x += gap;
1109a6eb0e1e8a8de7371cd9604f34619b8f87de66fsenorblanco@chromium.org            SkRect rect = SkRect::MakeXYWH(x, y, SkIntToScalar(WW), SkIntToScalar(HH));
1119a6eb0e1e8a8de7371cd9604f34619b8f87de66fsenorblanco@chromium.org            canvas->saveLayer(&rect, NULL);
1129a6eb0e1e8a8de7371cd9604f34619b8f87de66fsenorblanco@chromium.org            canvas->drawBitmap(dst, x, y, NULL);
1139a6eb0e1e8a8de7371cd9604f34619b8f87de66fsenorblanco@chromium.org            SkXfermode* xfer = SkArithmeticMode::Create(k[0], k[1], k[2], k[3]);
1149a6eb0e1e8a8de7371cd9604f34619b8f87de66fsenorblanco@chromium.org            SkPaint paint;
1159a6eb0e1e8a8de7371cd9604f34619b8f87de66fsenorblanco@chromium.org            paint.setXfermode(xfer)->unref();
1169a6eb0e1e8a8de7371cd9604f34619b8f87de66fsenorblanco@chromium.org            canvas->drawBitmap(src, x, y, &paint);
1179a6eb0e1e8a8de7371cd9604f34619b8f87de66fsenorblanco@chromium.org            canvas->restore();
118e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org            x += gap;
119e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org            show_k_text(canvas, x, y, k);
120e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org            k += 4;
121eb85630fd6105189df316bd3cde662a616ac1180reed@google.com            y += SkIntToScalar(src.height() + 12);
122e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org        }
123e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org    }
124e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org
125e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.orgprivate:
126e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org    typedef GM INHERITED;
127e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org};
128e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org
129e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org///////////////////////////////////////////////////////////////////////////////
130e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.org
131e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.orgstatic skiagm::GM* MyFactory(void*) { return new ArithmodeGM; }
132e51755fc64bf5df4bed9d74f4bca4f70897d59a9mike@reedtribe.orgstatic skiagm::GMRegistry reg(MyFactory);
133