From ystok-systema at rambler.ru Wed Dec 3 04:09:00 2014 From: ystok-systema at rambler.ru (Dmitry Ivanov) Date: Wed, 3 Dec 2014 07:09:00 +0300 Subject: [Cl-pdf-devel] pdf-geom improvements Message-ID: <000001d00eae$e5e4a650$8100a8c0@digo> 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