## PodofoImpose

PodofoImpose is a utility program which aims to provide a rather simple way to impose PDF documents. Originally written for my own use, it ended up in PoDoFo release as a show-case (don’t rely too much on it).

### Plan (built-in)

PodofoImpose is driven by a PLAN file. This file describes how pages from a source PDF document have to be relayout into a target document. We’ll describe how this file must be formated.

#### Records

Most of the PLAN file is composed of record lines of the form:
source page; target page; rotation; horizontal translation; vertical translation;
Each element of the record can be a numeric value, a constant or an expression involving both numerics and constants.

#### Constants

Constants can be declared everywhere in the PLAN file except in loops. They are 8 bits char strings (except "=") with a leading "$" character which makes them easy to identify. Their value is always interpreted as a float through std::atof. You can "overload" a constant value by redeclaring it. They are declared in this form:
$MyConstant = 123.456
Note that a PLAN file is valid only if it contains 2 required constants which are "$PageWidth" and "$PageHeight", giving target document dimensions. Now support the "$ScaleFactor" constant -- means that the declared scale factor will be added to the current transformation matrix for each placed page. Constants declarations can hold expressions:
$MyConstant = $AnotherConst * .5;
Source document pages count is provided as "$PageCount". Source first page geometry is provided as "$SourceWidth" and "$SourceHeight", reflecting geometry given by the MediaBox.

#### Expressions

An expression is a set of basic mathematic operations +, -, *,/ and % (operands of modulo will be first rounded). As a convenience, we added the | as "max(a,b)" it’s mainly there to allow user to prevent division by 0.
$ValueA / ( $ValueB | 0.000001 )
Operations are executed from left to right without taking care of any kind of precedance. You can use parenthesis to enclose operations that need to be computed separetly. Example:
123.456 * ( $ConstantA - ( $ConstantB / 3.14 ) )

#### Loops

Loops allow users to programmatically generate records. While the concept itself is familiar to programmers I can imagine that regular users would feel not so easy with it. So let me introduce a simple example to explain the thing.
Let say we have a source document, A4 format, which has 1000 pages and we just want to position each page of the first half of the document on the center of an A3 plate.
A4onA3.plan
$PageWidth=842.6 $PageHeight=1195.2 ## SourceWidth & SourceHeight $sw=597.6 $sh=842.4 $page=1 <$PageCount/2[$page+1] $page; $page; 0; ($PageWidth-$sw)/2; ($PageHeight-$sh)/2; >
The loop is what’s enclosed by "<" and ">"characters, the second just indicates the end of the loop. The first first indicates how many iterations (loops) have to be performed — 500 here. Then comes the interesting part, constants which appear in parenthesis will be incremented by the value following the "+" (can be a minus one, in that case don’t turn the "+" into a "-", just prefix the value with "-" as in [$foo+-1.23]), which means in this example that at each iteration, $page will see its value increased by 1.
Constants (which finally turn into variables ;-)) must be declared before the loop. Many constants can be put in loop declaration, separate them with semicolons.
There is an experimental support of nested loops.

#### Running

Once you’ve wrote the PLAN file you can run the program:
podofoimpose source.pdf target.pdf plan.plan
Note the source can be either a PDF file or a text file which is a listing of PDF files. In this case, listed files will be first merged in order.

### Plan (Lua)

PoDoFoImpose now supports Lua scripted plan files. Note that, mainly for security reasons, only the following modules are loaded: base, table, string, math. If you need more, just add luaopen_* calls to LuaMachina::LuaMachina().

#### Format

Records are pushed with:
PushRecord(source page, target page, rotation, x, y);
As for regular plan files, there are a couple of provided informations through global variables, specifically: "SourceWidth", "SourceHeight", "PageCount". You need to set "PageWidth" and "PageHeight". You may alter the global scale factor (from source to target) by setting "Scale".

#### Running

There is no format detection mechanism, so you need to append "lua" keyword to podofoimpose invocation when you want it to process a Lua script.

### Examples

For Lua scripts, some samples can be found in directory tools/podofoimpose/plans/lua of PoDoFo sources tree.

##### Add a stamp to a document

Shame on me, don’t even have a real stamp at my "office". So I tried something and it worked! Say you have that official one page A4 doc, named official.pdf, on which you want to add a nice stamp. You have your stamp in the file stamp.pdf. You first have to create two files:
pdf.list
official.pdf stamp.pdf
stamponator.plan
$PageWidth=597.6 $PageHeight=842.4 # original page is left unchanged; 1; 1; 0; 0; 0; # positionning stamp is up to you! 2; 1; 0; 350; 100;
Now you can run:
podofoimpose pdf.list stamped-official.pdf stamponator.plan

##### Make a tiled poster

Printing a large graphic onto a set of little paper sheets can be handful. Doing it automatically is even better! Latest changes allow us to provide you with a quasi all-automatic solution. The only thing that you would want to change (apart from debugging) is the output paper size (here ISO-A4, "Europe oblige !").
poster.plan
##POSTER printed on tiled A4 paper sheets. # destination (A4) $PageWidth = 597.6 $PageHeight = 842.4 $sW = $SourceWidth $sH = $SourceHeight # with a little trick to get integers $rows = (($sH / $PageHeight) + 1) % (2 * (($sH / $PageHeight)+1)) $cols = (($sW / $PageWidth) + 1) % (2 * (($sW / $PageWidth )+1)) $hbox = ($sW / ($cols | 1)) $vbox = ($sH/ ($rows | 1)) $hm = ($PageWidth - $hbox ) / 2 $vm = ($PageHeight - $vbox ) / 2 $R = 1 $C = 1 <$rows[$R+1] <$cols[$C+1] 1; (($R - 1)*$cols) + $C; 0; $hm - (($C -1) * $hbox); $vm - (($R-1) * $vbox); > >
podofoimpose poster.pdf poster_tiled.pdf poster.plan
Etc.