Pages

Tuesday, August 23, 2011

How to Develop a Cairo Clock using Common Lisp and GTK+

A Short Introduction

In my last project based on Lisp and GTK+ Toolkit, I need to use some graphics to build a drawing module. Then, the best solution found was the use of cairo libraries to render this kind of graphics. The Cairo API provides anti-aliasing and a simple handling.  However, I didn't find some books or tutorials that show how I could do it. With some searchs at Google, I found a tutorial made by the author of the Cairo bindings for Common Lisp, but the article didn't show an Cairo integration with Gtk+.

Then, in our laboratory, we understood the source code of the Cairo bindings for Lisp and built a solution to implement a application Lisp based, using Gtk+ and Cairo.

If you interested yourself or only want to learn the Common Lisp Language, I suggest the on-line book: "Practical Common Lisp". A suggestions for people who want to start programming Lisp is download, or a Eclipse plug-in called Cusp, or use Emacs running Slime. You can install the essentials packages using the command line,

$ sudo apt-get install emacs23 sbcl slime cl-alexandria cl-asdf cl-babel cl-cffi cl-closer-mop cl-clg cl-trivial-features cl-swank

The source packages of cl-cairo2 can be found at Cliki cl-cairo2 project. The installation is so easy, you need to extract the source and paste it in ~/.sbcl/site/. After create the symbolic links of all .asd,

$ ln -s ~/.sbcl/site/YOUR_CAIRO_FOLDER/*.asd ~/.sbcl/systems

Now, you're ready to start developing common lisp, gtk+ and cairo applications.


Developing Lisp Apps using Cairo and Gtk+

First you need to import the libraries using Asdf,

(asdf:load-system :cl-gtk2-gtk)
(asdf:load-system :cl-cairo2)
(asdf:load-system :cl-cairo2-x11)

The assignment of cairo context can be made with,

...
(let ((cr (make-instance 'cl-cairo2:context
                     :pointer cr-p
                     :width draw-w
                     :height draw-h
                     :pixel-based-p t)))
             (setq cl-cairo2:*context* cr)
             (cl-cairo2:rectangle 0 0 500 500 cr)
             (cl-cairo2:clip cr)
             (draw-clock cr)))))
...

The function that draws the cairo clock is,

;; Function to create the clock from a Cairo context
(defun draw-clock (context)
   (setq radius 180)
   (cl-cairo2:set-source-rgb 1 1 1 context)
   (cl-cairo2:arc (/ draw-h 2) (/ draw-w 2) (/ radius 2) 0 (* 2 pi) context)
   (cl-cairo2:fill-path context)
   (cl-cairo2:set-source-rgb 0 0 0 context)
   (cl-cairo2:arc (/ draw-h 2) (/ draw-w 2) (/ radius 2) 0 (* 2 pi) context)
   (cl-cairo2:stroke context)

   ;; 0 to 11 hours
   (loop for i from 1 to 12 do
          ...
   )
)

Then, we finished an example of using Cairo and Gtk on Lisp.
You can download the source code here: cairoclock.lisp


No comments:

Post a Comment