[cl-pdf-devel] lww 4.3.7. version of cl-pdf can't handle big pdffile
Marc Battyani
marc.battyani at fractalconcept.com
Tue Nov 2 09:09:57 UTC 2004
Chisheng Huang wrote:
> While generating a PDF scatterplot of ~20000 circles, my LWW 4.3.7 went
> belly up:
> Error: An error of type CONDITIONS::SIGNAL-HANDLER-ERROR occured,
arguments : (:
> SIGNAL-CONDITION #<SIMPLE-ERROR 2A6F52FC> :REAL-CONDITION #<SIMPLE-ERROR
2A6F52D
...
> I'm using cl-pdf-2.1 and the PDF::COMPRESS-STRING defined in
> contrib/zlib-lw.lisp. According to the backtrace, it looks like I hit an
> internal upper limit in LWW 4.3.7. To get around the problem, I hacked
> WRITE-OBJECT in pdf.lisp a bit:
Unfortunately, it's a know problem of LWW. Another generally even more
anoying one is the limitation of the strings at 8M. :(
This is a problem when one wants to generate a pdf file in memory (in a web
server for instance)
I've already asked Xanalys about this but feel free to ask too so that they
think it's a popular request.
> (defmethod write-object ((obj pdf-stream) &optional root-level)
> (declare (ignorable root-level))
> (when (and *compress-streams* (not (no-compression obj))
> (> (length (content obj)) *min-size-for-compression*))
> ;; Or put the HANDLER-CASE in COMPRESS-STRING ? - cph 01-Nov-2004
> (let ((compressed (handler-case
> (compress-string (content obj))
> (error ()
> nil))))
> (when compressed
> (setf (content obj) compressed)
> (let ((filter (get-dict-value obj "/Filter")))
> (if filter
> (change-dict-value obj "/Filter" (vector "/FlateDecode" filter))
> (add-dict-value obj "/Filter" "/FlateDecode"))))))
> ;; replaced by the above (WHEN ...). - cph 01-Nov-2004
> #+ignore
> (when (and *compress-streams* (not (no-compression obj))
> (> (length (content obj)) *min-size-for-compression*))
> (setf (content obj) (compress-string (content obj)))
> (let ((filter (get-dict-value obj "/Filter")))
> (if filter
> (change-dict-value obj "/Filter" (vector "/FlateDecode" filter))
> (add-dict-value obj "/Filter" "/FlateDecode"))))
> (call-next-method)
> (write-line "stream" *pdf-stream*)
> #+pdf-binary
> (write-sequence (content obj) *pdf-stream*)
> #-pdf-binary
> (if (stringp (content obj))
> (write-sequence (content obj) *pdf-stream*)
> (loop for c across (content obj) do
> (write-char (code-char c) *pdf-stream*)))
> (write-char #\Newline *pdf-stream*)
> (write-line "endstream" *pdf-stream*))
>
> Maybe this hack will be useful to someones.
Another possibility would be to change the way the coordonates are writen in
the pdf stream. So far I've put 3 digits after the dot but this could be
changed for your application.
The circle function uses besier and there are 6 numbers so the savings can
be significant:
(def-pdf-op bezier-to (x1 y1 x2 y2 x3 y3) "~,3f ~,3f ~,3f ~,3f ~,3f ~,3f
c~%")
Marc
More information about the cl-pdf-devel
mailing list