10

Background: All PDF has a MediaBox that describes the page size, for each page. This is found in the PDF as (for example, US letter) the text string /MediaBox [0 0 612 792] where the numbers are "big points."

It is easy to calculate what the MediaBox should be, based on page dimensions. MWE:

% Must work with pdflatex. Specifically pdflatex.  
\documentclass[letterpaper]{memoir} % All pages same size.  
\usepackage{pgf}  
\newcommand{\whatTexUsesForMBwidth}{That is the width question!}  
\newcommand{\whatTexUsesForMBheight}{That is the height question!}  
% First is where the result is stored, second is the input.  
% Input TeX pt, Result in bp to 0.1 no units.  
\newcommand{\getbigpoints}[2]{  
   \pgfmathsetmacro#1{round(0.99626401*(#2+0.005))}  
}  
\newcommand\getMediaBoxWidth{  
    \getbigpoints{\myMBW}{\stockwidth}  
}
\newcommand\getMediaBoxHeight{  
    \getbigpoints{\myMBH}{\stockheight}  
}  
\getMediaBoxWidth  
\getMediaBoxHeight  
\begin{document}  
My calculated MediaBox width = \myMBW\par  
My calculated MediaBox height = \myMBH\par  
TeX internal MediaBox width = \whatTexUsesForMBwidth\par  
TeX internal MediaBox height = \whatTexUsesForMBheight\par  
\end{document}  

OUTPUT:

My calculated MediaBox width = 612.0  
My calculated MediaBox height = 792.0  
TeX internal MediaBox width = That is the width question!  
TeX internal MediaBox height = That is the height question!  

Now, I can always inspect the PDF in an editor, and read the MediaBox directly. But what I want to do is learn the MediaBox string while TeX is running, so that I can use the string within the TeX document.

Why I want to do this: For compliance purposes, my documents require /TrimBox, which in my case is exactly /MediaBox. I can calculate the values and write the string into the PDF without problem using TeX with the correct packages (and it is valid, according to Adobe Acrobat Pro 9). But that's because I am currently using a standard page size. If I ever need to use an exotic page size, there is the risk that my calculation will differ from the TeX internal values by a fraction of a point. That could cause an undetected error. However, if I knew the actual /MediaBox string, I could merely copy it to /TrimBox without need of calculation.

I have already set up a mock landing strip and prayed for Cargo, without result.

egreg
  • 1,121,712
RobtA
  • 472

1 Answers1

10

I'm not sure you want the values rounded to integers, because in case of A4 paper, we find

/MediaBox[0 0 595.276 841.89]

However, this depends on the setting of \pdfdecimaldigits whose default value is 3. (Thanks to Heiko Oberdiek for remarking it.)

The parameters to use are \pdfpagewidth and \pdfpageheight:

\documentclass[letterpaper]{memoir} % All pages same size.
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\getMediaBox}{O{\MediaBox}}
 {
  \cs_gset:Npx #1
   {
    /MediaBox[0~0~
      \robta_get_in_bp:n {\pdfpagewidth}~
      \robta_get_in_bp:n {\pdfpageheight}]
   }
 }
\cs_new:Nn \robta_get_in_bp:n
 {
  \fp_eval:n
   {
    round ( \dim_to_decimal_in_bp:n { #1 } , \pdfdecimaldigits )
   }
 }
\ExplSyntaxOff

\begin{document}

\getMediaBox

\MediaBox

\end{document} 

Here's the output; the \MediaBox so obtained is a string that you can use in different ways. Other strings can be produced if you prefer.

enter image description here

Here's the output for A4 paper:

enter image description here

If you set \pdfdecimaldigits to 0 at the start of your document, with

\pdfdecimaldigits=0

then with A4 paper we get

/MediaBox[0 0 595 842]
egreg
  • 1,121,712
  • 1
    The magic number 3 is the value of \pdfdecimaldigits. – Heiko Oberdiek May 17 '15 at 23:19
  • Gotcha. I was misled by a Google search result, which said: "In PostScript, its dimensions [A4 paper] are rounded off to 595 × 842 points." Thought that might cause calculations to fail. As long as TrimBox does not exceed MediaBox, all is well. Doesn't matter if TrimBox is a fraction of a point smaller. – RobtA May 17 '15 at 23:20
  • @RobtA PDF has a very strange way to round numbers. Anyway, thanks to Heiko, you can decide yourself what number of decimal digits to use, I'll change it in my answer. – egreg May 17 '15 at 23:22
  • 2
    @HeikoOberdiek I believe that even the people at Adobe are quite uncertain about the matter, as proved by the misfeats of Reader that used to think that A4 paper doesn't fit on A4 paper when printing. – egreg May 18 '15 at 00:01
  • 1
    "PDF has a stange way to..." No kidding! I am busy writing an improved package for PDF/X. Existing pdfx cannot do it. Mine requires pdflatex, so full microtype can be used. Intent is US (and Western European) novelists (not mathematicians) who want POD with SWOP output intent, bleed, trim, etc. I am at the debugging stage, using Acrobat Pro. One possible bug would be if calculated TrimBox exceeded TeX MediaBox, due to roundoff error. – RobtA May 18 '15 at 00:08
  • 1
    @egreg Looking into the sources, it is much more complicate. For example, \pdfdecimaldigits is limited to 0 to 4, when the values for the MediaBox are calculated. – Heiko Oberdiek May 18 '15 at 01:05
  • @RobtA looking forward to a new and improved pdf/x-package! Maybe you want to put it on github or some place similar... – DG' May 18 '15 at 08:08
  • Oh: When I used the answer code, I had to remove \dim_to_decimal_in_bp:n and use the multiplier 0.99626401 in front of argument #1 there. Don't know why my setup did not grasp the \dim code. Also, I added \pdfcompresslevel=0 sothat I could read the result in an editor. Indeed, the MediaBox (tested with a4paper) is exactly the result described. I tried a few random non-standard sizes, and all came out correct. Now, when A4 PDF is exported from LibreOffice, it rounds to integers 595 and 842. Scribus does not round, showing to hundredths precision (with added zeroes to make 5 decimal digits). – RobtA May 18 '15 at 14:42
  • @RobtA Maybe you have an outdated version of expl3 – egreg May 18 '15 at 14:43
  • @egreg That's possible. My openSuSe 13.2 package manager says the kernel is 2013.84-svn4469svn29409-16.1.7. I realize that I might be able to get newer stuff via direct TexLive, but I won't do that: My efforts are directed to writers who cannot write (much) code and would simply follow no-brainer instructions from the easiest sources, whether on Linux or via Miktex. Again, I get code via prayers to Cargo. – RobtA May 18 '15 at 16:38
  • This code works in pdflatex and lualatex, but does not work in xelatex. How can one modify it to work with xelatex? – Leonid Dec 19 '15 at 13:16
  • 1
    @Leonid Just use an explicit value instead of \pdfdecimaldigits; xdvipdfmx uses a default of 2, and the parameter cannot be specified nor inspected within XeTeX, as far as I know. – egreg Dec 19 '15 at 14:03
  • Thank you @egreg! How to make it more expandable? I want to make \getTrimBox out of this answer and make it puttable inside something like \pdfpageattr\expandafter{\getTrimBox} Or should i ask different question? – Leonid Dec 19 '15 at 19:48