September 13th, 2007

Vecto teaser

Here is some demo code from something I'm working on:

(defun random-points (count variation)
  (loop repeat count collect (- variation (random (* variation 2)))))

(defun mo-money (file &key (random-steps 4) (random-variation 10)
                 (width 200)
                 (height 200))
  (let ((points (random-points random-steps random-variation))
        (step (/ width (1+ random-steps))))
    (flet ((graph-path ()
             (move-to 0 0)
             (loop for v in points
                  for y from step by step
                  for x from step by step
                  do (line-to x (+ y v)))
             (line-to width height)))
      (with-canvas (:width width :height height)
        (let ((font (get-font "folion.ttf")))
          (set-rgb-fill 0.9 0.9 0.9)
          (clear-canvas)
          (with-graphics-state
            (translate 10 10)
            (scale 0.8 0.8)
            (set-line-cap :butt)
            (set-line-join :miter)
            (translate 25 25)
            (set-line-width 4)
            ;; Shadow
            (set-rgba-stroke 0.5 0.5 0.5 0.5)
            (graph-path)
            (stroke)
            ;; Graph
            (set-rgb-stroke 0.4 0.5 1.0)
            (translate -1 1)
            (graph-path)
            (stroke))
          ;; Labels
          (set-font font 24)
          (with-graphics-state
            (translate 50 10)
            (set-rgba-fill 0 0 0 0.25)
            (draw-string "$Money")
            (translate -1 1)
            (set-rgb-fill 0.1 0.5 0.3)
            (draw-string "$Money"))
          (with-graphics-state
            (rotate-degrees 90)
            (translate 50 -24)
            (set-rgba-fill 0 0 0 0.25)
            (draw-string "Problems")
            (translate 1 1)
            (set-rgb-fill 0.9 0.3 0.1)
            (draw-string "Problems")))
        (save-png file)))))

Here's the result:

It's basically a PNG-generating cl-pdf-like sugar layer atop cl-vectors, salza-png, and zpb-ttf. Everything's in portable Common Lisp; none of the work is done by external C libraries. I have a bit of work left to do on text support, but it's almost ready for public consumption.