Bug 687430

Summary: Wrong transformation matrix with Form XObjects
Product: Ghostscript Reporter: SaGS <sags5495>
Component: PDF WriterAssignee: Igor Melichev <igor.melichev>
Status: NOTIFIED FIXED    
Severity: normal    
Priority: P2    
Version: master   
Hardware: PC   
OS: All   
Customer: Word Size: ---
Attachments: Proposed patch.

Description SaGS 2004-04-18 12:47:41 UTC
There are several problems with a Form XObject's /Matrix entry 
created by pdfmark_BP() and with the cm command written to PDF by 
pdfmark_SP(), which lead to Form XObjects being scaled and placed 
incorrectly. For a sample file, see the one attached to bug 687429 
"Form XObject's /BBox may contain reals in exponential format".

(1)
The parameters for the cm command written by pdfmark_SP() are 
wrong. With the sample file, even if the user space is not modified 
at /SP time relative to the user space at /BP time (as is the case 
for the first /SP), the Form XObjects are mirrored, scaled and 
placed incorrectly.

(2)
Currently, pdfmark_SP() should output a cm command that corresponds 
to the transformation between the user space in effect when the 
Form XObject is created (/BP) and the user space in effect when 
the Form XObject is rendered (/SP). For example, if the user space 
did not change the corect command is "1 0 0 1 0 0 cm"; if between 
/BP and /SP there is a "2 2 scale", the command is "2 0 0 2 0 0 cm" 
(to display the Form XObject twice as big). However, pdfmark_SP() 
does not have enough information to compute this transformation, 
because at /SP time there is no trace of the user space that was 
in effect at /BP time.

(3)
Previous problem could be solved by pdfmark_BP() storing the 
inverse of its CTM. However, the Form XObject itself would still 
be incorrect. Per the PDF Reference, its /Matrix entry must 
transform the form space to user space. With GhostScript, the 
form space == device space, and /Matrix is always the identity, 
so it transforms to device space, not user space. Even if 
pdfmark_SP() could compensate for this by concatenating the 
inverse CTM (eventualy) stored by pdfmark_BP() with its own CTM, 
the Form XObject will still display incorrectly if used in places 
other than /SP pdfmarks, for example as an annotation appearance.

The proposed patch solves these problems by changing pdfmark_BP() 
to set /Matrix to the inverse of CTM, and pdfmark_SP() to use its 
CTM for generating the cm command.

Note:
A better solution would be to set form space == user space and 
/Matrix to the identity transform. This (a) eliminates some 
rounding errors and (b) works even if the CTM at /BP time cannot 
be inverted (not really usefull...), but I suppose this requires 
extensive changes to current code.
Comment 1 SaGS 2004-04-18 12:52:07 UTC
Created attachment 627 [details]
Proposed patch.

Assumes the patch for bug 687429 has already been applied.
Comment 2 Igor Melichev 2004-05-26 01:46:48 UTC
Thank you for the patch suggested.
It has been committed with a minor adoptation as
http://www.ghostscript.com/pipermail/gs-cvs/2004-May/004502.html
Comment 3 SaGS 2004-07-05 10:23:26 UTC
I reopen this bug because a typo in the adopted patch makes current 
version (8.30) exhibit similar simptoms as the version before this 
patch did. With the original test file, the Form XObjects end up 
being placed off-page.

pprintg6() called from pdfamrk_BP() receives the X translation 
component of the inverted CTM twice. The second occurence should 
be replaced with the Y translation component of that matrix.
Comment 5 Igor Melichev 2004-07-13 05:05:38 UTC
Dear SaGS,

Let me know your real name if you want it to appear in gs/doc/History*.htm and 
possibly in other documents.