mirror of
https://github.com/rive-app/rive-cpp.git
synced 2026-01-18 21:21:17 +01:00
update scripted drawable clipping to new strategy and remove unused function (#11195) 8002b223a3
* update clipping to new strategy Co-authored-by: hernan <hernan@rive.app>
This commit is contained in:
@@ -1 +1 @@
|
||||
7fae9fb6c80697fd3d9dcb3dee87fb9922135b4a
|
||||
8002b223a3709255afb943a52d15eaa27ce72d53
|
||||
|
||||
@@ -32,7 +32,6 @@ protected:
|
||||
|
||||
public:
|
||||
BlendMode blendMode() const { return (BlendMode)blendModeValue(); }
|
||||
ClipResult applyClip(Renderer* renderer) const;
|
||||
virtual void draw(Renderer* renderer) = 0;
|
||||
virtual Core* hitTest(HitInfo*, const Mat2D&) = 0;
|
||||
bool hitTestPoint(const Vec2D& position,
|
||||
|
||||
@@ -57,6 +57,7 @@ public:
|
||||
std::vector<HitComponent*> hitComponents(StateMachineInstance* sm) override;
|
||||
bool worldToLocal(Vec2D world, Vec2D* local);
|
||||
void markNeedsUpdate() override;
|
||||
bool willDraw() override;
|
||||
Component* component() override { return this; }
|
||||
};
|
||||
|
||||
|
||||
@@ -43,38 +43,6 @@ void Drawable::addClippingShape(ClippingShape* shape)
|
||||
m_ClippingShapes.push_back(shape);
|
||||
}
|
||||
|
||||
ClipResult Drawable::applyClip(Renderer* renderer) const
|
||||
{
|
||||
if (m_ClippingShapes.size() == 0)
|
||||
{
|
||||
return ClipResult::noClip;
|
||||
}
|
||||
|
||||
renderer->save();
|
||||
|
||||
for (auto clippingShape : m_ClippingShapes)
|
||||
{
|
||||
if (!clippingShape->isVisible())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ShapePaintPath* path = clippingShape->path();
|
||||
if (path == nullptr)
|
||||
{
|
||||
return ClipResult::emptyClip;
|
||||
}
|
||||
RenderPath* renderPath = path->renderPath(this);
|
||||
if (renderPath == nullptr)
|
||||
{
|
||||
return ClipResult::emptyClip;
|
||||
}
|
||||
|
||||
renderer->clipPath(renderPath);
|
||||
}
|
||||
return ClipResult::clip;
|
||||
}
|
||||
|
||||
bool Drawable::willDraw() { return !isHidden(); }
|
||||
|
||||
bool Drawable::isChildOfLayout(LayoutComponent* layout)
|
||||
|
||||
@@ -17,43 +17,34 @@ bool ScriptedDrawable::scriptInit(LuaState* state)
|
||||
|
||||
void ScriptedDrawable::draw(Renderer* renderer)
|
||||
{
|
||||
if (m_state == nullptr || !draws())
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto state = m_state->state;
|
||||
|
||||
ClipResult clipResult = applyClip(renderer);
|
||||
if (clipResult == ClipResult::noClip)
|
||||
if (m_needsSaveOperation)
|
||||
{
|
||||
// We didn't clip, so make sure to save as we'll be doing some
|
||||
// transformations.
|
||||
renderer->save();
|
||||
}
|
||||
if (clipResult != ClipResult::emptyClip)
|
||||
{
|
||||
renderer->transform(worldTransform());
|
||||
renderer->transform(worldTransform());
|
||||
|
||||
rive_lua_pushRef(state, m_self);
|
||||
if (static_cast<lua_Type>(lua_getfield(state, -1, "draw")) !=
|
||||
LUA_TFUNCTION)
|
||||
{
|
||||
fprintf(stderr, "expected draw to be a function\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushvalue(state, -2);
|
||||
auto scriptedRenderer =
|
||||
lua_newrive<ScriptedRenderer>(state, renderer);
|
||||
if (static_cast<lua_Status>(rive_lua_pcall(state, 2, 0)) != LUA_OK)
|
||||
{
|
||||
rive_lua_pop(state, 1);
|
||||
}
|
||||
scriptedRenderer->end();
|
||||
}
|
||||
rive_lua_pop(state, 1);
|
||||
rive_lua_pushRef(state, m_self);
|
||||
if (static_cast<lua_Type>(lua_getfield(state, -1, "draw")) != LUA_TFUNCTION)
|
||||
{
|
||||
fprintf(stderr, "expected draw to be a function\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushvalue(state, -2);
|
||||
auto scriptedRenderer = lua_newrive<ScriptedRenderer>(state, renderer);
|
||||
if (static_cast<lua_Status>(rive_lua_pcall(state, 2, 0)) != LUA_OK)
|
||||
{
|
||||
rive_lua_pop(state, 1);
|
||||
}
|
||||
scriptedRenderer->end();
|
||||
}
|
||||
rive_lua_pop(state, 1);
|
||||
if (m_needsSaveOperation)
|
||||
{
|
||||
renderer->restore();
|
||||
}
|
||||
renderer->restore();
|
||||
}
|
||||
|
||||
std::vector<HitComponent*> ScriptedDrawable::hitComponents(
|
||||
@@ -111,6 +102,12 @@ HitResult HitScriptedDrawable::processEvent(Vec2D position,
|
||||
rive_lua_pop(state, 1);
|
||||
return hitResult;
|
||||
}
|
||||
|
||||
bool ScriptedDrawable::willDraw()
|
||||
{
|
||||
return Super::willDraw() && m_state != nullptr && draws();
|
||||
}
|
||||
|
||||
#else
|
||||
void ScriptedDrawable::draw(Renderer* renderer) {}
|
||||
|
||||
@@ -128,6 +125,9 @@ HitResult HitScriptedDrawable::processEvent(Vec2D position,
|
||||
{
|
||||
return HitResult::none;
|
||||
}
|
||||
|
||||
bool ScriptedDrawable::willDraw() { return Super::willDraw() && draws(); }
|
||||
|
||||
#endif
|
||||
|
||||
void ScriptedDrawable::update(ComponentDirt value)
|
||||
|
||||
@@ -104,69 +104,6 @@ TEST_CASE("artboard is clipped correctly", "[clipping]")
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Shape does not have any clipping paths visible", "[clipping]")
|
||||
{
|
||||
ClippingFactory factory;
|
||||
auto file = ReadRiveFile("assets/clip_tests.riv", &factory);
|
||||
|
||||
auto artboard = file->artboard("Empty-Shape");
|
||||
REQUIRE(artboard != nullptr);
|
||||
artboard->updateComponents();
|
||||
auto node = artboard->find("Ellipse-clipper");
|
||||
REQUIRE(node != nullptr);
|
||||
REQUIRE(node->is<rive::Shape>());
|
||||
rive::Shape* shape = static_cast<rive::Shape*>(node);
|
||||
REQUIRE(shape->isEmpty() == true);
|
||||
auto clippedNode = artboard->find("Rectangle-clipped");
|
||||
REQUIRE(clippedNode != nullptr);
|
||||
REQUIRE(clippedNode->is<rive::Shape>());
|
||||
rive::Shape* clippedShape = static_cast<rive::Shape*>(clippedNode);
|
||||
rive::NoOpRenderer renderer;
|
||||
auto clipResult = clippedShape->applyClip(&renderer);
|
||||
REQUIRE(clipResult == rive::ClipResult::emptyClip);
|
||||
}
|
||||
|
||||
TEST_CASE("Shape has at least a clipping path visible", "[clipping]")
|
||||
{
|
||||
ClippingFactory factory;
|
||||
auto file = ReadRiveFile("assets/clip_tests.riv", &factory);
|
||||
|
||||
auto artboard = file->artboard("Hidden-Path-Visible-Path");
|
||||
REQUIRE(artboard != nullptr);
|
||||
artboard->updateComponents();
|
||||
auto node = artboard->find("Ellipse-clipper");
|
||||
REQUIRE(node != nullptr);
|
||||
REQUIRE(node->is<rive::Shape>());
|
||||
rive::Shape* shape = static_cast<rive::Shape*>(node);
|
||||
REQUIRE(shape->isEmpty() == false);
|
||||
auto clippedNode = artboard->find("Rectangle-clipped");
|
||||
REQUIRE(clippedNode != nullptr);
|
||||
REQUIRE(clippedNode->is<rive::Shape>());
|
||||
rive::Shape* clippedShape = static_cast<rive::Shape*>(clippedNode);
|
||||
rive::NoOpRenderer renderer;
|
||||
auto clipResult = clippedShape->applyClip(&renderer);
|
||||
REQUIRE(clipResult == rive::ClipResult::clip);
|
||||
}
|
||||
|
||||
TEST_CASE("Shape returns an empty clip when one clipping shape is empty",
|
||||
"[clipping]")
|
||||
{
|
||||
ClippingFactory factory;
|
||||
auto file = ReadRiveFile("assets/clip_tests.riv", &factory);
|
||||
|
||||
auto artboard = file->artboard("One-Clipping-Shape-Visible-One-Hidden");
|
||||
REQUIRE(artboard != nullptr);
|
||||
artboard->updateComponents();
|
||||
auto node = artboard->find("Rectangle-clipped");
|
||||
REQUIRE(node != nullptr);
|
||||
REQUIRE(node->is<rive::Shape>());
|
||||
rive::Shape* shape = static_cast<rive::Shape*>(node);
|
||||
|
||||
rive::NoOpRenderer renderer;
|
||||
auto clipResult = shape->applyClip(&renderer);
|
||||
REQUIRE(clipResult == rive::ClipResult::emptyClip);
|
||||
}
|
||||
|
||||
TEST_CASE("Apply clipping to elements that are moved outside their hierarchy",
|
||||
"[clipping]")
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user