[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