Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 36216fb

Browse files
fmalitaSkia Commit-Bot
authored and
Skia Commit-Bot
committed
[skottie] Initial Fill layer effect support
Overwrite the layer content color with a color filter. TBR= Change-Id: I39f920225affb2641cc11ab1f0c1456d89b47cb7 Reviewed-on: https://skia-review.googlesource.com/145730 Reviewed-by: Florin Malita <[email protected]> Commit-Queue: Florin Malita <[email protected]>
1 parent ae64e49 commit 36216fb

File tree

4 files changed

+179
-8
lines changed

4 files changed

+179
-8
lines changed

modules/skottie/src/Skottie.cpp

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "SkPoint.h"
1818
#include "SkSGClipEffect.h"
1919
#include "SkSGColor.h"
20+
#include "SkSGColorFilter.h"
2021
#include "SkSGDraw.h"
2122
#include "SkSGGeometryTransform.h"
2223
#include "SkSGGradient.h"
@@ -258,9 +259,10 @@ sk_sp<sksg::GeometryNode> AttachPolystarGeometry(const skjson::ObjectValue& jsta
258259
return std::move(path_node);
259260
}
260261

261-
sk_sp<sksg::Color> AttachColor(const skjson::ObjectValue& jcolor, AttachContext* ctx) {
262+
sk_sp<sksg::Color> AttachColor(const skjson::ObjectValue& jcolor, AttachContext* ctx,
263+
const char prop_name[]) {
262264
auto color_node = sksg::Color::Make(SK_ColorBLACK);
263-
BindProperty<VectorValue>(jcolor["c"], &ctx->fAnimators,
265+
BindProperty<VectorValue>(jcolor[prop_name], &ctx->fAnimators,
264266
[color_node](const VectorValue& c) {
265267
color_node->setColor(ValueTraits<VectorValue>::As<SkColor>(c));
266268
});
@@ -357,15 +359,15 @@ sk_sp<sksg::PaintNode> AttachStroke(const skjson::ObjectValue& jstroke, AttachCo
357359
}
358360

359361
sk_sp<sksg::PaintNode> AttachColorFill(const skjson::ObjectValue& jfill, AttachContext* ctx) {
360-
return AttachPaint(jfill, ctx, AttachColor(jfill, ctx));
362+
return AttachPaint(jfill, ctx, AttachColor(jfill, ctx, "c"));
361363
}
362364

363365
sk_sp<sksg::PaintNode> AttachGradientFill(const skjson::ObjectValue& jfill, AttachContext* ctx) {
364366
return AttachPaint(jfill, ctx, AttachGradient(jfill, ctx));
365367
}
366368

367369
sk_sp<sksg::PaintNode> AttachColorStroke(const skjson::ObjectValue& jstroke, AttachContext* ctx) {
368-
return AttachStroke(jstroke, ctx, AttachPaint(jstroke, ctx, AttachColor(jstroke, ctx)));
370+
return AttachStroke(jstroke, ctx, AttachPaint(jstroke, ctx, AttachColor(jstroke, ctx, "c")));
369371
}
370372

371373
sk_sp<sksg::PaintNode> AttachGradientStroke(const skjson::ObjectValue& jstroke,
@@ -1106,14 +1108,55 @@ sk_sp<sksg::RenderNode> AttachMask(const skjson::ArrayValue* jmask,
11061108
return sksg::MaskEffect::Make(std::move(childNode), std::move(mask_group));
11071109
}
11081110

1111+
1112+
sk_sp<sksg::RenderNode> AttachFillLayerEffect(const skjson::ArrayValue* jeffect_props,
1113+
AttachContext* ctx,
1114+
sk_sp<sksg::RenderNode> layer) {
1115+
if (!jeffect_props) return layer;
1116+
1117+
sk_sp<sksg::Color> color_node;
1118+
1119+
for (const skjson::ObjectValue* jprop : *jeffect_props) {
1120+
if (!jprop) continue;
1121+
1122+
switch (const auto ty = ParseDefault<int>((*jprop)["ty"], -1)) {
1123+
case 2: // color
1124+
color_node = AttachColor(*jprop, ctx, "v");
1125+
break;
1126+
default:
1127+
LOG("?? Ignoring unsupported fill effect poperty type: %d\n", ty);
1128+
break;
1129+
}
1130+
}
1131+
1132+
return color_node
1133+
? sksg::ColorModeFilter::Make(std::move(layer), std::move(color_node), SkBlendMode::kSrcIn)
1134+
: nullptr;
1135+
}
1136+
1137+
sk_sp<sksg::RenderNode> AttachLayerEffects(const skjson::ArrayValue& jeffects,
1138+
AttachContext* ctx,
1139+
sk_sp<sksg::RenderNode> layer) {
1140+
for (const skjson::ObjectValue* jeffect : jeffects) {
1141+
if (!jeffect) continue;
1142+
1143+
switch (const auto ty = ParseDefault<int>((*jeffect)["ty"], -1)) {
1144+
case 21: // Fill
1145+
layer = AttachFillLayerEffect((*jeffect)["ef"], ctx, std::move(layer));
1146+
break;
1147+
default:
1148+
LOG("?? Unsupported layer effect type: %d\n", ty);
1149+
break;
1150+
}
1151+
}
1152+
1153+
return layer;
1154+
}
1155+
11091156
sk_sp<sksg::RenderNode> AttachLayer(const skjson::ObjectValue* jlayer,
11101157
AttachLayerContext* layerCtx) {
11111158
if (!jlayer) return nullptr;
11121159

1113-
if (!(*jlayer)["ef"].is<skjson::NullValue>()) {
1114-
LOG("?? Unsupported layer effect.\n");
1115-
}
1116-
11171160
using LayerAttacher = sk_sp<sksg::RenderNode> (*)(const skjson::ObjectValue&, AttachContext*);
11181161
static constexpr LayerAttacher gLayerAttachers[] = {
11191162
AttachCompLayer, // 'ty': 0
@@ -1157,6 +1200,11 @@ sk_sp<sksg::RenderNode> AttachLayer(const skjson::ObjectValue* jlayer,
11571200
layer = AttachOpacity(*jtransform, &local_ctx, std::move(layer));
11581201
}
11591202

1203+
// Optional layer effects.
1204+
if (const skjson::ArrayValue* jeffects = (*jlayer)["ef"]) {
1205+
layer = AttachLayerEffects(*jeffects, &local_ctx, std::move(layer));
1206+
}
1207+
11601208
class LayerController final : public sksg::GroupAnimator {
11611209
public:
11621210
LayerController(sksg::AnimatorList&& layer_animators,
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* Copyright 2018 Google Inc.
3+
*
4+
* Use of this source code is governed by a BSD-style license that can be
5+
* found in the LICENSE file.
6+
*/
7+
8+
#ifndef SkSGColorFilter_DEFINED
9+
#define SkSGColorFilter_DEFINED
10+
11+
#include "SkSGEffectNode.h"
12+
13+
#include "SkBlendMode.h"
14+
15+
class SkColorFilter;
16+
17+
namespace sksg {
18+
19+
class Color;
20+
21+
/**
22+
* Base class for nodes which apply a color filter when rendering their descendants.
23+
*
24+
*/
25+
class ColorFilter : public EffectNode {
26+
protected:
27+
explicit ColorFilter(sk_sp<RenderNode>);
28+
29+
void onRender(SkCanvas*) const final;
30+
31+
sk_sp<SkColorFilter> fColorFilter;
32+
33+
private:
34+
typedef EffectNode INHERITED;
35+
};
36+
37+
/**
38+
* Concrete SkModeColorFilter Effect node.
39+
*
40+
*/
41+
class ColorModeFilter final : public ColorFilter {
42+
public:
43+
~ColorModeFilter() override;
44+
45+
static sk_sp<ColorModeFilter> Make(sk_sp<RenderNode> child, sk_sp<Color> color,
46+
SkBlendMode mode) {
47+
return (child && color)
48+
? sk_sp<ColorModeFilter>(new ColorModeFilter(std::move(child), std::move(color), mode))
49+
: nullptr;
50+
}
51+
52+
SG_ATTRIBUTE(Mode , SkBlendMode, fMode )
53+
54+
protected:
55+
SkRect onRevalidate(InvalidationController*, const SkMatrix&) override;
56+
57+
private:
58+
ColorModeFilter(sk_sp<RenderNode>, sk_sp<Color>, SkBlendMode);
59+
60+
sk_sp<Color> fColor;
61+
SkBlendMode fMode;
62+
63+
typedef ColorFilter INHERITED;
64+
};
65+
66+
} // namespace sksg
67+
68+
#endif // SkSGColorFilter_DEFINED

modules/sksg/sksg.gni

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ _src = get_path_info("src", "abspath")
99
skia_sksg_sources = [
1010
"$_src/SkSGClipEffect.cpp",
1111
"$_src/SkSGColor.cpp",
12+
"$_src/SkSGColorFilter.cpp",
1213
"$_src/SkSGDraw.cpp",
1314
"$_src/SkSGEffectNode.cpp",
1415
"$_src/SkSGGeometryNode.cpp",

modules/sksg/src/SkSGColorFilter.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright 2018 Google Inc.
3+
*
4+
* Use of this source code is governed by a BSD-style license that can be
5+
* found in the LICENSE file.
6+
*/
7+
8+
#include "SkSGColorFilter.h"
9+
10+
#include "SkCanvas.h"
11+
#include "SkColorFilter.h"
12+
#include "SkSGColor.h"
13+
14+
namespace sksg {
15+
16+
ColorFilter::ColorFilter(sk_sp<RenderNode> child)
17+
: INHERITED(std::move(child)) {}
18+
19+
void ColorFilter::onRender(SkCanvas* canvas) const {
20+
if (this->bounds().isEmpty())
21+
return;
22+
23+
SkAutoCanvasRestore acr(canvas, false);
24+
25+
if (fColorFilter) {
26+
SkPaint p;
27+
p.setColorFilter(fColorFilter);
28+
canvas->saveLayer(this->bounds(), &p);
29+
}
30+
31+
this->INHERITED::onRender(canvas);
32+
}
33+
34+
ColorModeFilter::ColorModeFilter(sk_sp<RenderNode> child, sk_sp<Color> color, SkBlendMode mode)
35+
: INHERITED(std::move(child))
36+
, fColor(std::move(color))
37+
, fMode(mode) {
38+
this->observeInval(fColor);
39+
}
40+
41+
ColorModeFilter::~ColorModeFilter() {
42+
this->unobserveInval(fColor);
43+
}
44+
45+
SkRect ColorModeFilter::onRevalidate(InvalidationController* ic, const SkMatrix& ctm) {
46+
SkASSERT(this->hasInval());
47+
48+
fColor->revalidate(ic, ctm);
49+
fColorFilter = SkColorFilter::MakeModeFilter(fColor->getColor(), fMode);
50+
51+
return this->INHERITED::onRevalidate(ic, ctm);
52+
}
53+
54+
} // namespace sksg

0 commit comments

Comments
 (0)