From 02c7d85eddcb19519046f3fd418676df23266699 Mon Sep 17 00:00:00 2001 From: Omikhleia Date: Fri, 5 Aug 2022 22:08:07 +0200 Subject: [PATCH] fix(packages)!: Density applies to SVG in pixels, not other units --- packages/svg/init.lua | 32 +++++++++++++++++++++++++------- src/svg.c | 6 +++--- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/packages/svg/init.lua b/packages/svg/init.lua index d4c65ccc7..7bad0ec22 100644 --- a/packages/svg/init.lua +++ b/packages/svg/init.lua @@ -7,20 +7,34 @@ local svg = require("svg") local otparser = require("core.opentype-parser") local _drawSVG = function (svgdata, width, height, density, drop) + local scalefactor + density = density or 72 + local ratiodensity = 72 / density + print(ratiodensity) local svgfigure, svgwidth, svgheight = svg.svg_to_ps(svgdata, density) SU.debug("svg", string.format("PS: %s\n", svgfigure)) - local scalefactor = 1 if width and height then -- local aspect = svgwidth / svgheight SU.error("SILE cannot yet change SVG aspect ratios, specify either width or height but not both") elseif width then scalefactor = width:tonumber() / svgwidth + height = SILE.measurement(svgheight * scalefactor) + width = width elseif height then scalefactor = height:tonumber() / svgheight + width = SILE.measurement(svgwidth * scalefactor) + height = height * scalefactor + else + scalefactor = 1 * ratiodensity + width = SILE.measurement(svgwidth * scalefactor) + height = SILE.measurement(svgheight * scalefactor) end - width = SILE.measurement(svgwidth * scalefactor) - height = SILE.measurement(svgheight * scalefactor) - scalefactor = scalefactor * density / 72 + SU.debug("svg", string.format("SVG %s x %s (scaled %s) - %s x %s - density %s\n", + tostring(width), tostring(height), + tostring(scalefactor), + tostring(svgwidth), tostring(svgheight), + tostring(density))) + SILE.typesetter:pushHbox({ value = nil, height = height, @@ -39,7 +53,7 @@ function package:registerRawHandlers () local svgdata = content[1] local width = options.width and SU.cast("measurement", options.width):absolute() or nil local height = options.height and SU.cast("measurement", options.height):absolute() or nil - local density = options.density or 72 + local density = options.density and SU.cast("integer", options.density) -- See issue #1375: svg.svg_to_ps() called in _drawSVG has a apparently a side effect -- on the internal representation of the Lua string and corrupts it. -- So as a workaround, for the original string to be able to be reused, we must get a @@ -55,8 +69,12 @@ function package:registerCommands () local fn = SU.required(options, "src", "filename") local width = options.width and SU.cast("measurement", options.width):absolute() or nil local height = options.height and SU.cast("measurement", options.height):absolute() or nil - local density = options.density or 72 - local svgfile = io.open(fn) + local density = options.density and SU.cast("integer", options.density) + local svgfile, err = io.open(fn) + if not svgfile then + SU.error("Could not open SVG "..fn..": "..err) + return + end local svgdata = svgfile:read("*all") _drawSVG(svgdata, width, height, density) end) diff --git a/src/svg.c b/src/svg.c index fd3406efa..70fca492b 100644 --- a/src/svg.c +++ b/src/svg.c @@ -21,12 +21,12 @@ static char* safe_append(char* output, int* output_l, int* max_output, char* s2) int svg_to_ps(lua_State *L) { const char* input = luaL_checkstring(L, 1); - int em = 72; + int dpi = 72; if (lua_gettop(L) == 2) { - em = luaL_checkinteger(L, 2); + dpi = luaL_checkinteger(L, 2); } struct NSVGimage* image; - image = nsvgParse((char*)input, "pt", em); + image = nsvgParse((char*)input, "px", dpi); int max_output = 256; int output_l = 0; char *output = malloc(max_output);