deeplook / svglib

Read SVG files and convert them to other formats.
GNU Lesser General Public License v3.0
307 stars 79 forks source link

Units px and pt are wrong #386

Closed 13thirteen closed 8 months ago

13thirteen commented 10 months ago

Something is wrong with units px (pixels) and pt (points).

The following SVG file contains text and red bars of the same size in different units:

<svg xmlns="http://www.w3.org/2000/svg" width="300mm" height="300mm" font-family="sans-serif">
<rect x="0mm" y="30mm" width="96px" height="5mm" fill="#f00"></rect>
<rect x="0mm" y="60mm" width="2.54cm" height="5mm" fill="#f00"></rect>
<rect x="0mm" y="90mm" width="25.4mm" height="5mm" fill="#f00"></rect>
<rect x="0mm" y="120mm" width="1in" height="5mm" fill="#f00"></rect>
<rect x="0mm" y="150mm" width="6pc" height="5mm" fill="#f00"></rect>
<rect x="0mm" y="180mm" width="72pt" height="5mm" fill="#f00"></rect>

<text x="0mm" y="30mm" font-size="96px">Test 96px</text>
<text x="0mm" y="60mm" font-size="2.54cm">Test 2.54cm</text>
<text x="0mm" y="90mm" font-size="25.4mm">Test 25.4mm</text>
<text x="0mm" y="120mm" font-size="1in">Test 1in</text>
<text x="0mm" y="150mm" font-size="6pc">Test 6pc</text>
<text x="0mm" y="180mm" font-size="72pt">Test 72pt</text>
</svg>

From MDN: Absolute Length Units:

1px = 1in / 96 1cm = 96px / 2.54 1mm = 1cm / 10 1in = 2.54cm = 96px 1pc = 12pt = 1in / 6 1pt = 1in / 72

Which gives 96px = 2.54cm = 25.4mm = 1in = 6pc = 72pt

All text should have the same font size. All bars should have the same length.

The following are screenshots of the SVG and the PDF generated by svglib opened in Firefox: The SVG looks correct:

svg

The generated PDF looks wrong, the first and last units px and pt seem too big:

pdf

Tested with svglib 1.5.1, reportlab 4.0.5, Python 3.11.5, Windows 10

github-actions[bot] commented 10 months ago

Thank you for raising your first issue! Your help to improve svglib is much appreciated!

deeplook commented 9 months ago

Thanks for this report! Just to confirm I'm seeing the same effect for reportlab 3.5.68, svglib 1.4.1, and Python 3.10.6 on macOS 13.5.1. Might be a simple conversion buglet. Will check...

deeplook commented 9 months ago

It's embarrassing, but the pt unit in these tests is off by a factor of 1.25, and 1 px should be 1.3333333333333 pt. Will be fixed in Svg2RlgAttributeConverter.convertLength()...

deeplook commented 9 months ago

@13thirteen This feature branch should fix your issue: https://github.com/deeplook/svglib/tree/fix_units_pt_px. Can you please verify and give premission to add your SVG sample to the test cases?

13thirteen commented 9 months ago

Thank you for the fix! Yes, I can confirm that the PDF generated with the code in the feature branch looks correct: Units

Please feel free to use the SVG snippet in the tests.