Home | History | Annotate | Download | only in include
      1 /*
      2  * Copyright 2017 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 SkSGRenderNode_DEFINED
      9 #define SkSGRenderNode_DEFINED
     10 
     11 #include "SkSGNode.h"
     12 
     13 #include "SkColorFilter.h"
     14 
     15 class SkCanvas;
     16 class SkPaint;
     17 
     18 namespace sksg {
     19 
     20 /**
     21  * Base class for nodes which can render to a canvas.
     22  */
     23 class RenderNode : public Node {
     24 protected:
     25     struct RenderContext;
     26 
     27 public:
     28     // Render the node and its descendants to the canvas.
     29     void render(SkCanvas*, const RenderContext* = nullptr) const;
     30 
     31 protected:
     32     RenderNode();
     33 
     34     virtual void onRender(SkCanvas*, const RenderContext*) const = 0;
     35 
     36     // Paint property overrides.
     37     // These are deferred until we can determine whether they can be applied to the individual
     38     // draw paints, or whether they require content isolation (applied to a layer).
     39     struct RenderContext {
     40         sk_sp<SkColorFilter> fColorFilter;
     41         float                fOpacity = 1;
     42 
     43         // Returns true if the paint was modified.
     44         bool modulatePaint(SkPaint*) const;
     45     };
     46 
     47     class ScopedRenderContext final {
     48     public:
     49         ScopedRenderContext(SkCanvas*, const RenderContext*);
     50         ~ScopedRenderContext();
     51 
     52         ScopedRenderContext(ScopedRenderContext&& that) { *this = std::move(that); }
     53 
     54         ScopedRenderContext& operator=(ScopedRenderContext&& that) {
     55             fCanvas       = that.fCanvas;
     56             fCtx          = std::move(that.fCtx);
     57             fRestoreCount = that.fRestoreCount;
     58 
     59             // scope ownership is being transferred
     60             that.fRestoreCount = -1;
     61 
     62             return *this;
     63         }
     64 
     65         operator const RenderContext* () const { return &fCtx; }
     66 
     67         // Add (cumulative) paint overrides to a render node sub-DAG.
     68         ScopedRenderContext&& modulateOpacity(float opacity);
     69         ScopedRenderContext&& modulateColorFilter(sk_sp<SkColorFilter>);
     70 
     71         // Force content isolation for a node sub-DAG by applying the RenderContext
     72         // overrides via a layer.
     73         ScopedRenderContext&& setIsolation(const SkRect& bounds, bool do_isolate);
     74 
     75     private:
     76         // stack-only
     77         void* operator new(size_t)        = delete;
     78         void* operator new(size_t, void*) = delete;
     79 
     80         // Scopes cannot be copied.
     81         ScopedRenderContext(const ScopedRenderContext&)            = delete;
     82         ScopedRenderContext& operator=(const ScopedRenderContext&) = delete;
     83 
     84         SkCanvas*     fCanvas;
     85         RenderContext fCtx;
     86         int           fRestoreCount;
     87     };
     88 
     89 private:
     90     typedef Node INHERITED;
     91 };
     92 
     93 } // namespace sksg
     94 
     95 #endif // SkSGRenderNode_DEFINED
     96