如何将两个PDF页面拼接成一个大页面?
How to stitch two PDF pages together as one big page?
我有两张 36" x 48" 的海报 (LaTeX),我想将它们添加到一张 72" x 48" 的海报中(垂直堆叠)。
浏览 SO 和 GS 文档,我没有任何线索(我不是 CLI 向导)。我该怎么做?
(此外,该过程不应有损地压缩光栅图像,因为这将以 2400*1200 DPI 打印。)
由于 OP 没有提供(link)原始输入海报,这个答案将分三个步骤进行:
- 创建 2 张虚拟海报作为第 3 步的输入
- 创建一个嵌入 2 个虚拟海报的 LaTeX 文档
- 运行
pdflatex
从步骤 2 中的 LaTeX 文档创建 PDF
第 1 步:创建 2 张虚拟海报(尺寸为 36in x 48in
)
我创建了两个不同的 PDF 虚拟海报,向您展示如何使用 LaTeX 来实现。 (这意味着:您至少需要在系统上安装基本的 LaTeX,包括 pdflatex
实用程序。)
这两个假人是我在 Ghostscript 的帮助下创建的。因为对于 Ghostscript 的 pdfwrite
设备 1in == 72pt == 720pixels
,命令是这样的(因为 36in == 2592pt == 25920pixels
和 48in == 3456pt == 34560pixels
):
gs -o poster1.pdf \
-g25920x34560 \
-sDEVICE=pdfwrite \
-c " /Helvetica-Bold findfont" \
-c " 500 scalefont" \
-c " setfont" \
-c " 50 2000 moveto" \
-c " (POSTER 1) show" \
-c " 1 0 0 setrgbcolor" \
-c " 10 setlinewidth" \
-c " 20 20 2552 3416 rectstroke" \
-c " showpage"
gs -o poster2.pdf \
-g25920x34560 \
-sDEVICE=pdfwrite \
-c " /Helvetica-Bold findfont" \
-c " 600 scalefont" \
-c " setfont" \
-c " 50 2000 moveto" \
-c " (Poster 1) show" \
-c " 1 0 0 setrgbcolor" \
-c " 10 setlinewidth" \
-c " 20 20 2552 3416 rectstroke" \
-c " showpage"
这里有 2 个屏幕截图显示了这些 "posters":
第 2 步:创建一个 LaTeX 小程序 运行 和 pdflatex
有一个名为 'pdfpages' 的 LaTeX 软件包,它可以将 PDF 页面插入到 LaTeX 文档中,但也可以从 PDF 页面创建 "n-up" 布局。 (除了基本的 LaTeX 安装之外,您还需要该软件包。)
这是一个您可以使用的小型 LaTeX 程序。另存为 2up-poster.tex
:
\documentclass{article}
\usepackage{pdfpages}
\usepackage[paperwidth=72in, paperheight=48in]{geometry}
\pagestyle{plain} % Don't use page numbers
\begin{document}
\setlength\voffset{+0.0in} % adj. vert. offset as needed
\setlength\hoffset{+0.0in} % adj. horiz. offset as needed
\includepdfmerge[nup=2x1,
noautoscale=true, % set "false" if larger inputs
frame=false, % set "true" for frames
templatesize={36in}{48in}] % adjust as needed
{poster1.pdf,poster2.pdf} % modify for file names
\end{document}
第 3 步:运行pdflatex
现在您可以运行以下命令来创建您的合成海报:
pdflatex 2up-poster.tex
这将创建一个名为 2up-poster.pdf
的 PDF 文件。
结果截图如下:
这个 Ghostscript 程序(取自 this answer)做 PDF 页面拼接(a.k.a。拼版)。
我是这样使用的:
gs -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -sFile=twopage.pdf -sOutputFile=onepage.pdf imposition.ps
不需要 LaTeX 工具链——只需要 gs
解释器。
%!PS
% Copyright (C) 2011 Artifex Software, Inc. All rights reserved.
%
% This software is provided AS-IS with no warranty, either express or
% implied.
%
% This software is distributed under license and may not be copied,
% modified or distributed except as expressly authorized under the terms
% of the license contained in the file LICENSE in this distribution.
%
% For more information about licensing, please refer to
% http://www.ghostscript.com/licensing/. For information on
% commercial licensing, go to http://www.artifex.com/licensing/ or
% contact Artifex Software, Inc., 101 Lucas Valley Road #110,
% San Rafael, CA 94903, U.S.A., +1(415)492-9861.
%
% Make a PDF file '2-up'
% This program deliberately does NOT attempt to preserve metadata
% such as DEST links, bookmarks and so forth as these will be
% mostly incorrect after imposition.
%
% usage: gs -dNODISPLAY -sFile=____.pdf [-dVerbose] 2-up.ps
%
% Make, and open, a working dictionary to store stuff
%
/PDF_2UPDict 20 dict dup begin def
%
% Check the parameters to see they are present and of the correct type
%
/Usage {
( usage: gs -dNODISPLAY -q -sFile=____.pdf [-dVerbose] 2-up.ps\n) =
flush
quit
} bind def
/File where not {
(\n *** Missing source file. \(use -sFile=____.pdf\)\n) =
Usage
} {
pop
}ifelse
/Verbose where not {
/Verbose false def
}{
pop /Verbose true def
} ifelse
%%
%% This code is copied from pdf_main.ps, pdfshowpage_finish
%% sadly that routine always calls showpage, and we want that
%% to be under our control, so we have to duplicate the code
%% here. Not only that but it uses GS extensions which aren't
%% available outside of startup, so some things it simply can't
%% replicate. As a result some of the error handling is less
%% good.
%%
%% I plan to extend the PDF interpreter with two new
%% routines, pdfnoshowpage_finish and then have both
%% that and pdfshowpage_finish call pdfoptionalshowpage_finish
%% which will take a boolean determining whether to actually
%% call the showpage. At that time we'll alter this code.
%%
/draw_page_content { % <pagedict> pdfshowpage_finish -
save /PDFSave exch store
/PDFdictstackcount countdictstack store
/PDFexecstackcount count 2 sub store
(before exec) VMDEBUG
% set up color space substitution (this must be inside the page save)
pdfshowpage_setcspacesub
% Display the actual page contents.
8 dict begin
/BXlevel 0 def
/BMClevel 0 def
/OFFlevels 0 dict def
/BGDefault currentblackgeneration def
/UCRDefault currentundercolorremoval def
%****** DOESN'T HANDLE COLOR TRANSFER YET ******
/TRDefault currenttransfer def
matrix currentmatrix
2 dict
dictbeginpage setmatrix
/DefaultQstate qstate store
count 1 sub /pdfemptycount exch store
% If the page uses any transparency features, show it within
% a transparency group.
dup pageusestransparency dup /PDFusingtransparency exch def {
% Show the page within a PDF 1.4 device filter.
0 .pushpdf14devicefilter {
/DefaultQstate qstate store % device has changed -- reset DefaultQstate
% If the page has a Group, enclose contents in transparency group.
% (Adobe Tech Note 5407, sec 9.2)
dup /Group knownoget {
1 index /CropBox pget {
/CropBox exch
} {
1 index get_media_box pop /MediaBox exch
} ifelse
oforce_elems normrect_elems fix_empty_rect_elems 4 array astore .beginformgroup
showpagecontents
.endtransparencygroup
} {
showpagecontents
} ifelse
} stopped {
% abort the transparency device
.abortpdf14devicefilter
/DefaultQstate qstate store % device has changed -- reset DefaultQstate
stop
} if .poppdf14devicefilter
/DefaultQstate qstate store % device has changed -- reset DefaultQstate
} {
showpagecontents
} ifelse
.free_page_resources
% todo: mixing drawing ops outside the device filter could cause
% problems, for example with the pnga device.
end % scratch dict
% Some PDF files don't have matching q/Q (gsave/grestore) so we need
% to clean up any left over dicts from the dictstack
PDFdictstackcount //false
{ countdictstack 2 index le { exit } if
currentdict /n known not or
end
} loop
pop
count PDFexecstackcount sub { pop } repeat
Repaired % pass Repaired state around the restore
PDFSave restore
currentglobal pdfdict gcheck .setglobal
.setglobal
/Repaired exch def
} bind def
%%
%% First we open the PDF file
%%
File dup (r) file runpdfbegin pop
process_trailer_attrs
%%
%% FInd out how many pages are in teh PDF file
%%
/PDFPageCount pdfpagecount def
Verbose {(PageCount is ) print PageCount ==} if
%
% Set up our bookkeeping
%
% First get the size of the page from page 1 of the PDF file
% We assume that all PDF pages are the same size.
%
1 pdfgetpage get_any_box
exch pop dup 2 get exch 3 get
/PDFHeight exch def
/PDFWidth exch def
PDFWidth PDFHeight gt {
/PDFLandscape true def
}{
/PDFLandscape false def
}ifelse
Verbose{
(PDFHeight is ) print PDFHeight ==
(PDFWidth is ) print PDFWidth ==
(PDFLandscape is ) print PDFLandscape ==
} if
%
% Now get the page size of the current device. We will fit
% the PDF pages onto this using rotation and scaling as
% required.
%
currentpagedevice /PageSize get
dup 0 get /PageWidth exch def
1 get /PageHeight exch def
PageWidth PageHeight gt {
/PageLandscape true def
}{
/PageLandscape false def
}ifelse
Verbose{
(PageHeight is ) print PageHeight ==
(PageWidth is ) print PageWidth ==
(PageLandscape is ) print PageLandscape ==
} if
%
% Now figure out how best to fit the pages 2-up
%
PageLandscape PDFLandscape and {
%% Both landscape
/ScaleY PageHeight PDFWidth div
/ScaleX PageWidth 2 div PDFHeight div
ScaleX ScaleY lt {
/Scale ScaleX def
} {
/Scale ScaleY def
}ifelse
/Rotate 90
/OriginYTx PDFHeight neg def
/OriginXTx 0 def
/PageYTx PDFHeight def
/PageXTx 0 def
}{
PageLandscape {
%% Page is landscape, PDF is portrait
/ScaleY PageHeight PDFHeight div def
/ScaleX PageWidth 2 div PDFWidth div def
ScaleX ScaleY lt {
/Scale ScaleX def
} {
/Scale ScaleY def
}ifelse
/Rotate 0 def
/OriginXTx 0 def
/OriginYTx 0 def
/PageXTx PDFWidth def
/PageYTx 0 def
}{
PDFLandscape {
%% PDF is landscape, Page is portrait
/ScaleY PageHeight 2 div PDFHeight div def
/ScaleX PageWidth PDFWidth div def
ScaleX ScaleY lt {
/Scale ScaleX def
} {
/Scale ScaleY def
}ifelse
/Rotate 0 def
/OriginXTx 0 def
/OriginYTy PDFHeight def
/PageXTx 0 def
/PageYTx PDFHeight neg def
} {
%% Both portrait
/ScaleY PageHeight 2 div PDFWidth div def
/ScaleX PageWidth PDFHeight div def
ScaleX ScaleY lt {
/Scale ScaleX def
} {
/Scale ScaleY def
}ifelse
/Rotate 90 def
/OriginXTx 0 def
/OriginYTx PDFHeight neg def
/PageYTx 0 def
/PageXTx PDFWidth def
} ifelse
}ifelse
} ifelse
Verbose{
(ScaleX is ) print ScaleX ==
(ScaleY is ) print ScaleY ==
(Scale is ) print Scale ==
(Rotate is ) print Rotate ==
(OriginXTx is ) print OriginXTx ==
(OriginYTx is ) print OriginYTx ==
(PageXTx is ) print PageXTx ==
(PageYTx is ) print PageYTx ==
} if
%
% Starting at 0, count by 2, and stop at the last page, however
% account for the fact that the number of pages in the PDF
% file may not be even, in which case draw a final empty
%page
%
0 2 PDFPageCount 1 sub PDFPageCount 2 mod add {
%% loop counter
save %% save the state
exch %% exch the save state and the loop counter
Rotate rotate %%
Scale Scale scale %% set up our calculated CTM
OriginXTx OriginYTx translate %%
save %% and save this too
exch %% swap the save state and the loop counter
dup 1 add %% copy the loop counter, then add 1, stack: -save- -save- loop loop+1
Verbose {(Drawing page ) print dup ==} if
0 0 PageWidth PageHeight rectclip %% clip the page contents to the page size (in case of bleeds)
pdfgetpage %% get the page from the PDF file, stack: -save- -save- loop -dict-
dup /Page exch store %% save a copy of the page dict inside itself
pdfshowpage_init %% initialise the page
draw_page_content %% se above, draws the graphical objects, stack -save- -save- loop
exch %% swap back teh save object, stack: -save- loop -save-
restore %% restore back to our calculated CTM
PageXTx PageYTx translate %% Move to draw page 2
2 add dup PDFPageCount gt { %% If we have to draw an extra page, and this is it
Verbose {(Drawing extra page ) print dup ==} if
pop showpage %% pop the spare loop and draw an empty page, stack: -save-
}{
Verbose {(Drawing page ) print dup ==} if
0 0 PageWidth PageHeight rectclip
pdfgetpage
dup /Page exch store
pdfshowpage_init % <pagedict>
draw_page_content
showpage
} ifelse
restore %% restore back to the original CTM
} for
//runpdfend exec %% End the PDF file
end %% our working dictioanry
我有两张 36" x 48" 的海报 (LaTeX),我想将它们添加到一张 72" x 48" 的海报中(垂直堆叠)。
浏览 SO 和 GS 文档,我没有任何线索(我不是 CLI 向导)。我该怎么做?
(此外,该过程不应有损地压缩光栅图像,因为这将以 2400*1200 DPI 打印。)
由于 OP 没有提供(link)原始输入海报,这个答案将分三个步骤进行:
- 创建 2 张虚拟海报作为第 3 步的输入
- 创建一个嵌入 2 个虚拟海报的 LaTeX 文档
- 运行
pdflatex
从步骤 2 中的 LaTeX 文档创建 PDF
第 1 步:创建 2 张虚拟海报(尺寸为 36in x 48in
)
我创建了两个不同的 PDF 虚拟海报,向您展示如何使用 LaTeX 来实现。 (这意味着:您至少需要在系统上安装基本的 LaTeX,包括 pdflatex
实用程序。)
这两个假人是我在 Ghostscript 的帮助下创建的。因为对于 Ghostscript 的 pdfwrite
设备 1in == 72pt == 720pixels
,命令是这样的(因为 36in == 2592pt == 25920pixels
和 48in == 3456pt == 34560pixels
):
gs -o poster1.pdf \
-g25920x34560 \
-sDEVICE=pdfwrite \
-c " /Helvetica-Bold findfont" \
-c " 500 scalefont" \
-c " setfont" \
-c " 50 2000 moveto" \
-c " (POSTER 1) show" \
-c " 1 0 0 setrgbcolor" \
-c " 10 setlinewidth" \
-c " 20 20 2552 3416 rectstroke" \
-c " showpage"
gs -o poster2.pdf \
-g25920x34560 \
-sDEVICE=pdfwrite \
-c " /Helvetica-Bold findfont" \
-c " 600 scalefont" \
-c " setfont" \
-c " 50 2000 moveto" \
-c " (Poster 1) show" \
-c " 1 0 0 setrgbcolor" \
-c " 10 setlinewidth" \
-c " 20 20 2552 3416 rectstroke" \
-c " showpage"
这里有 2 个屏幕截图显示了这些 "posters":
第 2 步:创建一个 LaTeX 小程序 运行 和 pdflatex
有一个名为 'pdfpages' 的 LaTeX 软件包,它可以将 PDF 页面插入到 LaTeX 文档中,但也可以从 PDF 页面创建 "n-up" 布局。 (除了基本的 LaTeX 安装之外,您还需要该软件包。)
这是一个您可以使用的小型 LaTeX 程序。另存为 2up-poster.tex
:
\documentclass{article}
\usepackage{pdfpages}
\usepackage[paperwidth=72in, paperheight=48in]{geometry}
\pagestyle{plain} % Don't use page numbers
\begin{document}
\setlength\voffset{+0.0in} % adj. vert. offset as needed
\setlength\hoffset{+0.0in} % adj. horiz. offset as needed
\includepdfmerge[nup=2x1,
noautoscale=true, % set "false" if larger inputs
frame=false, % set "true" for frames
templatesize={36in}{48in}] % adjust as needed
{poster1.pdf,poster2.pdf} % modify for file names
\end{document}
第 3 步:运行pdflatex
现在您可以运行以下命令来创建您的合成海报:
pdflatex 2up-poster.tex
这将创建一个名为 2up-poster.pdf
的 PDF 文件。
结果截图如下:
这个 Ghostscript 程序(取自 this answer)做 PDF 页面拼接(a.k.a。拼版)。
我是这样使用的:
gs -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -sFile=twopage.pdf -sOutputFile=onepage.pdf imposition.ps
不需要 LaTeX 工具链——只需要 gs
解释器。
%!PS
% Copyright (C) 2011 Artifex Software, Inc. All rights reserved.
%
% This software is provided AS-IS with no warranty, either express or
% implied.
%
% This software is distributed under license and may not be copied,
% modified or distributed except as expressly authorized under the terms
% of the license contained in the file LICENSE in this distribution.
%
% For more information about licensing, please refer to
% http://www.ghostscript.com/licensing/. For information on
% commercial licensing, go to http://www.artifex.com/licensing/ or
% contact Artifex Software, Inc., 101 Lucas Valley Road #110,
% San Rafael, CA 94903, U.S.A., +1(415)492-9861.
%
% Make a PDF file '2-up'
% This program deliberately does NOT attempt to preserve metadata
% such as DEST links, bookmarks and so forth as these will be
% mostly incorrect after imposition.
%
% usage: gs -dNODISPLAY -sFile=____.pdf [-dVerbose] 2-up.ps
%
% Make, and open, a working dictionary to store stuff
%
/PDF_2UPDict 20 dict dup begin def
%
% Check the parameters to see they are present and of the correct type
%
/Usage {
( usage: gs -dNODISPLAY -q -sFile=____.pdf [-dVerbose] 2-up.ps\n) =
flush
quit
} bind def
/File where not {
(\n *** Missing source file. \(use -sFile=____.pdf\)\n) =
Usage
} {
pop
}ifelse
/Verbose where not {
/Verbose false def
}{
pop /Verbose true def
} ifelse
%%
%% This code is copied from pdf_main.ps, pdfshowpage_finish
%% sadly that routine always calls showpage, and we want that
%% to be under our control, so we have to duplicate the code
%% here. Not only that but it uses GS extensions which aren't
%% available outside of startup, so some things it simply can't
%% replicate. As a result some of the error handling is less
%% good.
%%
%% I plan to extend the PDF interpreter with two new
%% routines, pdfnoshowpage_finish and then have both
%% that and pdfshowpage_finish call pdfoptionalshowpage_finish
%% which will take a boolean determining whether to actually
%% call the showpage. At that time we'll alter this code.
%%
/draw_page_content { % <pagedict> pdfshowpage_finish -
save /PDFSave exch store
/PDFdictstackcount countdictstack store
/PDFexecstackcount count 2 sub store
(before exec) VMDEBUG
% set up color space substitution (this must be inside the page save)
pdfshowpage_setcspacesub
% Display the actual page contents.
8 dict begin
/BXlevel 0 def
/BMClevel 0 def
/OFFlevels 0 dict def
/BGDefault currentblackgeneration def
/UCRDefault currentundercolorremoval def
%****** DOESN'T HANDLE COLOR TRANSFER YET ******
/TRDefault currenttransfer def
matrix currentmatrix
2 dict
dictbeginpage setmatrix
/DefaultQstate qstate store
count 1 sub /pdfemptycount exch store
% If the page uses any transparency features, show it within
% a transparency group.
dup pageusestransparency dup /PDFusingtransparency exch def {
% Show the page within a PDF 1.4 device filter.
0 .pushpdf14devicefilter {
/DefaultQstate qstate store % device has changed -- reset DefaultQstate
% If the page has a Group, enclose contents in transparency group.
% (Adobe Tech Note 5407, sec 9.2)
dup /Group knownoget {
1 index /CropBox pget {
/CropBox exch
} {
1 index get_media_box pop /MediaBox exch
} ifelse
oforce_elems normrect_elems fix_empty_rect_elems 4 array astore .beginformgroup
showpagecontents
.endtransparencygroup
} {
showpagecontents
} ifelse
} stopped {
% abort the transparency device
.abortpdf14devicefilter
/DefaultQstate qstate store % device has changed -- reset DefaultQstate
stop
} if .poppdf14devicefilter
/DefaultQstate qstate store % device has changed -- reset DefaultQstate
} {
showpagecontents
} ifelse
.free_page_resources
% todo: mixing drawing ops outside the device filter could cause
% problems, for example with the pnga device.
end % scratch dict
% Some PDF files don't have matching q/Q (gsave/grestore) so we need
% to clean up any left over dicts from the dictstack
PDFdictstackcount //false
{ countdictstack 2 index le { exit } if
currentdict /n known not or
end
} loop
pop
count PDFexecstackcount sub { pop } repeat
Repaired % pass Repaired state around the restore
PDFSave restore
currentglobal pdfdict gcheck .setglobal
.setglobal
/Repaired exch def
} bind def
%%
%% First we open the PDF file
%%
File dup (r) file runpdfbegin pop
process_trailer_attrs
%%
%% FInd out how many pages are in teh PDF file
%%
/PDFPageCount pdfpagecount def
Verbose {(PageCount is ) print PageCount ==} if
%
% Set up our bookkeeping
%
% First get the size of the page from page 1 of the PDF file
% We assume that all PDF pages are the same size.
%
1 pdfgetpage get_any_box
exch pop dup 2 get exch 3 get
/PDFHeight exch def
/PDFWidth exch def
PDFWidth PDFHeight gt {
/PDFLandscape true def
}{
/PDFLandscape false def
}ifelse
Verbose{
(PDFHeight is ) print PDFHeight ==
(PDFWidth is ) print PDFWidth ==
(PDFLandscape is ) print PDFLandscape ==
} if
%
% Now get the page size of the current device. We will fit
% the PDF pages onto this using rotation and scaling as
% required.
%
currentpagedevice /PageSize get
dup 0 get /PageWidth exch def
1 get /PageHeight exch def
PageWidth PageHeight gt {
/PageLandscape true def
}{
/PageLandscape false def
}ifelse
Verbose{
(PageHeight is ) print PageHeight ==
(PageWidth is ) print PageWidth ==
(PageLandscape is ) print PageLandscape ==
} if
%
% Now figure out how best to fit the pages 2-up
%
PageLandscape PDFLandscape and {
%% Both landscape
/ScaleY PageHeight PDFWidth div
/ScaleX PageWidth 2 div PDFHeight div
ScaleX ScaleY lt {
/Scale ScaleX def
} {
/Scale ScaleY def
}ifelse
/Rotate 90
/OriginYTx PDFHeight neg def
/OriginXTx 0 def
/PageYTx PDFHeight def
/PageXTx 0 def
}{
PageLandscape {
%% Page is landscape, PDF is portrait
/ScaleY PageHeight PDFHeight div def
/ScaleX PageWidth 2 div PDFWidth div def
ScaleX ScaleY lt {
/Scale ScaleX def
} {
/Scale ScaleY def
}ifelse
/Rotate 0 def
/OriginXTx 0 def
/OriginYTx 0 def
/PageXTx PDFWidth def
/PageYTx 0 def
}{
PDFLandscape {
%% PDF is landscape, Page is portrait
/ScaleY PageHeight 2 div PDFHeight div def
/ScaleX PageWidth PDFWidth div def
ScaleX ScaleY lt {
/Scale ScaleX def
} {
/Scale ScaleY def
}ifelse
/Rotate 0 def
/OriginXTx 0 def
/OriginYTy PDFHeight def
/PageXTx 0 def
/PageYTx PDFHeight neg def
} {
%% Both portrait
/ScaleY PageHeight 2 div PDFWidth div def
/ScaleX PageWidth PDFHeight div def
ScaleX ScaleY lt {
/Scale ScaleX def
} {
/Scale ScaleY def
}ifelse
/Rotate 90 def
/OriginXTx 0 def
/OriginYTx PDFHeight neg def
/PageYTx 0 def
/PageXTx PDFWidth def
} ifelse
}ifelse
} ifelse
Verbose{
(ScaleX is ) print ScaleX ==
(ScaleY is ) print ScaleY ==
(Scale is ) print Scale ==
(Rotate is ) print Rotate ==
(OriginXTx is ) print OriginXTx ==
(OriginYTx is ) print OriginYTx ==
(PageXTx is ) print PageXTx ==
(PageYTx is ) print PageYTx ==
} if
%
% Starting at 0, count by 2, and stop at the last page, however
% account for the fact that the number of pages in the PDF
% file may not be even, in which case draw a final empty
%page
%
0 2 PDFPageCount 1 sub PDFPageCount 2 mod add {
%% loop counter
save %% save the state
exch %% exch the save state and the loop counter
Rotate rotate %%
Scale Scale scale %% set up our calculated CTM
OriginXTx OriginYTx translate %%
save %% and save this too
exch %% swap the save state and the loop counter
dup 1 add %% copy the loop counter, then add 1, stack: -save- -save- loop loop+1
Verbose {(Drawing page ) print dup ==} if
0 0 PageWidth PageHeight rectclip %% clip the page contents to the page size (in case of bleeds)
pdfgetpage %% get the page from the PDF file, stack: -save- -save- loop -dict-
dup /Page exch store %% save a copy of the page dict inside itself
pdfshowpage_init %% initialise the page
draw_page_content %% se above, draws the graphical objects, stack -save- -save- loop
exch %% swap back teh save object, stack: -save- loop -save-
restore %% restore back to our calculated CTM
PageXTx PageYTx translate %% Move to draw page 2
2 add dup PDFPageCount gt { %% If we have to draw an extra page, and this is it
Verbose {(Drawing extra page ) print dup ==} if
pop showpage %% pop the spare loop and draw an empty page, stack: -save-
}{
Verbose {(Drawing page ) print dup ==} if
0 0 PageWidth PageHeight rectclip
pdfgetpage
dup /Page exch store
pdfshowpage_init % <pagedict>
draw_page_content
showpage
} ifelse
restore %% restore back to the original CTM
} for
//runpdfend exec %% End the PDF file
end %% our working dictioanry