• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "SkSVGRenderContext.h"
10 #include "SkSVGSVG.h"
11 #include "SkSVGValue.h"
12 
SkSVGSVG()13 SkSVGSVG::SkSVGSVG() : INHERITED(SkSVGTag::kSvg) { }
14 
onPrepareToRender(SkSVGRenderContext * ctx) const15 bool SkSVGSVG::onPrepareToRender(SkSVGRenderContext* ctx) const {
16     auto viewPortRect  = ctx->lengthContext().resolveRect(fX, fY, fWidth, fHeight);
17     auto contentMatrix = SkMatrix::MakeTrans(viewPortRect.x(), viewPortRect.y());
18     auto viewPort      = SkSize::Make(viewPortRect.width(), viewPortRect.height());
19 
20     if (fViewBox.isValid()) {
21         const SkRect& viewBox = *fViewBox.get();
22 
23         // An empty viewbox disables rendering.
24         if (viewBox.isEmpty()) {
25             return false;
26         }
27 
28         // A viewBox overrides the intrinsic viewport.
29         viewPort = SkSize::Make(viewBox.width(), viewBox.height());
30 
31         contentMatrix.preConcat(
32             SkMatrix::MakeRectToRect(viewBox, viewPortRect, SkMatrix::kFill_ScaleToFit));
33     }
34 
35     if (!contentMatrix.isIdentity()) {
36         ctx->canvas()->save();
37         ctx->canvas()->concat(contentMatrix);
38     }
39 
40     if (viewPort != ctx->lengthContext().viewPort()) {
41         ctx->writableLengthContext()->setViewPort(viewPort);
42     }
43 
44     return this->INHERITED::onPrepareToRender(ctx);
45 }
46 
setX(const SkSVGLength & x)47 void SkSVGSVG::setX(const SkSVGLength& x) {
48     fX = x;
49 }
50 
setY(const SkSVGLength & y)51 void SkSVGSVG::setY(const SkSVGLength& y) {
52     fY = y;
53 }
54 
setWidth(const SkSVGLength & w)55 void SkSVGSVG::setWidth(const SkSVGLength& w) {
56     fWidth = w;
57 }
58 
setHeight(const SkSVGLength & h)59 void SkSVGSVG::setHeight(const SkSVGLength& h) {
60     fHeight = h;
61 }
62 
setViewBox(const SkSVGViewBoxType & vb)63 void SkSVGSVG::setViewBox(const SkSVGViewBoxType& vb) {
64     fViewBox.set(vb);
65 }
66 
onSetAttribute(SkSVGAttribute attr,const SkSVGValue & v)67 void SkSVGSVG::onSetAttribute(SkSVGAttribute attr, const SkSVGValue& v) {
68     switch (attr) {
69     case SkSVGAttribute::kX:
70         if (const auto* x = v.as<SkSVGLengthValue>()) {
71             this->setX(*x);
72         }
73         break;
74     case SkSVGAttribute::kY:
75         if (const auto* y = v.as<SkSVGLengthValue>()) {
76             this->setY(*y);
77         }
78         break;
79     case SkSVGAttribute::kWidth:
80         if (const auto* w = v.as<SkSVGLengthValue>()) {
81             this->setWidth(*w);
82         }
83         break;
84     case SkSVGAttribute::kHeight:
85         if (const auto* h = v.as<SkSVGLengthValue>()) {
86             this->setHeight(*h);
87         }
88         break;
89     case SkSVGAttribute::kViewBox:
90         if (const auto* vb = v.as<SkSVGViewBoxValue>()) {
91             this->setViewBox(*vb);
92         }
93         break;
94     default:
95         this->INHERITED::onSetAttribute(attr, v);
96     }
97 }
98 
99 // https://www.w3.org/TR/SVG/coords.html#IntrinsicSizing
intrinsicSize(const SkSVGLengthContext & lctx) const100 SkSize SkSVGSVG::intrinsicSize(const SkSVGLengthContext& lctx) const {
101     // Percentage values do not provide an intrinsic size.
102     if (fWidth.unit() == SkSVGLength::Unit::kPercentage ||
103         fHeight.unit() == SkSVGLength::Unit::kPercentage) {
104         return SkSize::Make(0, 0);
105     }
106 
107     return SkSize::Make(lctx.resolve(fWidth, SkSVGLengthContext::LengthType::kHorizontal),
108                         lctx.resolve(fHeight, SkSVGLengthContext::LengthType::kVertical));
109 }
110