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.

11
  • 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, 2023 at 7: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. Sep 12, 2023 at 7:22
  • 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. Sep 12, 2023 at 8:11
  • 1
    bug report github.com/pgf-tikz/pgf/issues/1275 Sep 12, 2023 at 13:46
  • 1
    I know :). It was me who answered. Though #1275 has not been closed yet.
    – AlexG
    Sep 12, 2023 at 20:44

1 Answer 1

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}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .