summaryrefslogtreecommitdiff
path: root/pdf/pdf.mak
diff options
context:
space:
mode:
authorKen Sharp <ken.sharp@artifex.com>2022-05-14 13:32:48 +0100
committerKen Sharp <ken.sharp@artifex.com>2022-05-14 14:36:38 +0100
commitcf21335a57b279bdd4ee950e20c02ae3dee34996 (patch)
tree24534cd9e4f3b1568fbd0525aa8f4217a9eafa27 /pdf/pdf.mak
parent860d0ca2ed2264ef98503e6a63f800c93dd77fb6 (diff)
downloadghostpdl-cf21335a57b279bdd4ee950e20c02ae3dee34996.tar.gz
GhostPDF - Defer path construction until painting
Bug #705252 "Transformation matrix sometimes not applied with the new PDF interpreter" PDF does not maintain the current path as part of the graphics state; as noted in section 4.4.1 of the 1.7 PDF Reference Manual. As can be seen from this bug report, and previously with grestore, the path segments are accumulated and not transformed from user space to device space until a path-painting operation occurs. This means that all path segments are mapped using the same CTM, not the CTM in force at the time the path construction operator was encountered. In the old PDF interpreter, and previously in GhostPDF, we dealt with this rather painfully by constructing the path as we went and if we came to an operator which might change the CTM (cm or Q) while there was a partial path, we would traverse the path accumulating the path operations and applying the inverse of the CTM to transform the co-ords back to user space, perform the CTM-changing operation, and then run the path again with the new CTM. Obviously that's laborious and somewhat prone to error. So here we completely change the way we deal with paths. We now behave in a manner similar to that which the specification implies for Acrobat; we store the path operations until a path-painting operator occurs, only then do we execute the path construction, transforming the user space co-ordinates to device space. We store the path operations in a simple array; a char representing the operation followed by 0 to 6 doubles depending on the nature of the segment. The array size is increased 4KB at a time when exhausted to try and strike a balance between memory use and performance; we don't want to continually reallocate and copy the accumulated path for each segment. For PDF files which do not rely on this 'feature' of the PDF spec we do end up using slightly more memory but for files which do use it, we use less memory and are slightly faster. In addition the code for the cm and Q operators is simplified, as are other path construction operators. At Chris's suggestion I did look at using a gs_path to store the segments, and then scaling it when it was needed, but looking at the way that we create paths in the graphics library this would have led to considerably more floating point multiplications which would hurt performance as they would be done for all path construction operations. On a historical note; this behaviour of PDF is not documented in the 1.0, 1.1 or 1.2 specifications and in fact those versions of the spec are written in a way which certainly strongly implies that the intention is that paths should behave as they do in PostScript. This 'feature' is introduced without fanfare in the PDF 1.3 spec. I am suspicious that someone discovered that Acrobat had been written in this way, and rather than change the application Adobe chose to quietly change the specification. In passing; noted that a 'M' operation (set miter limit) with an operand of < 1 was causing an error. The old code silently clamped values less than 1 to 1, so we do the same here.
Diffstat (limited to 'pdf/pdf.mak')
-rw-r--r--pdf/pdf.mak2
1 files changed, 1 insertions, 1 deletions
diff --git a/pdf/pdf.mak b/pdf/pdf.mak
index 7040a72e9..118a0b7d5 100644
--- a/pdf/pdf.mak
+++ b/pdf/pdf.mak
@@ -188,7 +188,7 @@ $(PDFOBJ)pdf_stack.$(OBJ): $(PDFSRC)pdf_stack.c $(PDFINCLUDES) $(PDF_MAK) $(MAKE
$(PDFOBJ)pdf_gstate.$(OBJ): $(PDFSRC)pdf_gstate.c $(PDFINCLUDES) $(gsstate_h) \
$(gsmatrix_h) $(gslparam_h) $(gstparam_h) $(gxdht_h) $(gxht_h) $(gzht_h) $(gsht_h) \
- $(gscoord_h) $(gsutil_h) $(gscolor3_h) $(PDF_MAK) $(MAKEDIRS)
+ $(gscoord_h) $(gsutil_h) $(gscolor3_h) $(PDF_MAK) $(MAKEDIRS) $(gzpath_h) $(gspenum_h)
$(PDFCCC) $(PDFSRC)pdf_gstate.c $(PDFO_)pdf_gstate.$(OBJ)
$(PDFOBJ)pdf_colour.$(OBJ): $(PDFSRC)pdf_colour.c $(PDFINCLUDES) \