Coverage Report

Created: 2024-05-20 07:14

/src/skia/modules/skottie/src/layers/shapelayer/TrimPaths.cpp
Line
Count
Source
1
/*
2
 * Copyright 2020 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/SkRefCnt.h"
9
#include "include/core/SkScalar.h"
10
#include "include/effects/SkTrimPathEffect.h"
11
#include "modules/skottie/src/Adapter.h"
12
#include "modules/skottie/src/SkottieJson.h"
13
#include "modules/skottie/src/SkottiePriv.h"
14
#include "modules/skottie/src/SkottieValue.h"
15
#include "modules/skottie/src/layers/shapelayer/ShapeLayer.h"
16
#include "modules/sksg/include/SkSGGeometryEffect.h"
17
#include "modules/sksg/include/SkSGGeometryNode.h"
18
#include "modules/sksg/include/SkSGMerge.h"
19
#include "src/utils/SkJSON.h"
20
21
#include <algorithm>
22
#include <cstddef>
23
#include <utility>
24
#include <vector>
25
26
namespace skottie {
27
namespace internal {
28
29
namespace  {
30
31
class TrimEffectAdapter final : public DiscardableAdapterBase<TrimEffectAdapter, sksg::TrimEffect> {
32
public:
33
    TrimEffectAdapter(const skjson::ObjectValue& jtrim,
34
                      const AnimationBuilder& abuilder,
35
                      sk_sp<sksg::GeometryNode> child)
36
1.05M
        : INHERITED(sksg::TrimEffect::Make(std::move(child))) {
37
1.05M
        this->bind(abuilder, jtrim["s"], &fStart);
38
1.05M
        this->bind(abuilder, jtrim["e"], &fEnd);
39
1.05M
        this->bind(abuilder, jtrim["o"], &fOffset);
40
1.05M
    }
41
42
private:
43
1.05M
    void onSync() override {
44
        // BM semantics: start/end are percentages, offset is "degrees" (?!).
45
1.05M
        const auto  start = fStart  / 100,
46
1.05M
                      end = fEnd    / 100,
47
1.05M
                   offset = fOffset / 360;
48
49
1.05M
        auto startT = std::min(start, end) + offset,
50
1.05M
              stopT = std::max(start, end) + offset;
51
1.05M
        auto   mode = SkTrimPathEffect::Mode::kNormal;
52
53
1.05M
        if (stopT - startT < 1) {
54
294k
            startT -= SkScalarFloorToScalar(startT);
55
294k
            stopT  -= SkScalarFloorToScalar(stopT);
56
57
294k
            if (startT > stopT) {
58
289k
                using std::swap;
59
289k
                swap(startT, stopT);
60
289k
                mode = SkTrimPathEffect::Mode::kInverted;
61
289k
            }
62
758k
        } else {
63
758k
            startT = 0;
64
758k
            stopT  = 1;
65
758k
        }
66
67
1.05M
        this->node()->setStart(startT);
68
1.05M
        this->node()->setStop(stopT);
69
1.05M
        this->node()->setMode(mode);
70
1.05M
    }
71
72
    ScalarValue fStart  =   0,
73
                fEnd    = 100,
74
                fOffset =   0;
75
76
    using INHERITED = DiscardableAdapterBase<TrimEffectAdapter, sksg::TrimEffect>;
77
};
78
79
} // namespace
80
81
std::vector<sk_sp<sksg::GeometryNode>> ShapeBuilder::AttachTrimGeometryEffect(
82
        const skjson::ObjectValue& jtrim,
83
        const AnimationBuilder* abuilder,
84
136k
        std::vector<sk_sp<sksg::GeometryNode>>&& geos) {
85
86
136k
    enum class Mode {
87
136k
        kParallel, // "m": 1 (Trim Multiple Shapes: Simultaneously)
88
136k
        kSerial,   // "m": 2 (Trim Multiple Shapes: Individually)
89
136k
    } gModes[] = { Mode::kParallel, Mode::kSerial};
90
91
136k
    const auto mode = gModes[std::min<size_t>(ParseDefault<size_t>(jtrim["m"], 1) - 1,
92
136k
                                            std::size(gModes) - 1)];
93
94
136k
    std::vector<sk_sp<sksg::GeometryNode>> inputs;
95
136k
    if (mode == Mode::kSerial) {
96
3.37k
        inputs.push_back(ShapeBuilder::MergeGeometry(std::move(geos), sksg::Merge::Mode::kMerge));
97
132k
    } else {
98
132k
        inputs = std::move(geos);
99
132k
    }
100
101
136k
    std::vector<sk_sp<sksg::GeometryNode>> trimmed;
102
136k
    trimmed.reserve(inputs.size());
103
104
1.05M
    for (const auto& i : inputs) {
105
1.05M
        trimmed.push_back(
106
1.05M
            abuilder->attachDiscardableAdapter<TrimEffectAdapter>(jtrim, *abuilder, i));
107
1.05M
    }
108
109
136k
    return trimmed;
110
136k
}
111
112
} // namespace internal
113
} // namespace skottie