Home | History | Annotate | Download | only in model
      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