PDF Text objects ("BT"/ "ET") cannot be nested directly, but they can be nested indirectly, for example if using a Type 3 font who's glyphs do text operations. Current opdfread.ps does not cope with this posibility. At "BT" time, it stores the CTM in "InitialTextMatrix". Unfortunately, a single matrix is shared by all streams, so if the stream for a Type 3 glyph gets executed, and this glyph contains another "BT", "InitialTextMatrix" is overwritten. As a result, the next "Tm" in the outer "BT" will place characters incorrectly, sometimes off page. Note: No amount of "q"/"Q" that may or may not enclose the nested stream will help. Graphics state save/ restore is implemented with PS dict copy; values of composite objects refered from these dicts are shared; so all current and saved graphic states, for all streams, share a single InitialTextMatrix.
Created attachment 3310 [details] Short PostScript file to demonstrate the problem. Steps to reproduce: - Convert attached file using ps2write; - Pass the ps2write output to a PS interpreter. Note the 3rd "@" is missing. By stripping the procset, the remaining part is a PDF that displays correctly in both GS and Adobe Reader.
Created attachment 3311 [details] Suggested patch. opdfread.ps: Bracket substream execution with save/ restore of "InitialTextMatrix"; this makes "InitialTextMatrix" stream-local, and accounts for possible nested "BT"/"ET". Note that saving/ restoring of "InitialTextMatrix" is not related to "q"/ "Q". Since "q"/ "Q" do not appear inside "BT"/"ET", they do not need to care about "InitialTextMatrix".
The problem described above still exists in current HEAD (rev 11680), so I’m going to mark the report as confirmed. The patch above still applies (the file is in Resource\Init\ and not in lib\ anymore, plus there are offsets 4/52/4 lines, but otherwise it’s OK) and fixes the bug.
Adopted this patch as revision 11722 : http://ghostscript.com/pipermail/gs-cvs/2010-September/011740.html Looks good to me, thanks for your work SaGS and I apologise for taking so long to review this.