I pushed out Vecto 1.3.1. New in this version:
Many thanks to Ben Deane for providing a functional fill patch that made adding gradients much easier, and for suggesting the text-to-paths functionality. Thanks also to Jakub Higersberger for showing me how easy gradients could be. (I wound up using a very simple formula straight from the Adobe PDF Reference.)
This uses a simple white-to-transparent gradient:
Here's some code that uses all three new features:
(defun text-paths (file) (with-canvas (:width 400 :height 100) (set-font (get-font "/tmp/font.ttf") 70) (centered-string-paths 200 15 "Hello, world!") (set-line-join :round) (set-line-cap :round) (set-line-width 3) (set-dash-pattern #(0 5) 0) (stroke-to-paths) (set-gradient-fill 0 0 1 0 0 0.5 0 100 1 1 1 1) (fill-path) (save-png file)))
I fell short of exporting and documenting the functional fill option that enabled gradients, because I've run out of time. Maybe next release!
I have a few more pending features that should become part of Vecto soon, including tilty ellipses, arbitrary fill functions (both courtesy of Ben, again), and simple gradient support courtesy of Ramarren. They'll make it even easier to draw really pretty things with Vecto.
Vecto 1.0.2 is out. It depends on the new 1.0.1 release of Salza-PNG to support writing the backing PNG out to a stream instead of to a file. My favorite new and exciting thing, though, is the addition of a clipping path.
There have been some little documentation & code fixes too. (This will be the last release announcement that makes it to Planet Lisp, until there's something really big and new and exciting to announce.)
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.