From 6015e2eb327564cd491cf64eec070779c6ec532e 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: {