0

I want to (manually) insert additional postscript commands in a postscript file that was converted from a PDF file via ghostscript’s pdf2ps. For the purpose of testing I created a PDF file from the following file using pdflatex:

\documentclass[a4paper]{article}
\begin{document}
Mostly empty.
\end{document}

In the converted postscript file I make the following edit:

...
%%Page: 1 1
%%PageBoundingBox: 0 0 595 841
%%BeginPageSetup
4 0 obj
<</Type/Page/MediaBox [0 0 595.28 841.89]
/Parent 3 0 R
/Resources<</ProcSet[/PDF]
/Font 8 0 R
>>
/Contents 5 0 R
>>
endobj
%%EndPageSetup
% BEGIN MANUAL EDIT
0 setgray 0 0 moveto 595 841 lineto stroke
% END MANUAL EDIT
5 0 obj
<</Length 257>>stream
q 0.1 0 0 0.1 0 0 cm
0 G
0 g
q
10 0 0 10 0 0 cm BT
/R6 9.9626 Tf
1 0 0 1 139.746 706.129 Tm
[(M)-0.699638(os)-0.399443(t)-0.900585(l)-0.798886(y)-333.819(e)-0.400668(m)-0.300195(p)-0.599165(t)26.0974(y)83.192(.)-0.800112]TJ
154.421 -615.691 Td
(1)Tj
ET
Q
Q

endstream
endobj
pagesave restore
%%PageTrailer
%%Trailer
end
%%EOF

Instead of producing a diagonal line the postscipt/PDF file remains (seemingly) unchanged. However, if I alter the page dimensions from A4 to letter size the line is shown:

%%Page: 1 1
%%PageBoundingBox: 0 0 612 792
%%BeginPageSetup
4 0 obj
<</Type/Page/MediaBox [0 0 612 792]
...

I am obviously missing something here (which is not surprising given my rudimentary knowledge of postscript). My question is: How can I make the line appear while keeping the page dimensions unchanged?

P.S.: A comment I stumbled across mentioned that pdftops (from poppler-utils) is in some sense superior to pdf2ps. Indeed, inserting commands into the converted postscript file immediately before the showpage command (which is not there at all when using pdf2ps) worked fine. So I have probably already found a solution to my problem. However, I would like to learn what the page dimensions have to do with it when using pdf2ps.


Solution

Thanks to KenS’s advice and referring to his answer to this question I was able to achieve the desired effect by adding an EndPage procedure to the postscript file:

<<
/EndPage
{
  exch pop 2 lt
  {
    gsave
    0 0 translate
    0 setgray 0 0 moveto 596 842 lineto stroke
    grestore
    true
  }{false} ifelse
} bind
>> setpagedevice

(This assumes the page size is a4.)

spirossi
  • 353
  • 2
  • 7

1 Answers1

2

PostScript is a write-only language :-)

Seriously, its a programming language. In order to understand what's going on, you need to understand the program, which in the case of the output from Ghostscript's ps2write device, is distinctly non-trivial.

The syntax is basically PDF, with a prolog program which interprets it in PostScript terms.

The program will use showpage, it does it when the procedure EndStream is executed, which is (basically) when the endobj keyword is encoutnered in a page stream. You'll see that it looks like:

ET
Q
Q
Q

endstream
endobj
%%Page: 2 2

You could place anything you like between the endstream and the endobj, but you need to be aware that the graphics state at that point is determined by whatever operations have already taken place. This can include scaling, oration, skeing, flipping the vertical axis, etc. So simply inserting some PostScript into there is unlikely to work. You could do an initgraphics which would at least reset the graphics state to a known setup.

As a test I ran Ghostscript'sd ps2write device like this:

gs -sDEVICE=pdfwrite -o out.ps -c "showpage" -f

which produces a PostScript program where the (effective) content is:

%%EndResource
%%EndProlog
%%Page: 1 1
%%PageBoundingBox: 0 0 595 842
%%BeginPageSetup
4 0 obj
<</Type/Page/MediaBox [0 0 595 842]
/Parent 3 0 R
/Resources<</ProcSet[/PDF]
>>
/Contents 5 0 R
>>
endobj
%%EndPageSetup
5 0 obj
<</Length 23>>stream
q 0.1 0 0 0.1 0 0 cm
Q

endstream
endobj
%%Trailer
end
%%EOF

I then modified this more or less as you suggested:

%%EndPageSetup
0 setgray 0 0 moveto 595 842 lineto stroke
5 0 obj
<</Length 23>>stream
q 0.1 0 0 0.1 0 0 cm
Q

endstream
endobj
%%Trailer

For me this produced the expected stroke from bottom left to top right. Obviously without the PostScript file you originally produced I can't tell you why your experience is different. (no I'm not in a position to run latex to produce such a thing, and even if I did I have no way to know which version of Ghostscript and the other tools you used).

My guess would be that 'something' in your PDF file overwrote the entire page, its not entirely uncommon.

KenS
  • 30,202
  • 3
  • 34
  • 51
  • Thanks! I tried to understand what’s going on by looking up how the commands (q, Q, g, G, Td, ...) in the page descriptions are defined (I also added it to my original post). At least one of them (`/Td{translate 0 0 moveto}bind def`) indeed translates the coordinate system. I also noticed that when commenting the object (`5 0 obj` to `endobj`) the line is drawn, but the effective page size seems to be of letter size instead of a4. So it seems your guess is right and unless I can figure where to tap into the non-trivial code I’m out of luck (using pdf2ps, that is). :-/ – spirossi Feb 25 '19 at 08:43
  • 1
    As I said, you could stick an 'initgraphics' into the code after the endstream before the endobj. But there are more ways to alter the output, than simply editing the file, depending on exactly what you are trying to acheive. You could, for example, supply a BeginPage or EndPage procedure. If that works for you you don't have to edit the file, and it will work on any level 2 or better PostScript printer too (basically anything except a museum exhibit). – KenS Feb 25 '19 at 12:06
  • initgraphics did not make a difference. But the pointer to the BeginPage/EndPage procedure is exactly what I was looking for: In the end I would like to put a barcode on every page of a (externally supplied) PDF file; I attempted to boil it down to a more basic problem in my original question. I probably should have mentioned my ultimate goal ... Thank you very much for guiding me to the solution! (I will mark your answer as solution and add it to my post.) – spirossi Feb 25 '19 at 20:02