From ddfe8775913f13cb5bc49f2109abd2bac4d4ff47 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: {