shadertext.cpp revision 65cdba6ba78aaec0c0a4596bb5941020c789482b
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
6771a6cbfc585959738dc0b375603696ca7f60605freedstatic SkShader* Make2Conical(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));
7371a6cbfc585959738dc0b375603696ca7f60605freed    return SkGradientShader::CreateTwoPointConical(
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[] = {
8271a6cbfc585959738dc0b375603696ca7f60605freed    MakeLinear, MakeRadial, MakeSweep, Make2Conical
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() {
9065cdba6ba78aaec0c0a4596bb5941020c789482bcaryclark        this->setBGColor(sk_tool_utils::color_to_565(0xFFDDDDDD));
9148dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    }
920fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
930fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.comprotected:
940fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
9536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    SkString onShortName() override {
960fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        return SkString("shadertext");
970fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    }
980fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
9936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    SkISize onISize() override { return SkISize::Make(1450, 500); }
1000fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
10136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void onDraw(SkCanvas* canvas) override {
1020fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        const char text[] = "Shaded Text";
1030fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        const int textLen = SK_ARRAY_COUNT(text) - 1;
1043914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com        const int pointSize = 36;
1050fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
106da8cf5accb67d26a7f2e77d15cc918910e594e64reed        const int w = pointSize * textLen;
107da8cf5accb67d26a7f2e77d15cc918910e594e64reed        const int h = pointSize;
1080fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
1090fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        SkPoint pts[2] = {
1100fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com            { 0, 0 },
1110fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com            { SkIntToScalar(w), SkIntToScalar(h) }
1120fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        };
1130fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        SkScalar textBase = SkIntToScalar(h/2);
1140fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
1150fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        SkShader::TileMode tileModes[] = {
1160fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com            SkShader::kClamp_TileMode,
1170fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com            SkShader::kRepeat_TileMode,
1180fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com            SkShader::kMirror_TileMode
1190fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        };
1200fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
1210fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        static const int gradCount = SK_ARRAY_COUNT(gGradData) *
1220fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com                                     SK_ARRAY_COUNT(gGradMakers);
1230fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        static const int bmpCount = SK_ARRAY_COUNT(tileModes) *
1240fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com                                    SK_ARRAY_COUNT(tileModes);
1250fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        SkShader* shaders[gradCount + bmpCount];
1260fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
1270fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        int shdIdx = 0;
1280fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        for (size_t d = 0; d < SK_ARRAY_COUNT(gGradData); ++d) {
1290fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com            for (size_t m = 0; m < SK_ARRAY_COUNT(gGradMakers); ++m) {
1300fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com                shaders[shdIdx++] = gGradMakers[m](pts,
1310fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com                                                   gGradData[d],
13283f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.org                                                   SkShader::kClamp_TileMode);
1330fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com            }
1340fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        }
135da8cf5accb67d26a7f2e77d15cc918910e594e64reed
136da8cf5accb67d26a7f2e77d15cc918910e594e64reed        SkBitmap bm;
137da8cf5accb67d26a7f2e77d15cc918910e594e64reed        makebm(&bm, w/16, h/4);
1380fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        for (size_t tx = 0; tx < SK_ARRAY_COUNT(tileModes); ++tx) {
1390fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com            for (size_t ty = 0; ty < SK_ARRAY_COUNT(tileModes); ++ty) {
140da8cf5accb67d26a7f2e77d15cc918910e594e64reed                shaders[shdIdx++] = SkShader::CreateBitmapShader(bm, tileModes[tx], tileModes[ty]);
1410fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com            }
1420fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        }
1430fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
1440fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        SkPaint paint;
1450fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        paint.setDither(true);
1460fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        paint.setAntiAlias(true);
14765cdba6ba78aaec0c0a4596bb5941020c789482bcaryclark        sk_tool_utils::set_portable_typeface_always(&paint);
1480fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        paint.setTextSize(SkIntToScalar(pointSize));
1490fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
1500fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        canvas->save();
1510fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        canvas->translate(SkIntToScalar(20), SkIntToScalar(10));
1520fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
1533914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com        SkPath path;
154137c428290ac7a4804edf564c552711ffb9dfa58bsalomon@google.com        path.arcTo(SkRect::MakeXYWH(SkIntToScalar(-40), SkIntToScalar(15),
155ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com                                    SkIntToScalar(300), SkIntToScalar(90)),
156ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com                                    SkIntToScalar(225), SkIntToScalar(90),
157137c428290ac7a4804edf564c552711ffb9dfa58bsalomon@google.com                                    false);
1583914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com        path.close();
1593914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com
1600fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        static const int testsPerCol = 8;
1610fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        static const int rowHeight = 60;
1620fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        static const int colWidth = 300;
1630fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        canvas->save();
164e9cd27d4a3c92393cc6c79d4d6f93d266411d95erobertphillips@google.com        for (int s = 0; s < static_cast<int>(SK_ARRAY_COUNT(shaders)); s++) {
1650fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com            canvas->save();
1663914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com            int i = 2*s;
1673914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com            canvas->translate(SkIntToScalar((i / testsPerCol) * colWidth),
1683914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com                              SkIntToScalar((i % testsPerCol) * rowHeight));
1693914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com            paint.setShader(shaders[s])->unref();
1700fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com            canvas->drawText(text, textLen, 0, textBase, paint);
1710fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com            canvas->restore();
1723914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com            canvas->save();
1733914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com            ++i;
1743914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com            canvas->translate(SkIntToScalar((i / testsPerCol) * colWidth),
1753914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com                              SkIntToScalar((i % testsPerCol) * rowHeight));
1763914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com            canvas->drawTextOnPath(text, textLen, path, NULL, paint);
1773914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com            canvas->restore();
1780fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        }
1790fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com        canvas->restore();
1803914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com
1810fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    }
1820fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
1830fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.comprivate:
1840fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com    typedef GM INHERITED;
1850fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com};
1860fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
1870fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com///////////////////////////////////////////////////////////////////////////////
1880fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com
1890fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.comstatic GM* MyFactory(void*) { return new ShaderTextGM; }
1900fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.comstatic GMRegistry reg(MyFactory);
1910fdaa22dea3b139d7afa1daec4248aca1793460absalomon@google.com}
192