6

I want to produce an SVG file with a node shape, e.g. rectangle. I use the following LaTeX code:

\def\pgfsysdriver{pgfsys-dvisvgm.def}
\documentclass{article}
\usepackage[usenames]{color}
\pagestyle{empty}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric}
\begin{document}
\pagecolor{white}%
\begin{tikzpicture}
  \node (start) [draw, rectangle, minimum width=24mm, minimum height=16mm] {How are you?};
\end{tikzpicture}
\end{document}

and then I use xelatex and then dvisvgm to produce the SVG file:

xelatex -no-pdf -interaction nonstopmode -output-directory .\ test1.tex & dvisvgm -n -o .\test1.svg test1.xdv

Unfortunately, the produced SVG file has a background object with larger width than the width of the rectangle, resulting in a TikZ picture with larger width. The width is depended on the text width, i.e., if the text is short, the resulting background object width is not longer than the rectangle width, and there is no problem. But when the text width is longer than some critical length, the tikzpicture width is not the same as the drawn object width. Also, I noticed the same problem with the height. In the following example, the problem appears on the top of the tikzpicture:

\def\pgfsysdriver{pgfsys-dvisvgm.def}
\documentclass{article}
\usepackage[usenames]{color}
\pagestyle{empty}             % do not remove
\usepackage{tikz}
\usetikzlibrary{shapes.geometric}
\begin{document}
\pagecolor{white}%
\begin{tikzpicture}
  \node (point1) [coordinate] {};
  \node at (0,-3cm) (start) [draw, color=black, rectangle, minimum width=24mm, minimum height=16mm] {How are you?};
  \draw (point1) -- (start);
\end{tikzpicture}
\end{document}

with the following command to be executed:

xelatex -no-pdf -interaction nonstopmode -output-directory .\ test3.tex & dvisvgm -n -o .\test3.svg test1.xdv

I am using: Windows 11 MiKTeX-XeTeX 4.10 (MiKTeX 23.5) dvisvgm 3.0.4 pgf 3.1.10

I am expecting the produced SVG file to contain the correct sized objects.

  • In both your examples the text fits in the node rectangles, so I see no problem. Note that by default, dvisvgm crops the output SVG to the visible objects in the page. – AlexG Sep 12 '23 at 07:17
  • @AlexG I corrected the code, because I copied it incorrectly. However, the problem is not if the text is fit inside the rectangle, but the size of the tikzpicture, or the border of the whole tikzpicture is not on the rectangle. – Christos Sevastiadis Sep 12 '23 at 07:22
  • Ah I see the problem. There seems to be an issue with Pgf's dvisvgm driver. With the Postscript output driver \def\pgfsysdriver{pgfsys-dvips.def} I get the correct result (SVG with correct bounding box). – AlexG Sep 12 '23 at 07:46
  • Maybe you file a bug report at https://github.com/pgf-tikz/pgf ? – AlexG Sep 12 '23 at 07:48
  • 1
    @AlexG it looks as if there is an hardcoded 1in in the driver, probably to compensate the offset. As soon as the picture is larger than 1in x 1in the svg dimensions are ok. – Ulrike Fischer Sep 12 '23 at 08:11
  • @UlrikeFischer I think I found a fix. There seems to be a conflict between forced bbox setting by pgfsys-dvisvgm and automatic computation by dvisvgm. – AlexG Sep 12 '23 at 12:15
  • 1
    bug report https://github.com/pgf-tikz/pgf/issues/1275 – muzimuzhi Z Sep 12 '23 at 13:46
  • @AlexG I had filed the bug report github.com/pgf-tikz/pgf/issues/1275, and it is already answered and corrected. – Christos Sevastiadis Sep 12 '23 at 18:58
  • 1
    I know :). It was me who answered. Though #1275 has not been closed yet. – AlexG Sep 12 '23 at 20:44
  • @ChristosSevastiadis Btw, if the answer below was helpful and solves your problem, please consider accepting it by clicking on the check mark on its left side. – AlexG Sep 13 '23 at 07:02
  • @AlexG, I didn't know that you are the same person :) – Christos Sevastiadis Sep 13 '23 at 07:24

1 Answers1

6

When a graphical object (node, shape etc.) is inserted using \box..., PGF's output driver first pushes the final output dimensions by inserting a dvisvgm:bbox ... special with the correct dimensions of the inserted TeX box. However, dvisvgm itself computes and re-dimensions the output by examining the content of the inserted material. This should be prevented in case of forced bbox adjustment.

Here is a fix for the pgfsys-dvisvgm driver which places dvisvgm:bbox lock and dvisvgm:bbox unlock specials around the \box... command. It prevents further bounding box computations during DVI processing by dvisvgm. Typeset with

latex example
dvisvgm --font-format=woff2 --exact --zoom=-1 example

or

xelatex --no-pdf example
dvisvgm --font-format=woff2 --exact --zoom=-1 example.xdv

The dvisvgm option zoom=-1 makes the SVG responsive in order fill the available display size of the Web browser. It makes the effect of the proposed fix more obvious.

For comparison: SVG with driver fix and SVG without driver fix.

\def\pgfsysdriver{pgfsys-dvisvgm.def}

\documentclass{article} %\usepackage[usenames]{color} \pagestyle{empty} \usepackage{tikz}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % fix bounding box setting of inserted tikz objects % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \makeatletter \def\pgfsys@typesetpicturebox#1{% \pgf@ya=\pgf@shift@baseline\relax% \advance\pgf@ya by-\pgf@picminy\relax% % % \advance\pgf@picmaxy by-\pgf@picminy\relax% maxy is now the height \advance\pgf@picmaxx by-\pgf@picminx\relax% maxx is now the width \setbox#1=\hbox{\hskip-\pgf@picminx\lower\pgf@picminy\box#1}% \ht#1=\pgf@picmaxy% \wd#1=\pgf@picmaxx% \dp#1=0pt% \leavevmode% \pgf@xa=\pgf@trimleft@final\relax \ifdim\pgf@xa=0pt \else\kern\pgf@xa\fi% \raise-\pgf@ya\hbox{\ifpgf@sys@svg@inpicture\else\special{dvisvgm:bbox \pgf@sys@tonumber\pgf@picmaxx\space\pgf@sys@tonumber\pgf@picmaxy}\special{dvisvgm:bbox lock}\fi\box#1\ifpgf@sys@svg@inpicture\else\special{dvisvgm:bbox unlock}\fi}% \pgf@xa=\pgf@trimright@final\relax \ifdim\pgf@xa=0pt \else\kern\pgf@xa\fi% } \makeatother %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%\usetikzlibrary{shapes.geometric} \begin{document} \pagecolor{white}% \begin{tikzpicture} \node (start) [draw, rectangle, minimum width=24mm, minimum height=16mm] {How are you?}; \end{tikzpicture} \end{document}

AlexG
  • 54,894