up-to-date submodule(rive-cpp)
[platform/core/uifw/rive-tizen.git] / submodule / src / shapes / clipping_shape.cpp
1 #include "shapes/clipping_shape.hpp"
2 #include "artboard.hpp"
3 #include "core_context.hpp"
4 #include "node.hpp"
5 #include "renderer.hpp"
6 #include "shapes/path_composer.hpp"
7 #include "shapes/shape.hpp"
8
9 using namespace rive;
10
11 StatusCode ClippingShape::onAddedClean(CoreContext* context)
12 {
13         auto clippingHolder = parent();
14
15         auto artboard = static_cast<Artboard*>(context);
16         for (auto core : artboard->objects())
17         {
18                 if (core == nullptr)
19                 {
20                         continue;
21                 }
22                 // Iterate artboard to find drawables that are parented to this clipping
23                 // shape, they need to know they'll be clipped by this shape.
24                 if (core->is<Drawable>())
25                 {
26                         auto drawable = core->as<Drawable>();
27                         for (ContainerComponent* component = drawable; component != nullptr;
28                              component = component->parent())
29                         {
30                                 if (component == clippingHolder)
31                                 {
32                                         drawable->addClippingShape(this);
33                                         break;
34                                 }
35                         }
36                 }
37
38                 // Iterate artboard to find shapes that are parented to the source,
39                 // their paths will need to be RenderPaths in order to be used for
40                 // clipping operations.
41                 if (core->is<Shape>() && core != clippingHolder)
42                 {
43                         auto component = core->as<ContainerComponent>();
44                         while (component != nullptr)
45                         {
46                                 if (component == m_Source)
47                                 {
48                                         auto shape = core->as<Shape>();
49                                         shape->addDefaultPathSpace(PathSpace::World |
50                                                                    PathSpace::Clipping);
51                                         m_Shapes.push_back(shape);
52                                         break;
53                                 }
54                                 component = component->parent();
55                         }
56                 }
57         }
58
59         m_RenderPath = rive::makeRenderPath();
60
61         return StatusCode::Ok;
62 }
63
64 StatusCode ClippingShape::onAddedDirty(CoreContext* context)
65 {
66         StatusCode code = Super::onAddedDirty(context);
67         if (code != StatusCode::Ok)
68         {
69                 return code;
70         }
71         auto coreObject = context->resolve(sourceId());
72         if (coreObject == nullptr || !coreObject->is<Node>())
73         {
74                 return StatusCode::MissingObject;
75         }
76
77         m_Source = reinterpret_cast<Node*>(coreObject);
78
79         return StatusCode::Ok;
80 }
81
82 void ClippingShape::buildDependencies()
83 {
84         for (auto shape : m_Shapes)
85         {
86                 shape->pathComposer()->addDependent(this);
87         }
88 }
89
90 static Mat2D identity;
91 void ClippingShape::update(ComponentDirt value)
92 {
93         if (hasDirt(value, ComponentDirt::Path | ComponentDirt::WorldTransform))
94         {
95                 m_RenderPath->reset();
96
97                 m_RenderPath->fillRule((FillRule)fillRule());
98                 for (auto shape : m_Shapes)
99                 {
100                         m_RenderPath->addPath(shape->pathComposer()->worldPath(), identity);
101                 }
102         }
103 }