fix follow path not working with path as target and shape with 0 opacity

fixes #7155
We have to also check all paths belonging to a shape before deferring the path update

Diffs=
1c7e61b8a fix follow path not working with path as target and shape with 0 opacity (#7156)

Co-authored-by: hernan <hernan@rive.app>
diff --git a/.rive_head b/.rive_head
index 3d7de34..1b876f8 100644
--- a/.rive_head
+++ b/.rive_head
@@ -1 +1 @@
-328d307dfdfcc3c4a9d7c726f783b5325bfbef43
+1c7e61b8a075b2eaacbcce4f5438d6072b30e420
diff --git a/include/rive/shapes/path.hpp b/include/rive/shapes/path.hpp
index b92428a..5732cfb 100644
--- a/include/rive/shapes/path.hpp
+++ b/include/rive/shapes/path.hpp
@@ -52,6 +52,7 @@
     void update(ComponentDirt value) override;
 
     void addDefaultPathSpace(PathSpace space);
+    bool canDeferPathUpdate();
     void addVertex(PathVertex* vertex);
 
     virtual void markPathDirty();
diff --git a/src/shapes/path.cpp b/src/shapes/path.cpp
index 71371f3..5354580 100644
--- a/src/shapes/path.cpp
+++ b/src/shapes/path.cpp
@@ -60,6 +60,12 @@
 
 void Path::addDefaultPathSpace(PathSpace space) { m_DefaultPathSpace |= space; }
 
+bool Path::canDeferPathUpdate()
+{
+    return ((m_DefaultPathSpace & PathSpace::Clipping) != PathSpace::Clipping) &&
+           ((m_DefaultPathSpace & PathSpace::FollowPath) != PathSpace::FollowPath);
+}
+
 const Mat2D& Path::pathTransform() const { return worldTransform(); }
 
 void Path::buildPath(CommandPath& commandPath) const
diff --git a/src/shapes/shape.cpp b/src/shapes/shape.cpp
index 820b5b1..420b82d 100644
--- a/src/shapes/shape.cpp
+++ b/src/shapes/shape.cpp
@@ -23,8 +23,20 @@
 
 bool Shape::canDeferPathUpdate()
 {
-    return renderOpacity() == 0 && (pathSpace() & PathSpace::Clipping) != PathSpace::Clipping &&
-           (pathSpace() & PathSpace::FollowPath) != PathSpace::FollowPath;
+    auto canDefer = renderOpacity() == 0 &&
+                    (pathSpace() & PathSpace::Clipping) != PathSpace::Clipping &&
+                    (pathSpace() & PathSpace::FollowPath) != PathSpace::FollowPath;
+    if (canDefer)
+    {
+        for (auto path : m_Paths)
+        {
+            if (!path->canDeferPathUpdate())
+            {
+                return false;
+            }
+        }
+    }
+    return canDefer;
 }
 
 void Shape::update(ComponentDirt value)
diff --git a/test/assets/follow_path_path_0_opacity.riv b/test/assets/follow_path_path_0_opacity.riv
new file mode 100644
index 0000000..ce4f0fb
--- /dev/null
+++ b/test/assets/follow_path_path_0_opacity.riv
Binary files differ
diff --git a/test/follow_path_constraint_test.cpp b/test/follow_path_constraint_test.cpp
index 2090186..faff9ec 100644
--- a/test/follow_path_constraint_test.cpp
+++ b/test/follow_path_constraint_test.cpp
@@ -46,3 +46,23 @@
     REQUIRE(targetComponents.x() == rectComponents.x());
     REQUIRE(targetComponents.y() == rectComponents.y());
 }
+
+TEST_CASE("follow path constraint with path at 0 opacity updates world transform", "[file]")
+{
+    auto file = ReadRiveFile("../../test/assets/follow_path_path_0_opacity.riv");
+
+    auto artboard = file->artboard();
+
+    REQUIRE(artboard->find<rive::TransformComponent>("target") != nullptr);
+    auto target = artboard->find<rive::TransformComponent>("target");
+
+    REQUIRE(artboard->find<rive::TransformComponent>("rect") != nullptr);
+    auto rectangle = artboard->find<rive::TransformComponent>("rect");
+
+    artboard->advance(0.0f);
+
+    auto targetComponents = target->worldTransform().decompose();
+    auto rectComponents = rectangle->worldTransform().decompose();
+    REQUIRE(targetComponents.x() == rectComponents.x());
+    REQUIRE(targetComponents.y() == rectComponents.y());
+}