How to get rsvg to assume 96 dpi for SVG? - svg

When I use
rsvg-convert.exe -f pdf -o <output-name>.pdf <input-name>.svg
I get a result that differs from how the SVG is rendered in Inkscape and Firefox.
This is a simple test SVG:
<svg width="150" height="100" xmlns="http://www.w3.org/2000/svg">
<text y="50" font-size="12" fill="black">Test</text>
<text x="50" y="50" font-size="12pt" fill="black">Test</text>
<text x="100" y="50" font-size="16px" fill="black">Test</text>
</svg>
In Inkscape and Firefox the middel and right text have the exact same size since these applications seem to assume that 1pt = 1.333333px which is the CSS recommendation. However, rsvg seems to assume 1pt = 1.25px which leads to different sizes of the texts. How can I get rsvg to output it correctly (as Inkscape and Firefox).
I tried the options -p and -d with 96 but that didn't give the correct result either.

Setting the dpi works here with rsvg-convert 2.40.20:
rsvg-convert -f pdf --dpi-x=96 --dpi-y=96 -o <output-name>.pdf <input-name>.svg
I also confirmed setting the output format to svg (text will be converted to paths) and comparing the height in Inkscape.

Many applications correctly handle SVG where the width and height are inches, such as
<svg width="1.5in" height="1in" xmlns="http://www.w3.org/2000/svg">
</svg>
I'm not familiar with rsvg-convert.exe, but it's the first thing I'd try. Adjust the width and height as needed.

Related

svg + inkscape + unwanted cropping

Given the following test.svg file
<?xml version="1.0" encoding="utf-8" ?>
<svg baseProfile="tiny"
height="5cm" version="1.2"
viewBox="-1 -1 2 2"
width="5cm" xmlns="http://www.w3.org/2000/svg"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns:xlink="http://www.w3.org/1999/xlink">
<defs />
<rect fill="blue" height="1" width="1" x="0" y="0" />
</svg>
using the command
inkscape -D -z --file=test.svg --export-pdf=text.pdf --export-latex
I get a pdf of 25mm x 25mm. The proportions are correct (I use only half the width and half the height), my question is how do avoid an automatic crop of the picture. I need a PDF of 50mm x 50mm, with only the left upper square filled.
In the inkscape documentation for the option -D (that I use) there is the comment without margins or cropping that is exactly what I need. The result is as described above, cropped.
man inkscape shows the following explanation for -D:
In SVG, PNG, PDF, PS, and EPS export, exported area is the drawing (not page), i.e. the bounding box of all objects of the document...
That is what you describe as cropping. For -C it says:
In SVG, PNG, PDF, PS, and EPS export, exported area is the page. This is the default for SVG, PNG, PDF, and PS, so you don't need to specify this...
So, simply leave off the -D option.

Zero stroke-width in SVG

