1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
783f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.org
80fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com#include "SampleCode.h"
90fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com#include "SkView.h"
100fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com#include "SkCanvas.h"
110fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com#include "SkGradientShader.h"
120fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
13a8c183125f2861067daf432cada06d431a795cd0commit-bot@chromium.orgstatic void makebm(SkBitmap* bm, int w, int h) {
14a8c183125f2861067daf432cada06d431a795cd0commit-bot@chromium.org    bm->allocN32Pixels(w, h);
15dbfac8a72393eaf01670aeb3244de0e18d8faf98junov@google.com    bm->eraseColor(SK_ColorTRANSPARENT);
160fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
170fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    SkCanvas    canvas(*bm);
18261b8e2ca1cf22303ad95267f0bdc6e87e1bbe70reed@google.com    SkScalar s = SkIntToScalar(w < h ? w : h);
1964cc579efa7e416c7298ed159d76b074b283c0f9senorblanco@chromium.org    SkPoint     pts[] = { { 0, 0 }, { s, s } };
200fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    SkColor     colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
210fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    SkScalar    pos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
220fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    SkPaint     paint;
230fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
240fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    paint.setDither(true);
250fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    paint.setShader(SkGradientShader::CreateLinear(pts, colors, pos,
2683f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.org                                    SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode))->unref();
270fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    canvas.drawPaint(paint);
280fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com}
290fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
3002939ce4bddd3223d9e8cc98d4abd02939b7f70acaryclark@google.comstatic SkShader* MakeBitmapShader(SkShader::TileMode tx, SkShader::TileMode ty,
310fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com                           int w, int h) {
320fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    static SkBitmap bmp;
330fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    if (bmp.isNull()) {
34a8c183125f2861067daf432cada06d431a795cd0commit-bot@chromium.org        makebm(&bmp, w/2, h/4);
350fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    }
360fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    return SkShader::CreateBitmapShader(bmp, tx, ty);
370fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com}
380fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
390fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com///////////////////////////////////////////////////////////////////////////////
400fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
410fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.comstruct GradData {
420fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    int             fCount;
430fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    const SkColor*  fColors;
440fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    const SkScalar* fPos;
450fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com};
460fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
470fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.comstatic const SkColor gColors[] = {
480fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK
490fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com};
500fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
510fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.comstatic const GradData gGradData[] = {
520fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    { 2, gColors, NULL },
530fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    { 5, gColors, NULL },
540fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com};
550fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
5683f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.orgstatic SkShader* MakeLinear(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
5783f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.org    return SkGradientShader::CreateLinear(pts, data.fColors, data.fPos, data.fCount, tm);
580fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com}
590fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
6083f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.orgstatic SkShader* MakeRadial(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
610fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    SkPoint center;
620fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    center.set(SkScalarAve(pts[0].fX, pts[1].fX),
630fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com               SkScalarAve(pts[0].fY, pts[1].fY));
640fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    return SkGradientShader::CreateRadial(center, center.fX, data.fColors,
6583f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.org                                          data.fPos, data.fCount, tm);
660fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com}
670fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
6883f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.orgstatic SkShader* MakeSweep(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
690fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    SkPoint center;
700fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    center.set(SkScalarAve(pts[0].fX, pts[1].fX),
710fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com               SkScalarAve(pts[0].fY, pts[1].fY));
7283f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.org    return SkGradientShader::CreateSweep(center.fX, center.fY, data.fColors, data.fPos, data.fCount);
730fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com}
740fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
7583f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.orgstatic SkShader* Make2Radial(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
760fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    SkPoint center0, center1;
770fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
780fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com                SkScalarAve(pts[0].fY, pts[1].fY));
790fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
800fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com                SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
810fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    return SkGradientShader::CreateTwoPointRadial(
820fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com                            center1, (pts[1].fX - pts[0].fX) / 7,
830fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com                            center0, (pts[1].fX - pts[0].fX) / 2,
8483f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.org                            data.fColors, data.fPos, data.fCount, tm);
850fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com}
860fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
8783f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.orgtypedef SkShader* (*GradMaker)(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm);
8883f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.org
890fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.comstatic const GradMaker gGradMakers[] = {
900fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    MakeLinear, MakeRadial, MakeSweep, Make2Radial
910fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com};
920fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
930fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com///////////////////////////////////////////////////////////////////////////////
940fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
95f21833999d90ad9c8c584cff3238797b39cfc00breed@google.comclass ShaderTextView : public SampleView {
960fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.compublic:
97ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com    ShaderTextView() {
98f21833999d90ad9c8c584cff3238797b39cfc00breed@google.com        this->setBGColor(0xFFDDDDDD);
99f21833999d90ad9c8c584cff3238797b39cfc00breed@google.com    }
1000fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
1010fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.comprotected:
1020fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    // overrides from SkEventSink
1030fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    virtual bool onQuery(SkEvent* evt) {
1040fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        if (SampleCode::TitleQ(*evt)) {
1050fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com            SampleCode::TitleR(evt, "Shader Text");
1060fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com            return true;
1070fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        }
1080fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        return this->INHERITED::onQuery(evt);
1090fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    }
1100fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
111f21833999d90ad9c8c584cff3238797b39cfc00breed@google.com    virtual void onDrawContent(SkCanvas* canvas) {
1120fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        const char text[] = "Shaded Text";
1130fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        const int textLen = SK_ARRAY_COUNT(text) - 1;
1143914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com        static int pointSize = 36;
1150fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
1160fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        int w = pointSize * textLen;
1170fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        int h = pointSize;
1180fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
1190fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        SkPoint pts[2] = {
1200fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com            { 0, 0 },
1210fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com            { SkIntToScalar(w), SkIntToScalar(h) }
1220fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        };
1230fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        SkScalar textBase = SkIntToScalar(h/2);
1240fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
1250fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        SkShader::TileMode tileModes[] = {
1260fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com            SkShader::kClamp_TileMode,
1270fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com            SkShader::kRepeat_TileMode,
1280fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com            SkShader::kMirror_TileMode
1290fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        };
1300fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
1310fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        static const int gradCount = SK_ARRAY_COUNT(gGradData) *
1320fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com                                     SK_ARRAY_COUNT(gGradMakers);
1330fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        static const int bmpCount = SK_ARRAY_COUNT(tileModes) *
1340fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com                                    SK_ARRAY_COUNT(tileModes);
1350fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        SkShader* shaders[gradCount + bmpCount];
1360fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
1370fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        int shdIdx = 0;
1380fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        for (size_t d = 0; d < SK_ARRAY_COUNT(gGradData); ++d) {
1390fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com            for (size_t m = 0; m < SK_ARRAY_COUNT(gGradMakers); ++m) {
1400fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com                shaders[shdIdx++] = gGradMakers[m](pts,
1410fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com                                                   gGradData[d],
14283f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.org                                                   SkShader::kClamp_TileMode);
1430fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com            }
1440fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        }
1450fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        for (size_t tx = 0; tx < SK_ARRAY_COUNT(tileModes); ++tx) {
1460fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com            for (size_t ty = 0; ty < SK_ARRAY_COUNT(tileModes); ++ty) {
1470fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com                shaders[shdIdx++] = MakeBitmapShader(tileModes[tx],
1480fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com                                                     tileModes[ty],
1490fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com                                                     w/8, h);
1500fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com            }
1510fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        }
1520fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
1530fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        SkPaint paint;
1540fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        paint.setDither(true);
1550fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        paint.setAntiAlias(true);
1560fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        paint.setTextSize(SkIntToScalar(pointSize));
1570fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
1580fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        canvas->save();
1590fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        canvas->translate(SkIntToScalar(20), SkIntToScalar(10));
1600fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
1613914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com        SkPath path;
162137c428290ac7a4804edf564c552711ffb9dfa58bsalomon@google.com        path.arcTo(SkRect::MakeXYWH(SkIntToScalar(-40), SkIntToScalar(15),
163ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com                                    SkIntToScalar(300), SkIntToScalar(90)),
164ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com                                    SkIntToScalar(225), SkIntToScalar(90),
165137c428290ac7a4804edf564c552711ffb9dfa58bsalomon@google.com                                    false);
1663914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com        path.close();
1673914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com
1680fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        static const int testsPerCol = 8;
1690fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        static const int rowHeight = 60;
1700fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        static const int colWidth = 300;
1710fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        canvas->save();
1720fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        for (size_t s = 0; s < SK_ARRAY_COUNT(shaders); s++) {
1730fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com            canvas->save();
1747fa2a65c0cfc714364490cb715171461143024e0reed@google.com            size_t i = 2*s;
1753914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com            canvas->translate(SkIntToScalar((i / testsPerCol) * colWidth),
1763914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com                              SkIntToScalar((i % testsPerCol) * rowHeight));
177e580bc195ad337bd7088db1b3c376543612b5061senorblanco@chromium.org            paint.setShader(shaders[s])->unref();
1780fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com            canvas->drawText(text, textLen, 0, textBase, paint);
1790fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com            canvas->restore();
1803914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com            canvas->save();
1813914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com            ++i;
1823914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com            canvas->translate(SkIntToScalar((i / testsPerCol) * colWidth),
1833914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com                              SkIntToScalar((i % testsPerCol) * rowHeight));
1843914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com            canvas->drawTextOnPath(text, textLen, path, NULL, paint);
1853914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com            canvas->restore();
1860fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        }
1870fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        canvas->restore();
1880fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    }
1890fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
1900fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.comprivate:
191f21833999d90ad9c8c584cff3238797b39cfc00breed@google.com    typedef SampleView INHERITED;
1920fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com};
1930fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
1940fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com///////////////////////////////////////////////////////////////////////////////
1950fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
1960fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.comstatic SkView* MyFactory() { return new ShaderTextView; }
1970fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.comstatic SkViewRegister reg(MyFactory);
198