[Cl-pdf-devel] pdf-geom improvements

Dmitry Ivanov ystok-systema at rambler.ru
Wed Dec 3 04:09:00 UTC 2014


Hello folks,

I have been playing with functions form pdf-geom.lisp lately and found
them surprisingly useful. But let me a few notes.

First, for representing a point internally a two-element list is used. Why
not just cons? I mean (cons x y)  instead of (list x y) and car/cdr instead
of first/second.

This obvious improvement would lead to code to cons smaller. Are there any
external constraints or other reasons for using (list x y)?

Second, can the function fillet return something meaningful? Yes, the code
can be easily rewritten to return the last point we have finished drawing
at.

Third, I suggest adding the round parameter to the rectangle function. In
addition to rounding corners, it helps in specifying what corner or corners
are to be rounded exactly.

This stuff could allow to improve tables in CL-Typesetting further. I am
going to speak about this in another post.

An example of a "rounded" table is available in
http://lisp.ystok.ru/cl-pdf/ex-1251.pdf

My code is as follows.

(defun rectangle (x y dx dy &key (radius 0) (round :all))
;;; Args: dy    Rectangle height, either positive or negative.
  ;;       dx  Rectangle width, cannot be negative if radius is not zero.
  ;;       round ::= :all | designator | (designator1 designator2 ...),
  ;;             where  designator ::= :bottom-left-corner |
:bottom-right-corner
  ;;                                 | :top-right-corner | :top-left-corner
  (if (zerop radius)
      (basic-rect x y dx dy)
      ;; Mimic closed naive polyline
      (loop with first = (cons x y)
            and fourth = (cons x (+ y dy))
            with midpoint = (midpoint first fourth #1=1/2)
            and end
            initially #+debug (assert (plusp dx))
                      (move-to (car midpoint) (cdr midpoint))
            for corner in (if (minusp dy)
                              '(:top-left-corner :top-right-corner
                                :bottom-right-corner :bottom-left-corner)
                              '(:bottom-left-corner :bottom-right-corner
                                :top-right-corner :top-left-corner))
            and (p next) on (list first (cons (+ x dx) y)
                                       (cons (+ x dx) (+ y dy)) fourth
                                  midpoint)
            and start = midpoint then end
            if (or (eq round :all)
                   (if (consp round)
                     (member corner round)
                     (eq corner round)))
            do (setq end (fillet p start next radius))   ; rounded angle
            else do (line-to (car (setq end p)) (cdr p)) ; ordinary angle
            finally (line-to (car midpoint) (cdr midpoint)) )))
--
Sincerely,
Dmitry Ivanov
lisp.ystok.ru





More information about the cl-pdf-devel mailing list