Clipping and baseline

The way we were computing the bounds for clipping was off which also exposed it was off in the runtime for transform constraints! This was also breaking the Lottie converter.

Now the origin, baseline, bounds, and clipping all look right in Flutter + C++. Goldens would help here too @mjtalbot

<img width="1152" alt="CleanShot 2023-08-02 at 11 50 36@2x" src="https://github.com/rive-app/rive/assets/454182/5b7d580e-9d82-4e7b-8b91-7155a2c89fa6">

Fixes #5732
Fixes issue discussed here: https://2dimensions.slack.com/archives/CLLCU09T6/p1690977600095549

Diffs=
d3e75b38d Clipping and baseline (#5734)

Co-authored-by: Luigi Rosso <luigi-rosso@users.noreply.github.com>
diff --git a/.rive_head b/.rive_head
index b9d3c3b..812cc49 100644
--- a/.rive_head
+++ b/.rive_head
@@ -1 +1 @@
-da909105ad9ad42fc9245fc2ae05ac10f6bca41c
+d3e75b38d209bf0b85f2e243a6ef599ebf144acd
diff --git a/include/rive/math/aabb.hpp b/include/rive/math/aabb.hpp
index 10a43c3..2ffca9a 100644
--- a/include/rive/math/aabb.hpp
+++ b/include/rive/math/aabb.hpp
@@ -97,12 +97,6 @@
         return Vec2D(width() == 0.0f ? 0.0f : (point.x - left()) * 2.0f / width() - 1.0f,
                      (height() == 0.0f ? 0.0f : point.y - top()) * 2.0f / height() - 1.0f);
     }
-
-    /// Get the point at x/y factor (where [0, 0] is top left, [0.5, 0.5] is center).
-    Vec2D pointAt(float xf, float yf) const
-    {
-        return Vec2D(left() + width() * xf, top() + height() * yf);
-    }
 };
 
 } // namespace rive
diff --git a/src/text/text.cpp b/src/text/text.cpp
index 138fde9..c0cfafe 100644
--- a/src/text/text.cpp
+++ b/src/text/text.cpp
@@ -233,24 +233,6 @@
 {
     const float paragraphSpace = paragraphSpacing();
 
-    // Build the clip path if we want it.
-    if (overflow() == TextOverflow::clipped)
-    {
-        if (m_clipRenderPath == nullptr)
-        {
-            m_clipRenderPath = artboard()->factory()->makeEmptyRenderPath();
-        }
-        else
-        {
-            m_clipRenderPath->rewind();
-        }
-        m_clipRenderPath->addRect(0.0f, 0.0f, width(), height());
-    }
-    else
-    {
-        m_clipRenderPath = nullptr;
-    }
-
     for (TextStyle* style : m_renderStyles)
     {
         style->rewindPath();
@@ -262,6 +244,11 @@
     float y = 0.0f;
     float minY = 0.0f;
     float maxWidth = 0.0f;
+    if (textOrigin() == TextOrigin::baseline && !m_lines.empty() && !m_lines[0].empty())
+    {
+        y -= m_lines[0][0].baseline;
+        minY = y;
+    }
 
     int ellipsisLine = -1;
     bool isEllipsisLineLast = false;
@@ -304,11 +291,6 @@
 
     int lineIndex = 0;
     paragraphIndex = 0;
-    if (textOrigin() == TextOrigin::baseline && !m_lines.empty() && !m_lines[0].empty())
-    {
-        y -= m_lines[0][0].baseline;
-        minY = y;
-    }
     switch (sizing())
     {
         case TextSizing::autoWidth:
@@ -322,7 +304,32 @@
             break;
     }
 
+    // Build the clip path if we want it.
+    if (overflow() == TextOverflow::clipped)
+    {
+        if (m_clipRenderPath == nullptr)
+        {
+            m_clipRenderPath = artboard()->factory()->makeEmptyRenderPath();
+        }
+        else
+        {
+            m_clipRenderPath->rewind();
+        }
+
+        AABB bounds = localBounds();
+
+        m_clipRenderPath->addRect(bounds.minX, bounds.minY, bounds.width(), bounds.height());
+    }
+    else
+    {
+        m_clipRenderPath = nullptr;
+    }
+
     y = -m_bounds.height() * originY();
+    if (textOrigin() == TextOrigin::baseline && !m_lines.empty() && !m_lines[0].empty())
+    {
+        y -= m_lines[0][0].baseline;
+    }
     paragraphIndex = 0;
 
     bool hasModifiers = haveModifiers();
@@ -692,8 +699,12 @@
 
 AABB Text::localBounds() const
 {
-    auto origin = m_bounds.pointAt(originX(), originY());
-    return AABB(origin, origin + m_bounds.size());
+    float width = m_bounds.width();
+    float height = m_bounds.height();
+    return AABB::fromLTWH(m_bounds.minX - width * originX(),
+                          m_bounds.minY - height * originY(),
+                          width,
+                          height);
 }
 
 Core* Text::hitTest(HitInfo*, const Mat2D&)
@@ -706,10 +717,22 @@
     return nullptr;
 }
 
-void Text::originValueChanged() { markPaintDirty(); }
+void Text::originValueChanged()
+{
+    markPaintDirty();
+    markWorldTransformDirty();
+}
 
-void Text::originXChanged() { markPaintDirty(); }
-void Text::originYChanged() { markPaintDirty(); }
+void Text::originXChanged()
+{
+    markPaintDirty();
+    markWorldTransformDirty();
+}
+void Text::originYChanged()
+{
+    markPaintDirty();
+    markWorldTransformDirty();
+}
 
 #else
 // Text disabled.