BoundingBox in PostScript output for A4 is too large and the computation with its comment are bogus

Al Ma alma0 at ro.ru
Sat Mar 9 13:48:53 CET 2024


Feeding `latex` with
\documentclass[a4paper]{article} \begin{document} Test \end{document}
or
\documentclass{article} \setlength\paperheight{297mm}% \setlength\paperwidth{210mm} \begin{document} Test \end{document}
and running `dvips` on the resulting DVI file yields the following lines (among many others) in the PostScript file:
%%BoundingBox: 0 0 596 842 %%DocumentPaperSizes: a4
%%BeginPaperSize: a4
{ pop << /PageSize [595 842] >> setpagedevice } { /a4 where { pop a4 } if }
inside mwe.ps. The contents of the document does not touch any margins; it's pointless and confusing to have the bounding box wider than the paper (596 pt > 595 pt).
Apparently, 596 is computed in the following function of output.c of dvips:
/*
 *   Convert scaled points to PostScript points.  This is the same
 *   as return (i * 72 / (65536 * 72.27)), which is the same as
 *   dividing by 65781.76, but we want to round up.
 */
static int
topoints(integer i)
{
   i += 65780L;
   return (i / 6578176L)*100 + (i % 6578176) * 100 / 6578176;
} This has two big issues:
• Why rounding UP (and not in some other way, e.g., towards the nearest integer; also cf. https://en.wikipedia.org/wiki/Rounding https://en.wikipedia.org/wiki/Rounding )? The function comment provides us with no rationale here, but it should. (E.g., you can claim that you don't wish to clip hypothetically drawn stuff away. However, it's a weak argument; a counterargument would be that you also don't wish to invent a whole 1-pt-wide column or 1-pt-high row out of nowhere. Further, if the paper were later really cut (e.g., by a high-end printer) according to BoundingBox rather than PageSize, the paper wouldn't fit into the real-world tight enclosures for A4. In my view so far, rounding towards the nearest integer would be more natural.)
• The code does NOT always compute ⌈i÷65781.76⌉, where ÷ is mathematical division. This can be witnessed already by i=1: the code yields (65781/6578176)·100 + (65781%6578176)·100/6578176 = 0·100 + 65781·100/6578176 = 0 + 6578100/6578176 = 0 (where `/` and `%` are the division and remainder on the type `integer` (int or long) in C), whereas it should yield ⌈1÷65781.76⌉ = 1. If anyone wishes to round up after all, here's how to do it without risking an overflow: http://stackoverflow.com/a/78127921 http://stackoverflow.com/a/78127921. For rounding towards the nearest integer, use, e.g., `return (25LL*i+822272)/1644544;` and C99 (there might be an overflow-free and portable variant thereof; I have not tried).
Kudos go to David in http://tex.stackexchange.com/a/712493 http://tex.stackexchange.com/a/712493; many thanks!
So three items need to be fixed:
(1) BoundingBox should probably stay within the paper size. If really nothing is drawn outside the paper, BoundingBox should definitely stay within the paper.
(2) The kind of rounding should be critically reevaluated and probably changed.
(3) The C code should actually implement the chosen rounding.
Gratefully,
AlMa
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://tug.org/pipermail/tex-live/attachments/20240309/a4023aba/attachment.htm>


More information about the tex-live mailing list.