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