Using SVG module from Skia

Hossein Nourikhah hossein at libreoffice.org
Tue Apr 25 12:19:21 UTC 2023


Hello,

I have studied some of the bugs from the svgio module of LibreOffice. As 
described in the svgio/README.md, "svgio module uses sax for reading xml 
and turns it into drawinglayer primitives. The rendering is done via 
drawinglayer primitives".

There are problems with the current implementation in different aspects:

1. Format support
The supported subset of SVG that is supported for import is limited. 
Some of the problems with SVG import are listed in the meta bug:

Bug 88278 (SVG-Import) - [META] SVG import image filter (all modules)
https://bugs.documentfoundation.org/showdependencytree.cgi?id=88278&hide_resolved=1

2. Performance
While trying to load, and/or converting the SVG files into PDF, the 
performance is sometimes very slow. Compared to Chrome, displaying SVG 
and converting it to PDF is several times slower. See this bug report:

Bug 146319 - [SVG] load/export of W3C SVG example car.svg is slow
https://bugs.documentfoundation.org/show_bug.cgi?id=146319

In the previous week, I mentioned this in the IRC chat, and one answer 
was that at the time there was no good SVG implementation in C++. Now 
that we build and use Skia in LibreOffice (external/skia), one option 
can be using Skia SVG module. So, I tried to take a look at it, and here 
are the results:

Skia SVG module is out of experimental mode since 2020, so it is a good 
candidate:

[svg] Relocate out of experimental
https://skia.googlesource.com/skia/+/6fc4106a9d641933abccc6703516206c8ae6d7eb

Let's look at the comparison:

1. Format support
I've tested with a complex SVG example (car.svg), that used in 
tdf#146319. The result with the Skia/PDF m111 onwards is very good. One 
can simply use Chromium PDF output to see the result.

2. Performance
The performance difference is significant. Comparing the LibreOffice and 
Chrome, I see a ten times difference:

$ time libreoffice7.5 --headless --convert-to pdf car.svg
convert /out/car.svg -> /out/car.pdf using filter : draw_pdf_Export

real    0m4.372s
user    0m3.414s
sys    0m0.679s

$ time google-chrome --headless --disable-gpu --print-to-pdf car.svg
1348088 bytes written to file output.pdf

real    0m0.497s
user    0m0.070s
sys    0m0.069s

I even tried to write an example using Python and C++. See the 
difference. Please note that skia-python uses an older version of Skia, 
so it is faster.

-------------------
import skia
from PIL import Image

skia_stream = skia.Stream.MakeFromFile("input.svg")
skia_svg = skia.SVGDOM.MakeFromStream(skia_stream)

svg_width, svg_height = skia_svg.containerSize()
surface_width, surface_height = 1024, 720

stream = skia.FILEWStream("output.pdf")
with skia.PDF.MakeDocument(stream) as document:
     with document.page(surface_width, surface_height) as canvas:
         canvas.scale(surface_width / svg_width, surface_height / 
svg_height)
         skia_svg.render(canvas)
-------------------

Python (see the attached skia-svg2pdf.py)
$ time python3 car.py

real    0m0.116s
user    0m0.066s
sys    0m0.013s

C++ (see the attached skia-svg2pdf.cpp)
$ time ./main

real    0m0.126s
user    0m0.111s
sys    0m0.000s

3. Complexity
The code in skia/modules/svg seem to be mostly the work of one 
developer, and it is 6.7k C++ code:

$ cloc ~/skia/modules/svg/
       99 text files.
       98 unique files.
        3 files ignored.

github.com/AlDanial/cloc v 1.90  T=0.02 s (4638.4 files/s, 465529.1 
lines/s)
-------------------------------------------------------------------------------
Language                     files          blank        comment         
   code
-------------------------------------------------------------------------------
C++                             45            893            594         
   4355
C/C++ Header                    48            824            426         
   2419
Bazel                            3              9              3         
    112
-------------------------------------------------------------------------------
SUM:                            96           1726           1023         
   6886
-------------------------------------------------------------------------------

Compared to this, svgio is even bigger, around 12.5K line of code.

$ cloc ~/libreoffice/core/svgio/
      137 text files.
      137 unique files.
        0 files ignored.

github.com/AlDanial/cloc v 1.90  T=0.06 s (2360.2 files/s, 332764.5 
lines/s)
-----------------------------------------------------------------------------------
Language                         files          blank        comment     
       code
-----------------------------------------------------------------------------------
C++                                 39           1931           1619     
      10818
C/C++ Header                        35            569            956     
       1708

4. Output size
You can compare the PDF output size from LibreOffice and Skia. With the 
latest version, Skia output is around 700 KB, but LO output is around 
3.2 MB.

5. Architecture
It may be possible to bypass svgio/cairo/etc. for creating the output, 
or when the Skia backend is used in GUI. Then it would make sense to 
create the output, or load the SVG in GUI, much faster.

I appreciate your comments.

Regards,
Hossein
-------------- next part --------------
A non-text attachment was scrubbed...
Name: skia-m111.pdf
Type: application/pdf
Size: 718840 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/libreoffice/attachments/20230425/d24fb125/attachment-0003.pdf>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: libreoffice-7.6-dev.pdf
Type: application/pdf
Size: 3373893 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/libreoffice/attachments/20230425/d24fb125/attachment-0004.pdf>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: skia-m114-chromium.pdf
Type: application/pdf
Size: 1348387 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/libreoffice/attachments/20230425/d24fb125/attachment-0005.pdf>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: skia-svg2pdf.py
Type: text/x-script.python
Size: 514 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/libreoffice/attachments/20230425/d24fb125/attachment-0002.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: skia-svg2pdf.cpp
Type: text/x-c
Size: 1422 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/libreoffice/attachments/20230425/d24fb125/attachment-0003.bin>


More information about the LibreOffice mailing list