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 "gm.h"
90fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com#include "SkCanvas.h"
100fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com#include "SkGradientShader.h"
110fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
120fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.comnamespace skiagm {
130fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
14dac522589e9395b4654a1a708f1bd971f37f95a5commit-bot@chromium.orgstatic void makebm(SkBitmap* bm, int w, int h) {
15dac522589e9395b4654a1a708f1bd971f37f95a5commit-bot@chromium.org    bm->allocN32Pixels(w, h);
16dbfac8a72393eaf01670aeb3244de0e18d8faf98junov@google.com    bm->eraseColor(SK_ColorTRANSPARENT);
170fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
180fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    SkCanvas    canvas(*bm);
19b28b5e4e26183b6e14846fb00501cc445a4fdd7eepoger@google.com    SkScalar    s = SkIntToScalar(SkMin32(w, h));
20386900790bbb2c07a6cc39bd46feb2e6526dbe01reed@google.com    SkPoint     pts[] = { { 0, 0 }, { s, s } };
210fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    SkColor     colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
220fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    SkScalar    pos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
230fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    SkPaint     paint;
240fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
250fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    paint.setDither(true);
260fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    paint.setShader(SkGradientShader::CreateLinear(pts, colors, pos,
2783f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.org                SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode))->unref();
280fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    canvas.drawPaint(paint);
290fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com}
300fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
310fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com///////////////////////////////////////////////////////////////////////////////
320fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
330fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.comstruct GradData {
340fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    int             fCount;
350fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    const SkColor*  fColors;
360fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    const SkScalar* fPos;
370fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com};
380fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
390fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.comstatic const SkColor gColors[] = {
400fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK
410fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com};
420fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
430fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.comstatic const GradData gGradData[] = {
440fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    { 2, gColors, NULL },
450fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    { 5, gColors, NULL },
460fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com};
470fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
4883f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.orgstatic SkShader* MakeLinear(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
4983f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.org    return SkGradientShader::CreateLinear(pts, data.fColors, data.fPos, data.fCount, tm);
500fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com}
510fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
5283f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.orgstatic SkShader* MakeRadial(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
530fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    SkPoint center;
540fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    center.set(SkScalarAve(pts[0].fX, pts[1].fX),
550fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com               SkScalarAve(pts[0].fY, pts[1].fY));
560fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    return SkGradientShader::CreateRadial(center, center.fX, data.fColors,
5783f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.org                                          data.fPos, data.fCount, tm);
580fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com}
590fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
6083f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.orgstatic SkShader* MakeSweep(const SkPoint pts[2], const GradData& data, SkShader::TileMode) {
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));
6483f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.org    return SkGradientShader::CreateSweep(center.fX, center.fY, data.fColors, data.fPos, data.fCount);
650fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com}
660fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
6783f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.orgstatic SkShader* Make2Radial(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
680fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    SkPoint center0, center1;
690fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
700fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com                SkScalarAve(pts[0].fY, pts[1].fY));
710fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
720fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com                SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
730fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    return SkGradientShader::CreateTwoPointRadial(
740fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com                            center1, (pts[1].fX - pts[0].fX) / 7,
750fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com                            center0, (pts[1].fX - pts[0].fX) / 2,
7683f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.org                            data.fColors, data.fPos, data.fCount, tm);
770fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com}
780fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
7983f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.orgtypedef SkShader* (*GradMaker)(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm);
807693dbf46e9bf0159cc9032059738d418469a7adskia.committer@gmail.com
810fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.comstatic const GradMaker gGradMakers[] = {
820fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    MakeLinear, MakeRadial, MakeSweep, Make2Radial
830fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com};
840fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
850fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com///////////////////////////////////////////////////////////////////////////////
860fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
870fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.comclass ShaderTextGM : public GM {
880fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.compublic:
89ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com    ShaderTextGM() {
9048dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com        this->setBGColor(0xFFDDDDDD);
9148dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    }
920fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
930fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.comprotected:
94a90c6803865766d28e92091f56f718f5e41fe80fcommit-bot@chromium.org    virtual uint32_t onGetFlags() const SK_OVERRIDE {
95a90c6803865766d28e92091f56f718f5e41fe80fcommit-bot@chromium.org        return kSkipTiled_Flag;
96a90c6803865766d28e92091f56f718f5e41fe80fcommit-bot@chromium.org    }
970fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
980fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    SkString onShortName() {
990fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        return SkString("shadertext");
1000fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    }
1010fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
102f539318f0d3dba743ec1886d5d9df0fb1be628a1tfarina    SkISize onISize() { return SkISize::Make(1450, 500); }
1030fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
1040fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    virtual void onDraw(SkCanvas* canvas) {
1050fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        const char text[] = "Shaded Text";
1060fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        const int textLen = SK_ARRAY_COUNT(text) - 1;
1073914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com        const int pointSize = 36;
1080fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
109da8cf5accb67d26a7f2e77d15cc918910e594e64reed        const int w = pointSize * textLen;
110da8cf5accb67d26a7f2e77d15cc918910e594e64reed        const int h = pointSize;
1110fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
1120fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        SkPoint pts[2] = {
1130fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com            { 0, 0 },
1140fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com            { SkIntToScalar(w), SkIntToScalar(h) }
1150fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        };
1160fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        SkScalar textBase = SkIntToScalar(h/2);
1170fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
1180fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        SkShader::TileMode tileModes[] = {
1190fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com            SkShader::kClamp_TileMode,
1200fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com            SkShader::kRepeat_TileMode,
1210fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com            SkShader::kMirror_TileMode
1220fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        };
1230fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
1240fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        static const int gradCount = SK_ARRAY_COUNT(gGradData) *
1250fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com                                     SK_ARRAY_COUNT(gGradMakers);
1260fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        static const int bmpCount = SK_ARRAY_COUNT(tileModes) *
1270fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com                                    SK_ARRAY_COUNT(tileModes);
1280fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        SkShader* shaders[gradCount + bmpCount];
1290fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
1300fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        int shdIdx = 0;
1310fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        for (size_t d = 0; d < SK_ARRAY_COUNT(gGradData); ++d) {
1320fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com            for (size_t m = 0; m < SK_ARRAY_COUNT(gGradMakers); ++m) {
1330fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com                shaders[shdIdx++] = gGradMakers[m](pts,
1340fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com                                                   gGradData[d],
13583f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.org                                                   SkShader::kClamp_TileMode);
1360fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com            }
1370fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        }
138da8cf5accb67d26a7f2e77d15cc918910e594e64reed
139da8cf5accb67d26a7f2e77d15cc918910e594e64reed        SkBitmap bm;
140da8cf5accb67d26a7f2e77d15cc918910e594e64reed        makebm(&bm, w/16, h/4);
1410fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        for (size_t tx = 0; tx < SK_ARRAY_COUNT(tileModes); ++tx) {
1420fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com            for (size_t ty = 0; ty < SK_ARRAY_COUNT(tileModes); ++ty) {
143da8cf5accb67d26a7f2e77d15cc918910e594e64reed                shaders[shdIdx++] = SkShader::CreateBitmapShader(bm, tileModes[tx], tileModes[ty]);
1440fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com            }
1450fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        }
1460fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
1470fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        SkPaint paint;
1480fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        paint.setDither(true);
1490fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        paint.setAntiAlias(true);
150992c7b03ef7914a18bfd78e965b0b4c99a5f5672Cary Clark        sk_tool_utils::set_portable_typeface(&paint);
1510fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        paint.setTextSize(SkIntToScalar(pointSize));
1520fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
1530fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        canvas->save();
1540fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        canvas->translate(SkIntToScalar(20), SkIntToScalar(10));
1550fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
1563914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com        SkPath path;
157137c428290ac7a4804edf564c552711ffb9dfa58bsalomon@google.com        path.arcTo(SkRect::MakeXYWH(SkIntToScalar(-40), SkIntToScalar(15),
158ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com                                    SkIntToScalar(300), SkIntToScalar(90)),
159ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com                                    SkIntToScalar(225), SkIntToScalar(90),
160137c428290ac7a4804edf564c552711ffb9dfa58bsalomon@google.com                                    false);
1613914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com        path.close();
1623914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com
1630fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        static const int testsPerCol = 8;
1640fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        static const int rowHeight = 60;
1650fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        static const int colWidth = 300;
1660fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        canvas->save();
167e9cd27d4a3c92393cc6c79d4d6f93d266411d95erobertphillips@google.com        for (int s = 0; s < static_cast<int>(SK_ARRAY_COUNT(shaders)); s++) {
1680fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com            canvas->save();
1693914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com            int i = 2*s;
1703914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com            canvas->translate(SkIntToScalar((i / testsPerCol) * colWidth),
1713914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com                              SkIntToScalar((i % testsPerCol) * rowHeight));
1723914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com            paint.setShader(shaders[s])->unref();
1730fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com            canvas->drawText(text, textLen, 0, textBase, paint);
1740fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com            canvas->restore();
1753914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com            canvas->save();
1763914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com            ++i;
1773914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com            canvas->translate(SkIntToScalar((i / testsPerCol) * colWidth),
1783914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com                              SkIntToScalar((i % testsPerCol) * rowHeight));
1793914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com            canvas->drawTextOnPath(text, textLen, path, NULL, paint);
1803914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com            canvas->restore();
1810fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        }
1820fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        canvas->restore();
1833914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com
1840fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    }
1850fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
1860fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.comprivate:
1870fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    typedef GM INHERITED;
1880fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com};
1890fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
1900fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com///////////////////////////////////////////////////////////////////////////////
1910fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
1920fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.comstatic GM* MyFactory(void*) { return new ShaderTextGM; }
1930fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.comstatic GMRegistry reg(MyFactory);
1940fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com}
195