41 const AnimationBuilder*);
42static constexpr GeometryAttacherT gGeometryAttachers[] = {
49using GeometryEffectAttacherT =
51 const AnimationBuilder*,
53static constexpr GeometryEffectAttacherT gGeometryEffectAttachers[] = {
62 const AnimationBuilder*);
63static constexpr PaintAttacherT gPaintAttachers[] = {
71static constexpr GeometryEffectAttacherT gPaintGeometryAdjusters[] = {
77static_assert(std::size(gPaintGeometryAdjusters) == std::size(gPaintAttachers),
"");
79using DrawEffectAttacherT =
81 const AnimationBuilder*,
84static constexpr DrawEffectAttacherT gDrawEffectAttachers[] = {
97enum ShapeFlags : uint16_t {
99 kSuppressDraws = 0x01,
110 static constexpr ShapeInfo gShapeInfo[] = {
111 {
"el", ShapeType::kGeometry , 2,
kNone },
112 {
"fl", ShapeType::kPaint , 0,
kNone },
113 {
"gf", ShapeType::kPaint , 2,
kNone },
114 {
"gr", ShapeType::kGroup , 0,
kNone },
115 {
"gs", ShapeType::kPaint , 3,
kNone },
116 {
"mm", ShapeType::kGeometryEffect, 0, kSuppressDraws },
117 {
"op", ShapeType::kGeometryEffect, 3,
kNone },
118 {
"pb", ShapeType::kGeometryEffect, 4,
kNone },
119 {
"rc", ShapeType::kGeometry , 1,
kNone },
120 {
"rd", ShapeType::kGeometryEffect, 2,
kNone },
121 {
"rp", ShapeType::kDrawEffect , 0,
kNone },
122 {
"sh", ShapeType::kGeometry , 0,
kNone },
123 {
"sr", ShapeType::kGeometry , 3,
kNone },
124 {
"st", ShapeType::kPaint , 1,
kNone },
125 {
"tm", ShapeType::kGeometryEffect, 1,
kNone },
126 {
"tr", ShapeType::kTransform , 0,
kNone },
134 const auto*
info = bsearch(
type->begin(),
136 std::size(gShapeInfo),
138 [](
const void*
key,
const void*
info) {
139 return strcmp(static_cast<const char*>(key),
140 static_cast<const ShapeInfo*>(info)->fTypeString);
143 return static_cast<const ShapeInfo*
>(
info);
146struct GeometryEffectRec {
160 std::vector<GeometryEffectRec>* effects,
161 size_t committedAnimators)
173 bool suppress_draws)
const {
183 const ShapeInfo& fInfo;
193 std::vector<ShapeRec> recs;
194 for (
size_t i = 0; i < jshape->
size(); ++i) {
196 if (!shape)
continue;
198 const auto*
info = FindShapeInfo(*shape);
204 if (ParseDefault<bool>((*shape)[
"hd"],
false)) {
209 recs.push_back({ *shape, *
info, suppress_draws });
212 suppress_draws |= (
info->fFlags & kSuppressDraws) != 0;
214 switch (
info->fShapeType) {
215 case ShapeType::kTransform:
219 case ShapeType::kGeometryEffect:
220 SkASSERT(
info->fAttacherIndex < std::size(gGeometryEffectAttachers));
222 { *shape, gGeometryEffectAttachers[
info->fAttacherIndex] });
234 std::vector<sk_sp<sksg::GeometryNode>> geos;
235 std::vector<sk_sp<sksg::RenderNode >> draws;
239 draws.push_back(this->attachBlendMode(rec.fJson, std::move(
draw)));
242 for (
auto rec = recs.rbegin(); rec != recs.rend(); ++rec) {
245 switch (rec->fInfo.fShapeType) {
246 case ShapeType::kGeometry: {
247 SkASSERT(rec->fInfo.fAttacherIndex < std::size(gGeometryAttachers));
248 if (
auto geo = gGeometryAttachers[rec->fInfo.fAttacherIndex](rec->fJson,
this)) {
249 geos.push_back(std::move(geo));
252 case ShapeType::kGeometryEffect: {
254 SkASSERT(rec->fInfo.fAttacherIndex < std::size(gGeometryEffectAttachers));
256 geos = gGeometryEffectAttachers[rec->fInfo.fAttacherIndex](rec->fJson,
263 gGeometryEffectAttachers[rec->fInfo.fAttacherIndex]);
266 case ShapeType::kGroup: {
267 AttachShapeContext groupShapeCtx(&geos,
271 this->attachShape(rec->fJson[
"it"], &groupShapeCtx, rec->fSuppressed)) {
272 add_draw(std::move(subgroup), *rec);
277 case ShapeType::kPaint: {
278 SkASSERT(rec->fInfo.fAttacherIndex < std::size(gPaintAttachers));
279 auto paint = gPaintAttachers[rec->fInfo.fAttacherIndex](rec->fJson,
this);
280 if (!
paint || geos.empty() || rec->fSuppressed)
283 auto drawGeos = geos;
288 drawGeos = it->fAttach(it->fJson,
this, std::move(drawGeos));
292 SkASSERT(rec->fInfo.fAttacherIndex < std::size(gPaintGeometryAdjusters));
293 if (
const auto adjuster = gPaintGeometryAdjusters[rec->fInfo.fAttacherIndex]) {
294 drawGeos = adjuster(rec->fJson,
this, std::move(drawGeos));
298 auto geo = drawGeos.size() > 1
306 case ShapeType::kDrawEffect: {
307 SkASSERT(rec->fInfo.fAttacherIndex < std::size(gDrawEffectAttachers));
308 if (!draws.empty()) {
309 draws = gDrawEffectAttachers[rec->fInfo.fAttacherIndex](rec->fJson,
324 if (draws.size() == 1) {
326 shape_wrapper = std::move(draws.front());
327 }
else if (!draws.empty()) {
329 std::reverse(draws.begin(), draws.end());
330 draws.shrink_to_fit();
343 AutoScope ascope(
this);
345 if ((shape_transform = this->
attachMatrix2D(*jtransform,
nullptr))) {
348 shape_wrapper = this->
attachOpacity(*jtransform, std::move(shape_wrapper));
350 auto local_scope = ascope.release();
352 std::make_move_iterator(local_scope.begin()),
353 std::make_move_iterator(local_scope.end()));
358 for (
auto& geo : geos) {
364 return shape_wrapper;
369 std::vector<sk_sp<sksg::GeometryNode>> geometryStack;
370 std::vector<GeometryEffectRec> geometryEffectStack;
371 AttachShapeContext shapeCtx(&geometryStack, &geometryEffectStack,
372 fCurrentAnimatorScope->size());
373 auto shapeNode = this->attachShape(layer[
"shapes"], &shapeCtx);
379 SkASSERT(shapeCtx.fCommittedAnimators <= fCurrentAnimatorScope->size());
380 fCurrentAnimatorScope->resize(shapeCtx.fCommittedAnimators);
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
const skjson::ObjectValue & fJson
GeometryEffectAttacherT fAttach
static void draw(SkCanvas *canvas, SkRect &target, int x, int y)
sk_sp< sksg::Path > attachPath(const skjson::Value &) const
void sk_sp< sksg::Transform > attachMatrix2D(const skjson::ObjectValue &, sk_sp< sksg::Transform >, bool auto_orient=false) const
sk_sp< sksg::RenderNode > attachOpacity(const skjson::ObjectValue &, sk_sp< sksg::RenderNode >) const
void log(Logger::Level, const skjson::Value *, const char fmt[],...) const SK_PRINTF_LIKE(4
static sk_sp< sksg::GeometryNode > AttachPathGeometry(const skjson::ObjectValue &, const AnimationBuilder *)
static sk_sp< sksg::GeometryNode > AttachPolystarGeometry(const skjson::ObjectValue &, const AnimationBuilder *)
static std::vector< sk_sp< sksg::RenderNode > > AttachRepeaterDrawEffect(const skjson::ObjectValue &, const AnimationBuilder *, std::vector< sk_sp< sksg::RenderNode > > &&)
static std::vector< sk_sp< sksg::GeometryNode > > AttachOffsetGeometryEffect(const skjson::ObjectValue &, const AnimationBuilder *, std::vector< sk_sp< sksg::GeometryNode > > &&)
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 std::vector< sk_sp< sksg::GeometryNode > > AttachRoundGeometryEffect(const skjson::ObjectValue &, const AnimationBuilder *, std::vector< sk_sp< sksg::GeometryNode > > &&)
static sk_sp< sksg::PaintNode > AttachGradientStroke(const skjson::ObjectValue &, const AnimationBuilder *)
static sk_sp< sksg::GeometryNode > AttachEllipseGeometry(const skjson::ObjectValue &, const AnimationBuilder *)
static std::vector< sk_sp< sksg::GeometryNode > > AttachMergeGeometryEffect(const skjson::ObjectValue &, const AnimationBuilder *, std::vector< sk_sp< sksg::GeometryNode > > &&)
static sk_sp< sksg::GeometryNode > AttachRRectGeometry(const skjson::ObjectValue &, const AnimationBuilder *)
static sk_sp< sksg::PaintNode > AttachGradientFill(const skjson::ObjectValue &, const AnimationBuilder *)
static sk_sp< sksg::Merge > MergeGeometry(std::vector< sk_sp< sksg::GeometryNode > > &&, sksg::Merge::Mode)
static std::vector< sk_sp< sksg::GeometryNode > > AttachPuckerBloatGeometryEffect(const skjson::ObjectValue &, const AnimationBuilder *, std::vector< sk_sp< sksg::GeometryNode > > &&)
static std::vector< sk_sp< sksg::GeometryNode > > AttachTrimGeometryEffect(const skjson::ObjectValue &, const AnimationBuilder *, std::vector< sk_sp< sksg::GeometryNode > > &&)
static sk_sp< Draw > Make(sk_sp< GeometryNode > geo, sk_sp< PaintNode > paint)
static sk_sp< Group > Make()
static constexpr char kTransform[]
std::vector< sk_sp< sksg::GeometryNode > > * fGeometryStack
AttachShapeContext(std::vector< sk_sp< sksg::GeometryNode > > *geos, std::vector< GeometryEffectRec > *effects, size_t committedAnimators)
std::vector< GeometryEffectRec > * fGeometryEffectStack
size_t fCommittedAnimators