typst / svg2pdf

Converts SVG files to PDF.
Apache License 2.0
273 stars 32 forks source link

Make converted SVGs use up less space #35

Closed LaurenzV closed 1 year ago

LaurenzV commented 1 year ago

Currently, in cases of bigger SVGs, svg2pdf will often create SVGs that take up much more space than they should.

Consider the following SVG: test2

The SVG itself is 770KB. Once converted with svg2pdf, it takes about 568KB of space. However, cloud converters manage to get it down to around ~220KB.

The reason for that is twofold: One the one hand, we create way too many XObjects, meaning that we can't make full use of the compression using Deflate. Not only that, but we also sometimes create XObject that are completely empty. Here is an example from the SVG above:

12 0 obj
<<
  /Length 3
  /Type /XObject
  /Subtype /Form
  /Resources <<
    /ColorSpace <<
      /srgb [/CalRGB <<
        /WhitePoint [0.9505 1 1.0888]
        /Gamma [2.2 2.2 2.2]
        /Matrix [0.4124 0.2126 0.0193 0.3576 0.715 0.1192 0.1805 0.0722 0.9505]
      >>]
    >>
    /ProcSet [/PDF /ImageC /ImageB]
  >>
  /Group <<
    /Type /Group
    /S /Transparency
    /I true
    /K false
    /CS [/CalRGB <<
      /WhitePoint [0.9505 1 1.0888]
      /Gamma [2.2 2.2 2.2]
      /Matrix [0.4124 0.2126 0.0193 0.3576 0.715 0.1192 0.1805 0.0722 0.9505]
    >>]
  >>
  /BBox [46.428413 367 545.4284 966]
  /Matrix [0.18334149 0 0 0.18334149 163.40727 -242.72272]
>>
stream
q
Q
endstream
endobj

Something like this could be avoided if we checked wether a usvg::Group actually contains paths/children before creating an XOBject for that. However, the main issue is still that we have so many XObjects which all have the Group and ColorSpace entry. which bloats the PDF unnecessarily.

Some things we could do to improve this: