SVGs are broken in subtle ways (spacing issues)

Hey. I have noticed that the SVG (and only SVGs, PNGs and JPEGs are fine) tend to insert padding and space where it shouldn’t. Sample 1 has extra padding to the right and Sample 2 has extra space after purple text.

I suspect font issues. I have tried to display similar SVGs on Windows, but they were identical. It could rely on the fonts that are available during the DOT → SVG rendering process.

How can I solve this?

EDIT: I have tried to install Microsoft fonts from http://corefonts.sourceforge.net. I have tested my dot graphs and observed that in the places where there was excessive whitespace before, there is now not enough whitespace (in all of them, not only in the following example):

image

Sample 1:

digraph {
    node [shape=plaintext]

    provider [label=<
<TABLE BORDER="1" CELLBORDER="0" CELLSPACING="0">
  <TR><TD>My table element</TD></TR>
</TABLE>>]
}

Sample 1 SVG:
first

Sample 1 screenshot:
image

Sample 2:

digraph {
    bgcolor="white"
    ratio=compress
    size="12"

    subgraph answers {
        node [shape=rectangle,penwidth=2]

        allow_missing [color=red,label="Documentation is NOT linked\n(not recommended)"]
        error_out [color=yellow,label="Error message is printed\nmeson fails during setup"]
        online_doc [color=green,label="Tagfile taken from dependency\ndocumentation source taken from online documentation"]
        direct_link_answer [color=yellow,label="Tagfile taken from dependency\ndocumentation source taken from internal meson subproject\n(for developers only, do not distribute)"]
        local_link_answer [color=green,label="Tagfile taken from dependency\ndocumentation source taken from installed documentation"]
    }

    find_dep_tagfile [label="Find UniSettings dependency tagfile\n(using pkg-config's tagdir or using meson native dependency)"]
    allow_missing_tagfiles [label="Is \"docs-allow-missing-tagfiles\" set?"]
    local_link [label=<Is <FONT COLOR="PURPLE">"docs-local-link"</FONT> set?>]
    direct_link [label=<Is <FONT COLOR="PURPLE">"docs-devel-direct-link"</FONT> set?>]

    find_dep_tagfile -> allow_missing_tagfiles [label="not found"]
    allow_missing_tagfiles -> allow_missing [label="Yes"]
    allow_missing_tagfiles -> error_out [label="No (default)"]
    find_dep_tagfile -> local_link [label="found"]
    local_link -> online_doc [label="No (default)"]
    local_link -> direct_link [label="Yes"]
    direct_link -> direct_link_answer [label="Yes"]
    direct_link -> local_link_answer [label="No (default)"]
}

Sample 2 SVG:
second

Sample 2 screenshot:

@meator,

I’m not an expert. However, I also had many similar problems with the SVG format. Unfortunately, SVG is a terrible format for pictures with text. SVG doesn’t embed fonts. Thus, there is no guarantee that the SVG image will look the same on every system. In my case, for instance, GraphViz was using a different Times New Roman font than my browser. I don’t know why.

The spacing issues are caused by GraphViz calculating the positions of the text based on the font that it uses at the moment of generation. But when you open SVG, you might use a different font, and thus, the spacing gets messed up because the text sizes are different.

This is also why PDF format embeds fonts.

I have tested your Dot Graph. I get the same issue on Windows.
If you add node [fontname="Consolas", fontsize=12]; in the beginning, then SVG works properly.
It is definitely a problem with the font. You can try different font types to see which one works.

The best option would be to choose a different format, like PDF.

