aboutsummaryrefslogtreecommitdiffhomepage
path: root/modules/sksg/include
diff options
context:
space:
mode:
authorGravatar Florin Malita <fmalita@chromium.org>2018-05-25 12:43:51 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-05-25 17:11:52 +0000
commit3b526b05d652ad6c310d9c636187b20b51c7648c (patch)
tree6c6fa99f2e80db81e9c3f593fe5883aabdaa442b /modules/sksg/include
parent59da548b0c4d4239e0ec1855d3f7f77a2bff4b93 (diff)
"Modularize" SkSG
* relocate all SkSG-related files under modules/sksg/ * fix various tidbits to make non-sksg builds possible * drop obsolete SampleSGInval.cpp Change-Id: I54e6c5bb1a09f45030fa8d607b3eb3f7cba78957 Reviewed-on: https://skia-review.googlesource.com/130025 Commit-Queue: Florin Malita <fmalita@chromium.org> Reviewed-by: Mike Klein <mtklein@google.com>
Diffstat (limited to 'modules/sksg/include')
-rw-r--r--modules/sksg/include/SkSGClipEffect.h50
-rw-r--r--modules/sksg/include/SkSGColor.h37
-rw-r--r--modules/sksg/include/SkSGDraw.h48
-rw-r--r--modules/sksg/include/SkSGEffectNode.h38
-rw-r--r--modules/sksg/include/SkSGGeometryNode.h49
-rw-r--r--modules/sksg/include/SkSGGeometryTransform.h58
-rw-r--r--modules/sksg/include/SkSGGradient.h105
-rw-r--r--modules/sksg/include/SkSGGroup.h47
-rw-r--r--modules/sksg/include/SkSGImage.h49
-rw-r--r--modules/sksg/include/SkSGInvalidationController.h43
-rw-r--r--modules/sksg/include/SkSGMaskEffect.h51
-rw-r--r--modules/sksg/include/SkSGMerge.h64
-rw-r--r--modules/sksg/include/SkSGNode.h107
-rw-r--r--modules/sksg/include/SkSGOpacityEffect.h42
-rw-r--r--modules/sksg/include/SkSGPaintNode.h60
-rw-r--r--modules/sksg/include/SkSGPath.h48
-rw-r--r--modules/sksg/include/SkSGPlane.h40
-rw-r--r--modules/sksg/include/SkSGRect.h76
-rw-r--r--modules/sksg/include/SkSGRenderNode.h36
-rw-r--r--modules/sksg/include/SkSGRoundEffect.h50
-rw-r--r--modules/sksg/include/SkSGScene.h85
-rw-r--r--modules/sksg/include/SkSGText.h69
-rw-r--r--modules/sksg/include/SkSGTransform.h81
-rw-r--r--modules/sksg/include/SkSGTrimEffect.h58
24 files changed, 1391 insertions, 0 deletions
diff --git a/modules/sksg/include/SkSGClipEffect.h b/modules/sksg/include/SkSGClipEffect.h
new file mode 100644
index 0000000000..674edb2b5c
--- /dev/null
+++ b/modules/sksg/include/SkSGClipEffect.h
@@ -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 SkSGClipEffect_DEFINED
+#define SkSGClipEffect_DEFINED
+
+#include "SkSGEffectNode.h"
+
+namespace sksg {
+
+class GeometryNode;
+
+/**
+ * Concrete Effect node, applying a clip to its descendants.
+ *
+ */
+class ClipEffect final : public EffectNode {
+public:
+ static sk_sp<ClipEffect> Make(sk_sp<RenderNode> child, sk_sp<GeometryNode> clip,
+ bool aa = false) {
+ return (child && clip)
+ ? sk_sp<ClipEffect>(new ClipEffect(std::move(child), std::move(clip), aa))
+ : nullptr;
+ }
+
+ ~ClipEffect() override;
+
+protected:
+ ClipEffect(sk_sp<RenderNode>, sk_sp<GeometryNode>, bool aa);
+
+ void onRender(SkCanvas*) const override;
+
+ SkRect onRevalidate(InvalidationController*, const SkMatrix&) override;
+
+private:
+ const sk_sp<GeometryNode> fClipNode;
+ const bool fAntiAlias;
+
+ bool fNoop = false;
+
+ typedef EffectNode INHERITED;
+};
+
+} // namespace sksg
+
+#endif // SkSGClipEffect_DEFINED
diff --git a/modules/sksg/include/SkSGColor.h b/modules/sksg/include/SkSGColor.h
new file mode 100644
index 0000000000..a19921cfd3
--- /dev/null
+++ b/modules/sksg/include/SkSGColor.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkSGColor_DEFINED
+#define SkSGColor_DEFINED
+
+#include "SkSGPaintNode.h"
+
+#include "SkColor.h"
+
+namespace sksg {
+
+/**
+ * Concrete Paint node, wrapping an SkColor.
+ */
+class Color : public PaintNode {
+public:
+ static sk_sp<Color> Make(SkColor c) { return sk_sp<Color>(new Color(c)); }
+
+ SG_ATTRIBUTE(Color, SkColor, fColor)
+
+protected:
+ void onApplyToPaint(SkPaint*) const override;
+
+private:
+ explicit Color(SkColor);
+
+ SkColor fColor;
+};
+
+} // namespace sksg
+
+#endif // SkSGColor_DEFINED
diff --git a/modules/sksg/include/SkSGDraw.h b/modules/sksg/include/SkSGDraw.h
new file mode 100644
index 0000000000..20ead3d5f6
--- /dev/null
+++ b/modules/sksg/include/SkSGDraw.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkSGDraw_DEFINED
+#define SkSGDraw_DEFINED
+
+#include "SkSGRenderNode.h"
+
+namespace sksg {
+
+class GeometryNode;
+class PaintNode;
+
+/**
+ * Concrete rendering node.
+ *
+ * Wraps and draws a [geometry, paint] tuple.
+ *
+ * Think Skia SkCanvas::drawFoo(foo, paint) calls.
+ */
+class Draw : public RenderNode {
+public:
+ static sk_sp<Draw> Make(sk_sp<GeometryNode> geo, sk_sp<PaintNode> paint) {
+ return (geo && paint) ? sk_sp<Draw>(new Draw(std::move(geo), std::move(paint))) : nullptr;
+ }
+
+protected:
+ Draw(sk_sp<GeometryNode>, sk_sp<PaintNode> paint);
+ ~Draw() override;
+
+ void onRender(SkCanvas*) const override;
+
+ SkRect onRevalidate(InvalidationController*, const SkMatrix&) override;
+
+private:
+ sk_sp<GeometryNode> fGeometry;
+ sk_sp<PaintNode> fPaint;
+
+ typedef RenderNode INHERITED;
+};
+
+} // namespace sksg
+
+#endif // SkSGDraw_DEFINED
diff --git a/modules/sksg/include/SkSGEffectNode.h b/modules/sksg/include/SkSGEffectNode.h
new file mode 100644
index 0000000000..ab0968e96c
--- /dev/null
+++ b/modules/sksg/include/SkSGEffectNode.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkSGEffectNode_DEFINED
+#define SkSGEffectNode_DEFINED
+
+#include "SkSGRenderNode.h"
+
+namespace sksg {
+
+/**
+ * Base class for nodes which apply some transformation when rendering
+ * their descendants.
+ *
+ * This includes transforms, clipping, filters, etc.
+ */
+class EffectNode : public RenderNode {
+protected:
+ explicit EffectNode(sk_sp<RenderNode>);
+ ~EffectNode() override;
+
+ void onRender(SkCanvas*) const override;
+
+ SkRect onRevalidate(InvalidationController*, const SkMatrix&) override;
+
+private:
+ sk_sp<RenderNode> fChild;
+
+ typedef RenderNode INHERITED;
+};
+
+} // namespace sksg
+
+#endif // SkSGEffectNode_DEFINED
diff --git a/modules/sksg/include/SkSGGeometryNode.h b/modules/sksg/include/SkSGGeometryNode.h
new file mode 100644
index 0000000000..7ce3aa9b79
--- /dev/null
+++ b/modules/sksg/include/SkSGGeometryNode.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkSGGeometryNode_DEFINED
+#define SkSGGeometryNode_DEFINED
+
+#include "SkSGNode.h"
+
+class SkCanvas;
+class SkPaint;
+class SkPath;
+
+namespace sksg {
+
+/**
+ * Base class for nodes which provide 'geometry' (as opposed to paint)
+ * for drawing.
+ *
+ * Think SkRect, SkPath, etc.
+ */
+class GeometryNode : public Node {
+public:
+ void clip(SkCanvas*, bool antiAlias) const;
+ void draw(SkCanvas*, const SkPaint&) const;
+
+ SkPath asPath() const;
+
+protected:
+ GeometryNode();
+
+ virtual void onClip(SkCanvas*, bool antiAlias) const = 0;
+
+ virtual void onDraw(SkCanvas*, const SkPaint&) const = 0;
+
+ virtual SkPath onAsPath() const = 0;
+
+private:
+ friend class Draw; // wants to know the cached bounds.
+
+ typedef Node INHERITED;
+};
+
+} // namespace sksg
+
+#endif // SkSGGeometryNode_DEFINED
diff --git a/modules/sksg/include/SkSGGeometryTransform.h b/modules/sksg/include/SkSGGeometryTransform.h
new file mode 100644
index 0000000000..fe7e026031
--- /dev/null
+++ b/modules/sksg/include/SkSGGeometryTransform.h
@@ -0,0 +1,58 @@
+/*
+ * 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 SkSGGeometryTransform_DEFINED
+#define SkSGGeometryTransform_DEFINED
+
+#include "SkSGGeometryNode.h"
+
+#include "SkPath.h"
+#include "SkSGTransform.h"
+
+class SkMatrix;
+
+namespace sksg {
+
+/**
+ * Concrete Effect node, binding a Matrix to a GeometryNode.
+ */
+class GeometryTransform final : public GeometryNode {
+public:
+ static sk_sp<GeometryTransform> Make(sk_sp<GeometryNode> child, sk_sp<Matrix> matrix) {
+ return child && matrix
+ ? sk_sp<GeometryTransform>(new GeometryTransform(std::move(child), std::move(matrix)))
+ : nullptr;
+ }
+
+ static sk_sp<GeometryTransform> Make(sk_sp<GeometryNode> child, const SkMatrix& m) {
+ return Make(std::move(child), Matrix::Make(m));
+ }
+
+ ~GeometryTransform() override;
+
+ const sk_sp<Matrix>& getMatrix() const { return fMatrix; }
+
+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:
+ GeometryTransform(sk_sp<GeometryNode>, sk_sp<Matrix>);
+
+ const sk_sp<GeometryNode> fChild;
+ const sk_sp<Matrix> fMatrix;
+ SkPath fTransformed;
+
+ using INHERITED = GeometryNode;
+};
+
+}
+
+#endif // SkSGGeometryTransform_DEFINED
diff --git a/modules/sksg/include/SkSGGradient.h b/modules/sksg/include/SkSGGradient.h
new file mode 100644
index 0000000000..d69cb1495c
--- /dev/null
+++ b/modules/sksg/include/SkSGGradient.h
@@ -0,0 +1,105 @@
+/*
+ * 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 SkSGGradient_DEFINED
+#define SkSGGradient_DEFINED
+
+#include "SkSGPaintNode.h"
+
+#include "SkColor.h"
+#include "SkPoint.h"
+#include "SkScalar.h"
+#include "SkShader.h"
+
+#include <vector>
+
+namespace sksg {
+
+/**
+ * Gradient base class.
+ */
+class Gradient : public PaintNode {
+public:
+ struct ColorStop {
+ SkScalar fPosition;
+ SkColor fColor;
+
+ bool operator==(const ColorStop& other) const {
+ return fPosition == other.fPosition && fColor == other.fColor;
+ }
+ };
+
+ SG_ATTRIBUTE(ColorStops, std::vector<ColorStop>, fColorStops)
+ SG_ATTRIBUTE(TileMode , SkShader::TileMode , fTileMode )
+
+protected:
+ void onApplyToPaint(SkPaint*) const final;
+
+ virtual sk_sp<SkShader> onMakeShader(const std::vector<SkColor>& colors,
+ const std::vector<SkScalar>& positions) const = 0;
+
+protected:
+ Gradient() = default;
+
+private:
+ std::vector<ColorStop> fColorStops;
+ SkShader::TileMode fTileMode = SkShader::kClamp_TileMode;
+
+ using INHERITED = PaintNode;
+};
+
+class LinearGradient final : public Gradient {
+public:
+ static sk_sp<LinearGradient> Make() {
+ return sk_sp<LinearGradient>(new LinearGradient());
+ }
+
+ SG_ATTRIBUTE(StartPoint, SkPoint, fStartPoint)
+ SG_ATTRIBUTE(EndPoint , SkPoint, fEndPoint )
+
+protected:
+ sk_sp<SkShader> onMakeShader(const std::vector<SkColor>& colors,
+ const std::vector<SkScalar>& positions) const override;
+
+private:
+ LinearGradient() = default;
+
+ SkPoint fStartPoint = SkPoint::Make(0, 0),
+ fEndPoint = SkPoint::Make(0, 0);
+
+ using INHERITED = Gradient;
+};
+
+class RadialGradient final : public Gradient {
+public:
+ static sk_sp<RadialGradient> Make() {
+ return sk_sp<RadialGradient>(new RadialGradient());
+ }
+
+ SG_ATTRIBUTE(StartCenter, SkPoint , fStartCenter)
+ SG_ATTRIBUTE(EndCenter , SkPoint , fEndCenter )
+ SG_ATTRIBUTE(StartRadius, SkScalar, fStartRadius)
+ SG_ATTRIBUTE(EndRadius , SkScalar, fEndRadius )
+
+protected:
+ sk_sp<SkShader> onMakeShader(const std::vector<SkColor>& colors,
+ const std::vector<SkScalar>& positions) const override;
+
+private:
+ RadialGradient() = default;
+
+ SkPoint fStartCenter = SkPoint::Make(0, 0),
+ fEndCenter = SkPoint::Make(0, 0);
+ SkScalar fStartRadius = 0,
+ fEndRadius = 0;
+
+ using INHERITED = Gradient;
+};
+
+} // namespace sksg
+
+#endif // SkSGGradient_DEFINED
diff --git a/modules/sksg/include/SkSGGroup.h b/modules/sksg/include/SkSGGroup.h
new file mode 100644
index 0000000000..482f10db8c
--- /dev/null
+++ b/modules/sksg/include/SkSGGroup.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkSGGroup_DEFINED
+#define SkSGGroup_DEFINED
+
+#include "SkSGRenderNode.h"
+
+#include "SkTArray.h"
+
+namespace sksg {
+
+/**
+ * Concrete node, grouping together multiple descendants.
+ */
+class Group : public RenderNode {
+public:
+ static sk_sp<Group> Make() {
+ return sk_sp<Group>(new Group());
+ }
+
+ 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;
+
+ void onRender(SkCanvas*) const override;
+ SkRect onRevalidate(InvalidationController*, const SkMatrix&) override;
+
+private:
+ SkTArray<sk_sp<RenderNode>, true> fChildren;
+
+ typedef RenderNode INHERITED;
+};
+
+} // namespace sksg
+
+#endif // SkSGGroup_DEFINED
diff --git a/modules/sksg/include/SkSGImage.h b/modules/sksg/include/SkSGImage.h
new file mode 100644
index 0000000000..7d17a50aaa
--- /dev/null
+++ b/modules/sksg/include/SkSGImage.h
@@ -0,0 +1,49 @@
+/*
+ * 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 SkSGImage_DEFINED
+#define SkSGImage_DEFINED
+
+#include "SkSGRenderNode.h"
+
+#include "SkFilterQuality.h"
+
+class SkImage;
+
+namespace sksg {
+
+/**
+ * Concrete rendering node, wrapping an SkImage.
+ *
+ */
+class Image final : public RenderNode {
+public:
+ static sk_sp<Image> Make(sk_sp<SkImage> image) {
+ return image ? sk_sp<Image>(new Image(std::move(image))) : nullptr;
+ }
+
+ SG_ATTRIBUTE(Quality , SkFilterQuality, fQuality )
+ SG_ATTRIBUTE(AntiAlias, bool , fAntiAlias)
+
+protected:
+ explicit Image(sk_sp<SkImage>);
+
+ void onRender(SkCanvas*) const override;
+
+ SkRect onRevalidate(InvalidationController*, const SkMatrix&) override;
+
+private:
+ const sk_sp<SkImage> fImage;
+ SkFilterQuality fQuality = kLow_SkFilterQuality;
+ bool fAntiAlias = true;
+
+ typedef RenderNode INHERITED;
+};
+
+} // namespace sksg
+
+#endif // SkSGImage_DEFINED
diff --git a/modules/sksg/include/SkSGInvalidationController.h b/modules/sksg/include/SkSGInvalidationController.h
new file mode 100644
index 0000000000..df3857c1fe
--- /dev/null
+++ b/modules/sksg/include/SkSGInvalidationController.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkSGInvalidationController_DEFINED
+#define SkSGInvalidationController_DEFINED
+
+#include "SkMatrix.h"
+#include "SkTDArray.h"
+#include "SkTypes.h"
+
+struct SkRect;
+
+namespace sksg {
+
+/**
+ * Receiver for invalidation events.
+ *
+ * Tracks dirty regions for repaint.
+ */
+class InvalidationController : public SkNoncopyable {
+public:
+ InvalidationController();
+
+ void inval(const SkRect&, const SkMatrix& ctm = SkMatrix::I());
+
+ const SkRect& bounds() const { return fBounds; }
+ const SkRect* begin() const { return fRects.begin(); }
+ const SkRect* end() const { return fRects.end(); }
+
+private:
+ SkTDArray<SkRect> fRects;
+ SkRect fBounds;
+
+ typedef SkNoncopyable INHERITED;
+};
+
+} // namespace sksg
+
+#endif // SkSGInvalidationController_DEFINED
diff --git a/modules/sksg/include/SkSGMaskEffect.h b/modules/sksg/include/SkSGMaskEffect.h
new file mode 100644
index 0000000000..c4fd0120e5
--- /dev/null
+++ b/modules/sksg/include/SkSGMaskEffect.h
@@ -0,0 +1,51 @@
+/*
+ * 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 SkSGMaskEffect_DEFINED
+#define SkSGMaskEffect_DEFINED
+
+#include "SkSGEffectNode.h"
+
+namespace sksg {
+
+/**
+ * Concrete Effect node, applying a mask to its descendants.
+ *
+ */
+class MaskEffect final : public EffectNode {
+public:
+ enum class Mode {
+ kNormal,
+ kInvert
+ };
+
+ static sk_sp<MaskEffect> Make(sk_sp<RenderNode> child, sk_sp<RenderNode> mask,
+ Mode mode = Mode::kNormal) {
+ return (child && mask)
+ ? sk_sp<MaskEffect>(new MaskEffect(std::move(child), std::move(mask), mode))
+ : nullptr;
+ }
+
+ ~MaskEffect() override;
+
+protected:
+ MaskEffect(sk_sp<RenderNode>, sk_sp<RenderNode> mask, Mode);
+
+ void onRender(SkCanvas*) const override;
+
+ SkRect onRevalidate(InvalidationController*, const SkMatrix&) override;
+
+private:
+ const sk_sp<RenderNode> fMaskNode;
+ const Mode fMaskMode;
+
+ typedef EffectNode INHERITED;
+};
+
+} // namespace sksg
+
+#endif // SkSGMaskEffect_DEFINED
diff --git a/modules/sksg/include/SkSGMerge.h b/modules/sksg/include/SkSGMerge.h
new file mode 100644
index 0000000000..54924d6475
--- /dev/null
+++ b/modules/sksg/include/SkSGMerge.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkSGMerge_DEFINED
+#define SkSGMerge_DEFINED
+
+#include "SkSGGeometryNode.h"
+
+#include "SkPath.h"
+
+#include <vector>
+
+class SkCanvas;
+class SkPaint;
+
+namespace sksg {
+
+/**
+ * Concrete Geometry node, combining other geometries based on Mode.
+ */
+class Merge final : public GeometryNode {
+public:
+ enum class Mode {
+ // Append path mode.
+ kMerge,
+
+ // SkPathOp ops.
+ kUnion,
+ kIntersect,
+ kDifference,
+ kReverseDifference,
+ kXOR,
+ };
+
+ static sk_sp<Merge> Make(std::vector<sk_sp<GeometryNode>>&& geos, Mode mode) {
+ return sk_sp<Merge>(new Merge(std::move(geos), mode));
+ }
+
+ ~Merge() override;
+
+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:
+ Merge(std::vector<sk_sp<GeometryNode>>&& geos, Mode);
+
+ std::vector<sk_sp<GeometryNode>> fGeos;
+ SkPath fMerged;
+ Mode fMode;
+
+ using INHERITED = GeometryNode;
+};
+
+} // namespace sksg
+
+#endif // SkSGMerge_DEFINED
diff --git a/modules/sksg/include/SkSGNode.h b/modules/sksg/include/SkSGNode.h
new file mode 100644
index 0000000000..17619de485
--- /dev/null
+++ b/modules/sksg/include/SkSGNode.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkSGNode_DEFINED
+#define SkSGNode_DEFINED
+
+#include "SkRect.h"
+#include "SkRefCnt.h"
+#include "SkTDArray.h"
+
+class SkCanvas;
+class SkMatrix;
+
+namespace sksg {
+
+class InvalidationController;
+
+/**
+ * Base class for all scene graph nodes.
+ *
+ * Handles ingress edge management for the DAG (i.e. node -> "parent" node mapping),
+ * and invalidation.
+ *
+ * Note: egress edges are only implemented/supported in container subclasses
+ * (e.g. Group, Effect, Draw).
+ */
+class Node : public SkRefCnt {
+public:
+ // Traverse the DAG and revalidate any dependant/invalidated nodes.
+ // Returns the bounding box for the DAG fragment.
+ const SkRect& revalidate(InvalidationController*, const SkMatrix&);
+
+protected:
+ enum InvalTraits {
+ // Nodes with this trait never generate direct damage -- instead,
+ // the damage bubbles up to ancestors.
+ kBubbleDamage_Trait = 1 << 0,
+ };
+
+ explicit Node(uint32_t invalTraits);
+ ~Node() override;
+
+ const SkRect& bounds() const {
+ SkASSERT(!this->hasInval());
+ return fBounds;
+ }
+
+ // Tag this node for invalidation and optional damage.
+ void invalidate(bool damage = true);
+ bool hasInval() const { return fFlags & kInvalidated_Flag; }
+
+ // Dispatched on revalidation. Subclasses are expected to recompute/cache their properties
+ // and return their bounding box in local coordinates.
+ virtual SkRect onRevalidate(InvalidationController*, const SkMatrix& ctm) = 0;
+
+ // Register/unregister |this| to receive invalidation events from a descendant.
+ void observeInval(const sk_sp<Node>&);
+ void unobserveInval(const sk_sp<Node>&);
+
+private:
+ enum Flags {
+ kInvalidated_Flag = 1 << 0, // the node or its descendants require revalidation
+ kDamage_Flag = 1 << 1, // the node contributes damage during revalidation
+ kObserverArray_Flag = 1 << 2, // the node has more than one inval observer
+ kInTraversal_Flag = 1 << 3, // the node is part of a traversal (cycle detection)
+ };
+
+ template <typename Func>
+ void forEachInvalObserver(Func&&) const;
+
+ class ScopedFlag;
+
+ union {
+ Node* fInvalObserver;
+ SkTDArray<Node*>* fInvalObserverArray;
+ };
+ SkRect fBounds;
+ const uint32_t fInvalTraits : 16;
+ uint32_t fFlags : 16;
+
+ typedef SkRefCnt INHERITED;
+};
+
+// Helper for defining attribute getters/setters in subclasses.
+#define SG_ATTRIBUTE(attr_name, attr_type, attr_container) \
+ const attr_type& get##attr_name() const { return attr_container; } \
+ void set##attr_name(const attr_type& v) { \
+ if (attr_container == v) return; \
+ attr_container = v; \
+ this->invalidate(); \
+ }
+
+#define SG_MAPPED_ATTRIBUTE(attr_name, attr_type, attr_container) \
+ attr_type get##attr_name() const { return attr_container.get##attr_name(); } \
+ void set##attr_name(const attr_type& v) { \
+ if (attr_container.get##attr_name() == v) return; \
+ attr_container.set##attr_name(v); \
+ this->invalidate(); \
+ }
+
+} // namespace sksg
+
+#endif // SkSGNode_DEFINED
diff --git a/modules/sksg/include/SkSGOpacityEffect.h b/modules/sksg/include/SkSGOpacityEffect.h
new file mode 100644
index 0000000000..d906775b44
--- /dev/null
+++ b/modules/sksg/include/SkSGOpacityEffect.h
@@ -0,0 +1,42 @@
+/*
+ * 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 SkSGOpacityEffect_DEFINED
+#define SkSGOpacityEffect_DEFINED
+
+#include "SkSGEffectNode.h"
+
+namespace sksg {
+
+/**
+ * Concrete Effect node, applying opacity to its descendants.
+ *
+ */
+class OpacityEffect final : public EffectNode {
+public:
+ static sk_sp<OpacityEffect> Make(sk_sp<RenderNode> child, float opacity = 1) {
+ return child ? sk_sp<OpacityEffect>(new OpacityEffect(std::move(child), opacity)) : nullptr;
+ }
+
+ SG_ATTRIBUTE(Opacity, float, fOpacity)
+
+protected:
+ OpacityEffect(sk_sp<RenderNode>, float);
+
+ void onRender(SkCanvas*) const override;
+
+ SkRect onRevalidate(InvalidationController*, const SkMatrix&) override;
+
+private:
+ float fOpacity;
+
+ typedef EffectNode INHERITED;
+};
+
+} // namespace sksg
+
+#endif // SkSGOpacityEffect_DEFINED
diff --git a/modules/sksg/include/SkSGPaintNode.h b/modules/sksg/include/SkSGPaintNode.h
new file mode 100644
index 0000000000..5c9563b3a6
--- /dev/null
+++ b/modules/sksg/include/SkSGPaintNode.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkSGPaintNode_DEFINED
+#define SkSGPaintNode_DEFINED
+
+#include "SkSGNode.h"
+
+#include "SkPaint.h"
+
+namespace sksg {
+
+/**
+ * Base class for nodes which provide a 'paint' (as opposed to geometry) for
+ * drawing (e.g. colors, gradients, patterns).
+ *
+ * Roughly equivalent to Skia's SkPaint.
+ */
+class PaintNode : public Node {
+public:
+ const SkPaint& makePaint();
+
+ 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 )
+ SG_ATTRIBUTE(StrokeJoin , SkPaint::Join , fStrokeJoin )
+ SG_ATTRIBUTE(StrokeCap , SkPaint::Cap , fStrokeCap )
+
+protected:
+ PaintNode();
+
+ virtual void onApplyToPaint(SkPaint*) const = 0;
+
+ SkRect onRevalidate(InvalidationController*, const SkMatrix&) final;
+
+private:
+ SkPaint fPaint;
+
+ SkScalar fOpacity = 1,
+ 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;
+
+ typedef Node INHERITED;
+};
+
+} // namespace sksg
+
+#endif // SkSGGeometryNode_DEFINED
diff --git a/modules/sksg/include/SkSGPath.h b/modules/sksg/include/SkSGPath.h
new file mode 100644
index 0000000000..1a8718868d
--- /dev/null
+++ b/modules/sksg/include/SkSGPath.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkSGPath_DEFINED
+#define SkSGPath_DEFINED
+
+#include "SkSGGeometryNode.h"
+
+#include "SkPath.h"
+
+class SkCanvas;
+class SkPaint;
+
+namespace sksg {
+
+/**
+ * Concrete Geometry node, wrapping an SkPath.
+ */
+class Path : public GeometryNode {
+public:
+ static sk_sp<Path> Make() { return sk_sp<Path>(new Path(SkPath())); }
+ static sk_sp<Path> Make(const SkPath& r) { return sk_sp<Path>(new Path(r)); }
+
+ SG_ATTRIBUTE(Path, SkPath, fPath)
+ SG_MAPPED_ATTRIBUTE(FillType, SkPath::FillType, fPath)
+
+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 Path(const SkPath&);
+
+ SkPath fPath;
+
+ using INHERITED = GeometryNode;
+};
+
+} // namespace sksg
+
+#endif // SkSGPath_DEFINED
diff --git a/modules/sksg/include/SkSGPlane.h b/modules/sksg/include/SkSGPlane.h
new file mode 100644
index 0000000000..c0a26375b2
--- /dev/null
+++ b/modules/sksg/include/SkSGPlane.h
@@ -0,0 +1,40 @@
+/*
+ * 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 SkSGPlane_DEFINED
+#define SkSGPlane_DEFINED
+
+#include "SkSGGeometryNode.h"
+
+class SkCanvas;
+class SkPaint;
+
+namespace sksg {
+
+/**
+ * Concrete Geometry node, representing the whole canvas.
+ */
+class Plane final : public GeometryNode {
+public:
+ static sk_sp<Plane> Make() { return sk_sp<Plane>(new Plane()); }
+
+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:
+ Plane();
+
+ using INHERITED = GeometryNode;
+};
+
+} // namespace sksg
+
+#endif // SkSGPlane_DEFINED
diff --git a/modules/sksg/include/SkSGRect.h b/modules/sksg/include/SkSGRect.h
new file mode 100644
index 0000000000..f5fcb962c6
--- /dev/null
+++ b/modules/sksg/include/SkSGRect.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkSGRect_DEFINED
+#define SkSGRect_DEFINED
+
+#include "SkSGGeometryNode.h"
+
+#include "SkRect.h"
+#include "SkRRect.h"
+
+class SkCanvas;
+class SkPaint;
+
+namespace sksg {
+
+/**
+ * Concrete Geometry node, wrapping an SkRect.
+ */
+class Rect final : public GeometryNode {
+public:
+ static sk_sp<Rect> Make() { return sk_sp<Rect>(new Rect(SkRect::MakeEmpty())); }
+ static sk_sp<Rect> Make(const SkRect& r) { return sk_sp<Rect>(new Rect(r)); }
+
+ SG_ATTRIBUTE(L, SkScalar, fRect.fLeft )
+ SG_ATTRIBUTE(T, SkScalar, fRect.fTop )
+ SG_ATTRIBUTE(R, SkScalar, fRect.fRight )
+ SG_ATTRIBUTE(B, SkScalar, fRect.fBottom)
+
+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 Rect(const SkRect&);
+
+ SkRect fRect;
+
+ using INHERITED = GeometryNode;
+};
+
+/**
+ * Concrete Geometry node, wrapping an SkRRect.
+ */
+class RRect final : public GeometryNode {
+public:
+ static sk_sp<RRect> Make() { return sk_sp<RRect>(new RRect(SkRRect())); }
+ static sk_sp<RRect> Make(const SkRRect& rr) { return sk_sp<RRect>(new RRect(rr)); }
+
+ SG_ATTRIBUTE(RRect, SkRRect, fRRect)
+
+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 RRect(const SkRRect&);
+
+ SkRRect fRRect;
+
+ using INHERITED = GeometryNode;
+};
+
+} // namespace sksg
+
+#endif // SkSGRect_DEFINED
diff --git a/modules/sksg/include/SkSGRenderNode.h b/modules/sksg/include/SkSGRenderNode.h
new file mode 100644
index 0000000000..4ca1aec616
--- /dev/null
+++ b/modules/sksg/include/SkSGRenderNode.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkSGRenderNode_DEFINED
+#define SkSGRenderNode_DEFINED
+
+#include "SkSGNode.h"
+
+class SkCanvas;
+
+namespace sksg {
+
+/**
+ * Base class for nodes which can render to a canvas.
+ */
+class RenderNode : public Node {
+public:
+ // Render the node and its descendants to the canvas.
+ void render(SkCanvas*) const;
+
+protected:
+ RenderNode();
+
+ virtual void onRender(SkCanvas*) const = 0;
+
+private:
+ typedef Node INHERITED;
+};
+
+} // namespace sksg
+
+#endif // SkSGRenderNode_DEFINED
diff --git a/modules/sksg/include/SkSGRoundEffect.h b/modules/sksg/include/SkSGRoundEffect.h
new file mode 100644
index 0000000000..67124ca072
--- /dev/null
+++ b/modules/sksg/include/SkSGRoundEffect.h
@@ -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
diff --git a/modules/sksg/include/SkSGScene.h b/modules/sksg/include/SkSGScene.h
new file mode 100644
index 0000000000..2081c1d747
--- /dev/null
+++ b/modules/sksg/include/SkSGScene.h
@@ -0,0 +1,85 @@
+/*
+ * 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 SkSGScene_DEFINED
+#define SkSGScene_DEFINED
+
+#include "SkRefCnt.h"
+#include "SkTypes.h"
+
+#include <memory>
+#include <vector>
+
+class SkCanvas;
+
+namespace sksg {
+
+class RenderNode;
+
+/**
+ * Base class for animators.
+ *
+ */
+class Animator : public SkNoncopyable {
+public:
+ virtual ~Animator();
+
+ void tick(float t);
+
+protected:
+ Animator();
+
+ virtual void onTick(float t) = 0;
+
+private:
+ using INHERITED = SkNoncopyable;
+};
+
+using AnimatorList = std::vector<std::unique_ptr<Animator>>;
+
+class GroupAnimator : public Animator {
+protected:
+ explicit GroupAnimator(AnimatorList&&);
+
+ void onTick(float t) override;
+
+private:
+ const AnimatorList fAnimators;
+
+ using INHERITED = Animator;
+};
+
+/**
+ * Holds a scene root and a list of animators.
+ *
+ * Provides high-level mehods for driving rendering and animations.
+ *
+ */
+class Scene final : SkNoncopyable {
+public:
+ static std::unique_ptr<Scene> Make(sk_sp<RenderNode> root, AnimatorList&& animators);
+ ~Scene();
+
+ void render(SkCanvas*) const;
+ void animate(float t);
+
+ void setShowInval(bool show) { fShowInval = show; }
+
+private:
+ Scene(sk_sp<RenderNode> root, AnimatorList&& animators);
+
+ const sk_sp<RenderNode> fRoot;
+ const AnimatorList fAnimators;
+
+ bool fShowInval = false;
+
+ using INHERITED = SkNoncopyable;
+};
+
+} // namespace sksg
+
+#endif // SkSGScene_DEFINED
diff --git a/modules/sksg/include/SkSGText.h b/modules/sksg/include/SkSGText.h
new file mode 100644
index 0000000000..eb43337a10
--- /dev/null
+++ b/modules/sksg/include/SkSGText.h
@@ -0,0 +1,69 @@
+/*
+ * 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 SkSGText_DEFINED
+#define SkSGText_DEFINED
+
+#include "SkSGGeometryNode.h"
+
+#include "SkPaintDefaults.h"
+#include "SkPoint.h"
+#include "SkString.h"
+
+class SkCanvas;
+class SkPaint;
+class SkTextBlob;
+class SkTypeface;
+
+namespace sksg {
+
+/**
+ * Concrete Geometry node, wrapping a (shaped) SkTextBlob.
+ */
+class Text final : public GeometryNode {
+public:
+ static sk_sp<Text> Make(sk_sp<SkTypeface> tf, const SkString& text);
+ ~Text() override;
+
+ SG_ATTRIBUTE(Text , SkString , fText )
+ SG_ATTRIBUTE(Flags , uint32_t , fFlags )
+ SG_ATTRIBUTE(Position, SkPoint , fPosition)
+ SG_ATTRIBUTE(Size , SkScalar , fSize )
+ SG_ATTRIBUTE(ScaleX , SkScalar , fScaleX )
+ SG_ATTRIBUTE(SkewX , SkScalar , fSkewX )
+ SG_ATTRIBUTE(Align , SkPaint::Align, fAlign )
+
+ // TODO: add shaping functionality.
+
+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 Text(sk_sp<SkTypeface>, const SkString&);
+
+ const sk_sp<SkTypeface> fTypeface;
+ SkString fText;
+ uint32_t fFlags = SkPaintDefaults_Flags;
+ SkPoint fPosition = SkPoint::Make(0, 0);
+ SkScalar fSize = SkPaintDefaults_TextSize;
+ SkScalar fScaleX = 1;
+ SkScalar fSkewX = 0;
+ SkPaint::Align fAlign = SkPaint::kLeft_Align;
+ SkPaint::Hinting fHinting = SkPaintDefaults_Hinting;
+
+ sk_sp<SkTextBlob> fBlob; // cached text blob
+
+ using INHERITED = GeometryNode;
+};
+
+} // namespace sksg
+
+#endif // SkSGText_DEFINED
diff --git a/modules/sksg/include/SkSGTransform.h b/modules/sksg/include/SkSGTransform.h
new file mode 100644
index 0000000000..6b7fbc010b
--- /dev/null
+++ b/modules/sksg/include/SkSGTransform.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkSGTransform_DEFINED
+#define SkSGTransform_DEFINED
+
+#include "SkSGEffectNode.h"
+
+#include "SkMatrix.h"
+
+namespace sksg {
+
+/**
+ * Concrete node, wrapping an SkMatrix, with an optional parent Matrix (to allow chaining):
+ *
+ * M' = parent x M
+ */
+class Matrix : public Node {
+public:
+ static sk_sp<Matrix> Make(const SkMatrix& m, sk_sp<Matrix> parent = nullptr) {
+ return sk_sp<Matrix>(new Matrix(m, std::move(parent)));
+ }
+
+ ~Matrix() override;
+
+ SG_ATTRIBUTE(Matrix, SkMatrix, fLocalMatrix)
+
+ const SkMatrix& getTotalMatrix() const { return fTotalMatrix; }
+
+protected:
+ Matrix(const SkMatrix&, sk_sp<Matrix>);
+
+ SkRect onRevalidate(InvalidationController*, const SkMatrix&) override;
+
+private:
+ sk_sp<Matrix> fParent;
+ SkMatrix fLocalMatrix,
+ fTotalMatrix; // cached during revalidation
+
+ typedef Node INHERITED;
+};
+
+/**
+ * Concrete Effect node, binding a Matrix to a RenderNode.
+ */
+class Transform final : public EffectNode {
+public:
+ static sk_sp<Transform> Make(sk_sp<RenderNode> child, sk_sp<Matrix> matrix) {
+ return child && matrix
+ ? sk_sp<Transform>(new Transform(std::move(child), std::move(matrix)))
+ : nullptr;
+ }
+
+ static sk_sp<Transform> Make(sk_sp<RenderNode> child, const SkMatrix& m) {
+ return Make(std::move(child), Matrix::Make(m));
+ }
+
+ ~Transform() override;
+
+ const sk_sp<Matrix>& getMatrix() const { return fMatrix; }
+
+protected:
+ void onRender(SkCanvas*) const override;
+
+ SkRect onRevalidate(InvalidationController*, const SkMatrix&) override;
+
+private:
+ Transform(sk_sp<RenderNode>, sk_sp<Matrix>);
+
+ const sk_sp<Matrix> fMatrix;
+
+ typedef EffectNode INHERITED;
+};
+
+} // namespace sksg
+
+#endif // SkSGTransform_DEFINED
diff --git a/modules/sksg/include/SkSGTrimEffect.h b/modules/sksg/include/SkSGTrimEffect.h
new file mode 100644
index 0000000000..18f15921e7
--- /dev/null
+++ b/modules/sksg/include/SkSGTrimEffect.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkSGTrimEffect_DEFINED
+#define SkSGTrimEffect_DEFINED
+
+#include "SkSGGeometryNode.h"
+
+#include "SkPath.h"
+#include "SkTrimPathEffect.h"
+
+class SkCanvas;
+class SkPaint;
+
+namespace sksg {
+
+/**
+ * Concrete Geometry node, applying a trim effect to its child.
+ */
+class TrimEffect final : public GeometryNode {
+public:
+ static sk_sp<TrimEffect> Make(sk_sp<GeometryNode> child) {
+ return child ? sk_sp<TrimEffect>(new TrimEffect(std::move(child))) : nullptr;
+ }
+
+ ~TrimEffect() override;
+
+ SG_ATTRIBUTE(Start , SkScalar , fStart )
+ SG_ATTRIBUTE(Stop , SkScalar , fStop )
+ SG_ATTRIBUTE(Mode , SkTrimPathEffect::Mode, fMode )
+
+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 TrimEffect(sk_sp<GeometryNode>);
+
+ const sk_sp<GeometryNode> fChild;
+
+ SkPath fTrimmedPath;
+ SkScalar fStart = 0,
+ fStop = 1;
+ SkTrimPathEffect::Mode fMode = SkTrimPathEffect::Mode::kNormal;
+
+ using INHERITED = GeometryNode;
+};
+
+} // namespace sksg
+
+#endif // SkSGTrimEffect_DEFINED