1589708bf7c706348b763e8277004cb160b202bdbrileya@google.com/*
2589708bf7c706348b763e8277004cb160b202bdbrileya@google.com * Copyright 2012 Google Inc.
3589708bf7c706348b763e8277004cb160b202bdbrileya@google.com *
4589708bf7c706348b763e8277004cb160b202bdbrileya@google.com * Use of this source code is governed by a BSD-style license that can be
5589708bf7c706348b763e8277004cb160b202bdbrileya@google.com * found in the LICENSE file.
6589708bf7c706348b763e8277004cb160b202bdbrileya@google.com */
7589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
84cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian Salomon#include "SkLinearGradient.h"
9d4e9ec86cf934107cc441f651ee2429078188d02Florin Malita
10bc590c01b00ef79e1e1f30058e7a70a29419f2a9fmalita#include "Sk4fLinearGradient.h"
116cc6ae7573fdfd0af1f9488349b1d2bb88c1b01dMatt Sarett#include "SkColorSpaceXformer.h"
12d4e9ec86cf934107cc441f651ee2429078188d02Florin Malita#include "SkReadBuffer.h"
13d4e9ec86cf934107cc441f651ee2429078188d02Florin Malita#include "SkWriteBuffer.h"
14589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
15cc695fee81613dc92746c1c6bb27f45cfc6ce73emtkleinstatic SkMatrix pts_to_unit_matrix(const SkPoint pts[2]) {
16589708bf7c706348b763e8277004cb160b202bdbrileya@google.com    SkVector    vec = pts[1] - pts[0];
17589708bf7c706348b763e8277004cb160b202bdbrileya@google.com    SkScalar    mag = vec.length();
18589708bf7c706348b763e8277004cb160b202bdbrileya@google.com    SkScalar    inv = mag ? SkScalarInvert(mag) : 0;
19589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
20589708bf7c706348b763e8277004cb160b202bdbrileya@google.com    vec.scale(inv);
21cc695fee81613dc92746c1c6bb27f45cfc6ce73emtklein    SkMatrix matrix;
22cc695fee81613dc92746c1c6bb27f45cfc6ce73emtklein    matrix.setSinCos(-vec.fY, vec.fX, pts[0].fX, pts[0].fY);
23cc695fee81613dc92746c1c6bb27f45cfc6ce73emtklein    matrix.postTranslate(-pts[0].fX, -pts[0].fY);
24cc695fee81613dc92746c1c6bb27f45cfc6ce73emtklein    matrix.postScale(inv, inv);
25cc695fee81613dc92746c1c6bb27f45cfc6ce73emtklein    return matrix;
26589708bf7c706348b763e8277004cb160b202bdbrileya@google.com}
27589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
28589708bf7c706348b763e8277004cb160b202bdbrileya@google.com///////////////////////////////////////////////////////////////////////////////
29589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
30addf2edf3da20f053daa3897cfe2c52d7369a7b1reedSkLinearGradient::SkLinearGradient(const SkPoint pts[2], const Descriptor& desc)
31cc695fee81613dc92746c1c6bb27f45cfc6ce73emtklein    : SkGradientShaderBase(desc, pts_to_unit_matrix(pts))
32589708bf7c706348b763e8277004cb160b202bdbrileya@google.com    , fStart(pts[0])
33cc695fee81613dc92746c1c6bb27f45cfc6ce73emtklein    , fEnd(pts[1]) {
34589708bf7c706348b763e8277004cb160b202bdbrileya@google.com}
35589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
3660c9b58b3214b0154c931656e91e39b230e987d8reedsk_sp<SkFlattenable> SkLinearGradient::CreateProc(SkReadBuffer& buffer) {
379fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed    DescriptorScope desc;
389fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed    if (!desc.unflatten(buffer)) {
3996fcdcc219d2a0d3579719b84b28bede76efba64halcanary        return nullptr;
409fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed    }
419fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed    SkPoint pts[2];
429fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed    pts[0] = buffer.readPoint();
439fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed    pts[1] = buffer.readPoint();
44e25d71ccbcdb47c7ee7bdf13235066092ae11af3brianosman    return SkGradientShader::MakeLinear(pts, desc.fColors, std::move(desc.fColorSpace), desc.fPos,
45e25d71ccbcdb47c7ee7bdf13235066092ae11af3brianosman                                        desc.fCount, desc.fTileMode, desc.fGradFlags,
46e25d71ccbcdb47c7ee7bdf13235066092ae11af3brianosman                                        desc.fLocalMatrix);
479fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed}
48589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
498b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkLinearGradient::flatten(SkWriteBuffer& buffer) const {
50589708bf7c706348b763e8277004cb160b202bdbrileya@google.com    this->INHERITED::flatten(buffer);
51589708bf7c706348b763e8277004cb160b202bdbrileya@google.com    buffer.writePoint(fStart);
52589708bf7c706348b763e8277004cb160b202bdbrileya@google.com    buffer.writePoint(fEnd);
53589708bf7c706348b763e8277004cb160b202bdbrileya@google.com}
54589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
554aed13889bd9085337e0d4c20df28686687b833bFlorin MalitaSkShaderBase::Context* SkLinearGradient::onMakeContext(
5683e939bcb79790f5ae3b28c398fbcf034675a6e5Herb Derby    const ContextRec& rec, SkArenaAlloc* alloc) const
5783e939bcb79790f5ae3b28c398fbcf034675a6e5Herb Derby{
58aa0ce825b877871f73532beb6fde6bf2f80e99ddFlorin Malita    return CheckedMakeContext<LinearGradient4fContext>(alloc, *this, rec);
5987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org}
6087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org
6147e55a5115bd1d47bdb097d37b6b9e0ecdd4fa86Florin MalitaSkShaderBase::Context* SkLinearGradient::onMakeBurstPipelineContext(
6247e55a5115bd1d47bdb097d37b6b9e0ecdd4fa86Florin Malita    const ContextRec& rec, SkArenaAlloc* alloc) const {
6347e55a5115bd1d47bdb097d37b6b9e0ecdd4fa86Florin Malita
64dfc0e910dfdf7ad11995d357e44c029d839f2e73Mike Reed    if (fTileMode == SkShader::kDecal_TileMode) {
65dfc0e910dfdf7ad11995d357e44c029d839f2e73Mike Reed        // we only support decal w/ stages
66dfc0e910dfdf7ad11995d357e44c029d839f2e73Mike Reed        return nullptr;
67dfc0e910dfdf7ad11995d357e44c029d839f2e73Mike Reed    }
68a924dd3b7ec550791224a0f1b9cf55e8b5a1ab64Florin Malita    // Raster pipeline has a 2-stop specialization faster than our burst.
69a924dd3b7ec550791224a0f1b9cf55e8b5a1ab64Florin Malita    return fColorCount > 2 ? CheckedMakeContext<LinearGradient4fContext>(alloc, *this, rec)
70a924dd3b7ec550791224a0f1b9cf55e8b5a1ab64Florin Malita                           : nullptr;
7147e55a5115bd1d47bdb097d37b6b9e0ecdd4fa86Florin Malita}
7247e55a5115bd1d47bdb097d37b6b9e0ecdd4fa86Florin Malita
7350b2084bd15e7aea416dc8c6fd2373864c50f023Florin Malitavoid SkLinearGradient::appendGradientStages(SkArenaAlloc*, SkRasterPipeline*,
7450b2084bd15e7aea416dc8c6fd2373864c50f023Florin Malita                                            SkRasterPipeline*) const {
7550b2084bd15e7aea416dc8c6fd2373864c50f023Florin Malita    // No extra stage needed for linear gradients.
76c86e470c190934a2f7680ed10cf9fad757e1ab75Florin Malita}
77c86e470c190934a2f7680ed10cf9fad757e1ab75Florin Malita
786cc6ae7573fdfd0af1f9488349b1d2bb88c1b01dMatt Sarettsk_sp<SkShader> SkLinearGradient::onMakeColorSpace(SkColorSpaceXformer* xformer) const {
7939d71dec606781037839faf49a9be25be7560bf1Florin Malita    const AutoXformColors xformedColors(*this, xformer);
806cc6ae7573fdfd0af1f9488349b1d2bb88c1b01dMatt Sarett    SkPoint pts[2] = { fStart, fEnd };
8139d71dec606781037839faf49a9be25be7560bf1Florin Malita    return SkGradientShader::MakeLinear(pts, xformedColors.fColors.get(), fOrigPos, fColorCount,
826cc6ae7573fdfd0af1f9488349b1d2bb88c1b01dMatt Sarett                                        fTileMode, fGradFlags, &this->getLocalMatrix());
836cc6ae7573fdfd0af1f9488349b1d2bb88c1b01dMatt Sarett}
846cc6ae7573fdfd0af1f9488349b1d2bb88c1b01dMatt Sarett
85589708bf7c706348b763e8277004cb160b202bdbrileya@google.comSkShader::GradientType SkLinearGradient::asAGradient(GradientInfo* info) const {
86589708bf7c706348b763e8277004cb160b202bdbrileya@google.com    if (info) {
87589708bf7c706348b763e8277004cb160b202bdbrileya@google.com        commonAsAGradient(info);
88589708bf7c706348b763e8277004cb160b202bdbrileya@google.com        info->fPoint[0] = fStart;
89589708bf7c706348b763e8277004cb160b202bdbrileya@google.com        info->fPoint[1] = fEnd;
90589708bf7c706348b763e8277004cb160b202bdbrileya@google.com    }
91589708bf7c706348b763e8277004cb160b202bdbrileya@google.com    return kLinear_GradientType;
92589708bf7c706348b763e8277004cb160b202bdbrileya@google.com}
93589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
94cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
95cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com
9694efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon#include "GrShaderCaps.h"
977ea439b2203855db97330b25945b87dd4b170b8begdaniel#include "glsl/GrGLSLFragmentShaderBuilder.h"
989de5b514d38c5b36066bcdc14fba2f7e5196d372dandov#include "SkGr.h"
992eaaefd7e6a58339b3f93333f1e9cc92252cc303bsalomon@google.com
100d7cc651b8da11d52ae90e910b948f5e2d15daaf9rileya@google.com/////////////////////////////////////////////////////////////////////
101d7cc651b8da11d52ae90e910b948f5e2d15daaf9rileya@google.com
10298e8b6de04e4c20451fbe3353645e3e384a76550rileya@google.comclass GrLinearGradient : public GrGradientEffect {
10398e8b6de04e4c20451fbe3353645e3e384a76550rileya@google.compublic:
10455d318d35f672e9a4b7e1f2f10ce4e31312f49b6fmenozzi    class GLSLLinearProcessor;
10598e8b6de04e4c20451fbe3353645e3e384a76550rileya@google.com
106aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon    static std::unique_ptr<GrFragmentProcessor> Make(const CreateArgs& args) {
1075911a7cf214ccd824a8c7830f8e29f218c8fe422Brian Osman        return GrGradientEffect::AdjustFP(std::unique_ptr<GrLinearGradient>(
1085911a7cf214ccd824a8c7830f8e29f218c8fe422Brian Osman                new GrLinearGradient(args)),
1095911a7cf214ccd824a8c7830f8e29f218c8fe422Brian Osman                args);
1100ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com    }
1110ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com
11236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    const char* name() const override { return "Linear Gradient"; }
113eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
114aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon    std::unique_ptr<GrFragmentProcessor> clone() const override {
115aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon        return std::unique_ptr<GrFragmentProcessor>(new GrLinearGradient(*this));
116f8480b90551d29484d51e74f6a43c9ab95b5d95cBrian Salomon    }
117f8480b90551d29484d51e74f6a43c9ab95b5d95cBrian Salomon
11898e8b6de04e4c20451fbe3353645e3e384a76550rileya@google.comprivate:
119f8480b90551d29484d51e74f6a43c9ab95b5d95cBrian Salomon    explicit GrLinearGradient(const CreateArgs& args)
120abff956455637b12eab374fd44b99e1338799113Ethan Nicholas            : INHERITED(kGrLinearGradient_ClassID, args, args.fShader->colorsAreOpaque()) {
121f8480b90551d29484d51e74f6a43c9ab95b5d95cBrian Salomon    }
122f8480b90551d29484d51e74f6a43c9ab95b5d95cBrian Salomon
123abff956455637b12eab374fd44b99e1338799113Ethan Nicholas    explicit GrLinearGradient(const GrLinearGradient& that) : INHERITED(that) {}
1244b3050b410254d0cb38df9a30ae2e209124fa1a2wangyix
12555d318d35f672e9a4b7e1f2f10ce4e31312f49b6fmenozzi    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
126b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyix
1270c26a9dbd0b6546731df63c01411cb2aaa5ba236Brian Salomon    GR_DECLARE_FRAGMENT_PROCESSOR_TEST
12898e8b6de04e4c20451fbe3353645e3e384a76550rileya@google.com
12998e8b6de04e4c20451fbe3353645e3e384a76550rileya@google.com    typedef GrGradientEffect INHERITED;
13098e8b6de04e4c20451fbe3353645e3e384a76550rileya@google.com};
13198e8b6de04e4c20451fbe3353645e3e384a76550rileya@google.com
13298e8b6de04e4c20451fbe3353645e3e384a76550rileya@google.com/////////////////////////////////////////////////////////////////////
13398e8b6de04e4c20451fbe3353645e3e384a76550rileya@google.com
13455d318d35f672e9a4b7e1f2f10ce4e31312f49b6fmenozziclass GrLinearGradient::GLSLLinearProcessor : public GrGradientEffect::GLSLProcessor {
13555d318d35f672e9a4b7e1f2f10ce4e31312f49b6fmenozzipublic:
13655d318d35f672e9a4b7e1f2f10ce4e31312f49b6fmenozzi    GLSLLinearProcessor(const GrProcessor&) {}
13755d318d35f672e9a4b7e1f2f10ce4e31312f49b6fmenozzi
13855d318d35f672e9a4b7e1f2f10ce4e31312f49b6fmenozzi    virtual void emitCode(EmitArgs&) override;
13955d318d35f672e9a4b7e1f2f10ce4e31312f49b6fmenozzi
14055d318d35f672e9a4b7e1f2f10ce4e31312f49b6fmenozziprivate:
14155d318d35f672e9a4b7e1f2f10ce4e31312f49b6fmenozzi    typedef GrGradientEffect::GLSLProcessor INHERITED;
14255d318d35f672e9a4b7e1f2f10ce4e31312f49b6fmenozzi};
14355d318d35f672e9a4b7e1f2f10ce4e31312f49b6fmenozzi
14455d318d35f672e9a4b7e1f2f10ce4e31312f49b6fmenozzi/////////////////////////////////////////////////////////////////////
14555d318d35f672e9a4b7e1f2f10ce4e31312f49b6fmenozzi
14655d318d35f672e9a4b7e1f2f10ce4e31312f49b6fmenozziGrGLSLFragmentProcessor* GrLinearGradient::onCreateGLSLInstance() const {
14755d318d35f672e9a4b7e1f2f10ce4e31312f49b6fmenozzi    return new GrLinearGradient::GLSLLinearProcessor(*this);
14855d318d35f672e9a4b7e1f2f10ce4e31312f49b6fmenozzi}
14955d318d35f672e9a4b7e1f2f10ce4e31312f49b6fmenozzi
15055d318d35f672e9a4b7e1f2f10ce4e31312f49b6fmenozzi/////////////////////////////////////////////////////////////////////
15155d318d35f672e9a4b7e1f2f10ce4e31312f49b6fmenozzi
152b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrLinearGradient);
153d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com
1546f6961ebad65c582318564b3688e78e5c99f3935Hal Canary#if GR_TEST_UTILS
155aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomonstd::unique_ptr<GrFragmentProcessor> GrLinearGradient::TestCreate(GrProcessorTestData* d) {
1560067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    SkPoint points[] = {{d->fRandom->nextUScalar1(), d->fRandom->nextUScalar1()},
1570067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt                        {d->fRandom->nextUScalar1(), d->fRandom->nextUScalar1()}};
158d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com
1593f748606d8dcac21c7fcdd07c2083f611c633ad5Brian Osman    RandomGradientParams params(d->fRandom);
160a2196536782903d22011ed7145b8640c66fc72ffBrian Osman    auto shader = params.fUseColors4f ?
161a2196536782903d22011ed7145b8640c66fc72ffBrian Osman        SkGradientShader::MakeLinear(points, params.fColors4f, params.fColorSpace, params.fStops,
162a2196536782903d22011ed7145b8640c66fc72ffBrian Osman                                     params.fColorCount, params.fTileMode) :
163a2196536782903d22011ed7145b8640c66fc72ffBrian Osman        SkGradientShader::MakeLinear(points, params.fColors, params.fStops,
164a2196536782903d22011ed7145b8640c66fc72ffBrian Osman                                     params.fColorCount, params.fTileMode);
1659f532a3598891a74375a4659e0dc498b704e3cf1Brian Osman    GrTest::TestAsFPArgs asFPArgs(d);
166aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon    std::unique_ptr<GrFragmentProcessor> fp = as_SB(shader)->asFragmentProcessor(asFPArgs.args());
167c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon    GrAlwaysAssert(fp);
168b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    return fp;
169d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com}
1706f6961ebad65c582318564b3688e78e5c99f3935Hal Canary#endif
171d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com
172d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com/////////////////////////////////////////////////////////////////////
173d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com
17455d318d35f672e9a4b7e1f2f10ce4e31312f49b6fmenozzivoid GrLinearGradient::GLSLLinearProcessor::emitCode(EmitArgs& args) {
1757c157a988845fb00f9024d6db6dda142c3458033wangyix    const GrLinearGradient& ge = args.fFp.cast<GrLinearGradient>();
1767ea439b2203855db97330b25945b87dd4b170b8begdaniel    this->emitUniforms(args.fUniformHandler, ge);
1771a1aa9303484106a955e5549bf8ae24950f54e7absalomon    SkString t = args.fFragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
178d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com    t.append(".x");
1797ea439b2203855db97330b25945b87dd4b170b8begdaniel    this->emitColor(args.fFragBuilder,
1807ea439b2203855db97330b25945b87dd4b170b8begdaniel                    args.fUniformHandler,
1811edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon                    args.fShaderCaps,
18255d318d35f672e9a4b7e1f2f10ce4e31312f49b6fmenozzi                    ge,
18355d318d35f672e9a4b7e1f2f10ce4e31312f49b6fmenozzi                    t.c_str(),
1844ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                    args.fOutputColor,
1854ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                    args.fInputColor,
1863f6f76f98b6b37d17d1492791ff0feb1b7586bd6cdalton                    args.fTexSamplers);
187d7cc651b8da11d52ae90e910b948f5e2d15daaf9rileya@google.com}
188d7cc651b8da11d52ae90e910b948f5e2d15daaf9rileya@google.com
189d7cc651b8da11d52ae90e910b948f5e2d15daaf9rileya@google.com/////////////////////////////////////////////////////////////////////
190d7cc651b8da11d52ae90e910b948f5e2d15daaf9rileya@google.com
191aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomonstd::unique_ptr<GrFragmentProcessor> SkLinearGradient::asFragmentProcessor(
192e3429e62b0d020b27de3daa55893953eff581c4fMike Reed        const GrFPArgs& args) const {
193839345d63466a4209a0985654ec033624821fd78brianosman    SkASSERT(args.fContext);
1943f3b3d003527861dc0bd89733857576408906431mtklein
195dfdb7e5240276493077b7c6e1f3cc8b8a0e195babsalomon@google.com    SkMatrix matrix;
196f94b3a4cebd4adab09c40ebe23c02a615e10c394bsalomon@google.com    if (!this->getLocalMatrix().invert(&matrix)) {
197c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon        return nullptr;
198dfdb7e5240276493077b7c6e1f3cc8b8a0e195babsalomon@google.com    }
199839345d63466a4209a0985654ec033624821fd78brianosman    if (args.fLocalMatrix) {
20096fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org        SkMatrix inv;
201839345d63466a4209a0985654ec033624821fd78brianosman        if (!args.fLocalMatrix->invert(&inv)) {
202c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon            return nullptr;
20396fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org        }
20496fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org        matrix.postConcat(inv);
20596fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org    }
206f94b3a4cebd4adab09c40ebe23c02a615e10c394bsalomon@google.com    matrix.postConcat(fPtsToUnit);
2073f3b3d003527861dc0bd89733857576408906431mtklein
2085911a7cf214ccd824a8c7830f8e29f218c8fe422Brian Osman    return GrLinearGradient::Make(GrGradientEffect::CreateArgs(
2094cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian Salomon            args.fContext, this, &matrix, fTileMode, args.fDstColorSpaceInfo->colorSpace()));
210d7cc651b8da11d52ae90e910b948f5e2d15daaf9rileya@google.com}
211d7cc651b8da11d52ae90e910b948f5e2d15daaf9rileya@google.com
212cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com
213cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
21476f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com
2150f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org#ifndef SK_IGNORE_TO_STRING
21676f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.comvoid SkLinearGradient::toString(SkString* str) const {
21776f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com    str->append("SkLinearGradient (");
21876f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com
21976f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com    str->appendf("start: (%f, %f)", fStart.fX, fStart.fY);
22076f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com    str->appendf(" end: (%f, %f) ", fEnd.fX, fEnd.fY);
22176f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com
22276f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com    this->INHERITED::toString(str);
22376f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com
22476f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com    str->append(")");
22576f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com}
22676f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com#endif
227