[skottie] Initial mask support

TBR=

Change-Id: Ibf4baeb17f98e1ed359f04deefe2f1c09414540d
Reviewed-on: https://skia-review.googlesource.com/98840
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Florin Malita <fmalita@chromium.org>
This commit is contained in:
Florin Malita 2018-01-23 13:37:59 -05:00 committed by Skia Commit-Bot
parent 74d6e113a5
commit 25366fad43
4 changed files with 74 additions and 9 deletions

View File

@ -173,17 +173,18 @@ sk_sp<sksg::RenderNode> AttachOpacity(const Json::Value& jtransform, AttachConte
sk_sp<sksg::RenderNode> AttachComposition(const Json::Value&, AttachContext* ctx);
sk_sp<sksg::Path> AttachPath(const Json::Value& jpath, AttachContext* ctx) {
auto path_node = sksg::Path::Make();
return BindProperty<ShapeValue>(jpath, ctx, path_node,
[](sksg::Path* node, const ShapeValue& p) { node->setPath(p); })
? path_node
: nullptr;
}
sk_sp<sksg::GeometryNode> AttachPathGeometry(const Json::Value& jpath, AttachContext* ctx) {
SkASSERT(jpath.isObject());
auto path_node = sksg::Path::Make();
auto path_attached = BindProperty<ShapeValue>(jpath["ks"], ctx, path_node,
[](sksg::Path* node, const ShapeValue& p) { node->setPath(p); });
if (path_attached)
LOG("** Attached path geometry - verbs: %d\n", path_node->getPath().countVerbs());
return path_attached ? path_node : nullptr;
return AttachPath(jpath["ks"], ctx);
}
sk_sp<sksg::GeometryNode> AttachRRectGeometry(const Json::Value& jrect, AttachContext* ctx) {
@ -881,6 +882,62 @@ struct AttachLayerContext {
}
};
SkBlendMode MaskBlendMode(char mode) {
switch (mode) {
case 'a': return SkBlendMode::kSrcOver; // Additive
case 's': return SkBlendMode::kExclusion; // Subtract
case 'i': return SkBlendMode::kDstIn; // Intersect
case 'l': return SkBlendMode::kLighten; // Lighten
case 'd': return SkBlendMode::kDarken; // Darken
case 'f': return SkBlendMode::kDifference; // Difference
default: break;
}
return SkBlendMode::kSrcOver;
}
sk_sp<sksg::RenderNode> AttachMask(const Json::Value& jmask,
AttachContext* ctx,
sk_sp<sksg::RenderNode> childNode) {
if (!jmask.isArray())
return childNode;
auto mask_group = sksg::Group::Make();
for (const auto& m : jmask) {
if (!m.isObject())
continue;
const auto inverted = ParseBool(m["inv"], false);
// TODO
if (inverted) {
LogFail(m, "Unsupported inverse mask");
continue;
}
auto mask_path = AttachPath(m["pt"], ctx);
if (!mask_path) {
LogFail(m, "Could not parse mask path");
continue;
}
auto mode = ParseString(m["mode"], "");
if (mode.size() != 1 || !strcmp(mode.c_str(), "n")) // "None" masks have no effect.
continue;
auto mask_paint = sksg::Color::Make(SK_ColorBLACK);
mask_paint->setBlendMode(MaskBlendMode(mode.c_str()[0]));
BindProperty<ScalarValue>(m["o"], ctx, mask_paint,
[](sksg::Color* node, const ScalarValue& o) { node->setOpacity(o * 0.01f); });
mask_group->addChild(sksg::Draw::Make(std::move(mask_path), std::move(mask_paint)));
}
return mask_group->empty()
? childNode
: sksg::MaskEffect::Make(std::move(childNode), std::move(mask_group));
}
sk_sp<sksg::RenderNode> AttachLayer(const Json::Value& jlayer,
AttachLayerContext* layerCtx) {
if (!jlayer.isObject())
@ -903,8 +960,10 @@ sk_sp<sksg::RenderNode> AttachLayer(const Json::Value& jlayer,
// Layer content.
auto layer = gLayerAttachers[type](jlayer, layerCtx->fCtx);
// Optional layer mask.
layer = AttachMask(jlayer["masksProperties"], layerCtx->fCtx, std::move(layer));
// Optional layer transform.
if (auto layerMatrix = layerCtx->AttachLayerMatrix(jlayer)) {
// Optional layer transform.
layer = sksg::Transform::Make(std::move(layer), std::move(layerMatrix));
}
// Optional layer opacity.

View File

@ -26,6 +26,9 @@ public:
void addChild(sk_sp<RenderNode>);
void removeChild(const sk_sp<RenderNode>&);
size_t size() const { return SkTo<size_t>(fChildren.count()); }
bool empty() const { return fChildren.empty(); }
protected:
Group();
~Group() override;

View File

@ -23,6 +23,7 @@ SkRect PaintNode::onRevalidate(InvalidationController*, const SkMatrix&) {
fPaint.reset();
fPaint.setAntiAlias(fAntiAlias);
fPaint.setBlendMode(fBlendMode);
fPaint.setStyle(fStyle);
fPaint.setStrokeWidth(fStrokeWidth);
fPaint.setStrokeMiter(fStrokeMiter);

View File

@ -26,6 +26,7 @@ public:
SG_ATTRIBUTE(AntiAlias , bool , fAntiAlias )
SG_ATTRIBUTE(Opacity , SkScalar , fOpacity )
SG_ATTRIBUTE(BlendMode , SkBlendMode , fBlendMode )
SG_ATTRIBUTE(StrokeWidth, SkScalar , fStrokeWidth)
SG_ATTRIBUTE(StrokeMiter, SkScalar , fStrokeMiter)
SG_ATTRIBUTE(Style , SkPaint::Style, fStyle )
@ -46,6 +47,7 @@ private:
fStrokeWidth = 1,
fStrokeMiter = 4;
bool fAntiAlias = false;
SkBlendMode fBlendMode = SkBlendMode::kSrcOver;
SkPaint::Style fStyle = SkPaint::kFill_Style;
SkPaint::Join fStrokeJoin = SkPaint::kMiter_Join;
SkPaint::Cap fStrokeCap = SkPaint::kButt_Cap;