[skottie] Add support for round-corners geometry effects
TBR= Change-Id: I5505561df28d5953526662d60fe2300cb112bc37 Reviewed-on: https://skia-review.googlesource.com/124769 Reviewed-by: Florin Malita <fmalita@chromium.org> Commit-Queue: Florin Malita <fmalita@chromium.org>
This commit is contained in:
parent
8afbecbcc0
commit
41dff6ef68
1
BUILD.gn
1
BUILD.gn
@ -1489,6 +1489,7 @@ if (skia_enable_tools) {
|
||||
"experimental/sksg/geometry/SkSGPath.cpp",
|
||||
"experimental/sksg/geometry/SkSGPlane.cpp",
|
||||
"experimental/sksg/geometry/SkSGRect.cpp",
|
||||
"experimental/sksg/geometry/SkSGRoundEffect.cpp",
|
||||
"experimental/sksg/geometry/SkSGText.cpp",
|
||||
"experimental/sksg/geometry/SkSGTrimEffect.cpp",
|
||||
"experimental/sksg/paint/SkSGColor.cpp",
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "SkSGOpacityEffect.h"
|
||||
#include "SkSGPath.h"
|
||||
#include "SkSGRect.h"
|
||||
#include "SkSGRoundEffect.h"
|
||||
#include "SkSGScene.h"
|
||||
#include "SkSGTransform.h"
|
||||
#include "SkSGTrimEffect.h"
|
||||
@ -452,6 +453,25 @@ std::vector<sk_sp<sksg::GeometryNode>> AttachTrimGeometryEffect(
|
||||
return trimmed;
|
||||
}
|
||||
|
||||
std::vector<sk_sp<sksg::GeometryNode>> AttachRoundGeometryEffect(
|
||||
const Json::Value& jtrim, AttachContext* ctx, std::vector<sk_sp<sksg::GeometryNode>>&& geos) {
|
||||
|
||||
std::vector<sk_sp<sksg::GeometryNode>> rounded;
|
||||
rounded.reserve(geos.size());
|
||||
|
||||
for (const auto& g : geos) {
|
||||
const auto roundEffect = sksg::RoundEffect::Make(std::move(g));
|
||||
rounded.push_back(roundEffect);
|
||||
|
||||
BindProperty<ScalarValue>(jtrim["r"], &ctx->fAnimators,
|
||||
[roundEffect](const ScalarValue& r) {
|
||||
roundEffect->setRadius(r);
|
||||
});
|
||||
}
|
||||
|
||||
return rounded;
|
||||
}
|
||||
|
||||
using GeometryAttacherT = sk_sp<sksg::GeometryNode> (*)(const Json::Value&, AttachContext*);
|
||||
static constexpr GeometryAttacherT gGeometryAttachers[] = {
|
||||
AttachPathGeometry,
|
||||
@ -475,6 +495,7 @@ using GeometryEffectAttacherT =
|
||||
static constexpr GeometryEffectAttacherT gGeometryEffectAttachers[] = {
|
||||
AttachMergeGeometryEffect,
|
||||
AttachTrimGeometryEffect,
|
||||
AttachRoundGeometryEffect,
|
||||
};
|
||||
|
||||
enum class ShapeType {
|
||||
@ -500,6 +521,7 @@ const ShapeInfo* FindShapeInfo(const Json::Value& shape) {
|
||||
{ "gs", ShapeType::kPaint , 3 }, // gstroke -> AttachGradientStroke
|
||||
{ "mm", ShapeType::kGeometryEffect, 0 }, // merge -> AttachMergeGeometryEffect
|
||||
{ "rc", ShapeType::kGeometry , 1 }, // rrect -> AttachRRectGeometry
|
||||
{ "rd", ShapeType::kGeometryEffect, 2 }, // round -> AttachRoundGeometryEffect
|
||||
{ "sh", ShapeType::kGeometry , 0 }, // shape -> AttachPathGeometry
|
||||
{ "sr", ShapeType::kGeometry , 3 }, // polystar -> AttachPolyStarGeometry
|
||||
{ "st", ShapeType::kPaint , 1 }, // stroke -> AttachColorStroke
|
||||
|
56
experimental/sksg/geometry/SkSGRoundEffect.cpp
Normal file
56
experimental/sksg/geometry/SkSGRoundEffect.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2018 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "SkSGRoundEffect.h"
|
||||
|
||||
#include "SkCanvas.h"
|
||||
#include "SkCornerPathEffect.h"
|
||||
#include "SkStrokeRec.h"
|
||||
|
||||
namespace sksg {
|
||||
|
||||
RoundEffect::RoundEffect(sk_sp<GeometryNode> child)
|
||||
: fChild(std::move(child)) {
|
||||
this->observeInval(fChild);
|
||||
}
|
||||
|
||||
RoundEffect::~RoundEffect() {
|
||||
this->unobserveInval(fChild);
|
||||
}
|
||||
|
||||
void RoundEffect::onClip(SkCanvas* canvas, bool antiAlias) const {
|
||||
canvas->clipPath(fRoundedPath, SkClipOp::kIntersect, antiAlias);
|
||||
}
|
||||
|
||||
void RoundEffect::onDraw(SkCanvas* canvas, const SkPaint& paint) const {
|
||||
SkASSERT(!paint.getPathEffect());
|
||||
|
||||
canvas->drawPath(fRoundedPath, paint);
|
||||
}
|
||||
|
||||
SkPath RoundEffect::onAsPath() const {
|
||||
return fRoundedPath;
|
||||
}
|
||||
|
||||
SkRect RoundEffect::onRevalidate(InvalidationController* ic, const SkMatrix& ctm) {
|
||||
SkASSERT(this->hasInval());
|
||||
|
||||
const auto childbounds = fChild->revalidate(ic, ctm);
|
||||
const auto path = fChild->asPath();
|
||||
|
||||
if (auto round = SkCornerPathEffect::Make(fRadius)) {
|
||||
fRoundedPath.reset();
|
||||
SkStrokeRec rec(SkStrokeRec::kHairline_InitStyle);
|
||||
SkAssertResult(round->filterPath(&fRoundedPath, path, &rec, &childbounds));
|
||||
} else {
|
||||
fRoundedPath = path;
|
||||
}
|
||||
|
||||
return fRoundedPath.computeTightBounds();
|
||||
}
|
||||
|
||||
} // namespace sksg
|
50
experimental/sksg/geometry/SkSGRoundEffect.h
Normal file
50
experimental/sksg/geometry/SkSGRoundEffect.h
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2018 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkSGRoundEffect_DEFINED
|
||||
#define SkSGRoundEffect_DEFINED
|
||||
|
||||
#include "SkSGGeometryNode.h"
|
||||
|
||||
#include "SkPath.h"
|
||||
|
||||
namespace sksg {
|
||||
|
||||
/**
|
||||
* Concrete Geometry node, applying a rounded-corner effect to its child.
|
||||
*/
|
||||
class RoundEffect final : public GeometryNode {
|
||||
public:
|
||||
static sk_sp<RoundEffect> Make(sk_sp<GeometryNode> child) {
|
||||
return child ? sk_sp<RoundEffect>(new RoundEffect(std::move(child))) : nullptr;
|
||||
}
|
||||
|
||||
~RoundEffect() override;
|
||||
|
||||
SG_ATTRIBUTE(Radius, SkScalar, fRadius)
|
||||
|
||||
protected:
|
||||
void onClip(SkCanvas*, bool antiAlias) const override;
|
||||
void onDraw(SkCanvas*, const SkPaint&) const override;
|
||||
|
||||
SkRect onRevalidate(InvalidationController*, const SkMatrix&) override;
|
||||
SkPath onAsPath() const override;
|
||||
|
||||
private:
|
||||
explicit RoundEffect(sk_sp<GeometryNode>);
|
||||
|
||||
const sk_sp<GeometryNode> fChild;
|
||||
|
||||
SkPath fRoundedPath;
|
||||
SkScalar fRadius = 0;
|
||||
|
||||
using INHERITED = GeometryNode;
|
||||
};
|
||||
|
||||
} // namespace sksg
|
||||
|
||||
#endif // SkSGRoundEffect_DEFINED
|
@ -21,7 +21,7 @@ public:
|
||||
that should be "rounded".
|
||||
*/
|
||||
static sk_sp<SkPathEffect> Make(SkScalar radius) {
|
||||
return sk_sp<SkPathEffect>(new SkCornerPathEffect(radius));
|
||||
return radius > 0 ? sk_sp<SkPathEffect>(new SkCornerPathEffect(radius)) : nullptr;
|
||||
}
|
||||
|
||||
virtual bool filterPath(SkPath* dst, const SkPath& src,
|
||||
|
Loading…
Reference in New Issue
Block a user