433 {
435
438 AnimationBuilder::LayerInfo*) const;
439
440
441
442
443
444
445
446 enum : uint32_t {
447 kTransformEffects = 0x01,
448 kForceSeek = 0x02,
449 };
450
451 static constexpr struct {
453 uint32_t fFlags;
454 } gLayerBuildInfo[] = {
455 { &AnimationBuilder::attachPrecompLayer, kTransformEffects },
456 { &AnimationBuilder::attachSolidLayer , kTransformEffects },
457 { &AnimationBuilder::attachFootageLayer, kTransformEffects },
458 { &AnimationBuilder::attachNullLayer , 0 },
459 { &AnimationBuilder::attachShapeLayer , 0 },
460 { &AnimationBuilder::attachTextLayer , 0 },
461 { &AnimationBuilder::attachAudioLayer , kForceSeek },
462 { nullptr , 0 },
463 { nullptr , 0 },
464 { &AnimationBuilder::attachFootageLayer, kTransformEffects },
465 { nullptr , 0 },
466 { nullptr , 0 },
467 { nullptr , 0 },
468 { &AnimationBuilder::attachNullLayer , 0 },
469 { nullptr , 0 },
470 };
471
472 if (fType < 0 || static_cast<size_t>(fType) >= std::size(gLayerBuildInfo)) {
473 return nullptr;
474 }
475
476 const auto& build_info = gLayerBuildInfo[fType];
477
478
479 AnimationBuilder::AutoScope ascope(&abuilder, std::move(fLayerScope));
480
481
483
484
485 if (build_info.fBuilder) {
486 layer = (abuilder.*(build_info.fBuilder))(fJlayer, &fInfo);
487 }
488
489
491 if (::skottie::Parse<float>(fJlayer[
"w"], &
w) && ::skottie::Parse<float>(fJlayer[
"h"], &
h)) {
494#ifdef SK_LEGACY_SKOTTIE_CLIPPING
495 true, false);
496#else
497 true, true);
498#endif
499 }
500
501
502 layer = AttachMask(fJlayer["masksProperties"], &abuilder, std::move(layer));
503
504
505
506 const auto transform_effects = (build_info.fFlags & kTransformEffects);
507
508
509 if (fLayerTransform && !transform_effects) {
511 }
512
513
515 layer = EffectBuilder(&abuilder, fInfo.fSize, cbuilder)
516 .attachEffects(*jeffects, std::move(layer));
517 }
518
519
520 if (fLayerTransform && transform_effects) {
522 }
523
524
526 layer = EffectBuilder(&abuilder, fInfo.fSize, cbuilder)
527 .attachStyles(*jstyles, std::move(layer));
528 }
529
530
531
533 layer = abuilder.attachOpacity(*jtransform, std::move(layer));
534 }
535
536
537 fContentTree = layer;
538 if (ParseDefault<bool>(fJlayer["hd"], false)) {
539 layer = nullptr;
540 }
541
542 const auto has_animators = !abuilder.fCurrentAnimatorScope->empty();
543 const auto force_seek_count = build_info.fFlags & kForceSeek
544 ? abuilder.fCurrentAnimatorScope->size()
545 : fTransformAnimatorCount;
546
547 sk_sp<Animator> controller = sk_make_sp<LayerController>(ascope.release(),
548 layer,
549 force_seek_count,
550 fInfo.fInPoint,
551 fInfo.fOutPoint);
552
553
554 if (layer && has_animators && this->hasMotionBlur(cbuilder)) {
555
557 cbuilder->fMotionBlurSamples,
558 cbuilder->fMotionBlurAngle,
559 cbuilder->fMotionBlurPhase);
560 controller = sk_make_sp<MotionBlurController>(motion_blur);
561 layer = std::move(motion_blur);
562 }
563
564 abuilder.fCurrentAnimatorScope->push_back(std::move(controller));
565
566 if (ParseDefault<bool>(fJlayer["td"], false)) {
567
568 return nullptr;
569 }
570
571
572 const auto matte_mode = prev_layer
573 ? ParseDefault<size_t>(fJlayer["tt"], 0)
574 : 0;
575 if (matte_mode > 0) {
581 };
582
583 if (matte_mode <= std::size(gMatteModes)) {
584
586 prev_layer->fContentTree,
587 gMatteModes[matte_mode - 1]);
588 } else {
590 "Unknown track matte mode: %zu\n", matte_mode);
591 }
592 }
593
594
595
596 return abuilder.attachBlendMode(fJlayer, std::move(layer));
597}
LayerBuilder(const skjson::ObjectValue &jlayer, const SkSize &comp_size)
static sk_sp< MotionBlurEffect > Make(sk_sp< Animator > animator, sk_sp< sksg::RenderNode > child, size_t samples_per_frame, float shutter_angle, float shutter_phase)
static sk_sp< ClipEffect > Make(sk_sp< RenderNode > child, sk_sp< GeometryNode > clip, bool aa=false, bool force_clip=false)
static sk_sp< MaskEffect > Make(sk_sp< RenderNode > child, sk_sp< RenderNode > mask, Mode mode=Mode::kAlphaNormal)
static sk_sp< Rect > Make()
static constexpr SkRect MakeWH(float w, float h)