Move nonvirtual helpers into .cpp file
diff --git a/include/rive/renderer.hpp b/include/rive/renderer.hpp
index edced89..1b919ca 100644
--- a/include/rive/renderer.hpp
+++ b/include/rive/renderer.hpp
@@ -68,85 +68,22 @@
virtual void
drawImage(RenderImage* image, BlendMode value, float opacity) = 0;
+ // helpers
+
+ void translate(float x, float y);
+ void scale(float sx, float sy);
+ void rotate(float radians);
+
void computeAlignment(Mat2D& result,
Fit fit,
const Alignment& alignment,
const AABB& frame,
- const AABB& content) {
- float contentWidth = content[2] - content[0];
- float contentHeight = content[3] - content[1];
- float x = -content[0] - contentWidth / 2.0 -
- (alignment.x() * contentWidth / 2.0);
- float y = -content[1] - contentHeight / 2.0 -
- (alignment.y() * contentHeight / 2.0);
-
- float scaleX = 1.0, scaleY = 1.0;
-
- switch (fit) {
- case Fit::fill: {
- scaleX = frame.width() / contentWidth;
- scaleY = frame.height() / contentHeight;
- break;
- }
- case Fit::contain: {
- float minScale = std::fmin(frame.width() / contentWidth,
- frame.height() / contentHeight);
- scaleX = scaleY = minScale;
- break;
- }
- case Fit::cover: {
- float maxScale = std::fmax(frame.width() / contentWidth,
- frame.height() / contentHeight);
- scaleX = scaleY = maxScale;
- break;
- }
- case Fit::fitHeight: {
- float minScale = frame.height() / contentHeight;
- scaleX = scaleY = minScale;
- break;
- }
- case Fit::fitWidth: {
- float minScale = frame.width() / contentWidth;
- scaleX = scaleY = minScale;
- break;
- }
- case Fit::none: {
- scaleX = scaleY = 1.0;
- break;
- }
- case Fit::scaleDown: {
- float minScale = std::fmin(frame.width() / contentWidth,
- frame.height() / contentHeight);
- scaleX = scaleY = minScale < 1.0 ? minScale : 1.0;
- break;
- }
- }
-
- Mat2D translation;
- translation[4] = frame[0] + frame.width() / 2.0 +
- (alignment.x() * frame.width() / 2.0);
- translation[5] = frame[1] + frame.height() / 2.0 +
- (alignment.y() * frame.height() / 2.0);
- Mat2D scale;
- scale[0] = scaleX;
- scale[3] = scaleY;
-
- Mat2D translateBack;
- translateBack[4] = x;
- translateBack[5] = y;
-
- Mat2D::multiply(result, translation, scale);
- Mat2D::multiply(result, result, translateBack);
- }
+ const AABB& content);
void align(Fit fit,
const Alignment& alignment,
const AABB& frame,
- const AABB& content) {
- Mat2D result;
- computeAlignment(result, fit, alignment, frame, content);
- transform(result);
- }
+ const AABB& content);
};
extern RenderPath* makeRenderPath();
diff --git a/src/nested_artboard.cpp b/src/nested_artboard.cpp
index e42eb14..bd5c608 100644
--- a/src/nested_artboard.cpp
+++ b/src/nested_artboard.cpp
@@ -34,10 +34,8 @@
}
renderer->save();
renderer->transform(worldTransform());
- Mat2D translation;
- translation[4] = -m_NestedInstance->originX() * m_NestedInstance->width();
- translation[5] = -m_NestedInstance->originY() * m_NestedInstance->height();
- renderer->transform(translation);
+ renderer->translate(-m_NestedInstance->originX() * m_NestedInstance->width(),
+ -m_NestedInstance->originY() * m_NestedInstance->height());
m_NestedInstance->draw(renderer);
renderer->restore();
}
@@ -89,4 +87,4 @@
{
m_NestedInstance->opacity(renderOpacity());
}
-}
\ No newline at end of file
+}
diff --git a/src/renderer.cpp b/src/renderer.cpp
new file mode 100644
index 0000000..7153488
--- /dev/null
+++ b/src/renderer.cpp
@@ -0,0 +1,99 @@
+#include "rive/math/mat2d.hpp"
+#include "rive/renderer.hpp"
+
+using namespace rive;
+
+void Renderer::translate(float tx, float ty) {
+ this->transform(Mat2D(1, 0, 0, 1, tx, ty));
+}
+
+void Renderer::scale(float sx, float sy) {
+ this->transform(Mat2D(sx, 0, 0, sy, 0, 0));
+}
+
+void Renderer::rotate(float radians) {
+ const float s = std::sin(radians);
+ const float c = std::cos(radians);
+ this->transform(Mat2D(c, s, -s, c, 0, 0));
+}
+
+void Renderer::computeAlignment(Mat2D& result,
+ Fit fit,
+ const Alignment& alignment,
+ const AABB& frame,
+ const AABB& content)
+{
+ float contentWidth = content[2] - content[0];
+ float contentHeight = content[3] - content[1];
+ float x = -content[0] - contentWidth / 2.0 -
+ (alignment.x() * contentWidth / 2.0);
+ float y = -content[1] - contentHeight / 2.0 -
+ (alignment.y() * contentHeight / 2.0);
+
+ float scaleX = 1.0, scaleY = 1.0;
+
+ switch (fit) {
+ case Fit::fill: {
+ scaleX = frame.width() / contentWidth;
+ scaleY = frame.height() / contentHeight;
+ break;
+ }
+ case Fit::contain: {
+ float minScale = std::fmin(frame.width() / contentWidth,
+ frame.height() / contentHeight);
+ scaleX = scaleY = minScale;
+ break;
+ }
+ case Fit::cover: {
+ float maxScale = std::fmax(frame.width() / contentWidth,
+ frame.height() / contentHeight);
+ scaleX = scaleY = maxScale;
+ break;
+ }
+ case Fit::fitHeight: {
+ float minScale = frame.height() / contentHeight;
+ scaleX = scaleY = minScale;
+ break;
+ }
+ case Fit::fitWidth: {
+ float minScale = frame.width() / contentWidth;
+ scaleX = scaleY = minScale;
+ break;
+ }
+ case Fit::none: {
+ scaleX = scaleY = 1.0;
+ break;
+ }
+ case Fit::scaleDown: {
+ float minScale = std::fmin(frame.width() / contentWidth,
+ frame.height() / contentHeight);
+ scaleX = scaleY = minScale < 1.0 ? minScale : 1.0;
+ break;
+ }
+ }
+
+ Mat2D translation;
+ translation[4] = frame[0] + frame.width() / 2.0 +
+ (alignment.x() * frame.width() / 2.0);
+ translation[5] = frame[1] + frame.height() / 2.0 +
+ (alignment.y() * frame.height() / 2.0);
+ Mat2D scale;
+ scale[0] = scaleX;
+ scale[3] = scaleY;
+
+ Mat2D translateBack;
+ translateBack[4] = x;
+ translateBack[5] = y;
+
+ Mat2D::multiply(result, translation, scale);
+ Mat2D::multiply(result, result, translateBack);
+}
+
+void Renderer::align(Fit fit,
+ const Alignment& alignment,
+ const AABB& frame,
+ const AABB& content) {
+ Mat2D result;
+ computeAlignment(result, fit, alignment, frame, content);
+ transform(result);
+}
diff --git a/src/shapes/image.cpp b/src/shapes/image.cpp
index 4bc4b6a..78d7204 100644
--- a/src/shapes/image.cpp
+++ b/src/shapes/image.cpp
@@ -21,12 +21,8 @@
auto width = renderImage->width();
auto height = renderImage->height();
- const Mat2D& transform = worldTransform();
- renderer->transform(transform);
-
- Mat2D originTranslation(
- 1.0f, 0.0f, 0.0f, 1.0f, -width / 2.0f, -height / 2.0f);
- renderer->transform(originTranslation);
+ renderer->transform(worldTransform());
+ renderer->translate(-width / 2.0f, -height / 2.0f);
renderer->drawImage(renderImage, blendMode(), renderOpacity());
@@ -58,4 +54,4 @@
Image* twin = ImageBase::clone()->as<Image>();
twin->m_ImageAsset = m_ImageAsset;
return twin;
-}
\ No newline at end of file
+}
diff --git a/src/shapes/shape.cpp b/src/shapes/shape.cpp
index 2ffe390..78fbb30 100644
--- a/src/shapes/shape.cpp
+++ b/src/shapes/shape.cpp
@@ -44,8 +44,7 @@
bool paintsInLocal =
(shapePaint->pathSpace() & PathSpace::Local) == PathSpace::Local;
if (paintsInLocal) {
- const Mat2D& transform = worldTransform();
- renderer->transform(transform);
+ renderer->transform(worldTransform());
}
shapePaint->draw(renderer,
paintsInLocal ? m_PathComposer.localPath()
@@ -84,4 +83,4 @@
}
// This ensures context propagates to path composer too.
return m_PathComposer.onAddedDirty(context);
-}
\ No newline at end of file
+}