1 #include "shapes/clipping_shape.hpp"
2 #include "artboard.hpp"
3 #include "core_context.hpp"
5 #include "renderer.hpp"
6 #include "shapes/path_composer.hpp"
7 #include "shapes/shape.hpp"
11 StatusCode ClippingShape::onAddedClean(CoreContext* context)
13 auto clippingHolder = parent();
15 auto artboard = static_cast<Artboard*>(context);
16 for (auto core : artboard->objects())
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>())
26 auto drawable = core->as<Drawable>();
27 for (ContainerComponent* component = drawable; component != nullptr;
28 component = component->parent())
30 if (component == clippingHolder)
32 drawable->addClippingShape(this);
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)
43 auto component = core->as<ContainerComponent>();
44 while (component != nullptr)
46 if (component == m_Source)
48 auto shape = core->as<Shape>();
49 shape->addDefaultPathSpace(PathSpace::World |
51 m_Shapes.push_back(shape);
54 component = component->parent();
59 m_RenderPath = rive::makeRenderPath();
61 return StatusCode::Ok;
64 StatusCode ClippingShape::onAddedDirty(CoreContext* context)
66 StatusCode code = Super::onAddedDirty(context);
67 if (code != StatusCode::Ok)
71 auto coreObject = context->resolve(sourceId());
72 if (coreObject == nullptr || !coreObject->is<Node>())
74 return StatusCode::MissingObject;
77 m_Source = reinterpret_cast<Node*>(coreObject);
79 return StatusCode::Ok;
82 void ClippingShape::buildDependencies()
84 for (auto shape : m_Shapes)
86 shape->pathComposer()->addDependent(this);
90 static Mat2D identity;
91 void ClippingShape::update(ComponentDirt value)
93 if (hasDirt(value, ComponentDirt::Path | ComponentDirt::WorldTransform))
95 m_RenderPath->reset();
97 m_RenderPath->fillRule((FillRule)fillRule());
98 for (auto shape : m_Shapes)
100 m_RenderPath->addPath(shape->pathComposer()->worldPath(), identity);