I have done some googling and have stumbled upon Unwanted space around html font tags with svg output (#1891) · Issues · graphviz / graphviz · GitLab

This looks right it is not going to get solved anytime soon. I would understand if the image was rendering all right on the computer which generated it but was generating wrong on other computers, but the SVG is broken right as it leaves dot.

I have thought that using monospace fonts would fix the spacing (since it’s uniform), but no.

Exactly, either use pdf, or dot -Tsvg:cairo because cairopango SVG goes to the trouble of embedding font glyphs as paths (shapes) but the graphviz native driver is hope-based and just emits the raw text and hope the downstream renderer does whatever cairopango does internally (when graphviz estimates the size of rendered text). Of course as we’ve learned, sometimes it’s OK and sometimes it’s not. My impression is the problems are a little worse on Windows.

It’s probably too late to make -Tsvg default to -Tsvg:cairo

dot -Tsvg:cairo?

@scnorth,

Thank you for the suggestion.
Unfortunately, svg:cairo renders the font very ugly.
The picture below shows the comparison between dot -Tsvg:cairo 1.txt -o 1.svg and dot -Tpdf 1.txt -o 1.pdf

As you can see, the SVG has correct spacing, but the font is very ugly. At the same time, PDF is rendered perfectly, exactly as you would expect.

Note: I can’t attach the proper image because this website downsamples it dramatically, and now it is hard to see the difference. You have to generate pdf and svg:cairo yourself.

Thank you, fixed. (But, I’m starting to worry that MacBook keyboard problems are still with us.)

The same example, processed with dot -Tsvg:cairo and then loaded into MacOS Safari (latest release) looks good. I’ll attach the image.

I’m sorry to see these problems. The most obvious suspect is the port of PangoCairo to the environment that manifests this problem (some version of Windows?) The bug appears to be outside Graphviz. Graphviz is oblivious to how any renderer handles individual glyphs.

If someone would like to pursue this, probably that means submitting a bug to the GTK project. Perhaps they would be responsive to an example created by making small modifications to their demo text rendering program at PangoCairo – 1.0: Rendering with Cairo

It’s tempting at this point to conclude it was a mistake to even have SVG drivers in Graphviz, because of these problems. TGraphviz is certainly dependent on precise text rendering and that looks like the Achilles’ heel of SVG. For better or worse, though, SVG is also quite useful as one of the only structured formats Graphviz generates.

It’s interesting that MacOS core graphics doesn’t support SVG in any way. Also, Adobe Illustrator .ai file format is proprietary; apparently they did not find SVG to be sufficient, either, although Adobe was involved with defining its standard.

I did my test on Windows 11 using Graphviz-12.2.1.
I tried to open SVG with different tools, but they all showed the same ugly font rendering.

Below is an svg:cairo generated on Windows:

Below the image I generated on Ubuntu with svg:cairo, opened on Windows:


The rendering is much better.

However, here is the pdf generated on Ubuntu and opened on Windows:


It is much better.

It’s a little surprising that the default (Times/serif) font looks so ragged when generated in SVG on Windows. It might be instructive to add the -v flag when running the command and try to notice what font file is being bound. There’s an outside chance it might help to run fc-cache first (in Windows cmd or Powershell) in case fontconfig isn’t finding the right fonts for some reason.

I am surprised that my issue has sparked such conversation.

By the way, Doxygen has brought me to this issue. Its INTERACTIVE_SVG feature relies on the simple SVG outputted by -Tsvg. The SVG format is popular for some Doxygen users[1] (including myself) for its high quality rendering, scaling and the selectability of text.

These graphs are intended to be viewed in my online Doxygen documentation. Would it be possible to bundle some font with the website, use that font to generate the graph and then convince the web browser to use the website’s font (which could be for example a .woff2 file hosted on the website) to render the SVG? I’m looking for a way to completely remove the reader’s installed fonts from the equation.


  1. Doxygen Awesome, a poppular theme for Doxygen, recommends using -Tsvg: Doxygen Awesome: Tips & Tricks ↩︎

Also, generated PNG on Ubuntu:


It is also very good. Much better than svg:cairo.

I think I know why svg:cairo and pdf are different.
svg:cairo renders the font during image generation as if it is a shape, and it uses some default font rendering options like anti-aliasing and so on.
pdf embeds the font, and then when you open a PDF, the font is rendered according to your screen DPI and font settings. That is why it looks good.

Also interesting that fonts in a PNG image are rendered decently. But Cairo seems to be using different font rendering settings.

Yes, it seems that you can tell Doxygen to use a particular font during SVG generation and add CSS style with the font to all pages.
Check that the SVG file uses the correct font name during generation (just open the SVG file and look for font-family attribute)

That may explain a lot of things.

I was going to point out how the Graphviz pango driver enables several font antialiasing options, but it doesn’t help any of this because it would only affect pixel based output.

An article unrelated to Graphviz mentions the possible benefits of shape-rendering="optimizeQuality" on SVG elements, but I didn’t see any difference locally. Curiously, a Stackoverflow comment says to set it to “optimizeQuality” on the root element, but MDN documentation doesn’t say this is a legal value, and implies it is only valid on circle, ellipse, line, path, polygon, polyline and rect.

Also, here’s someone from 10 years ago complaining that font kerning is broken in Windows pangocairo, but in win32 fonts only.

I realize this is not important, we are just nerding out tonight.

:slight_smile:
By the way, interestingly enough, it seems that it is possible to embed the font inside SVG to make it work the same way as PDF does.
SVG supports HTML CSS style definitions. Thus, we can convert .woff font into BASE64 and put it inside the .svg file

<style type="text/css">
  @font-face {
    font-family: 'MyEmbeddedFont';
    src: url('data:font/woff;charset=utf-8;base64,BASE64-DATA-HERE') format('woff');
  }
  
  text {
    font-family: 'MyEmbeddedFont', sans-serif;
    font-size: 20px;
  }
</style>

Thus, GraphViz could generate SVG with the font inside.

So it’s just a bunch of programming? It’s good to know it’s feasible, but it looks difficult within the graphviz core svg driver.

After wasting a little time in CoPilot, then looking at the Pango font face object API Pango.FontFace, I have to conclude this is only possible if Graphviz somehow finds and reads the same font file that PangoCairo has. I have no idea if that is even possible.

  • I believe that the cairo svg driver already embeds fonts, though seemingly using a different technique (see Font FAQ | Graphviz)
  • if you are asking for Graphviz to embed fonts, please create an issue here
  • If anyone wants to jump in and take on this request, the Graphviz svg driver is pretty approachable (see plugin/core/gvrender_core_svg.c)
  • In the interim, it seems that font embedding can be
    accomplished with a post-processor (e.g. https://transfonter.org/)

I was successful with using web fonts in Doxygen to eliminate the rendering inconsistencies. I have documented my solution at SVG dot graphs have added padding · Issue #11308 · doxygen/doxygen · GitHub

This was pretty hard to figure out. I was in the middle of writing a post on this topic ranting about it not working, but then I realized where I made the error. I am not a webdev. But using web fonts to solve this should guarantee that the fonts will be available on the target system and that it will be identical to the font used when creating the SVG.