From 00ef2703e211cab8efea365b2690c7118cbbe661 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole-Andr=C3=A9=20Rodlie?= Date: Tue, 11 Jun 2024 21:12:52 +0200 Subject: [PATCH] Update CairoHelper * https://github.com/NatronGitHub/openfx-arena/issues/25 * https://github.com/NatronGitHub/Natron/issues/970 --- Helpers/CairoHelper.cpp | 68 +++++++++++++++++++++++++++++++++++------ Helpers/CairoHelper.h | 36 ++++++++++++++++++---- 2 files changed, 88 insertions(+), 16 deletions(-) diff --git a/Helpers/CairoHelper.cpp b/Helpers/CairoHelper.cpp index 5f382f8..69b0bfc 100644 --- a/Helpers/CairoHelper.cpp +++ b/Helpers/CairoHelper.cpp @@ -20,22 +20,70 @@ #include -void CairoHelper::applyRotate(cairo_t *cr, - double rotate, - XY origin) +void +CairoHelper::applyFlip(cairo_t *cr, + const int &height) { - if (!cr || rotate == 0.) { return; } + if (!cr || height < 1) { return; } + cairo_scale(cr, 1.0f, -1.0f); + cairo_translate(cr, 0.0f, -height); +} + +void +CairoHelper::applyPosition(cairo_t *cr, + const _XY &position) +{ + if (!cr) { return; } + cairo_move_to(cr, position.x, position.y); +} + +void +CairoHelper::applyScale(cairo_t *cr, + const _XY &scale) +{ + if (!cr || (scale.x == 0. && scale.y == 0.)) { return; } + cairo_scale(cr, scale.x, scale.y); +} +void +CairoHelper::applySkew(cairo_t *cr, + const _XY &skew, + const _XY &origin) +{ + if (!cr || (skew.x == 0. && skew.y == 0.)) { return; } + double x = skew.x; + double y = skew.y; + if (x != 0.) { x = -x; } + if (y != 0.) { y = -y; } + cairo_matrix_t matrix = { + 1.0, y, + x , 1.0, + 0.0, 0.0 + }; cairo_translate(cr, origin.x, origin.y); - cairo_rotate(cr, -rotate * (M_PI / 180.0)); + cairo_transform(cr, &matrix); cairo_translate(cr, -origin.x, -origin.y); } -void CairoHelper::applyFlip(cairo_t *cr, - int height) +void +CairoHelper::applyRotate(cairo_t *cr, + const double &rotate, + const _XY &origin) { - if (!cr || height < 1) { return; } + if (!cr || rotate == 0.) { return; } + cairo_translate(cr, origin.x, origin.y); + cairo_rotate(cr, -rotate * (M_PI / 180.0)); + cairo_translate(cr, -origin.x, -origin.y); +} - cairo_scale(cr, 1.0f, -1.0f); - cairo_translate(cr, 0.0f, -height); +void +CairoHelper::applyTransform(cairo_t *cr, + const _Transform &transform) +{ + if (!cr) { return; } + if (transform.flip) { applyFlip(cr, transform.height); } + if (transform.position) { applyPosition(cr, transform.origin); } + applyScale(cr, transform.scale); + applySkew(cr, transform.skew, transform.origin); + applyRotate(cr, transform.rotate, transform.origin); } diff --git a/Helpers/CairoHelper.h b/Helpers/CairoHelper.h index 1bf47bd..9f3e7e7 100644 --- a/Helpers/CairoHelper.h +++ b/Helpers/CairoHelper.h @@ -24,18 +24,42 @@ class CairoHelper { public: - struct XY + struct _XY { double x; double y; }; - /** @brief apply rotate */ - static void applyRotate(cairo_t *cr, - double rotate, - XY origin); + struct _Transform + { + _XY origin; + _XY scale; + _XY skew; + int width; + int height; + double rotate; + bool position; + bool flip; + }; /** @brief apply flip */ static void applyFlip(cairo_t *cr, - int height); + const int &height); + /** @brief apply position */ + static void applyPosition(cairo_t *cr, + const _XY &position); + /** @brief apply scale */ + static void applyScale(cairo_t *cr, + const _XY &scale); + /** @brief apply skew */ + static void applySkew(cairo_t *cr, + const _XY &skew, + const _XY &origin); + /** @brief apply rotate */ + static void applyRotate(cairo_t *cr, + const double &rotate, + const _XY &origin); + /** @brief apply transform */ + static void applyTransform(cairo_t *cr, + const _Transform &transform); }; #endif // CAIROHELPER_H