Incorrect tikzpicture size when using dvisvgm output driver (PGF/TikZ)

dvisvgmtikz-pgf

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.

Best Answer

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}