blob: b0d6f93b77cd893454c5315600e91569482b10a0 [file] [log] [blame]
Florin Malita6a69c052017-10-11 14:02:11 -04001/*
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 "SkSVGUse.h"
9
10#include "SkCanvas.h"
11#include "SkSVGRenderContext.h"
12#include "SkSVGValue.h"
13
14SkSVGUse::SkSVGUse() : INHERITED(SkSVGTag::kUse) {}
15
16void SkSVGUse::appendChild(sk_sp<SkSVGNode>) {
17 SkDebugf("cannot append child nodes to this element.\n");
18}
19
20void SkSVGUse::setHref(const SkSVGStringType& href) {
21 fHref = href;
22}
23
24void SkSVGUse::setX(const SkSVGLength& x) {
25 fX = x;
26}
27
28void SkSVGUse::setY(const SkSVGLength& y) {
29 fY = y;
30}
31
32void SkSVGUse::onSetAttribute(SkSVGAttribute attr, const SkSVGValue& v) {
33 switch (attr) {
34 case SkSVGAttribute::kHref:
35 if (const auto* href = v.as<SkSVGStringValue>()) {
36 this->setHref(*href);
37 }
38 break;
39 case SkSVGAttribute::kX:
40 if (const auto* x = v.as<SkSVGLengthValue>()) {
41 this->setX(*x);
42 }
43 break;
44 case SkSVGAttribute::kY:
45 if (const auto* y = v.as<SkSVGLengthValue>()) {
46 this->setY(*y);
47 }
48 break;
49 default:
50 this->INHERITED::onSetAttribute(attr, v);
51 }
52}
53
54bool SkSVGUse::onPrepareToRender(SkSVGRenderContext* ctx) const {
55 if (fHref.value().isEmpty() || !INHERITED::onPrepareToRender(ctx)) {
56 return false;
57 }
58
59 if (fX.value() || fY.value()) {
60 // Restored when the local SkSVGRenderContext leaves scope.
Florin Malitab36be142017-10-11 14:11:16 -040061 ctx->saveOnce();
Florin Malita6a69c052017-10-11 14:02:11 -040062 ctx->canvas()->translate(fX.value(), fY.value());
63 }
64
65 // TODO: width/height override for <svg> targets.
66
67 return true;
68}
69
70void SkSVGUse::onRender(const SkSVGRenderContext& ctx) const {
71 const auto* ref = ctx.findNodeById(fHref);
72 if (!ref) {
73 return;
74 }
75
76 ref->render(ctx);
77}
78
79SkPath SkSVGUse::onAsPath(const SkSVGRenderContext& ctx) const {
80 const auto* ref = ctx.findNodeById(fHref);
81 if (!ref) {
82 return SkPath();
83 }
84
85 return ref->asPath(ctx);
86}