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