Flutter Engine
The Flutter Engine
Classes | Public Member Functions | Friends | List of all members
skottie::internal::AnimationBuilder Class Referencefinal

#include <SkottiePriv.h>

Inheritance diagram for skottie::internal::AnimationBuilder:
SkNoncopyable

Classes

struct  AnimationInfo
 
struct  AttachShapeContext
 
class  AutoPropertyTracker
 
class  AutoScope
 
struct  FontInfo
 

Public Member Functions

 AnimationBuilder (sk_sp< ResourceProvider >, sk_sp< SkFontMgr >, sk_sp< PropertyObserver >, sk_sp< Logger >, sk_sp< MarkerObserver >, sk_sp< PrecompInterceptor >, sk_sp< ExpressionManager >, sk_sp< SkShapers::Factory >, Animation::Builder::Stats *, const SkSize &comp_size, float duration, float framerate, uint32_t flags)
 
AnimationInfo parse (const skjson::ObjectValue &)
 
const FontInfofindFont (const SkString &name) const
 
void log (Logger::Level, const skjson::Value *, const char fmt[],...) const SK_PRINTF_LIKE(4
 
void sk_sp< sksg::TransformattachMatrix2D (const skjson::ObjectValue &, sk_sp< sksg::Transform >, bool auto_orient=false) const
 
sk_sp< sksg::TransformattachMatrix3D (const skjson::ObjectValue &, sk_sp< sksg::Transform >, bool auto_orient=false) const
 
sk_sp< sksg::TransformattachCamera (const skjson::ObjectValue &jlayer, const skjson::ObjectValue &jtransform, sk_sp< sksg::Transform >, const SkSize &) const
 
sk_sp< sksg::RenderNodeattachOpacity (const skjson::ObjectValue &, sk_sp< sksg::RenderNode >) const
 
sk_sp< sksg::PathattachPath (const skjson::Value &) const
 
bool hasNontrivialBlending () const
 
template<typename T >
void attachDiscardableAdapter (sk_sp< T > adapter) const
 
template<typename T , typename... Args>
auto attachDiscardableAdapter (Args &&... args) const -> typename std::decay< decltype(T::Make(std::forward< Args >(args)...) ->node())>::type
 
bool dispatchColorProperty (const sk_sp< sksg::Color > &) const
 
bool dispatchOpacityProperty (const sk_sp< sksg::OpacityEffect > &) const
 
bool dispatchTextProperty (const sk_sp< TextAdapter > &, const skjson::ObjectValue *jtext) const
 
bool dispatchTransformProperty (const sk_sp< TransformAdapter2D > &) const
 
sk_sp< ExpressionManagerexpression_manager () const
 
const skjson::ObjectValuegetSlotsRoot () const
 
void parseFonts (const skjson::ObjectValue *jfonts, const skjson::ArrayValue *jchars)
 
- Public Member Functions inherited from SkNoncopyable
 SkNoncopyable ()=default
 
 SkNoncopyable (SkNoncopyable &&)=default
 
SkNoncopyableoperator= (SkNoncopyable &&)=default
 

Friends

class CompositionBuilder
 
class CustomFont
 
class LayerBuilder
 
class AnimatablePropertyContainer
 

Detailed Description

Definition at line 66 of file SkottiePriv.h.

Constructor & Destructor Documentation

◆ AnimationBuilder()

skottie::internal::AnimationBuilder::AnimationBuilder ( sk_sp< ResourceProvider rp,
sk_sp< SkFontMgr fontmgr,
sk_sp< PropertyObserver pobserver,
sk_sp< Logger logger,
sk_sp< MarkerObserver mobserver,
sk_sp< PrecompInterceptor pi,
sk_sp< ExpressionManager expressionmgr,
sk_sp< SkShapers::Factory shapingFactory,
Animation::Builder::Stats stats,
const SkSize comp_size,
float  duration,
float  framerate,
uint32_t  flags 
)

Definition at line 140 of file Skottie.cpp.

148 : fResourceProvider(std::move(rp))
149 , fFontMgr(std::move(fontmgr))
150 , fPropertyObserver(std::move(pobserver))
151 , fLogger(std::move(logger))
152 , fMarkerObserver(std::move(mobserver))
153 , fPrecompInterceptor(std::move(pi))
154 , fExpressionManager(std::move(expressionmgr))
155 , fShapingFactory(std::move(shapingFactory))
156 , fRevalidator(sk_make_sp<SceneGraphRevalidator>())
157 , fSlotManager(sk_make_sp<SlotManager>(fRevalidator))
158 , fStats(stats)
159 , fCompSize(comp_size)
160 , fDuration(duration)
161 , fFrameRate(framerate)
162 , fFlags(flags)
163 , fHasNontrivialBlending(false) {}
double duration
Definition: examples.cpp:30
FlutterSemanticsFlag flags
dictionary stats
Definition: malisc.py:20

Member Function Documentation

◆ attachCamera()

sk_sp< sksg::Transform > skottie::internal::AnimationBuilder::attachCamera ( const skjson::ObjectValue jlayer,
const skjson::ObjectValue jtransform,
sk_sp< sksg::Transform parent,
const SkSize viewport_size 
) const

Definition at line 124 of file Camera.cpp.

127 {
128 auto adapter = sk_make_sp<CameraAdaper>(jlayer, jtransform, *this, viewport_size);
129
130 if (adapter->isStatic()) {
131 adapter->seek(0);
132 } else {
133 fCurrentAnimatorScope->push_back(adapter);
134 }
135
136 return sksg::Transform::MakeConcat(adapter->node(), std::move(parent));
137}
static sk_sp< Transform > MakeConcat(sk_sp< Transform > a, sk_sp< Transform > b)

◆ attachDiscardableAdapter() [1/2]

template<typename T , typename... Args>
auto skottie::internal::AnimationBuilder::attachDiscardableAdapter ( Args &&...  args) const -> typename std::decay<decltype(T::Make(std::forward<Args>(args)...)->node())>::type
inline

Definition at line 149 of file SkottiePriv.h.

151 {
152 using NodeType =
153 typename std::decay<decltype(T::Make(std::forward<Args>(args)...)->node())>::type;
154
155 NodeType node;
156 if (auto adapter = T::Make(std::forward<Args>(args)...)) {
157 node = adapter->node();
158 this->attachDiscardableAdapter(std::move(adapter));
159 }
160 return node;
161 }
GLenum type
void attachDiscardableAdapter(sk_sp< T > adapter) const
Definition: SkottiePriv.h:139
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
SK_API sk_sp< SkDocument > Make(SkWStream *dst, const SkSerialProcs *=nullptr, std::function< void(const SkPicture *)> onEndPage=nullptr)

◆ attachDiscardableAdapter() [2/2]

template<typename T >
void skottie::internal::AnimationBuilder::attachDiscardableAdapter ( sk_sp< T adapter) const
inline

Definition at line 139 of file SkottiePriv.h.

139 {
140 if (adapter->isStatic()) {
141 // Fire off a synthetic tick to force a single SG sync before discarding.
142 adapter->seek(0);
143 } else {
144 fCurrentAnimatorScope->push_back(std::move(adapter));
145 }
146 }

◆ attachMatrix2D()

sk_sp< sksg::Transform > skottie::internal::AnimationBuilder::attachMatrix2D ( const skjson::ObjectValue jtransform,
sk_sp< sksg::Transform parent,
bool  auto_orient = false 
) const

Definition at line 114 of file Transform.cpp.

116 {
117 const auto* jrotation = &jtransform["r"];
118 if (jrotation->is<skjson::NullValue>()) {
119 // Some 2D rotations are disguised as 3D...
120 jrotation = &jtransform["rz"];
121 }
122
123 auto adapter = TransformAdapter2D::Make(*this,
124 jtransform["a"],
125 jtransform["p"],
126 jtransform["s"],
127 *jrotation,
128 jtransform["sk"],
129 jtransform["sa"],
130 auto_orient);
131 SkASSERT(adapter);
132
133 const auto dispatched = this->dispatchTransformProperty(adapter);
134
135 if (adapter->isStatic()) {
136 if (!dispatched && adapter->totalMatrix().isIdentity()) {
137 // The transform has no observable effects - we can discard.
138 return parent;
139 }
140 adapter->seek(0);
141 } else {
142 fCurrentAnimatorScope->push_back(adapter);
143 }
144
145 return sksg::Transform::MakeConcat(std::move(parent), adapter->node());
146}
#define SkASSERT(cond)
Definition: SkAssert.h:116
bool dispatchTransformProperty(const sk_sp< TransformAdapter2D > &) const
Definition: Skottie.cpp:278

◆ attachMatrix3D()

sk_sp< sksg::Transform > skottie::internal::AnimationBuilder::attachMatrix3D ( const skjson::ObjectValue jtransform,
sk_sp< sksg::Transform parent,
bool  auto_orient = false 
) const

Definition at line 197 of file Transform.cpp.

199 {
200 auto adapter = TransformAdapter3D::Make(jtransform, *this);
201 SkASSERT(adapter);
202
203 if (adapter->isStatic()) {
204 // TODO: SkM44::isIdentity?
205 if (adapter->totalMatrix() == SkM44()) {
206 // The transform has no observable effects - we can discard.
207 return parent;
208 }
209 adapter->seek(0);
210 } else {
211 fCurrentAnimatorScope->push_back(adapter);
212 }
213
214 return sksg::Transform::MakeConcat(std::move(parent), adapter->node());
215}
Definition: SkM44.h:150

◆ attachOpacity()

sk_sp< sksg::RenderNode > skottie::internal::AnimationBuilder::attachOpacity ( const skjson::ObjectValue jobject,
sk_sp< sksg::RenderNode child_node 
) const

Definition at line 118 of file Skottie.cpp.

119 {
120 if (!child_node)
121 return nullptr;
122
123 auto adapter = OpacityAdapter::Make(jobject, child_node, *this);
124 if (adapter->isStatic()) {
125 adapter->seek(0);
126 }
127 auto dispatched = this->dispatchOpacityProperty(adapter->node());
128 if (adapter->isStatic()) {
129 if (!dispatched && adapter->node()->getOpacity() >= 1) {
130 // No obeservable effects - we can discard.
131 return child_node;
132 }
133 } else {
134 fCurrentAnimatorScope->push_back(adapter);
135 }
136
137 return adapter->node();
138}
bool dispatchOpacityProperty(const sk_sp< sksg::OpacityEffect > &) const
Definition: Skottie.cpp:242

◆ attachPath()

sk_sp< sksg::Path > skottie::internal::AnimationBuilder::attachPath ( const skjson::Value jpath) const

Definition at line 50 of file Path.cpp.

50 {
51 return this->attachDiscardableAdapter<PathAdapter>(jpath, *this);
52}

◆ dispatchColorProperty()

bool skottie::internal::AnimationBuilder::dispatchColorProperty ( const sk_sp< sksg::Color > &  c) const

Definition at line 228 of file Skottie.cpp.

228 {
229 bool dispatched = false;
230 if (fPropertyObserver) {
231 const char * node_name = fPropertyObserverContext;
232 fPropertyObserver->onColorProperty(node_name,
233 [&]() {
234 dispatched = true;
235 return std::make_unique<ColorPropertyHandle>(c, fRevalidator);
236 });
237 }
238
239 return dispatched;
240}

◆ dispatchOpacityProperty()

bool skottie::internal::AnimationBuilder::dispatchOpacityProperty ( const sk_sp< sksg::OpacityEffect > &  o) const

Definition at line 242 of file Skottie.cpp.

242 {
243 bool dispatched = false;
244
245 if (fPropertyObserver) {
246 fPropertyObserver->onOpacityProperty(fPropertyObserverContext,
247 [&]() {
248 dispatched = true;
249 return std::make_unique<OpacityPropertyHandle>(o, fRevalidator);
250 });
251 }
252
253 return dispatched;
254}

◆ dispatchTextProperty()

bool skottie::internal::AnimationBuilder::dispatchTextProperty ( const sk_sp< TextAdapter > &  t,
const skjson::ObjectValue jtext 
) const

Definition at line 256 of file Skottie.cpp.

257 {
258 bool dispatched = false;
259
260 if (jtext) {
261 if (const skjson::StringValue* slotID = (*jtext)["sid"]) {
262 fSlotManager->trackTextValue(SkString(slotID->begin()), t);
263 dispatched = true;
264 }
265 }
266
267 if (fPropertyObserver) {
268 fPropertyObserver->onTextProperty(fPropertyObserverContext,
269 [&]() {
270 dispatched = true;
271 return std::make_unique<TextPropertyHandle>(t, fRevalidator);
272 });
273 }
274
275 return dispatched;
276}

◆ dispatchTransformProperty()

bool skottie::internal::AnimationBuilder::dispatchTransformProperty ( const sk_sp< TransformAdapter2D > &  t) const

Definition at line 278 of file Skottie.cpp.

278 {
279 bool dispatched = false;
280
281 if (fPropertyObserver) {
282 fPropertyObserver->onTransformProperty(fPropertyObserverContext,
283 [&]() {
284 dispatched = true;
285 return std::make_unique<TransformPropertyHandle>(t, fRevalidator);
286 });
287 }
288
289 return dispatched;
290}

◆ expression_manager()

sk_sp< ExpressionManager > skottie::internal::AnimationBuilder::expression_manager ( ) const

Definition at line 292 of file Skottie.cpp.

292 {
293 return fExpressionManager;
294}

◆ findFont()

const AnimationBuilder::FontInfo * skottie::internal::AnimationBuilder::findFont ( const SkString name) const

Definition at line 349 of file TextLayer.cpp.

349 {
350 return fFonts.find(font_name);
351}

◆ getSlotsRoot()

const skjson::ObjectValue * skottie::internal::AnimationBuilder::getSlotsRoot ( ) const
inline

Definition at line 197 of file SkottiePriv.h.

197 {
198 return fSlotsRoot;
199 }

◆ hasNontrivialBlending()

bool skottie::internal::AnimationBuilder::hasNontrivialBlending ( ) const
inline

Definition at line 110 of file SkottiePriv.h.

110{ return fHasNontrivialBlending; }

◆ log()

void skottie::internal::AnimationBuilder::log ( Logger::Level  lvl,
const skjson::Value json,
const char  fmt[],
  ... 
) const

Definition at line 71 of file Skottie.cpp.

72 {
73 if (!fLogger) {
74 return;
75 }
76
77 char buff[1024];
78 va_list va;
79 va_start(va, fmt);
80 const auto len = vsnprintf(buff, sizeof(buff), fmt, va);
81 va_end(va);
82
83 if (len < 0) {
84 SkDebugf("!! Could not format log message !!\n");
85 return;
86 }
87
88 if (len >= SkToInt(sizeof(buff))) {
89 static constexpr char kEllipsesStr[] = "...";
90 strcpy(buff + sizeof(buff) - sizeof(kEllipsesStr), kEllipsesStr);
91 }
92
93 SkString jsonstr = json ? json->toString() : SkString();
94
95 fLogger->log(lvl, buff, jsonstr.c_str());
96}
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
constexpr int SkToInt(S x)
Definition: SkTo.h:29
const char * c_str() const
Definition: SkString.h:133
SkString toString() const
Definition: SkJSON.cpp:938
va_start(args, format)
va_end(args)
static SkString fmt(SkColor4f c)
Definition: p3.cpp:43

◆ parse()

AnimationBuilder::AnimationInfo skottie::internal::AnimationBuilder::parse ( const skjson::ObjectValue jroot)

Definition at line 165 of file Skottie.cpp.

165 {
166 this->dispatchMarkers(jroot["markers"]);
167
168 AutoScope ascope(this);
169 AutoPropertyTracker apt(this, jroot, PropertyObserver::NodeType::COMPOSITION);
170
171 this->parseAssets(jroot["assets"]);
172 this->parseFonts(jroot["fonts"], jroot["chars"]);
173 fSlotsRoot = jroot["slots"];
174
175 auto root = CompositionBuilder(*this, fCompSize, jroot).build(*this);
176
177 auto animators = ascope.release();
178 fStats->fAnimatorCount = animators.size();
179
180 // Point the revalidator to our final root, and perform initial revalidation.
181 fRevalidator->setRoot(root);
182 fRevalidator->revalidate();
183
184 return { std::move(root), std::move(animators), std::move(fSlotManager)};
185}
void parseFonts(const skjson::ObjectValue *jfonts, const skjson::ArrayValue *jchars)
Definition: TextLayer.cpp:115
string root
Definition: scale_cpu.py:20

◆ parseFonts()

void skottie::internal::AnimationBuilder::parseFonts ( const skjson::ObjectValue jfonts,
const skjson::ArrayValue jchars 
)

Definition at line 115 of file TextLayer.cpp.

116 {
117 // Optional array of font entries, referenced (by name) from text layer document nodes. E.g.
118 // "fonts": {
119 // "list": [
120 // {
121 // "ascent": 75,
122 // "fClass": "",
123 // "fFamily": "Roboto",
124 // "fName": "Roboto-Regular",
125 // "fPath": "https://fonts.googleapis.com/css?family=Roboto",
126 // "fPath": "",
127 // "fStyle": "Regular",
128 // "fWeight": "",
129 // "origin": 1
130 // }
131 // ]
132 // },
133 const skjson::ArrayValue* jlist = jfonts
134 ? static_cast<const skjson::ArrayValue*>((*jfonts)["list"])
135 : nullptr;
136 if (!jlist) {
137 return;
138 }
139
140 // First pass: collect font info.
141 for (const skjson::ObjectValue* jfont : *jlist) {
142 if (!jfont) {
143 continue;
144 }
145
146 const skjson::StringValue* jname = (*jfont)["fName"];
147 const skjson::StringValue* jfamily = (*jfont)["fFamily"];
148 const skjson::StringValue* jstyle = (*jfont)["fStyle"];
149 const skjson::StringValue* jpath = (*jfont)["fPath"];
150
151 if (!jname || !jname->size() ||
152 !jfamily || !jfamily->size() ||
153 !jstyle) {
154 this->log(Logger::Level::kError, jfont, "Invalid font.");
155 continue;
156 }
157
158 fFonts.set(SkString(jname->begin(), jname->size()),
159 {
160 SkString(jfamily->begin(), jfamily->size()),
161 SkString( jstyle->begin(), jstyle->size()),
162 jpath ? SkString( jpath->begin(), jpath->size()) : SkString(),
163 ParseDefault((*jfont)["ascent"] , 0.0f),
164 nullptr, // placeholder
165 CustomFont::Builder()
166 });
167 }
168
169 const auto has_comp_glyphs = [](const skjson::ArrayValue* jchars) {
170 if (!jchars) {
171 return false;
172 }
173
174 for (const skjson::ObjectValue* jchar : *jchars) {
175 if (!jchar) {
176 continue;
177 }
178 if (ParseDefault<int>((*jchar)["t"], 0) == 1) {
179 return true;
180 }
181 }
182
183 return false;
184 };
185
186 // Historically, Skottie has been loading native fonts before embedded glyphs, unless
187 // the opposite is explicitly requested via kPreferEmbeddedFonts. That's mostly because
188 // embedded glyphs used to be just a path representation of system fonts at export time,
189 // (and thus lower quality).
190 //
191 // OTOH embedded glyph *compositions* must be prioritized, as they are presumably more
192 // expressive than the system font equivalent.
193 const auto prioritize_embedded_fonts =
194 (fFlags & Animation::Builder::kPreferEmbeddedFonts) || has_comp_glyphs(jchars);
195
196 // Optional pass.
197 if (jchars && prioritize_embedded_fonts && this->resolveEmbeddedTypefaces(*jchars)) {
198 return;
199 }
200
201 // Native typeface resolution.
202 if (this->resolveNativeTypefaces()) {
203 return;
204 }
205
206 // Embedded typeface fallback.
207 if (jchars && !prioritize_embedded_fonts) {
208 this->resolveEmbeddedTypefaces(*jchars);
209 }
210}
const char * begin() const
Definition: SkJSON.h:315
size_t size() const
Definition: SkJSON.h:300
void log(Logger::Level, const skjson::Value *, const char fmt[],...) const SK_PRINTF_LIKE(4
Definition: Skottie.cpp:71

Friends And Related Function Documentation

◆ AnimatablePropertyContainer

friend class AnimatablePropertyContainer
friend

Definition at line 207 of file SkottiePriv.h.

◆ CompositionBuilder

friend class CompositionBuilder
friend

Definition at line 204 of file SkottiePriv.h.

◆ CustomFont

friend class CustomFont
friend

Definition at line 205 of file SkottiePriv.h.

◆ LayerBuilder

friend class LayerBuilder
friend

Definition at line 206 of file SkottiePriv.h.


The documentation for this class was generated from the following files: