2

I am working in a routine for crop PDF's and import them into a PDF template. I am using GhostScript, invoked with exec() from a PHP script, and FPDI. All running server-side.

So far, I am able to crop pdf documents with GhostScript using the procedure explained in this post (setting CropBox).

The next step is to crop differently the even and odd pages of a document. So I tried the method explained in this other post in SuperUser site, passing custom PostScript code into -c parameter to GhostScript:

-c "<< /CurrPageNum 1 def /Install { /CurrPageNum CurrPageNum 1 add def 
CurrPageNum 2 mod 1 eq {28 0 translate} {} ifelse } bind  >> setpagedevice"

This method shift odd pages 28 pt, and do none for even pages. So, I tried to modify this, passing CropBox(es) (the %s placeholders are replaced with appropriate coordinates in a sprintf sentence):

-c "<< /CurrPageNum 1 def /Install { /CurrPageNum CurrPageNum 1 add def 
CurrPageNum 2 mod 1 eq {[/CropBox [%s %s %s %s]} {[/CropBox [%s %s %s %s]} 
ifelse } bind  >> setpagedevice"

Here is the full command executed over a 4-page pdf file:

"C:\Program Files (x86)\gs\gs9.07\bin\gswin32c.exe" -sDEVICE=pdfwrite 
-o C:\inetpub\wwwroot\ledrail\tmp\output.pdf 
-c "<< /CurrPageNum 1 def /Install { /CurrPageNum CurrPageNum 1 add def 
CurrPageNum 2 mod 1 eq {[/CropBox [119.04 168.336 505.92 715.428]}
{[/CropBox [59.52 84.168 505.92 715.428]} ifelse } bind >> setpagedevice"
-f C:\inetpub\wwwroot\ledrail\documentacio\pdf\documentacio_15.pdf

Ovbiously, I get an error, because [/CropBox... is not valid PS code.

Error: /typecheck in --.postinstall--

EDIT for clarify:

So, my question is: how can I pass the equivalent to two CropBox(es) -for odd and even pages- to the PostScript code shown above? Or, there is another method for achieve this with GhostScript from command line?

Obviously, I know CropBox is not PostScript valid code, but what are alternatives?

Community
  • 1
  • 1
Laura
  • 193
  • 12

2 Answers2

1

You can't set a 'CropBox' in PostScript, because CropBox isn't part of the PostScript language, its PDF-specific.

You need to send a /PAGE pdfmark with a /CropBox, as the first post you reference says. You don't set a /Install.

KenS
  • 30,202
  • 3
  • 34
  • 51
  • I I have omitted to focus on my question. Of course, when I said I could establish a CropBox, I was using: `"C:\Program Files (x86)\gs\gs9.07\bin\gswin32c.exe" -sDEVICE=pdfwrite -o C:\inetpub\wwwroot\ledrail\tmp\output.pdf -c "[/CropBox[89.28 126.252 505.92 715.428] /PAGES pdfmark" -f C:\inetpub\wwwroot\ledrail\documentacio\pdf\documentacio_15.pdf` – Laura May 23 '15 at 18:54
  • You need a /PAGE pdfmark not a /PAGES pdfmark. The PAGES one affects *all* pages – KenS May 23 '15 at 19:11
  • Thanks, KenS. So, there is any other way -using GhostScript- to determine a range of pages, apart from `-f` and `-l` parameters -which determine consecutive pages? And in the command from my last comment, which page would apply `/PAGE` ? – Laura May 23 '15 at 19:30
  • 1
    -f is simply the end of PostScript input (on the command line). You need to combine your two approaches. You need a /EndPage procedure (which *does* get passed to setpagedevice) and that procedure needs to call the pdfmark. The EndPage procedure gets called with 2 value son the stack, one of them is the number of pages emitted so far. So you cna use that to determine which values to set for the pdfmark. See a previous answer here : http://stackoverflow.com/questions/26985557/how-do-i-resize-a-pdf-to-be-exactly-8-5-x-11-inches-using-ghostscript/26989410#26989410 – KenS May 23 '15 at 20:59
  • 1
    `-c "<> setpagedevice"` Well, that filally worked !!! If I understand the logic correctly (with the aid of PLRM ed.3), the outer `ifelse` tests (0 eq) for `showpage` execution; and the inner `ifelse` (2 mod 0 eq) tests for odd/even pages, supplying the corresponding CropBox when `setpagedevice` is called. – Laura May 24 '15 at 15:56
  • @Laura: If you found a *completely working* solution, you should also post it as an answer (even if it is to your own question)! – Kurt Pfeifle May 24 '15 at 16:37
1

GhostScript can process PostScript files and PostScript commands passed through -c parameter at command line. So, for achieve things non trivial, you should understand at least the basics of this language.

Get the relevant documentation fom the sources: PostScript Language Reference Manual, 3rd ed. and the PostScript Language Tutorial and Cookbook if you have not seen PostScript in your life (as is mi case).

KenS pointed me:

You need a /EndPage procedure (which does get passed to setpagedevice) and that procedure needs to call the pdfmark.

The docs states that EndPage is

A procedure to be executed at the end of each page. Before calling the procedure, the interpreter pushes two integers on the operand stack—a count of previous showpage executions for this device and a reason code indicating the circumstances under which this call is being made:

0 - During showpage or (LanguageLevel 3) copypage

1 - During copypage (LanguageLevel 2 only)

2 - At device deactivation

The procedure must return a boolean value specifying whether to transmit the page image to the physical output device.

So, this fragment of code (from KenS' previous answer)

<</EndPage {0 eq {[/CropBox [0 0 612 792] /PAGE pdfmark true}{false}ifelse}>> setpagedevice

passes a CropBox for current page -with coordinates specified- everytime EndPage is invoked with reason 0 (showpage) and returns true. Otherwise, nothing is done and returns false. This reason code is the first item in operands stack, and after it is "consumed" in operation 0 eq {true block}{false block} ifelse (is equal to 0?), there is no more in the stack.

So, the next value in the stack is the number of pages processed. We expand the code with another ifelse inside the true part of code shown above:

{2 mod 0 eq {[/CropBox [0 0 612 792] /PAGE pdfmark true} 
{[/CropBox [50 0 612 792] /PAGE pdfmark true} ifelse}

This performs modulus between current page (at top of stack) and 2, then tests if equals 0 (i.e. tests for odd/even page). If even (modulus = 0) passes the first CropBox, else the second, and returns true in both cases.

So, the full piece of PostScript code:

"<</EndPage {0 eq {2 mod 0 eq {[/CropBox [0 0 612 792] /PAGE pdfmark true}
{[/CropBox [50 0 612 792] /PAGE pdfmark true} ifelse}{false}ifelse}>> setpagedevice"

when passed in GhostScript as -c parameter allow us to crop differently even and odd pages of a PDF document, i.e. if we want to supress the extra space for binding of original.

Community
  • 1
  • 1
Laura
  • 193
  • 12