1 /* 2 * Copyright 2017 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "SkGradientShader.h" 9 #include "SkSVGRadialGradient.h" 10 #include "SkSVGRenderContext.h" 11 #include "SkSVGValue.h" 12 13 SkSVGRadialGradient::SkSVGRadialGradient() : INHERITED(SkSVGTag::kRadialGradient) {} 14 15 void SkSVGRadialGradient::setCx(const SkSVGLength& cx) { 16 fCx = cx; 17 } 18 19 void SkSVGRadialGradient::setCy(const SkSVGLength& cy) { 20 fCy = cy; 21 } 22 23 void SkSVGRadialGradient::setR(const SkSVGLength& r) { 24 fR = r; 25 } 26 27 void SkSVGRadialGradient::setFx(const SkSVGLength& fx) { 28 fFx.set(fx); 29 } 30 31 void SkSVGRadialGradient::setFy(const SkSVGLength& fy) { 32 fFy.set(fy); 33 } 34 35 void SkSVGRadialGradient::onSetAttribute(SkSVGAttribute attr, const SkSVGValue& v) { 36 switch (attr) { 37 case SkSVGAttribute::kCx: 38 if (const auto* cx = v.as<SkSVGLengthValue>()) { 39 this->setCx(*cx); 40 } 41 break; 42 case SkSVGAttribute::kCy: 43 if (const auto* cy = v.as<SkSVGLengthValue>()) { 44 this->setCy(*cy); 45 } 46 break; 47 case SkSVGAttribute::kR: 48 if (const auto* r = v.as<SkSVGLengthValue>()) { 49 this->setR(*r); 50 } 51 break; 52 case SkSVGAttribute::kFx: 53 if (const auto* fx = v.as<SkSVGLengthValue>()) { 54 this->setFx(*fx); 55 } 56 break; 57 case SkSVGAttribute::kFy: 58 if (const auto* fy = v.as<SkSVGLengthValue>()) { 59 this->setFy(*fy); 60 } 61 break; 62 default: 63 this->INHERITED::onSetAttribute(attr, v); 64 } 65 } 66 67 sk_sp<SkShader> SkSVGRadialGradient::onMakeShader(const SkSVGRenderContext& ctx, 68 const SkColor* colors, const SkScalar* pos, 69 int count, SkShader::TileMode tm, 70 const SkMatrix& m) const { 71 const auto& lctx = ctx.lengthContext(); 72 const auto r = lctx.resolve(fR , SkSVGLengthContext::LengthType::kOther); 73 const auto center = SkPoint::Make( 74 lctx.resolve(fCx, SkSVGLengthContext::LengthType::kHorizontal), 75 lctx.resolve(fCy, SkSVGLengthContext::LengthType::kVertical)); 76 const auto focal = SkPoint::Make( 77 fFx.isValid() ? lctx.resolve(*fFx.get(), SkSVGLengthContext::LengthType::kHorizontal) 78 : center.x(), 79 fFy.isValid() ? lctx.resolve(*fFy.get(), SkSVGLengthContext::LengthType::kVertical) 80 : center.y()); 81 82 return center == focal 83 ? SkGradientShader::MakeRadial(center, r, colors, pos, count, tm, 0, &m) 84 : SkGradientShader::MakeTwoPointConical(focal, 0, center, r, colors, pos, count, tm, 0, &m); 85 } 86