Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
FillStroke.cpp
Go to the documentation of this file.
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
22#include "src/utils/SkJSON.h"
23
24#include <algorithm>
25#include <cstddef>
26#include <utility>
27#include <vector>
28
29namespace skottie {
30namespace internal {
31
32namespace {
33
34class FillStrokeAdapter final : public DiscardableAdapterBase<FillStrokeAdapter, sksg::PaintNode> {
35public:
36 enum class Type { kFill, kStroke };
37
38 FillStrokeAdapter(const skjson::ObjectValue& jpaint,
39 const AnimationBuilder& abuilder,
40 sk_sp<sksg::PaintNode> paint_node,
42 Type type)
43 : INHERITED(std::move(paint_node))
44 , fShaderType(gradient_adapter ? ShaderType::kGradient : ShaderType::kColor) {
45
46 this->attachDiscardableAdapter(std::move(gradient_adapter));
47
48 this->bind(abuilder, jpaint["o"], fOpacity);
49
50 this->node()->setAntiAlias(true);
51
52 if (type == Type::kStroke) {
53 this->bind(abuilder, jpaint["w"], fStrokeWidth);
54
55 this->node()->setStyle(SkPaint::kStroke_Style);
56 this->node()->setStrokeMiter(ParseDefault<SkScalar>(jpaint["ml"], 4.0f));
57
58 static constexpr SkPaint::Join gJoins[] = {
62 };
63 this->node()->setStrokeJoin(
64 gJoins[std::min<size_t>(ParseDefault<size_t>(jpaint["lj"], 1) - 1,
65 std::size(gJoins) - 1)]);
66
67 static constexpr SkPaint::Cap gCaps[] = {
71 };
72 this->node()->setStrokeCap(
73 gCaps[std::min<size_t>(ParseDefault<size_t>(jpaint["lc"], 1) - 1,
74 std::size(gCaps) - 1)]);
75 }
76
77 if (fShaderType == ShaderType::kColor) {
78 this->bind(abuilder, jpaint["c"], fColor);
79 }
80 }
81
82private:
83 void onSync() override {
84 this->node()->setOpacity(fOpacity * 0.01f);
85 this->node()->setStrokeWidth(fStrokeWidth);
86
87 if (fShaderType == ShaderType::kColor) {
88 auto* color_node = static_cast<sksg::Color*>(this->node().get());
89 color_node->setColor(fColor);
90 }
91 }
92
93 enum class ShaderType { kColor, kGradient };
94
95 const ShaderType fShaderType;
96
97 ColorValue fColor;
98 ScalarValue fOpacity = 100,
99 fStrokeWidth = 1;
100
101 using INHERITED = DiscardableAdapterBase<FillStrokeAdapter, sksg::PaintNode>;
102};
103
104class DashAdapter final : public DiscardableAdapterBase<DashAdapter, sksg::DashEffect> {
105public:
106 DashAdapter(const skjson::ArrayValue& jdash,
107 const AnimationBuilder& abuilder,
109 : INHERITED(sksg::DashEffect::Make(std::move(geo))) {
110 SkASSERT(jdash.size() > 1);
111
112 // The dash is encoded as an arbitrary number of intervals (alternating dash/gap),
113 // plus a single trailing offset. Each value can be animated independently.
114 const auto interval_count = jdash.size() - 1;
115 fIntervals.resize(interval_count, 0);
116
117 for (size_t i = 0; i < jdash.size(); ++i) {
118 if (const skjson::ObjectValue* jint = jdash[i]) {
119 auto* target = i < interval_count
120 ? &fIntervals[i]
121 : &fOffset;
122 this->bind(abuilder, (*jint)["v"], target);
123 }
124 }
125 }
126
127private:
128 void onSync() override {
129 this->node()->setPhase(fOffset);
130 this->node()->setIntervals(fIntervals);
131 }
132
133 std::vector<ScalarValue> fIntervals;
134 ScalarValue fOffset = 0;
135
136 using INHERITED = DiscardableAdapterBase<DashAdapter, sksg::DashEffect>;
137};
138
139} // namespace
140
141sk_sp<sksg::PaintNode> ShapeBuilder::AttachFill(const skjson::ObjectValue& jpaint,
142 const AnimationBuilder* abuilder,
143 sk_sp<sksg::PaintNode> paint_node,
145 return abuilder->attachDiscardableAdapter<FillStrokeAdapter>
146 (jpaint,
147 *abuilder,
148 std::move(paint_node),
149 std::move(gradient),
150 FillStrokeAdapter::Type::kFill);
151}
152
153sk_sp<sksg::PaintNode> ShapeBuilder::AttachStroke(const skjson::ObjectValue& jpaint,
154 const AnimationBuilder* abuilder,
155 sk_sp<sksg::PaintNode> paint_node,
157 return abuilder->attachDiscardableAdapter<FillStrokeAdapter>
158 (jpaint,
159 *abuilder,
160 std::move(paint_node),
161 std::move(gradient),
162 FillStrokeAdapter::Type::kStroke);
163}
164
166 const AnimationBuilder* abuilder) {
167 auto color_node = sksg::Color::Make(SK_ColorBLACK);
168 auto color_paint = AttachFill(jpaint, abuilder, color_node);
169 abuilder->dispatchColorProperty(color_node);
170 return color_paint;
171}
172
174 const AnimationBuilder* abuilder) {
175 auto color_node = sksg::Color::Make(SK_ColorBLACK);
176 auto color_paint = AttachStroke(jpaint, abuilder, color_node);
177 abuilder->dispatchColorProperty(color_node);
178 return color_paint;
179}
180
181std::vector<sk_sp<sksg::GeometryNode>> ShapeBuilder::AdjustStrokeGeometry(
182 const skjson::ObjectValue& jstroke,
183 const AnimationBuilder* abuilder,
184 std::vector<sk_sp<sksg::GeometryNode>>&& geos) {
185
186 const skjson::ArrayValue* jdash = jstroke["d"];
187 if (jdash && jdash->size() > 1) {
188 for (size_t i = 0; i < geos.size(); ++i) {
189 geos[i] = abuilder->attachDiscardableAdapter<DashAdapter>(
190 *jdash, *abuilder, std::move(geos[i]));
191 }
192 }
193
194 return std::move(geos);
195}
196
197} // namespace internal
198} // namespace skottie
static constexpr SkColor kColor
#define SkASSERT(cond)
Definition SkAssert.h:116
constexpr SkColor SK_ColorBLACK
Definition SkColor.h:103
static std::unique_ptr< SkEncoder > Make(SkWStream *dst, const SkPixmap *src, const SkYUVAPixmaps *srcYUVA, const SkColorSpace *srcYUVAColorSpace, const SkJpegEncoder::Options &options)
#define INHERITED(method,...)
@ kRound_Cap
adds circle
Definition SkPaint.h:335
@ kButt_Cap
no stroke extension
Definition SkPaint.h:334
@ kSquare_Cap
adds square
Definition SkPaint.h:336
@ kStroke_Style
set to stroke geometry
Definition SkPaint.h:194
@ kRound_Join
adds circle
Definition SkPaint.h:360
@ kMiter_Join
extends to miter limit
Definition SkPaint.h:359
@ kBevel_Join
connects outside edges
Definition SkPaint.h:361
size_t size() const
Definition SkJSON.h:262
bool dispatchColorProperty(const sk_sp< sksg::Color > &) const
Definition Skottie.cpp:228
void attachDiscardableAdapter(sk_sp< T > adapter) const
static sk_sp< sksg::PaintNode > AttachColorStroke(const skjson::ObjectValue &, const AnimationBuilder *)
static sk_sp< sksg::PaintNode > AttachColorFill(const skjson::ObjectValue &, const AnimationBuilder *)
static std::vector< sk_sp< sksg::GeometryNode > > AdjustStrokeGeometry(const skjson::ObjectValue &, const AnimationBuilder *, std::vector< sk_sp< sksg::GeometryNode > > &&)
static sk_sp< Color > Make(SkColor c)
Definition SkSGPaint.cpp:44
uint32_t * target
SkScalar ScalarValue
Definition Skottie.h:32
Definition ref_ptr.h:256