From fc5ca21deae2801be99e77feef7447b680630e4e Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Fri, 26 Jan 2024 12:26:06 +0900 Subject: [PATCH] loader/svg: Apply specification of out-of-range elliptical arc parameters The three specifications below apply. Specification: https://www.w3.org/TR/SVG/paths.html#ArcOutOfRangeParameters - If the endpoint (x, y) of the segment is identical to the current point (e.g., the endpoint of the previous segment), then this is equivalent to omitting the elliptical arc segment entirely. - If either rx or ry is 0, then this arc is treated as a straight line segment(a "lineto") joining the endpoints. - If either rx or ry have negative signs, these are dropped; the absolute value is used instead. --- src/loaders/svg/tvgSvgPath.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/loaders/svg/tvgSvgPath.cpp b/src/loaders/svg/tvgSvgPath.cpp index f618a3c8..2c9c0615 100644 --- a/src/loaders/svg/tvgSvgPath.cpp +++ b/src/loaders/svg/tvgSvgPath.cpp @@ -53,6 +53,7 @@ #include #include #include +#include "tvgMath.h" #include "tvgShape.h" #include "tvgSvgLoaderCommon.h" #include "tvgSvgPath.h" @@ -471,9 +472,17 @@ static bool _processCommand(Array* cmds, Array* pts, char cm } case 'a': case 'A': { - _pathAppendArcTo(cmds, pts, cur, curCtl, arr[5], arr[6], arr[0], arr[1], arr[2], arr[3], arr[4]); - *cur = *curCtl = {arr[5], arr[6]}; - *isQuadratic = false; + if (arr[0] < FLT_EPSILON || arr[1] < FLT_EPSILON) { + Point p = {arr[5], arr[6]}; + cmds->push(PathCommand::LineTo); + pts->push(p); + *cur = {arr[5], arr[6]}; + } + else if (!mathEqual(cur->x, arr[5]) || !mathEqual(cur->y, arr[6])) { + _pathAppendArcTo(cmds, pts, cur, curCtl, arr[5], arr[6], fabsf(arr[0]), fabsf(arr[1]), arr[2], arr[3], arr[4]); + *cur = *curCtl = {arr[5], arr[6]}; + *isQuadratic = false; + } break; } default: {