mgieseki / dvisvgm

A fast DVI, EPS, and PDF to SVG converter
https://dvisvgm.de
GNU General Public License v3.0
295 stars 28 forks source link

Left edge of viewBox is always 0 with --exact-bbox #248

Closed bustercopley closed 9 months ago

bustercopley commented 9 months ago

There is apparently a mistake in calculating the minimum x coordinate of the bounding box (for DVI input). In the MWE below, the SVG viewBox is too wide, and has min-X equal to 0; however the content's left edge is about 0.5 units to the right. (The other three edges are correct.)

Here is a Bash script to reproduce the issue (tested on Debian and on Windows in MINGW64-variant MSYS bash, with dvisvgm built from master today).

#!/usr/bin/bash -xe

# Change to a temporary directory below the script directory
scriptdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
scratchdir=$(mktemp -d -p ${scriptdir})
cd ${scratchdir}

>example.tex echo '\shipout\hbox{$C$}\end'
tex example.tex
dvisvgm --no-fonts --exact-bbox example.dvi

The output from the script:

+++ dirname ./dvisvgm-test.sh
++ cd .
++ pwd
+ scriptdir=/home/buster
++ mktemp -d -p /home/buster
+ scratchdir=/home/buster/tmp.ac7C3BCWql
+ cd /home/buster/tmp.ac7C3BCWql
+ echo '\shipout\hbox{$C$}\end'
+ tex example.tex
This is TeX, Version 3.141592653 (TeX Live 2023/Built by MSYS2 project) (preloaded format=tex)
(./example.tex [1] )
Output written on example.dvi (1 page, 180 bytes).
Transcript written on example.log.
+ dvisvgm --no-fonts --exact-bbox example.dvi
pre-processing DVI file (format version 2)
processing page 1
  graphic size: 7.6pt x 7.27pt (2.671095mm x 2.555113mm)
  output written to example.svg
1 of 1 page converted in 0.309731 seconds

Attached are the output SVG (it's very small!) and a cropped screenshot from Inkscape showing the bounding box and content. example inkscape

muzimuzhi commented 9 months ago

Using concepts used in https://simoncozens.github.io/fonts-and-layout/concepts.html#advance-widths, it seems the outline bounding box for $C$ is wider than the corresponding glyph bounding box. That's said, the left sidebearing for C in math mode is positive.

\documentclass{article}
\pagestyle{empty}

\begin{document}
\fboxsep=0pt
\fbox{C}
\fbox{\textit{C}}
\fbox{$C$}
\end{document}

image

mgieseki commented 9 months ago

Yes, that's exactly the issue here. The character offset is not taken into account when computing the bounding box. I've fixed it and will commit the patch after some more testing.

bustercopley commented 9 months ago

Using concepts used in https://simoncozens.github.io/fonts-and-layout/concepts.html#advance-widths, it seems the outline bounding box for $C$ is wider than the corresponding glyph bounding box. That's said, the left sidebearing for C in math mode is positive.

Indeed! You would use other options (for example --bbox=dvi) to get a bounding box that takes such things into account, to allow further text layout operations.

muzimuzhi commented 9 months ago

Then my previous understanding of --bbox=min was wrong. I had thought side bearings are taken into consideration. Thank you both.

Update: Sorry I was wrong to think this issue is about --bbox-min, but actually it's about --exact-bbox. According to doc for --exact-bbox, yes it should trim side bearings.

mgieseki commented 9 months ago

Yes, they are usually enclosed in the box when calling dvisvgm without --exact-bbox because the TFM metrics used in this case include the side bearings and it's not possible to derive the glyph extents from them. In order to allow for tight boxes that only consider the visual parts of the characters, --exact-bbox was introduced.

bustercopley commented 9 months ago

Wow, that was fast! Looks great, thank you.