• 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 "include/core/SkCanvas.h"
9 #include "modules/svg/include/SkSVGRenderContext.h"
10 #include "modules/svg/include/SkSVGSVG.h"
11 #include "modules/svg/include/SkSVGValue.h"
12 
onPrepareToRender(SkSVGRenderContext * ctx) const13 bool SkSVGSVG::onPrepareToRender(SkSVGRenderContext* ctx) const {
14     // x/y are ignored for outermost svg elements
15     const auto x = fType == Type::kInner ? fX : SkSVGLength(0);
16     const auto y = fType == Type::kInner ? fY : SkSVGLength(0);
17 
18     auto viewPortRect  = ctx->lengthContext().resolveRectForSVG(x, y, fWidth, fHeight);
19     auto contentMatrix = SkMatrix::Translate(viewPortRect.x(), viewPortRect.y());
20     auto viewPort      = SkSize::Make(viewPortRect.width(), viewPortRect.height());
21 
22     if (fViewBox.isValid()) {
23         const SkRect& viewBox = *fViewBox;
24 
25         // An empty viewbox disables rendering.
26         if (viewBox.isEmpty()) {
27             return false;
28         }
29 
30         // A viewBox overrides the intrinsic viewport.
31         viewPort = SkSize::Make(viewBox.width(), viewBox.height());
32 
33         contentMatrix.preConcat(ComputeViewboxMatrix(viewBox, viewPortRect, fPreserveAspectRatio));
34     }
35 
36     if (!contentMatrix.isIdentity()) {
37         ctx->saveOnce();
38         ctx->canvas()->concat(contentMatrix);
39     }
40 
41     if (viewPort != ctx->lengthContext().viewPort()) {
42         ctx->writableLengthContext()->setViewPort(viewPort);
43     }
44 
45     return this->INHERITED::onPrepareToRender(ctx);
46 }
47 
onSetAttribute(SkSVGAttribute attr,const SkSVGValue & v)48 void SkSVGSVG::onSetAttribute(SkSVGAttribute attr, const SkSVGValue& v) {
49     switch (attr) {
50     case SkSVGAttribute::kX:
51         if (const auto* x = v.as<SkSVGLengthValue>()) {
52             this->setX(*x);
53         }
54         break;
55     case SkSVGAttribute::kY:
56         if (const auto* y = v.as<SkSVGLengthValue>()) {
57             this->setY(*y);
58         }
59         break;
60     case SkSVGAttribute::kWidth:
61         if (const auto* w = v.as<SkSVGLengthValue>()) {
62             this->setWidth(*w);
63         }
64         break;
65     case SkSVGAttribute::kHeight:
66         if (const auto* h = v.as<SkSVGLengthValue>()) {
67             this->setHeight(*h);
68         }
69         break;
70     case SkSVGAttribute::kViewBox:
71         if (const auto* vb = v.as<SkSVGViewBoxValue>()) {
72             this->setViewBox(*vb);
73         }
74         break;
75     case SkSVGAttribute::kPreserveAspectRatio:
76         if (const auto* par = v.as<SkSVGPreserveAspectRatioValue>()) {
77             this->setPreserveAspectRatio(*par);
78         }
79         break;
80     default:
81         this->INHERITED::onSetAttribute(attr, v);
82     }
83 }
84 
85 // https://www.w3.org/TR/SVG11/coords.html#IntrinsicSizing
intrinsicSize(const SkSVGLengthContext & lctx) const86 SkSize SkSVGSVG::intrinsicSize(const SkSVGLengthContext& lctx) const {
87     // Percentage values do not provide an intrinsic size.
88     if (fWidth.unit() == SkSVGLength::Unit::kPercentage ||
89         fHeight.unit() == SkSVGLength::Unit::kPercentage) {
90         return SkSize::Make(0, 0);
91     }
92 
93     return SkSize::Make(lctx.resolveForSVG(fWidth, SkSVGLengthContext::LengthType::kHorizontal),
94                         lctx.resolveForSVG(fHeight, SkSVGLengthContext::LengthType::kVertical));
95 }
96