/* * Copyright 2019 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef SkSGRenderEffect_DEFINED #define SkSGRenderEffect_DEFINED #include "modules/sksg/include/SkSGEffectNode.h" #include "include/core/SkBlendMode.h" #include "include/core/SkColor.h" #include "include/effects/SkImageFilters.h" #include #include // TODO: merge EffectNode.h with this header class SkImageFilter; class SkMaskFilter; class SkShader; namespace sksg { /** * Shader base class. */ class Shader : public Node { public: ~Shader() override; const sk_sp& getShader() const { SkASSERT(!this->hasInval()); return fShader; } protected: Shader(); SkRect onRevalidate(InvalidationController*, const SkMatrix&) final; virtual sk_sp onRevalidateShader() = 0; private: sk_sp fShader; using INHERITED = Node; }; /** * Attaches a shader to the render DAG. */ class ShaderEffect final : public EffectNode { public: ~ShaderEffect() override; static sk_sp Make(sk_sp child, sk_sp shader = nullptr); void setShader(sk_sp); protected: void onRender(SkCanvas*, const RenderContext*) const override; SkRect onRevalidate(InvalidationController*, const SkMatrix&) override; private: ShaderEffect(sk_sp child, sk_sp shader); sk_sp fShader; using INHERITED = EffectNode; }; /** * Attaches a mask shader to the render DAG. */ class MaskShaderEffect final : public EffectNode { public: static sk_sp Make(sk_sp, sk_sp = nullptr); SG_ATTRIBUTE(Shader, sk_sp, fShader) protected: void onRender(SkCanvas*, const RenderContext*) const override; private: MaskShaderEffect(sk_sp, sk_sp); sk_sp fShader; using INHERITED = EffectNode; }; /** * ImageFilter base class. */ class ImageFilter : public Node { public: ~ImageFilter() override; const sk_sp& getFilter() const { SkASSERT(!this->hasInval()); return fFilter; } protected: explicit ImageFilter(sk_sp input = nullptr); using InputsT = std::vector>; explicit ImageFilter(std::unique_ptr inputs); SkRect onRevalidate(InvalidationController*, const SkMatrix&) final; virtual sk_sp onRevalidateFilter() = 0; sk_sp refInput(size_t) const; private: const std::unique_ptr fInputs; sk_sp fFilter; using INHERITED = Node; }; /** * Attaches an ImageFilter (chain) to the render DAG. */ class ImageFilterEffect final : public EffectNode { public: ~ImageFilterEffect() override; static sk_sp Make(sk_sp child, sk_sp filter); protected: void onRender(SkCanvas*, const RenderContext*) const override; const RenderNode* onNodeAt(const SkPoint&) const override; SkRect onRevalidate(InvalidationController*, const SkMatrix&) override; private: ImageFilterEffect(sk_sp child, sk_sp filter); sk_sp fImageFilter; using INHERITED = EffectNode; }; /** * Wrapper for externally-managed SkImageFilters. */ class ExternalImageFilter final : public ImageFilter { public: ~ExternalImageFilter() override; static sk_sp Make() { return sk_sp(new ExternalImageFilter()); } SG_ATTRIBUTE(ImageFilter, sk_sp, fImageFilter) private: ExternalImageFilter(); sk_sp onRevalidateFilter() override { return fImageFilter; } sk_sp fImageFilter; }; /** * SkDropShadowImageFilter node. */ class DropShadowImageFilter final : public ImageFilter { public: ~DropShadowImageFilter() override; static sk_sp Make(sk_sp input = nullptr); enum class Mode { kShadowAndForeground, kShadowOnly }; SG_ATTRIBUTE(Offset, SkVector, fOffset) SG_ATTRIBUTE(Sigma , SkVector, fSigma ) SG_ATTRIBUTE(Color , SkColor , fColor ) SG_ATTRIBUTE(Mode , Mode , fMode ) protected: sk_sp onRevalidateFilter() override; private: explicit DropShadowImageFilter(sk_sp input); SkVector fOffset = { 0, 0 }, fSigma = { 0, 0 }; SkColor fColor = SK_ColorBLACK; Mode fMode = Mode::kShadowAndForeground; using INHERITED = ImageFilter; }; /** * SkBlurImageFilter node. */ class BlurImageFilter final : public ImageFilter { public: ~BlurImageFilter() override; static sk_sp Make(sk_sp input = nullptr); SG_ATTRIBUTE(Sigma , SkVector , fSigma ) SG_ATTRIBUTE(TileMode, SkTileMode, fTileMode) protected: sk_sp onRevalidateFilter() override; private: explicit BlurImageFilter(sk_sp input); SkVector fSigma = { 0, 0 }; SkTileMode fTileMode = SkTileMode::kClamp; using INHERITED = ImageFilter; }; /** * Applies a SkBlendMode to descendant render nodes. */ class BlendModeEffect final : public EffectNode { public: ~BlendModeEffect() override; static sk_sp Make(sk_sp child, SkBlendMode = SkBlendMode::kSrcOver); SG_ATTRIBUTE(Mode, SkBlendMode, fMode) protected: void onRender(SkCanvas*, const RenderContext*) const override; const RenderNode* onNodeAt(const SkPoint&) const override; private: BlendModeEffect(sk_sp, SkBlendMode); SkBlendMode fMode; using INHERITED = EffectNode; }; class LayerEffect final : public EffectNode { public: ~LayerEffect() override; static sk_sp Make(sk_sp child, SkBlendMode mode = SkBlendMode::kSrcOver); SG_ATTRIBUTE(Mode, SkBlendMode, fMode) private: LayerEffect(sk_sp child, SkBlendMode mode); void onRender(SkCanvas*, const RenderContext*) const override; SkBlendMode fMode; using INHERITED = EffectNode; }; } // namespace sksg #endif // SkSGRenderEffect_DEFINED