1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/* 2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2011 Google Inc. 3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * 4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be 5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file. 6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "gm.h" 9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "sk_tool_utils.h" 10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkCanvas.h" 11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkGradientShader.h" 12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPath.h" 13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotnamespace skiagm { 15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void makebm(SkBitmap* bm, int w, int h) { 17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bm->allocN32Pixels(w, h); 18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bm->eraseColor(SK_ColorTRANSPARENT); 19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCanvas canvas(*bm); 21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar s = SkIntToScalar(SkMin32(w, h)); 22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPoint pts[] = { { 0, 0 }, { s, s } }; 23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE }; 24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar pos[] = { 0, SK_Scalar1/2, SK_Scalar1 }; 25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPaint paint; 26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.setDither(true); 28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.setShader(SkGradientShader::MakeLinear(pts, colors, pos, SK_ARRAY_COUNT(colors), 29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkShader::kClamp_TileMode)); 30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas.drawPaint(paint); 31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/////////////////////////////////////////////////////////////////////////////// 34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstruct GradData { 36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int fCount; 37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkColor* fColors; 38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkScalar* fPos; 39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotconstexpr SkColor gColors[] = { 42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK 43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotconstexpr GradData gGradData[] = { 46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 2, gColors, nullptr }, 47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 5, gColors, nullptr }, 48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic sk_sp<SkShader> MakeLinear(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) { 51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return SkGradientShader::MakeLinear(pts, data.fColors, data.fPos, data.fCount, tm); 52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic sk_sp<SkShader> MakeRadial(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) { 55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPoint center; 56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot center.set(SkScalarAve(pts[0].fX, pts[1].fX), 57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalarAve(pts[0].fY, pts[1].fY)); 58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return SkGradientShader::MakeRadial(center, center.fX, data.fColors, data.fPos, data.fCount, 59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot tm); 60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic sk_sp<SkShader> MakeSweep(const SkPoint pts[2], const GradData& data, SkShader::TileMode) { 63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPoint center; 64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot center.set(SkScalarAve(pts[0].fX, pts[1].fX), 65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalarAve(pts[0].fY, pts[1].fY)); 66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return SkGradientShader::MakeSweep(center.fX, center.fY, data.fColors, data.fPos, data.fCount); 67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic sk_sp<SkShader> Make2Conical(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) { 70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPoint center0, center1; 71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot center0.set(SkScalarAve(pts[0].fX, pts[1].fX), 72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalarAve(pts[0].fY, pts[1].fY)); 73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5), 74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4)); 75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return SkGradientShader::MakeTwoPointConical( 76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot center1, (pts[1].fX - pts[0].fX) / 7, 77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot center0, (pts[1].fX - pts[0].fX) / 2, 78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot data.fColors, data.fPos, data.fCount, tm); 79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robottypedef sk_sp<SkShader> (*GradMaker)(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm); 82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotconstexpr GradMaker gGradMakers[] = { 84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot MakeLinear, MakeRadial, MakeSweep, Make2Conical 85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/////////////////////////////////////////////////////////////////////////////// 88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass ShaderTextGM : public GM { 90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic: 91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ShaderTextGM() { 92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->setBGColor(sk_tool_utils::color_to_565(0xFFDDDDDD)); 93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprotected: 96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkString onShortName() override { 98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return SkString("shadertext"); 99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkISize onISize() override { return SkISize::Make(1450, 500); } 102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void onDraw(SkCanvas* canvas) override { 104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const char text[] = "Shaded Text"; 105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const int textLen = SK_ARRAY_COUNT(text) - 1; 106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const int pointSize = 36; 107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const int w = pointSize * textLen; 109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const int h = pointSize; 110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPoint pts[2] = { 112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 0, 0 }, 113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { SkIntToScalar(w), SkIntToScalar(h) } 114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar textBase = SkIntToScalar(h/2); 116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkShader::TileMode tileModes[] = { 118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkShader::kClamp_TileMode, 119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkShader::kRepeat_TileMode, 120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkShader::kMirror_TileMode 121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot constexpr int gradCount = SK_ARRAY_COUNT(gGradData) * 124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SK_ARRAY_COUNT(gGradMakers); 125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot constexpr int bmpCount = SK_ARRAY_COUNT(tileModes) * 126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SK_ARRAY_COUNT(tileModes); 127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkShader> shaders[gradCount + bmpCount]; 128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int shdIdx = 0; 130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (size_t d = 0; d < SK_ARRAY_COUNT(gGradData); ++d) { 131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (size_t m = 0; m < SK_ARRAY_COUNT(gGradMakers); ++m) { 132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot shaders[shdIdx++] = gGradMakers[m](pts, 133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot gGradData[d], 134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkShader::kClamp_TileMode); 135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkBitmap bm; 139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot makebm(&bm, w/16, h/4); 140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (size_t tx = 0; tx < SK_ARRAY_COUNT(tileModes); ++tx) { 141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (size_t ty = 0; ty < SK_ARRAY_COUNT(tileModes); ++ty) { 142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot shaders[shdIdx++] = SkShader::MakeBitmapShader(bm, tileModes[tx], tileModes[ty]); 143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPaint paint; 147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.setDither(true); 148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.setAntiAlias(true); 149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_tool_utils::set_portable_typeface(&paint); 150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.setTextSize(SkIntToScalar(pointSize)); 151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->save(); 153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->translate(SkIntToScalar(20), SkIntToScalar(10)); 154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath path; 156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot path.arcTo(SkRect::MakeXYWH(SkIntToScalar(-40), SkIntToScalar(15), 157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkIntToScalar(300), SkIntToScalar(90)), 158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkIntToScalar(225), SkIntToScalar(90), 159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot false); 160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot path.close(); 161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot constexpr int testsPerCol = 8; 163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot constexpr int rowHeight = 60; 164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot constexpr int colWidth = 300; 165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->save(); 166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int s = 0; s < static_cast<int>(SK_ARRAY_COUNT(shaders)); s++) { 167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->save(); 168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int i = 2*s; 169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->translate(SkIntToScalar((i / testsPerCol) * colWidth), 170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkIntToScalar((i % testsPerCol) * rowHeight)); 171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.setShader(shaders[s]); 172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawText(text, textLen, 0, textBase, paint); 173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->restore(); 174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->save(); 175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ++i; 176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->translate(SkIntToScalar((i / testsPerCol) * colWidth), 177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkIntToScalar((i % testsPerCol) * rowHeight)); 178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawTextOnPath(text, textLen, path, nullptr, paint); 179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->restore(); 180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->restore(); 182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate: 186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot typedef GM INHERITED; 187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/////////////////////////////////////////////////////////////////////////////// 190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic GM* MyFactory(void*) { return new ShaderTextGM; } 192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic GMRegistry reg(MyFactory); 193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 194