1 /*
2  * Copyright 2016 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 "SkCanvas.h"
9 #include "SkRect.h"
10 #include "SkSVGRect.h"
11 #include "SkSVGRenderContext.h"
12 #include "SkSVGValue.h"
13 
SkSVGRect()14 SkSVGRect::SkSVGRect() : INHERITED(SkSVGTag::kRect) {}
15 
setX(const SkSVGLength & x)16 void SkSVGRect::setX(const SkSVGLength& x) {
17     fX = x;
18 }
19 
setY(const SkSVGLength & y)20 void SkSVGRect::setY(const SkSVGLength& y) {
21     fY = y;
22 }
23 
setWidth(const SkSVGLength & w)24 void SkSVGRect::setWidth(const SkSVGLength& w) {
25     fWidth = w;
26 }
27 
setHeight(const SkSVGLength & h)28 void SkSVGRect::setHeight(const SkSVGLength& h) {
29     fHeight = h;
30 }
31 
setRx(const SkSVGLength & rx)32 void SkSVGRect::setRx(const SkSVGLength& rx) {
33     fRx = rx;
34 }
35 
setRy(const SkSVGLength & ry)36 void SkSVGRect::setRy(const SkSVGLength& ry) {
37     fRy = ry;
38 }
39 
onSetAttribute(SkSVGAttribute attr,const SkSVGValue & v)40 void SkSVGRect::onSetAttribute(SkSVGAttribute attr, const SkSVGValue& v) {
41     switch (attr) {
42     case SkSVGAttribute::kX:
43         if (const auto* x = v.as<SkSVGLengthValue>()) {
44             this->setX(*x);
45         }
46         break;
47     case SkSVGAttribute::kY:
48         if (const auto* y = v.as<SkSVGLengthValue>()) {
49             this->setY(*y);
50         }
51         break;
52     case SkSVGAttribute::kWidth:
53         if (const auto* w = v.as<SkSVGLengthValue>()) {
54             this->setWidth(*w);
55         }
56         break;
57     case SkSVGAttribute::kHeight:
58         if (const auto* h = v.as<SkSVGLengthValue>()) {
59             this->setHeight(*h);
60         }
61         break;
62     case SkSVGAttribute::kRx:
63         if (const auto* rx = v.as<SkSVGLengthValue>()) {
64             this->setRx(*rx);
65         }
66         break;
67     case SkSVGAttribute::kRy:
68         if (const auto* ry = v.as<SkSVGLengthValue>()) {
69             this->setRy(*ry);
70         }
71         break;
72     default:
73         this->INHERITED::onSetAttribute(attr, v);
74     }
75 }
76 
resolve(const SkSVGLengthContext & lctx) const77 SkRRect SkSVGRect::resolve(const SkSVGLengthContext& lctx) const {
78     const SkRect rect = lctx.resolveRect(fX, fY, fWidth, fHeight);
79     const SkScalar rx = lctx.resolve(fRx, SkSVGLengthContext::LengthType::kHorizontal);
80     const SkScalar ry = lctx.resolve(fRy, SkSVGLengthContext::LengthType::kVertical);
81 
82     return SkRRect::MakeRectXY(rect, rx ,ry);
83 }
84 
onDraw(SkCanvas * canvas,const SkSVGLengthContext & lctx,const SkPaint & paint,SkPath::FillType) const85 void SkSVGRect::onDraw(SkCanvas* canvas, const SkSVGLengthContext& lctx,
86                        const SkPaint& paint, SkPath::FillType) const {
87     canvas->drawRRect(this->resolve(lctx), paint);
88 }
89 
onAsPath(const SkSVGRenderContext & ctx) const90 SkPath SkSVGRect::onAsPath(const SkSVGRenderContext& ctx) const {
91     SkPath path;
92     path.addRRect(this->resolve(ctx.lengthContext()));
93 
94     this->mapToParent(&path);
95 
96     return path;
97 }
98