[skottie] More masking fixes
Assorted bugfixes for the non-analytical mask code path.
1) SkSG modulatePaint() should only override the blend mode when
one is specified (!= kSrcOver).
2) Some modes (notably intersect) require touching pixels outside the
mask draw geometry. These modes must be applied as a layer.
Introduce an explicit layer node in SkSG, and inject for masks which
require it.
Also refactor Subtract to use more natural blend and pathops modes,
instead of always inverting geometry.
TBR=
Change-Id: I412168d1ff61eb8e59907babe8f0e091f6fffacf
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/303997
Reviewed-by: Florin Malita <fmalita@google.com>
Commit-Queue: Florin Malita <fmalita@google.com>
diff --git a/modules/skottie/src/Layer.cpp b/modules/skottie/src/Layer.cpp
index 211711f..26af798 100644
--- a/modules/skottie/src/Layer.cpp
+++ b/modules/skottie/src/Layer.cpp
@@ -42,10 +42,8 @@
{ SkBlendMode::kSrcOver , sksg::Merge::Mode::kUnion , false };
static constexpr MaskInfo k_int_info =
{ SkBlendMode::kSrcIn , sksg::Merge::Mode::kIntersect , false };
- // AE 'subtract' is the same as 'intersect' + inverted geometry
- // (draws the opacity-adjusted paint *outside* the shape).
static constexpr MaskInfo k_sub_info =
- { SkBlendMode::kSrcIn , sksg::Merge::Mode::kIntersect , true };
+ { SkBlendMode::kDstOut , sksg::Merge::Mode::kDifference, true };
static constexpr MaskInfo k_dif_info =
{ SkBlendMode::kXor , sksg::Merge::Mode::kXOR , false };
@@ -63,9 +61,13 @@
class MaskAdapter final : public AnimatablePropertyContainer {
public:
MaskAdapter(const skjson::ObjectValue& jmask, const AnimationBuilder& abuilder, SkBlendMode bm)
- : fMaskPaint(sksg::Color::Make(SK_ColorBLACK)) {
+ : fMaskPaint(sksg::Color::Make(SK_ColorBLACK))
+ , fBlendMode(bm) {
fMaskPaint->setAntiAlias(true);
- fMaskPaint->setBlendMode(bm);
+ if (!this->requires_isolation()) {
+ // We can mask at draw time.
+ fMaskPaint->setBlendMode(bm);
+ }
this->bind(abuilder, jmask["o"], fOpacity);
@@ -81,10 +83,16 @@
}
sk_sp<sksg::RenderNode> makeMask(sk_sp<sksg::Path> mask_path) const {
- auto mask = sksg::Draw::Make(std::move(mask_path), fMaskPaint);
+ sk_sp<sksg::RenderNode> mask = sksg::Draw::Make(std::move(mask_path), fMaskPaint);
// Optional mask blur (feather).
- return sksg::ImageFilterEffect::Make(std::move(mask), fMaskFilter);
+ mask = sksg::ImageFilterEffect::Make(std::move(mask), fMaskFilter);
+
+ if (this->requires_isolation()) {
+ mask = sksg::LayerEffect::Make(std::move(mask), fBlendMode);
+ }
+
+ return mask;
}
private:
@@ -98,7 +106,24 @@
}
}
+ bool requires_isolation() const {
+ SkASSERT(fBlendMode == SkBlendMode::kSrc ||
+ fBlendMode == SkBlendMode::kSrcOver ||
+ fBlendMode == SkBlendMode::kSrcIn ||
+ fBlendMode == SkBlendMode::kDstOut ||
+ fBlendMode == SkBlendMode::kXor);
+
+ // Some mask modes touch pixels outside the immediate draw geometry.
+ // These require a layer.
+ switch (fBlendMode) {
+ case (SkBlendMode::kSrcIn): return true;
+ default: return false;
+ }
+ SkUNREACHABLE;
+ }
+
const sk_sp<sksg::PaintNode> fMaskPaint;
+ const SkBlendMode fBlendMode;
sk_sp<sksg::BlurImageFilter> fMaskFilter; // optional "feather"
Vec2Value fFeather = {0,0};
@@ -146,24 +171,30 @@
continue;
}
- // "inv" is cumulative with mask info fInvertGeometry
- const auto inverted =
- (mask_info->fInvertGeometry != ParseDefault<bool>((*m)["inv"], false));
- mask_path->setFillType(inverted ? SkPathFillType::kInverseWinding
- : SkPathFillType::kWinding);
+ auto mask_blend_mode = mask_info->fBlendMode;
+ auto mask_merge_mode = mask_info->fMergeMode;
+ auto mask_inverted = ParseDefault<bool>((*m)["inv"], false);
- const auto blend_mode = mask_stack.empty() ? SkBlendMode::kSrc
- : mask_info->fBlendMode;
+ if (mask_stack.empty()) {
+ // First mask adjustments:
+ // - always draw in source mode
+ // - invert geometry if needed
+ mask_blend_mode = SkBlendMode::kSrc;
+ mask_merge_mode = sksg::Merge::Mode::kMerge;
+ mask_inverted = mask_inverted != mask_info->fInvertGeometry;
+ }
- auto mask_adapter = sk_make_sp<MaskAdapter>(*m, *abuilder, blend_mode);
+ mask_path->setFillType(mask_inverted ? SkPathFillType::kInverseWinding
+ : SkPathFillType::kWinding);
+
+ auto mask_adapter = sk_make_sp<MaskAdapter>(*m, *abuilder, mask_blend_mode);
abuilder->attachDiscardableAdapter(mask_adapter);
has_effect |= mask_adapter->hasEffect();
-
mask_stack.push_back({ std::move(mask_path),
std::move(mask_adapter),
- mask_info->fMergeMode });
+ mask_merge_mode });
}
@@ -183,8 +214,7 @@
merge_recs.reserve(SkToSizeT(mask_stack.count()));
for (auto& mask : mask_stack) {
- const auto mode = merge_recs.empty() ? sksg::Merge::Mode::kMerge : mask.merge_mode;
- merge_recs.push_back({std::move(mask.mask_path), mode});
+ merge_recs.push_back({std::move(mask.mask_path), mask.merge_mode });
}
clip_node = sksg::Merge::Make(std::move(merge_recs));
}
diff --git a/modules/sksg/include/SkSGRenderEffect.h b/modules/sksg/include/SkSGRenderEffect.h
index 1c0f93b..fb24ff6 100644
--- a/modules/sksg/include/SkSGRenderEffect.h
+++ b/modules/sksg/include/SkSGRenderEffect.h
@@ -248,6 +248,25 @@
using INHERITED = EffectNode;
};
+class LayerEffect final : public EffectNode {
+public:
+ ~LayerEffect() override;
+
+ static sk_sp<LayerEffect> Make(sk_sp<RenderNode> child,
+ SkBlendMode mode = SkBlendMode::kSrcOver);
+
+ SG_ATTRIBUTE(Mode, SkBlendMode, fMode)
+
+private:
+ LayerEffect(sk_sp<RenderNode> child, SkBlendMode mode);
+
+ void onRender(SkCanvas*, const RenderContext*) const override;
+
+ SkBlendMode fMode;
+
+ using INHERITED = EffectNode;
+};
+
} // namespace sksg
#endif // SkSGRenderEffect_DEFINED
diff --git a/modules/sksg/src/SkSGRenderEffect.cpp b/modules/sksg/src/SkSGRenderEffect.cpp
index 693e4f2..8109b47 100644
--- a/modules/sksg/src/SkSGRenderEffect.cpp
+++ b/modules/sksg/src/SkSGRenderEffect.cpp
@@ -224,4 +224,35 @@
return this->INHERITED::onNodeAt(p);
}
+sk_sp<LayerEffect> LayerEffect::Make(sk_sp<RenderNode> child, SkBlendMode mode) {
+ return child ? sk_sp<LayerEffect>(new LayerEffect(std::move(child), mode))
+ : nullptr;
+}
+
+LayerEffect::LayerEffect(sk_sp<RenderNode> child, SkBlendMode mode)
+ : INHERITED(std::move(child))
+ , fMode(mode) {}
+
+LayerEffect::~LayerEffect() = default;
+
+void LayerEffect::onRender(SkCanvas* canvas, const RenderContext* ctx) const {
+ SkAutoCanvasRestore acr(canvas, false);
+
+ // Commit any potential pending paint effects to their own layer.
+ const auto local_ctx = ScopedRenderContext(canvas, ctx).setIsolation(this->bounds(),
+ canvas->getTotalMatrix(),
+ true);
+
+ SkPaint layer_paint;
+ if (ctx) {
+ // Apply all optional context overrides upfront.
+ ctx->modulatePaint(canvas->getTotalMatrix(), &layer_paint);
+ }
+ layer_paint.setBlendMode(fMode);
+
+ canvas->saveLayer(nullptr, &layer_paint);
+
+ this->INHERITED::onRender(canvas, nullptr);
+}
+
} // namespace sksg
diff --git a/modules/sksg/src/SkSGRenderNode.cpp b/modules/sksg/src/SkSGRenderNode.cpp
index 7815ac4..accda879 100644
--- a/modules/sksg/src/SkSGRenderNode.cpp
+++ b/modules/sksg/src/SkSGRenderNode.cpp
@@ -98,7 +98,9 @@
if (fShader) {
paint->setShader(LocalShader(fShader, fShaderCTM, ctm));
}
- paint->setBlendMode(fBlendMode);
+ if (fBlendMode != SkBlendMode::kSrcOver) {
+ paint->setBlendMode(fBlendMode);
+ }
// Only apply the shader mask for regular paints. Isolation layers require
// special handling on restore.
diff --git a/resources/skottie/skottie-masking-solid.json b/resources/skottie/skottie-masking-opaque.json
similarity index 100%
rename from resources/skottie/skottie-masking-solid.json
rename to resources/skottie/skottie-masking-opaque.json
diff --git a/resources/skottie/skottie-masking-translucent.json b/resources/skottie/skottie-masking-translucent.json
new file mode 100644
index 0000000..73564b5
--- /dev/null
+++ b/resources/skottie/skottie-masking-translucent.json
@@ -0,0 +1 @@
+{"v":"5.7.0","fr":30,"ip":0,"op":150,"w":500,"h":500,"nm":"masking-translucent","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[83,150,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[33,33,100],"ix":6}},"ao":0,"shapes":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":0,"s":[500,500]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":75,"s":[500,150]},{"t":149,"s":[500,500]}],"ix":2},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[0,0],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75,"s":[0,175],"to":[0,0],"ti":[0,0]},{"t":149,"s":[0,0]}],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":0,"s":[500,500]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":75,"s":[150,500]},{"t":149,"s":[500,500]}],"ix":2},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[0,0],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75,"s":[175,0],"to":[0,0],"ti":[0,0]},{"t":149,"s":[0,0]}],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 2","mn":"ADBE Vector Shape - Rect","hd":false},{"d":1,"ty":"el","s":{"a":0,"k":[300,300],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[1,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":0,"op":150,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":1,"nm":"add","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[83,150,0],"ix":2},"a":{"a":0,"k":[250,250,0],"ix":1},"s":{"a":0,"k":[33,33,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0,0],[0,500],[500,500],[500,0]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[350,0],[350,500],[500,500],[500,0]],"c":true}]},{"t":149,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0,0],[0,500],[500,500],[500,0]],"c":true}]}],"ix":1},"o":{"a":0,"k":50,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"},{"inv":false,"mode":"a","pt":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0,0],[0,500],[500,500],[500,0]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0,350],[0,500],[500,500],[500,350]],"c":true}]},{"t":149,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0,0],[0,500],[500,500],[500,0]],"c":true}]}],"ix":1},"o":{"a":0,"k":50,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 2"},{"inv":false,"mode":"a","pt":{"a":0,"k":{"i":[[82.843,0],[0,-82.843],[-82.843,0],[0,82.843]],"o":[[-82.843,0],[0,82.843],[82.843,0],[0,-82.843]],"v":[[250,100],[100,250],[250,400],[400,250]],"c":true},"ix":1},"o":{"a":0,"k":50,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 3"}],"sw":500,"sh":500,"sc":"#00ff00","ip":0,"op":150,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,150,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[33,33,100],"ix":6}},"ao":0,"shapes":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":0,"s":[500,500]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":75,"s":[500,150]},{"t":149,"s":[500,500]}],"ix":2},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[0,0],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75,"s":[0,175],"to":[0,0],"ti":[0,0]},{"t":149,"s":[0,0]}],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":0,"s":[500,500]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":75,"s":[150,500]},{"t":149,"s":[500,500]}],"ix":2},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[0,0],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75,"s":[175,0],"to":[0,0],"ti":[0,0]},{"t":149,"s":[0,0]}],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 2","mn":"ADBE Vector Shape - Rect","hd":false},{"d":1,"ty":"el","s":{"a":0,"k":[300,300],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[1,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":0,"op":150,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":1,"nm":"subtract","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,150,0],"ix":2},"a":{"a":0,"k":[250,250,0],"ix":1},"s":{"a":0,"k":[33,33,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"s","pt":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0,0],[0,500],[500,500],[500,0]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[350,0],[350,500],[500,500],[500,0]],"c":true}]},{"t":149,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0,0],[0,500],[500,500],[500,0]],"c":true}]}],"ix":1},"o":{"a":0,"k":50,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"},{"inv":false,"mode":"s","pt":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0,0],[0,500],[500,500],[500,0]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0,350],[0,500],[500,500],[500,350]],"c":true}]},{"t":149,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0,0],[0,500],[500,500],[500,0]],"c":true}]}],"ix":1},"o":{"a":0,"k":50,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 2"},{"inv":false,"mode":"s","pt":{"a":0,"k":{"i":[[82.843,0],[0,-82.843],[-82.843,0],[0,82.843]],"o":[[-82.843,0],[0,82.843],[82.843,0],[0,-82.843]],"v":[[250,100],[100,250],[250,400],[400,250]],"c":true},"ix":1},"o":{"a":0,"k":50,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 3"}],"sw":500,"sh":500,"sc":"#00ff00","ip":0,"op":150,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Shape Layer 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[417,150,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[33,33,100],"ix":6}},"ao":0,"shapes":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":0,"s":[500,500]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":75,"s":[500,150]},{"t":149,"s":[500,500]}],"ix":2},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[0,0],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75,"s":[0,175],"to":[0,0],"ti":[0,0]},{"t":149,"s":[0,0]}],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":0,"s":[500,500]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":75,"s":[150,500]},{"t":149,"s":[500,500]}],"ix":2},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[0,0],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75,"s":[175,0],"to":[0,0],"ti":[0,0]},{"t":149,"s":[0,0]}],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 2","mn":"ADBE Vector Shape - Rect","hd":false},{"d":1,"ty":"el","s":{"a":0,"k":[300,300],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[1,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":0,"op":150,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":1,"nm":"intersect","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[417,150,0],"ix":2},"a":{"a":0,"k":[250,250,0],"ix":1},"s":{"a":0,"k":[33,33,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"i","pt":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0,0],[0,500],[500,500],[500,0]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[350,0],[350,500],[500,500],[500,0]],"c":true}]},{"t":149,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0,0],[0,500],[500,500],[500,0]],"c":true}]}],"ix":1},"o":{"a":0,"k":50,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"},{"inv":false,"mode":"i","pt":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0,0],[0,500],[500,500],[500,0]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0,350],[0,500],[500,500],[500,350]],"c":true}]},{"t":149,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0,0],[0,500],[500,500],[500,0]],"c":true}]}],"ix":1},"o":{"a":0,"k":50,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 2"},{"inv":false,"mode":"i","pt":{"a":0,"k":{"i":[[82.843,0],[0,-82.843],[-82.843,0],[0,82.843]],"o":[[-82.843,0],[0,82.843],[82.843,0],[0,-82.843]],"v":[[250,100],[100,250],[250,400],[400,250]],"c":true},"ix":1},"o":{"a":0,"k":50,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 3"}],"sw":500,"sh":500,"sc":"#00ff00","ip":0,"op":150,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Shape Layer 6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[83,350,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[33,33,100],"ix":6}},"ao":0,"shapes":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":0,"s":[500,500]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":75,"s":[500,150]},{"t":149,"s":[500,500]}],"ix":2},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[0,0],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75,"s":[0,175],"to":[0,0],"ti":[0,0]},{"t":149,"s":[0,0]}],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":0,"s":[500,500]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":75,"s":[150,500]},{"t":149,"s":[500,500]}],"ix":2},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[0,0],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75,"s":[175,0],"to":[0,0],"ti":[0,0]},{"t":149,"s":[0,0]}],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 2","mn":"ADBE Vector Shape - Rect","hd":false},{"d":1,"ty":"el","s":{"a":0,"k":[300,300],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[1,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":0,"op":150,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":1,"nm":"lighten","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[83,350,0],"ix":2},"a":{"a":0,"k":[250,250,0],"ix":1},"s":{"a":0,"k":[33,33,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"l","pt":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0,0],[0,500],[500,500],[500,0]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[350,0],[350,500],[500,500],[500,0]],"c":true}]},{"t":149,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0,0],[0,500],[500,500],[500,0]],"c":true}]}],"ix":1},"o":{"a":0,"k":50,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"},{"inv":false,"mode":"l","pt":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0,0],[0,500],[500,500],[500,0]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0,350],[0,500],[500,500],[500,350]],"c":true}]},{"t":149,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0,0],[0,500],[500,500],[500,0]],"c":true}]}],"ix":1},"o":{"a":0,"k":50,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 2"},{"inv":false,"mode":"l","pt":{"a":0,"k":{"i":[[82.843,0],[0,-82.843],[-82.843,0],[0,82.843]],"o":[[-82.843,0],[0,82.843],[82.843,0],[0,-82.843]],"v":[[250,100],[100,250],[250,400],[400,250]],"c":true},"ix":1},"o":{"a":0,"k":50,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 3"}],"sw":500,"sh":500,"sc":"#00ff00","ip":0,"op":150,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Shape Layer 5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,350,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[33,33,100],"ix":6}},"ao":0,"shapes":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":0,"s":[500,500]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":75,"s":[500,150]},{"t":149,"s":[500,500]}],"ix":2},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[0,0],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75,"s":[0,175],"to":[0,0],"ti":[0,0]},{"t":149,"s":[0,0]}],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":0,"s":[500,500]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":75,"s":[150,500]},{"t":149,"s":[500,500]}],"ix":2},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[0,0],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75,"s":[175,0],"to":[0,0],"ti":[0,0]},{"t":149,"s":[0,0]}],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 2","mn":"ADBE Vector Shape - Rect","hd":false},{"d":1,"ty":"el","s":{"a":0,"k":[300,300],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[1,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":0,"op":150,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":1,"nm":"darken","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,350,0],"ix":2},"a":{"a":0,"k":[250,250,0],"ix":1},"s":{"a":0,"k":[33,33,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"d","pt":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0,0],[0,500],[500,500],[500,0]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[350,0],[350,500],[500,500],[500,0]],"c":true}]},{"t":149,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0,0],[0,500],[500,500],[500,0]],"c":true}]}],"ix":1},"o":{"a":0,"k":50,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"},{"inv":false,"mode":"d","pt":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0,0],[0,500],[500,500],[500,0]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0,350],[0,500],[500,500],[500,350]],"c":true}]},{"t":149,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0,0],[0,500],[500,500],[500,0]],"c":true}]}],"ix":1},"o":{"a":0,"k":50,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 2"},{"inv":false,"mode":"d","pt":{"a":0,"k":{"i":[[82.843,0],[0,-82.843],[-82.843,0],[0,82.843]],"o":[[-82.843,0],[0,82.843],[82.843,0],[0,-82.843]],"v":[[250,100],[100,250],[250,400],[400,250]],"c":true},"ix":1},"o":{"a":0,"k":50,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 3"}],"sw":500,"sh":500,"sc":"#00ff00","ip":0,"op":150,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Shape Layer 4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[417,350,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[33,33,100],"ix":6}},"ao":0,"shapes":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":0,"s":[500,500]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":75,"s":[500,150]},{"t":149,"s":[500,500]}],"ix":2},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[0,0],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75,"s":[0,175],"to":[0,0],"ti":[0,0]},{"t":149,"s":[0,0]}],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":0,"s":[500,500]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":75,"s":[150,500]},{"t":149,"s":[500,500]}],"ix":2},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[0,0],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75,"s":[175,0],"to":[0,0],"ti":[0,0]},{"t":149,"s":[0,0]}],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 2","mn":"ADBE Vector Shape - Rect","hd":false},{"d":1,"ty":"el","s":{"a":0,"k":[300,300],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[1,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":0,"op":150,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":1,"nm":"difference","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[417,350,0],"ix":2},"a":{"a":0,"k":[250,250,0],"ix":1},"s":{"a":0,"k":[33,33,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"f","pt":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0,0],[0,500],[500,500],[500,0]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[350,0],[350,500],[500,500],[500,0]],"c":true}]},{"t":149,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0,0],[0,500],[500,500],[500,0]],"c":true}]}],"ix":1},"o":{"a":0,"k":50,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"},{"inv":false,"mode":"f","pt":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0,0],[0,500],[500,500],[500,0]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0,350],[0,500],[500,500],[500,350]],"c":true}]},{"t":149,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0,0],[0,500],[500,500],[500,0]],"c":true}]}],"ix":1},"o":{"a":0,"k":50,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 2"},{"inv":false,"mode":"f","pt":{"a":0,"k":{"i":[[82.843,0],[0,-82.843],[-82.843,0],[0,82.843]],"o":[[-82.843,0],[0,82.843],[82.843,0],[0,-82.843]],"v":[[250,100],[100,250],[250,400],[400,250]],"c":true},"ix":1},"o":{"a":0,"k":50,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 3"}],"sw":500,"sh":500,"sc":"#00ff00","ip":0,"op":150,"st":0,"bm":0},{"ddd":0,"ind":13,"ty":1,"nm":"White Solid 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[250,250,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"sw":500,"sh":500,"sc":"#ffffff","ip":0,"op":150,"st":0,"bm":0}],"markers":[]}
\ No newline at end of file