From 7176a5ddd4186b871a2971eb8f28d79634c0e4da Mon Sep 17 00:00:00 2001 From: Mira Grudzinska Date: Sun, 10 Oct 2021 23:41:52 +0200 Subject: [PATCH] svg_loader: define the scaling factors for units changing The values in absolute units are calculated based on the pixel unit. Till now the default value of 90dpi was used. Since CSS3 (now CSS4 is the most recent) 1 inch equals to 96 pixels. The necessary constants are introduces in this commit. --- src/loaders/svg/tvgSvgLoader.cpp | 36 +++++++++++++++++++------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/src/loaders/svg/tvgSvgLoader.cpp b/src/loaders/svg/tvgSvgLoader.cpp index 3ca7bdb2..e587c3a5 100644 --- a/src/loaders/svg/tvgSvgLoader.cpp +++ b/src/loaders/svg/tvgSvgLoader.cpp @@ -64,6 +64,17 @@ /* Internal Class Implementation */ /************************************************************************/ +/* + * According to: https://www.w3.org/TR/SVG2/coords.html#Units + * and: https://www.w3.org/TR/css-values-4/#absolute-lengths + */ +#define PX_PER_IN 96 //1 in = 96 px +#define PX_PER_PC 16 //1 pc = 1/6 in -> PX_PER_IN/6 +#define PX_PER_PT 1.333333f //1 pt = 1/72 in -> PX_PER_IN/72 +#define PX_PER_MM 3.779528f //1 in = 25.4 mm -> PX_PER_IN/25.4 +#define PX_PER_CM 37.79528f //1 in = 2.54 cm -> PX_PER_IN/2.54 + + typedef SvgNode* (*FactoryMethod)(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength); typedef SvgStyleGradient* (*GradientFactoryMethod)(SvgLoaderData* loader, const char* buf, unsigned bufLength); @@ -107,20 +118,16 @@ static bool _parseNumber(const char** content, float* number) /** * According to https://www.w3.org/TR/SVG/coords.html#Units - * - * TODO - * Since this documentation is not obvious, more clean recalculation with dpi - * is required, but for now default w3 constants would be used */ static float _toFloat(const SvgParser* svgParse, const char* str, SvgParserLengthType type) { float parsedValue = svgUtilStrtof(str, nullptr); - if (strstr(str, "cm")) parsedValue = parsedValue * 35.43307; - else if (strstr(str, "mm")) parsedValue = parsedValue * 3.543307; - else if (strstr(str, "pt")) parsedValue = parsedValue * 1.25; - else if (strstr(str, "pc")) parsedValue = parsedValue * 15; - else if (strstr(str, "in")) parsedValue = parsedValue * 90; + if (strstr(str, "cm")) parsedValue *= PX_PER_CM; + else if (strstr(str, "mm")) parsedValue *= PX_PER_MM; + else if (strstr(str, "pt")) parsedValue *= PX_PER_PT; + else if (strstr(str, "pc")) parsedValue *= PX_PER_PC; + else if (strstr(str, "in")) parsedValue *= PX_PER_IN; else if (strstr(str, "%")) { if (type == SvgParserLengthType::Vertical) parsedValue = (parsedValue / 100.0) * svgParse->global.h; else if (type == SvgParserLengthType::Horizontal) parsedValue = (parsedValue / 100.0) * svgParse->global.w; @@ -132,7 +139,6 @@ static float _toFloat(const SvgParser* svgParse, const char* str, SvgParserLengt parsedValue = (parsedValue / 100.0) * max; } } - //TODO: Implement 'em', 'ex' attributes return parsedValue; @@ -150,11 +156,11 @@ static float _gradientToFloat(const SvgParser* svgParse, const char* str, bool& parsedValue = parsedValue / 100.0; isPercentage = true; } - else if (strstr(str, "cm")) parsedValue = parsedValue * 35.43307; - else if (strstr(str, "mm")) parsedValue = parsedValue * 3.543307; - else if (strstr(str, "pt")) parsedValue = parsedValue * 1.25; - else if (strstr(str, "pc")) parsedValue = parsedValue * 15; - else if (strstr(str, "in")) parsedValue = parsedValue * 90; + else if (strstr(str, "cm")) parsedValue *= PX_PER_CM; + else if (strstr(str, "mm")) parsedValue *= PX_PER_MM; + else if (strstr(str, "pt")) parsedValue *= PX_PER_PT; + else if (strstr(str, "pc")) parsedValue *= PX_PER_PC; + else if (strstr(str, "in")) parsedValue *= PX_PER_IN; //TODO: Implement 'em', 'ex' attributes return parsedValue;