<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body text="#000000" bgcolor="#FFFFFF">
<div class="moz-cite-prefix"><br>
On 15/10/2023, 15:17, I wrote :<br>
</div>
<blockquote type="cite"
cite="mid:d338d3d9-e0ce-cf1e-b8fe-74962a737216@Hellenic-Institute.Uk">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
At the moment, one can include a PDF file using the following
syntax :<br>
<blockquote><tt>\XeTeXpdffile ⟨filename⟩ [ page ⟨int⟩ ] [ crop |
media | bleed | trim | art ]</tt><br>
<tt>[ scaled ⟨int⟩ | xscaled ⟨int⟩ | yscaled ⟨int⟩ | width
⟨dimen⟩ |</tt><br>
<tt>height ⟨dimen⟩ | rotated ⟨decimal⟩ ]</tt><br>
<tt>Insert (pages of) a PDF. See below for explanation</tt><br>
</blockquote>
where <tt>[ crop | media | bleed | trim | art ] </tt>specify to
which of the four boxes known to PDF the inserted file is to be
cropped. I frequently have the need to crop a PDF file during
inclusion to arbitrary dimensions, but at the moment that would
appear to be impossible (short of pre-massaging the PDF to be
inserted). Would it be possible to enhance XeTeX to recognise and
honour the following (or similar) syntax :<br>
<blockquote><tt>\XeTeXpdffile ⟨filename⟩ [ page ⟨int⟩ ] [ crop |
media | bleed | trim | art | custom [xmin ymin xmax ymax]]</tt><br>
<tt> [ scaled ⟨int⟩ | xscaled ⟨int⟩ | yscaled ⟨int⟩ | width
⟨dimen⟩ |</tt><br>
<tt> height ⟨dimen⟩ | rotated ⟨decimal⟩ ]</tt><br>
<tt> Insert (pages of) a PDF. See below for explanation</tt><br>
</blockquote>
</blockquote>
to which David Carlisle kindly replied :<br>
<br>
<blockquote type="cite">
<div>You can clip an arbitrary box so no need to have this as an
image inclusion feature.</div>
<div><br>
</div>
<div>\input{graphicx}<br>
\includegraphics{example-image.pdf}<br>
\bigskip<br>
\includegraphics[trim=20pt 50pt 50pt 100pt,
clip]{example-image.pdf}<br>
\bye</div>
</blockquote>
The need for this feature disappeared, so I did not pursue David’s
suggestion at the time, but the need returned yesterday so I gave
David's suggestion a try, and although it took me several attempts
to work out the correct dimensions to pass as parameter to
\includegraphics (in part because the PostScript/PDF bounding box is
bottom-up, while TeX assembles boxes top down (and the TeXworks
ruler also increases as one goes downwards)) I eventually managed to
make it work. However, while graphicx.tex is only 40 or so lines
long, graphicx.sty (which graphicx.tex slaves) is over 250 lines,
miniltx.tex is almost 600 lines, and then there are the driver files
(xetex.def is over 500 lines in itself). In total, maybe 1500 lines
of code or so. This seemed somewhat excessive to me, so I set about
finding out how graphicx.tex achieved my goal. It turned out that
the key part was less than 20 lines in length, and "hidden" in
xetex.def :<br>
<br>
<tt>\def\GPT@clipbox#1{%<br>
\setbox#1=\hbox{%<br>
\Gin@defaultbp\WIDTH{\wd#1}%<br>
\Gin@defaultbp\DEPTH{\dp#1}%<br>
\@tempdima\ht#1%<br>
\advance\@tempdima\dp#1%<br>
\Gin@defaultbp\TOTALHEIGHT{\@tempdima}%<br>
\special{x:gsave}%<br>
\special{%<br>
pdf:literal<br>
0 -\DEPTH\GPT@space \WIDTH\GPT@space \TOTALHEIGHT\GPT@space
re W n<br>
}%<br>
\rlap{\box#1}%<br>
\special{x:grestore}%<br>
\special{pdfcolorstack \@pdfcolorstack current}%<br>
\hskip\wd#1%<br>
}%<br>
}<br>
<br>
</tt>or in a somewhat more readable form (and omitting the
commercial-ats and most eol percent comments)<br>
<br>
<tt>\def \GPTclipbox #1%<br>
{%<br>
\setbox #1 = \hbox<br>
{%<br>
\Gindefaultbp \WIDTH = \wd#1<br>
\Gindefaultbp \DEPTH = \dp#1<br>
\tempdima = \ht #1<br>
\advance \tempdima by \dp #1<br>
\Gindefaultbp \TOTALHEIGHT = \tempdima<br>
\special {x:gsave}<br>
\special {pdf:literal 0 -\DEPTH \space \WIDTH \space
\TOTALHEIGHT \space re W n}<br>
\rlap {\box#1}<br>
\special {x:grestore}<br>
\special {pdfcolorstack \pdfcolorstack current}<br>
\hskip \wd #1<br>
}%<br>
}<br>
<br>
</tt>As the depth of most boxes is normally small, we can
approximate the key line as follows, omitting the \spaces for
readability :<br>
<blockquote><tt>\special {pdf:literal 0 0 \WIDTH \TOTALHEIGHT re W
n}</tt><br>
</blockquote>
where :<br>
<i><br>
</i>
<blockquote type="cite"><i>The </i><i><code>re</code></i><i>
operator constructs a rectangle. It takes four parameters (the
values preceding the operator) that define a rectangle: the x
co-ordinate of the lower-left corner, the y co-ordinate of the
lower-left corner, the width and the height. </i>
<p><i>The </i><i><code>W</code></i><i> operator sets the clipping
path, which in this case is the rectangle just drawn, for the
content that follows.</i></p>
<i> </i>
<p><i>The </i><i><code>n</code></i><i> operator starts a new
path. It discards the paths constructed so far. It thus
prevents the rectangle just drawn (used as clipping path) from
being drawn</i>.</p>
</blockquote>
Now as both co-ordinates of the lower left corner are (or almost
are) zero, the effect of the <tt>\special {pdf:literal ... re W n}
</tt>will be to clip the contents of the box passed as parameter to
a rectangle with lower-left corner approximately (0,0). But what
if we want a rectangle of the same size, but <i>not </i>with
origin (0, 0) ? Well, clearly, before this code is called, we mus
massage the contents of the box to be passed as parameter such that
our <i>intended</i> origin has been mapped to the (0, 0) point.
Once we realise this, we are in a position to write the code :<br>
<blockquote><tt>% !TeX Program=XeTeX</tt><tt><br>
</tt><tt><br>
</tt><tt>\pdfpageheight = 210 mm</tt><tt><br>
</tt><tt>\pdfpagewidth = 297 mm</tt><tt><br>
</tt><tt><br>
</tt><tt>\hsize = \pdfpagewidth</tt><tt><br>
</tt><tt>\vsize = \pdfpageheight</tt><tt><br>
</tt><tt><br>
</tt><tt>\parindent = 1 cm</tt><tt><br>
</tt><tt><br>
</tt><tt>\output = {\advance \hoffset by -1 in \advance \voffset
by -1 in \shipout \box 255 }</tt><tt><br>
</tt><tt><br>
</tt><tt>\newcount \xmin</tt><tt><br>
</tt><tt>\newcount \ymin</tt><tt><br>
</tt><tt>\newcount \xmax</tt><tt><br>
</tt><tt>\newcount \ymax</tt><tt><br>
</tt><tt>\newcount \height</tt><tt><br>
</tt><tt>\newcount \width</tt><tt><br>
</tt><tt><br>
</tt><tt>\xmin = 1900</tt><tt><br>
</tt><tt>\ymin = 300</tt><tt><br>
</tt><tt><br>
</tt><tt>\width = 700</tt><tt><br>
</tt><tt>\height = 70</tt><tt><br>
</tt><tt><br>
</tt><tt>\xmax = \numexpr \xmin + \width \relax</tt><tt><br>
</tt><tt>\ymax = \numexpr \ymin + \height \relax</tt><tt><br>
</tt><tt><br>
</tt><tt>\setbox 0 = \vbox {\XeTeXpdffile Example-image-3.pdf }</tt><tt><br>
</tt><tt>\setbox 0 = \hbox to \width bp {\kern - \xmin bp \box 0
\hss}</tt><tt><br>
</tt><tt>\setbox 0 = \vbox to \height bp {\kern \dimexpr \ymax bp
- (\ht 0 + \dp 0) \box 0 \vss}</tt><tt><br>
</tt><tt><br>
</tt><tt>\setbox 0 = \hbox</tt><tt><br>
</tt><tt> \bgroup</tt><tt><br>
</tt><tt> \special {x:gsave}</tt><tt><br>
</tt><tt> \special {pdf:literal 0 0 \number \width \space
\number \height \space re W n }</tt><tt><br>
</tt><tt> \box 0</tt><tt><br>
</tt><tt> \special {x:grestore}</tt><tt><br>
</tt><tt> \egroup</tt><tt><br>
</tt><tt><br>
</tt><tt>\topglue 1 cm</tt><tt><br>
</tt><tt>\leavevmode \box 0</tt><tt><br>
</tt><tt><br>
</tt><tt>\end</tt><tt><br>
</tt></blockquote>
Just over 40 lines in total. The file that I was seeking to clip,
renamed as Example-image-3.pdf, is attached. It is 100 cm wide by
20 cm tall (plus bleed and trim marks), or about 2800 x 600 bp, so I
would normally want to express \xmin, \ymin, ..., \width in cm
rather than in bp, as is implied in the code above, but that would
just be syntactic sugar so I leave the code as I initially wrote
it. Note that my code does not correctly handle non-zero box depths
as it stands.<br>
<br>
My sincere thanks to David Carlisle for his suggestion which led to
my being able to develop this code.<br>
-- <br>
<i>Philip Taylor</i><br>
<tt></tt>
</body>
</html>