Coverage Report

Created: 2024-09-14 07:19

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