From 9bc3d5e3b729ff50f21693a99fa1ca329cb72d32 Mon Sep 17 00:00:00 2001 From: Mira Grudzinska Date: Tue, 1 Apr 2025 20:33:01 +0200 Subject: [PATCH] lottie: fix stroke cap/join values ThorVG cap/join enums and lottie specs were not aligned. Problem was observed for StrokeCap::Square and StrokeJoin::Bevel. Note: this change breaks backward comatibility. --- inc/thorvg.h | 12 ++++++------ src/bindings/capi/thorvg_capi.h | 12 ++++++------ src/loaders/lottie/tvgLottieParser.cpp | 8 ++++---- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/inc/thorvg.h b/inc/thorvg.h index c9eeb2e5..28b70fb7 100644 --- a/inc/thorvg.h +++ b/inc/thorvg.h @@ -123,9 +123,9 @@ enum class PathCommand : uint8_t */ enum class StrokeCap : uint8_t { - Square = 0, ///< The stroke is extended in both end-points of a sub-path by a rectangle, with the width equal to the stroke width and the length equal to the half of the stroke width. For zero length sub-paths the square is rendered with the size of the stroke width. - Butt, ///< The stroke ends exactly at each of the two end-points of a sub-path. For zero length sub-paths no stroke is rendered. - Round ///< The stroke is extended in both end-points of a sub-path by a half circle, with a radius equal to the half of a stroke width. For zero length sub-paths a full circle is rendered. + Butt = 0, ///< The stroke ends exactly at each of the two end-points of a sub-path. For zero length sub-paths no stroke is rendered. + Round, ///< The stroke is extended in both end-points of a sub-path by a half circle, with a radius equal to the half of a stroke width. For zero length sub-paths a full circle is rendered. + Square ///< The stroke is extended in both end-points of a sub-path by a rectangle, with the width equal to the stroke width and the length equal to the half of the stroke width. For zero length sub-paths the square is rendered with the size of the stroke width. }; @@ -134,9 +134,9 @@ enum class StrokeCap : uint8_t */ enum class StrokeJoin : uint8_t { - Bevel = 0, ///< The outer corner of the joined path segments is bevelled at the join point. The triangular region of the corner is enclosed by a straight line between the outer corners of each stroke. - Miter, ///< The outer corner of the joined path segments is spiked. The spike is created by extension beyond the join point of the outer edges of the stroke until they intersect. In case the extension goes beyond the limit, the join style is converted to the Bevel style. - Round ///< The outer corner of the joined path segments is rounded. The circular region is centered at the join point. + Miter = 0, ///< The outer corner of the joined path segments is spiked. The spike is created by extension beyond the join point of the outer edges of the stroke until they intersect. In case the extension goes beyond the limit, the join style is converted to the Bevel style. + Round, ///< The outer corner of the joined path segments is rounded. The circular region is centered at the join point. + Bevel ///< The outer corner of the joined path segments is bevelled at the join point. The triangular region of the corner is enclosed by a straight line between the outer corners of each stroke. }; diff --git a/src/bindings/capi/thorvg_capi.h b/src/bindings/capi/thorvg_capi.h index de7cbe5d..7aca0a36 100644 --- a/src/bindings/capi/thorvg_capi.h +++ b/src/bindings/capi/thorvg_capi.h @@ -250,9 +250,9 @@ enum { * @brief Enumeration determining the ending type of a stroke in the open sub-paths. */ typedef enum { - TVG_STROKE_CAP_SQUARE = 0, ///< The stroke is extended in both endpoints of a sub-path by a rectangle, with the width equal to the stroke width and the length equal to the half of the stroke width. For zero length sub-paths the square is rendered with the size of the stroke width. - TVG_STROKE_CAP_BUTT, ///< The stroke ends exactly at each of the two endpoints of a sub-path. For zero length sub-paths no stroke is rendered. - TVG_STROKE_CAP_ROUND ///< The stroke is extended in both endpoints of a sub-path by a half circle, with a radius equal to the half of a stroke width. For zero length sub-paths a full circle is rendered. + TVG_STROKE_CAP_BUTT = 0, ///< The stroke ends exactly at each of the two endpoints of a sub-path. For zero length sub-paths no stroke is rendered. + TVG_STROKE_CAP_ROUND, ///< The stroke is extended in both endpoints of a sub-path by a half circle, with a radius equal to the half of a stroke width. For zero length sub-paths a full circle is rendered. + TVG_STROKE_CAP_SQUARE ///< The stroke is extended in both endpoints of a sub-path by a rectangle, with the width equal to the stroke width and the length equal to the half of the stroke width. For zero length sub-paths the square is rendered with the size of the stroke width. } Tvg_Stroke_Cap; @@ -260,9 +260,9 @@ typedef enum { * @brief Enumeration specifying how to fill the area outside the gradient bounds. */ typedef enum { - TVG_STROKE_JOIN_BEVEL = 0, ///< The outer corner of the joined path segments is bevelled at the join point. The triangular region of the corner is enclosed by a straight line between the outer corners of each stroke. - TVG_STROKE_JOIN_MITER, ///< The outer corner of the joined path segments is spiked. The spike is created by extension beyond the join point of the outer edges of the stroke until they intersect. In case the extension goes beyond the limit, the join style is converted to the Bevel style. - TVG_STROKE_JOIN_ROUND ///< The outer corner of the joined path segments is rounded. The circular region is centered at the join point. + TVG_STROKE_JOIN_MITER = 0, ///< The outer corner of the joined path segments is spiked. The spike is created by extension beyond the join point of the outer edges of the stroke until they intersect. In case the extension goes beyond the limit, the join style is converted to the Bevel style. + TVG_STROKE_JOIN_ROUND, ///< The outer corner of the joined path segments is rounded. The circular region is centered at the join point. + TVG_STROKE_JOIN_BEVEL ///< The outer corner of the joined path segments is bevelled at the join point. The triangular region of the corner is enclosed by a straight line between the outer corners of each stroke. } Tvg_Stroke_Join; diff --git a/src/loaders/lottie/tvgLottieParser.cpp b/src/loaders/lottie/tvgLottieParser.cpp index 7d4fbbb5..9ff2fab6 100644 --- a/src/loaders/lottie/tvgLottieParser.cpp +++ b/src/loaders/lottie/tvgLottieParser.cpp @@ -636,8 +636,8 @@ LottieSolidStroke* LottieParser::parseSolidStroke() else if (KEY_AS("c")) parseProperty(stroke->color, stroke); else if (KEY_AS("o")) parseProperty(stroke->opacity, stroke); else if (KEY_AS("w")) parseProperty(stroke->width, stroke); - else if (KEY_AS("lc")) stroke->cap = (StrokeCap) getInt(); - else if (KEY_AS("lj")) stroke->join = (StrokeJoin) getInt(); + else if (KEY_AS("lc")) stroke->cap = (StrokeCap) (getInt() - 1); + else if (KEY_AS("lj")) stroke->join = (StrokeJoin) (getInt() - 1); else if (KEY_AS("ml")) stroke->miterLimit = getFloat(); else if (KEY_AS("fillEnabled")) stroke->hidden |= !getBool(); else if (KEY_AS("d")) parseStrokeDash(stroke); @@ -769,8 +769,8 @@ LottieGradientStroke* LottieParser::parseGradientStroke() while (auto key = nextObjectKey()) { if (parseCommon(stroke, key)) continue; - else if (KEY_AS("lc")) stroke->cap = (StrokeCap) getInt(); - else if (KEY_AS("lj")) stroke->join = (StrokeJoin) getInt(); + else if (KEY_AS("lc")) stroke->cap = (StrokeCap) (getInt() - 1); + else if (KEY_AS("lj")) stroke->join = (StrokeJoin) (getInt() - 1); else if (KEY_AS("ml")) stroke->miterLimit = getFloat(); else if (KEY_AS("w")) parseProperty(stroke->width); else if (KEY_AS("d")) parseStrokeDash(stroke);