Author: tpapp Date: Thu Jul 12 10:01:08 2007 New Revision: 7
Added: tutorial/test-finalizer.lisp Modified: Makefile cairo.lisp cl-cairo2-swig.lisp cl-cairo2.asd cl-cairo2.i context.lisp package.lisp path.lisp surface.lisp tables.lisp transformations.lisp tutorial/tutorial.tex xlib-context.lisp Log: Code cleanup, also added finalizers
Modified: Makefile ============================================================================== --- Makefile (original) +++ Makefile Thu Jul 12 10:01:08 2007 @@ -1,4 +1,7 @@ -cl-cairo2-swig.lisp: cl-cairo2.i +CAIRO_INCLUDE_DIR=/usr/include/cairo +CAIRO_INCLUDE_FILES=$(wildcard $(CAIRO_INCLUDE_DIR)/*.h) + +cl-cairo2-swig.lisp: cl-cairo2.i $(CAIRO_INCLUDE_FILES) swig -cffi cl-cairo2.i
test-swig.lisp: test.i
Modified: cairo.lisp ============================================================================== --- cairo.lisp (original) +++ cairo.lisp Thu Jul 12 10:01:08 2007 @@ -1,10 +1,12 @@ (in-package :cl-cairo2)
-(define-foreign-library libcairo - (:unix (:or "libcairo.so.2" "libcairo.so")) - (t (:default "libcairo"))) +;; (define-foreign-library libcairo +;; (:unix (:or "libcairo.so.2" "libcairo.so")) +;; (t (:default "libcairo")))
-(use-foreign-library libcairo) +;; (use-foreign-library libcairo) + +(load-foreign-library '(:default "libcairo"))
(defun deg-to-rad (deg) "Convert degrees to radians."
Modified: cl-cairo2-swig.lisp ============================================================================== --- cl-cairo2-swig.lisp (original) +++ cl-cairo2-swig.lisp Thu Jul 12 10:01:08 2007 @@ -2,10 +2,10 @@ (in-package :cl-cairo2)
(defctype my-double :double) -;; (defmethod expand-to-foreign (value (type (eql 'my-double))) -;; `(coerce ,value 'double-float)) -(defmethod translate-to-foreign (value (type (eql 'my-double))) - (coerce value 'double-float)) +(defmethod cffi:expand-to-foreign (value (type (eql 'my-double))) + `(coerce ,value 'double-float)) +;; (defmethod translate-to-foreign (value (type my-double)) +;; (coerce value 'double-float))
;; typedefs: we don't want to create all of them automatically, ;; because typedefs for structures confuse with-foreign-slots @@ -81,9 +81,7 @@
(cl:defconstant CAIRO_VERSION_MINOR 4)
-(cl:defconstant CAIRO_VERSION_MICRO 6) - -(cl:defconstant CAIRO_VERSION_STRING "1.4.6") +(cl:defconstant CAIRO_VERSION_MICRO 10)
(cl:defconstant CAIRO_HAS_SVG_SURFACE 1)
Modified: cl-cairo2.asd ============================================================================== --- cl-cairo2.asd (original) +++ cl-cairo2.asd Thu Jul 12 10:01:08 2007 @@ -1,6 +1,6 @@ (defsystem cl-cairo2 :description "Cairo 1.4 bindings" - :version "0.2" + :version "0.2.1" :author "Tamas K Papp" :license "GPL" :components ((:file "package") @@ -8,10 +8,10 @@ (:file "cl-cairo2-swig" :depends-on ("cairo")) (:file "tables" :depends-on ("cl-cairo2-swig")) (:file "surface" :depends-on ("cairo" "tables" "cl-cairo2-swig")) - (:file "context" :depends-on ("surface" "cl-cairo2-swig")) - (:file "path" :depends-on ("context")) ; "cl-cairo2-swig")) - (:file "text" :depends-on ("context")) ; "cl-cairo2-swig")) - (:file "transformations" :depends-on ("context")) ; "cl-cairo2-swig"))) + (:file "context" :depends-on ("surface" "tables" "cl-cairo2-swig")) + (:file "path" :depends-on ("context")) + (:file "text" :depends-on ("context")) + (:file "transformations" :depends-on ("context")) (:file "xlib-context" :depends-on ("context") :in-order-to ((load-op (feature :unix)) (compile-op (feature :unix)))))
Modified: cl-cairo2.i ============================================================================== --- cl-cairo2.i (original) +++ cl-cairo2.i Thu Jul 12 10:01:08 2007 @@ -1,6 +1,7 @@ %module "cl-cairo2-swig"
%ignore CAIRO_VERSION; +%ignore CAIRO_VERSION_STRING;
%typemap(cin) double "my-double"; /* %typemap(cin) int ":my-int"; */ @@ -9,10 +10,10 @@ (in-package :cl-cairo2)
(defctype my-double :double) -;; (defmethod expand-to-foreign (value (type (eql 'my-double))) -;; `(coerce ,value 'double-float)) -(defmethod translate-to-foreign (value (type (eql 'my-double))) - (coerce value 'double-float)) +(defmethod cffi:expand-to-foreign (value (type (eql 'my-double))) + `(coerce ,value 'double-float)) +;; (defmethod translate-to-foreign (value (type my-double)) +;; (coerce value 'double-float))
;; typedefs: we don't want to create all of them automatically, ;; because typedefs for structures confuse with-foreign-slots
Modified: context.lisp ============================================================================== --- context.lisp (original) +++ context.lisp Thu Jul 12 10:01:08 2007 @@ -29,14 +29,23 @@ (with-surface (surface pointer) (let ((context (make-instance 'context))) (setf (slot-value context 'pointer) (cairo_create pointer)) - ;; !!! error checking + ;; register finalizer + (let ((context-pointer (slot-value context 'pointer))) + (finalize context + #'(lambda () + (cairo_destroy context-pointer)))) + ;; return context context))))
(defmethod destroy ((object context)) (with-slots (pointer) object (when pointer (cairo_destroy pointer) - (setf pointer nil)))) + (setf pointer nil))) + ;; deregister finalizer + (cancel-finalization object)) + +(defgeneric sync (object))
(defmethod sync ((object context)) ;; most contexts don't need syncing @@ -46,7 +55,7 @@ ;;;; default context and convenience macros ;;;;
-(export (defvar *context* nil "default cairo context")) +(defvar *context* nil "default cairo context")
(defmacro with-context ((context pointer) &body body) "Execute body with pointer pointing to context, and check status." @@ -121,7 +130,6 @@ ;;;; simple functions using context ;;;;
-(define-with-default-context save) (define-many-with-default-context (save) (restore)
Modified: package.lisp ============================================================================== --- package.lisp (original) +++ package.lisp Thu Jul 12 10:01:08 2007 @@ -1,5 +1,13 @@ (defpackage :cl-cairo2 (:use :common-lisp :cffi) - (:export deg-to-rad - make-trans-matrix trans-matrix-xx trans-matrix-yx trans-matrix-xy - trans-matrix-yy trans-matrix-x0 trans-matrix-y0 trans-matrix-p)) + (:export ; !!! when the interface + ; stabilizes, remove export's + ; from all other places and + ; list them here + ;; utility functions + deg-to-rad + ;; context + *context* + ;; transformations + make-trans-matrix trans-matrix-xx trans-matrix-yx trans-matrix-xy + trans-matrix-yy trans-matrix-x0 trans-matrix-y0 trans-matrix-p))
Modified: path.lisp ============================================================================== --- path.lisp (original) +++ path.lisp Thu Jul 12 10:01:08 2007 @@ -10,7 +10,6 @@ (line-to x y) (move-to x y) (rectangle x y width height) - (rel-curve-to dx1 dy1 dx2 dy2 dx3 dy3) (rel-move-to dx dy) (rel-curve-to dx1 dy1 dx2 dy2 dx3 dy3) (rel-line-to dx dy)
Modified: surface.lisp ============================================================================== --- surface.lisp (original) +++ surface.lisp Thu Jul 12 10:01:08 2007 @@ -44,12 +44,17 @@ (let ((surface (make-instance 'surface))) (check-surface-pointer-status pointer (setf (slot-value surface 'pointer) pointer) + ;; register finalizer + (finalize surface #'(lambda () (cairo_surface_destroy pointer))) + ;; return surface surface)))
(defmethod destroy ((object surface)) (with-alive-surface (object pointer) (cairo_surface_destroy pointer) - (setf pointer nil))) + (setf pointer nil)) + ;; deregister finalizer + (cancel-finalization object))
;;;; ;;;; Macros to create surfaces (that are written into files) and
Modified: tables.lisp ============================================================================== --- tables.lisp (original) +++ tables.lisp Thu Jul 12 10:01:08 2007 @@ -2,7 +2,8 @@
(defmacro exporting-table (name definition) `(progn - (export (defparameter ,name ,definition)) + (defparameter ,name ,definition) + (export ',name) (dolist (i ,name) ; (export (car i)) (export (cdr i)))))
Modified: transformations.lisp ============================================================================== --- transformations.lisp (original) +++ transformations.lisp Thu Jul 12 10:01:08 2007 @@ -138,7 +138,7 @@ "Define a matrix transformation function with matrix and args, which returns the new matrix." `(export - (defun ,(prepend-intern "trans-matrix-init-" name :replace-dash nil) (matrix ,@args) + (defun ,(prepend-intern "trans-matrix-" name :replace-dash nil) (matrix ,@args) (with-trans-matrix-in-out matrix matrix-pointer (,(prepend-intern "cairo_matrix_" name) matrix-pointer @@ -169,6 +169,3 @@ (with-trans-matrix-in matrix matrix-pointer (with-x-y (cairo_matrix_transform_point matrix-pointer xp yp))))) - - -
Added: tutorial/test-finalizer.lisp ============================================================================== --- (empty file) +++ tutorial/test-finalizer.lisp Thu Jul 12 10:01:08 2007 @@ -0,0 +1,13 @@ +(in-package :cl-cairo2) + +(setf *context* (create-pdf-context "/tmp/foo.pdf" 100 100)) +(move-to 0 0) +(line-to 100 100) +(set-source-rgb 0 0 1) +(stroke) + +;; destroy object, after this, it will be ready to be GC'd +(setf *context* nil) + +;; call GC +#+sbcl (sb-ext:gc)
Modified: tutorial/tutorial.tex ============================================================================== --- tutorial/tutorial.tex (original) +++ tutorial/tutorial.tex Thu Jul 12 10:01:08 2007 @@ -131,9 +131,11 @@ When the context is created from a surface, the reference count of the latter is incremented. You can immediately destroy the surface: it will not be destroyed (ie the file will not be closed) until you -destroy the context. The following code draws a white diagonal line -on a blue background, using a Postscript file -- the result is shown -in Figure~\ref{fig:example}. +destroy the context.\footnote{The file will also be closed if the + wrapper object is garbage collected. However, you should not rely + on this, as calling the garbage collector is not portable.} The +following code draws a white diagonal line on a blue background, using +a Postscript file -- the result is shown in Figure~\ref{fig:example}.
\lstinputlisting[firstline=13,lastline=27]{example.lisp}
Modified: xlib-context.lisp ============================================================================== --- xlib-context.lisp (original) +++ xlib-context.lisp Thu Jul 12 10:01:08 2007 @@ -69,12 +69,19 @@ (setf (slot-value xlc 'pointer) (mem-ref context-pointer :pointer)) (foreign-free xc-pointer) (foreign-free context-pointer) + ;; register finalizer + (let ((xc (slot-value xlc 'xc))) + (finalize xlc + #'(lambda () + (close_xlib_context xc)))) + ;; return object xlc))
(export 'create-xlib-context)
(defmethod destroy ((object xlib-context)) - (close_xlib_context (slot-value object 'xc))) + (close_xlib_context (slot-value object 'xc)) + (cancel-finalization object))
(defmethod sync ((object xlib-context)) (sync_xlib (slot-value object 'xc)))