[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