xref: /aosp_15_r20/external/skia/src/utils/SkCanvasStack.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2013 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 SkCanvasStack_DEFINED
9 #define SkCanvasStack_DEFINED
10 
11 #include "include/core/SkCanvas.h"
12 #include "include/core/SkM44.h"
13 #include "include/core/SkPoint.h"
14 #include "include/core/SkRefCnt.h"
15 #include "include/core/SkRegion.h"
16 #include "include/core/SkTypes.h"
17 #include "include/private/base/SkTArray.h"
18 #include "include/private/base/SkTypeTraits.h"
19 #include "include/utils/SkNWayCanvas.h"
20 
21 #include <memory>
22 #include <type_traits>
23 
24 class SkPath;
25 class SkRRect;
26 class SkShader;
27 enum class SkClipOp;
28 struct SkRect;
29 
30 /**
31  *  Like NWayCanvas, in that it forwards all canvas methods to each sub-canvas that is "pushed".
32  *
33  *  Unlike NWayCanvas, this takes ownership of each subcanvas, and deletes them when this canvas
34  *  is deleted.
35  */
36 class SkCanvasStack : public SkNWayCanvas {
37 public:
38     SkCanvasStack(int width, int height);
39     ~SkCanvasStack() override;
40 
41     void pushCanvas(std::unique_ptr<SkCanvas>, const SkIPoint& origin);
42     void removeAll() override;
43 
44     /*
45      * The following add/remove canvas methods are overrides from SkNWayCanvas
46      * that do not make sense in the context of our CanvasStack, but since we
47      * can share most of the other implementation of NWay we override those
48      * methods to be no-ops.
49      */
addCanvas(SkCanvas *)50     void addCanvas(SkCanvas*) override { SkDEBUGFAIL("Invalid Op"); }
removeCanvas(SkCanvas *)51     void removeCanvas(SkCanvas*) override { SkDEBUGFAIL("Invalid Op"); }
52 
53 protected:
54     void didSetM44(const SkM44&) override;
55 
56     void onClipRect(const SkRect&, SkClipOp, ClipEdgeStyle) override;
57     void onClipRRect(const SkRRect&, SkClipOp, ClipEdgeStyle) override;
58     void onClipPath(const SkPath&, SkClipOp, ClipEdgeStyle) override;
59     void onClipShader(sk_sp<SkShader>, SkClipOp) override;
60     void onClipRegion(const SkRegion&, SkClipOp) override;
61 
62 private:
63     void clipToZOrderedBounds();
64 
65     struct CanvasData {
66         SkIPoint origin;
67         SkRegion requiredClip;
68         std::unique_ptr<SkCanvas> ownedCanvas;
69 
70         static_assert(::sk_is_trivially_relocatable<decltype(origin)>::value);
71         static_assert(::sk_is_trivially_relocatable<decltype(requiredClip)>::value);
72         static_assert(::sk_is_trivially_relocatable<decltype(ownedCanvas)>::value);
73 
74         using sk_is_trivially_relocatable = std::true_type;
75     };
76 
77     skia_private::TArray<CanvasData> fCanvasData;
78 
79     using INHERITED = SkNWayCanvas;
80 };
81 
82 #endif
83