diff --git a/src/loaders/svg/tvgSvgLoader.cpp b/src/loaders/svg/tvgSvgLoader.cpp index 457fe285..be99ec08 100644 --- a/src/loaders/svg/tvgSvgLoader.cpp +++ b/src/loaders/svg/tvgSvgLoader.cpp @@ -2100,6 +2100,12 @@ static void _handleRadialFyAttr(SvgLoaderData* loader, SvgRadialGradient* radial } +static void _handleRadialFrAttr(SvgLoaderData* loader, SvgRadialGradient* radial, const char* value) +{ + radial->fr = _gradientToFloat(loader->svgParse, value, radial->isFrPercentage); +} + + static void _handleRadialRAttr(SvgLoaderData* loader, SvgRadialGradient* radial, const char* value) { radial->r = _gradientToFloat(loader->svgParse, value, radial->isRPercentage); @@ -2130,6 +2136,13 @@ static void _recalcRadialFyAttr(SvgLoaderData* loader, SvgRadialGradient* radial } +static void _recalcRadialFrAttr(SvgLoaderData* loader, SvgRadialGradient* radial, bool userSpace) +{ + // scaling factor based on the Units paragraph from : https://www.w3.org/TR/2015/WD-SVG2-20150915/coords.html + if (userSpace && !radial->isFrPercentage) radial->fr = radial->fr / (sqrtf(powf(loader->svgParse->global.h, 2) + powf(loader->svgParse->global.w, 2)) / sqrtf(2.0)); +} + + static void _recalcRadialRAttr(SvgLoaderData* loader, SvgRadialGradient* radial, bool userSpace) { // scaling factor based on the Units paragraph from : https://www.w3.org/TR/2015/WD-SVG2-20150915/coords.html @@ -2173,6 +2186,15 @@ static void _recalcInheritedRadialFyAttr(SvgLoaderData* loader, SvgRadialGradien } +static void _recalcInheritedRadialFrAttr(SvgLoaderData* loader, SvgRadialGradient* radial, bool userSpace) +{ + if (!radial->isFrPercentage) { + if (userSpace) radial->fr /= sqrtf(powf(loader->svgParse->global.h, 2) + powf(loader->svgParse->global.w, 2)) / sqrtf(2.0); + else radial->fr *= sqrtf(powf(loader->svgParse->global.h, 2) + powf(loader->svgParse->global.w, 2)) / sqrtf(2.0); + } +} + + static void _recalcInheritedRadialRAttr(SvgLoaderData* loader, SvgRadialGradient* radial, bool userSpace) { if (!radial->isRPercentage) { @@ -2214,6 +2236,14 @@ static void _inheritRadialFyAttr(SvgStyleGradient* to, SvgStyleGradient* from) } +static void _inheritRadialFrAttr(SvgStyleGradient* to, SvgStyleGradient* from) +{ + to->radial->fr = from->radial->fr; + to->radial->isFrPercentage = from->radial->isFrPercentage; + to->flags = (to->flags | SvgGradientFlags::Fr); +} + + static void _inheritRadialRAttr(SvgStyleGradient* to, SvgStyleGradient* from) { to->radial->r = from->radial->r; @@ -2247,7 +2277,8 @@ static constexpr struct RADIAL_DEF(cy, Cy, SvgGradientFlags::Cy), RADIAL_DEF(fx, Fx, SvgGradientFlags::Fx), RADIAL_DEF(fy, Fy, SvgGradientFlags::Fy), - RADIAL_DEF(r, R, SvgGradientFlags::R) + RADIAL_DEF(r, R, SvgGradientFlags::R), + RADIAL_DEF(fr, Fr, SvgGradientFlags::Fr) }; @@ -2315,6 +2346,7 @@ static SvgStyleGradient* _createRadialGradient(SvgLoaderData* loader, const char grad->radial->isFxPercentage = true; grad->radial->isFyPercentage = true; grad->radial->isRPercentage = true; + grad->radial->isFrPercentage = true; loader->svgParse->gradient.parsedFx = false; loader->svgParse->gradient.parsedFy = false; diff --git a/src/loaders/svg/tvgSvgLoaderCommon.h b/src/loaders/svg/tvgSvgLoaderCommon.h index a6074fdd..b4ee3e8e 100644 --- a/src/loaders/svg/tvgSvgLoaderCommon.h +++ b/src/loaders/svg/tvgSvgLoaderCommon.h @@ -184,7 +184,8 @@ enum class SvgGradientFlags Cy = 0x80, R = 0x100, Fx = 0x200, - Fy = 0x400 + Fy = 0x400, + Fr = 0x800 }; constexpr bool operator &(SvgGradientFlags a, SvgGradientFlags b) @@ -392,11 +393,13 @@ struct SvgRadialGradient float fx; float fy; float r; + float fr; bool isCxPercentage; bool isCyPercentage; bool isFxPercentage; bool isFyPercentage; bool isRPercentage; + bool isFrPercentage; }; struct SvgComposite diff --git a/src/loaders/svg/tvgSvgSceneBuilder.cpp b/src/loaders/svg/tvgSvgSceneBuilder.cpp index b04a81df..a76a76ab 100644 --- a/src/loaders/svg/tvgSvgSceneBuilder.cpp +++ b/src/loaders/svg/tvgSvgSceneBuilder.cpp @@ -26,11 +26,12 @@ #include "tvgShapeImpl.h" #include "tvgCompressor.h" #include "tvgPaint.h" +#include "tvgFill.h" +#include "tvgStr.h" #include "tvgSvgLoaderCommon.h" #include "tvgSvgSceneBuilder.h" #include "tvgSvgPath.h" #include "tvgSvgUtil.h" -#include "tvgStr.h" /************************************************************************/ /* Internal Class Implementation */ @@ -151,6 +152,7 @@ static unique_ptr _applyRadialGradientProperty(SvgStyleGradient* g->radial->r = g->radial->r * sqrtf(powf(vBox.w, 2.0f) + powf(vBox.h, 2.0f)) / sqrtf(2.0f); g->radial->fx = g->radial->fx * vBox.w; g->radial->fy = g->radial->fy * vBox.h; + g->radial->fr = g->radial->fr * sqrtf(powf(vBox.w, 2.0f) + powf(vBox.h, 2.0f)) / sqrtf(2.0f); } else { Matrix m = {vBox.w, 0, vBox.x, 0, vBox.h, vBox.y, 0, 0, 1}; if (isTransform) _transformMultiply(&m, &finalTransform); @@ -162,11 +164,7 @@ static unique_ptr _applyRadialGradientProperty(SvgStyleGradient* if (isTransform) fillGrad->transform(finalTransform); - //TODO: Tvg is not support to focal - //if (g->radial->fx != 0 && g->radial->fy != 0) { - // fillGrad->radial(g->radial->fx, g->radial->fy, g->radial->r); - //} - fillGrad->radial(g->radial->cx, g->radial->cy, g->radial->r); + P(fillGrad)->radial(g->radial->cx, g->radial->cy, g->radial->r, g->radial->fx, g->radial->fy, g->radial->fr); fillGrad->spread(g->spread); //Update the stops