Having used Postscript for years, I am now learning SVG. There is a feature of PS that I have not been able to replicate so far: zero-width lines. In PS, a line with zero width is always visible: PostScript converts zero line width to the smallest printable width. On the screen, when zooming they never get any thinkness, yet are visible no matter the scale. I have used them when I wanted to render very thin lines, without worring about the final resolution I was going to use, and they turned out really useful.
However, in the official SVG docs (https://www.w3.org/TR/svg-strokes/) it says that:
A zero value causes no stroke to be painted. A negative value is invalid.
Is there a way in SVG to build zero-width lines in the sense of PostScript?
As Robert said, the nearest thing to what you want in SVG is vector-effect="non-scaling-stroke". This fixes the stroke width at 1 no matter how the SVG is scaled.
This works on Chrome and Firefox (and probably Opera - haven't checked), but AFAIK not IE/Edge.
<svg viewBox="0 0 100 100">
<rect x="10" y="10" width="80" height="80"
fill="none" stroke="black" stroke-width="1"
vector-effect="non-scaling-stroke"/>
</svg>
Note that antialiasing will come into play depending on the position of the lines. The position will be affected by the scale.
If your lines are rectilinear (horizontal or vertical), you might also want to use shape-rendering="crispEdges". This will turn off antialiasing for the shape on which it is used, resulting in sharp one-pixel lines.
<svg viewBox="0 0 100 100">
<rect x="10" y="10" width="80" height="80"
fill="none" stroke="black" stroke-width="1"
vector-effect="non-scaling-stroke" shape-rendering="crispEdges"/>
</svg>

SVG in Safari: Element positioned incorrectly when translated

I am trying to make an SVG shape a dropzone, and it works perfectly in Chrome/Firefox, but when testing on Safari I have come across a strange behaviour which I am looking for a way to get round.
The problem (shown in the code below and this fiddle https://jsfiddle.net/tp5e98rs/) is that when the viewBox width/height does not match the view port width/height (the first SVG), a translated element is not positioned correctly when viewed in the inspector. If you inspect the first rectangle, the blue highlight is not directly over it, but if you inspect the second rectangle the blue highlight is, as you can see in the attached image. The difference between the two SVGs is that in one the viewbox doesn't match the view port, and in the other they do match. If you do the same in Chrome, the highlight is correct in both cases.
This is a problem for making dropzones from translated rectangles, because the dropzone ends up being where the incorrect highlight is shown.
Any ideas of a workaround to fix this problem?
<svg width="100" height="100" viewBox="0 0 200 200">
<rect transform="translate(20 20)" width="100" height="100" fill="#aaeeee"></rect>
</svg>
<svg width="100" height="100" viewBox="0 0 100 100">
<rect transform="translate(10 10)" width="50" height="50" fill="#aaeeee"></rect>
</svg>

Bad SVG text quality in Opera

I am trying to render an SVG document containing some text. Everything is good in Chrome/FF/Safari:
But in Opera (v12.14, Mac OS X) font looks very ugly:
Is this normal or maybe I am doing something wrong? Is it possible to improve rendering quality? Here is the code:
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="400" height="200" version="1.1" xmlns="http://www.w3.org/2000/svg">
<text x="10" y="30" font-family="Arial" font-size="12" font-weight="bold">123 xyz XYZ</text>
<text x="10" y="50" font-family="Arial" font-size="12" font-weight="bold" fill="#666">123 xyz XYZ</text>
<text x="10" y="70" font-family="Arial" font-size="12" font-weight="normal" fill="#444">123 xyz XYZ</text>
<text x="10" y="88" font-family="Arial" font-size="10" font-weight="normal" fill="#444">123 xyz XYZ</text>
</svg>
I've tried:
embedding fonts using #font-face;
using fonts other than Arial;
setting text-rendering="optimizeLegibility".
None of this helps.
Edit
The solution is to use text-rendering="geometricPrecision" (see Erik Dahlström's answer):
The result is still worse than in other browsers, but it seems that for now it is the best that one can get in Opera for Mac OS.
I've also tried to translate the content by 0.5px in both directions. It slightly changes the output, but doesn't improve the quality in general.
Looks like subpixel text rendering is disabled for text inside SVG on Mac.
A workaround is to specify text-rendering="geometricPrecision". That makes Opera use glyph outlines for rendering instead of deferring the text rendering to the platform. However, note that this typically tends to be slightly less performant. Also note that using geometricPrecision doesn't enable subpixel text rendering in Opera, but the text will usually look a little different (usually a slight blur depending on the pixel grid alignment).

SVG Font Rendering Problems while rendering Text on a Path in Chrome and Safari

I try to render some text along a bezier curve path in SVG:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<path id='menu_path' d="M 80,40 Q 200,85 245,205" stroke="none" fill="none"/>
<text fill="white">
<textPath xlink:href="#menu_path">News Info Presse Musik</textPath>
</text>
</svg>
In Firefox this works fine, but in Chrome and Safari, the text looks ugly (look at "Musik"). Even when I use monospace fonts and set the text to uppercase it does not change.
Here the Screenshots:
http://imageshack.us/a/img18/3195/svgrendering.png
http://imageshack.us/a/img705/7334/svgrenderingwithpath.png
Does somebody have an idea on how to avoid this?
I created a jsfiddle which shows the problem:
http://jsfiddle.net/v6esx/
Thank you!

Resources