chiark / gitweb /
Added then function NEW-SUB-PATH and some ,inor API changes
[clg] / cairo / cairo.lisp
1 ;; Common Lisp bindings for Cairo
2 ;; Copyright 2005 Espen S. Johnsen <espen@users.sf.net>
3 ;;
4 ;; Permission is hereby granted, free of charge, to any person obtaining
5 ;; a copy of this software and associated documentation files (the
6 ;; "Software"), to deal in the Software without restriction, including
7 ;; without limitation the rights to use, copy, modify, merge, publish,
8 ;; distribute, sublicense, and/or sell copies of the Software, and to
9 ;; permit persons to whom the Software is furnished to do so, subject to
10 ;; the following conditions:
11 ;;
12 ;; The above copyright notice and this permission notice shall be
13 ;; included in all copies or substantial portions of the Software.
14 ;;
15 ;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 ;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 ;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 ;; IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 ;; CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 ;; TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 ;; SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
23 ;; $Id: cairo.lisp,v 1.7 2006-12-24 14:28:20 espen Exp $
24
25 (in-package "CAIRO")
26
27 (eval-when (:compile-toplevel :load-toplevel :execute)
28   (define-enum-type surface-format :argb32 :rgb24 :a8 :a1)
29
30   (define-enum-type status
31     :success :no-memory :invalid-restore :invalid-pop-group
32     :no-current-point :invalid-matrix :invalid-status :null-pointer
33     :invalid-string :invalid-path-data :read-error :write-error
34     :surface-finished :surface-type-mismatch :pattern-type-mismatch
35     :invalid-content :invalid-format :invalid-visual :file-not-found
36     :invalid-dash)
37
38   (define-enum-type fill-rule :winding :even-odd)
39   (define-enum-type line-cap :butt :round :square)
40   (define-enum-type line-join :miter :round :bevel)    
41   (define-enum-type font-slant :normal :itaic :oblique)
42   (define-enum-type font-weight :normal :bold)
43
44   (define-enum-type operator
45    :clear :source :over :in :out :atop :dest :dest-over 
46    :dest-in :dest-out :dest-atop :xor :add :saturate)
47
48   (define-enum-type antialias :default :none :gray :subpixel)
49   (define-enum-type extend :none :repeat :reflect)
50   (define-enum-type filter :fast :good :best :nearest :bilinear :gaussian)
51   (define-enum-type subpixel-order :default :rgb :bgr :vrgb :vbgr)
52   (define-enum-type hint-style :default :none :slight :medium :full)
53   (define-enum-type hint-metrics :default :off :on)
54
55   (defclass glyph (struct)
56     ((index 
57       :allocation :alien 
58       :initarg :index 
59       :accessor glyph-index 
60       :type unsigned-long)
61      (x     
62       :allocation :alien 
63       :initarg :x 
64       :accessor glyph-x 
65       :type double-float)
66      (y     
67       :allocation :alien 
68       :initarg :y 
69       :accessor glyph-y
70       :type double-float))
71     (:metaclass struct-class))
72
73   (defclass font-face (proxy)
74     ()
75     (:metaclass proxy-class)
76     (:ref %font-face-reference)
77     (:unref %font-face-destroy))
78
79   (defclass font-options (proxy)
80     ((antialias
81       :allocation :virtual 
82       :getter "font_options_get_antialias"
83       :setter "font_options_set_antialias"
84       :accessor font-options-antialias
85       :type antialias)
86      (subpixel-order
87       :allocation :virtual 
88       :getter "font_options_get_subpixel_order"
89       :setter "font_options_set_subpixel_order"
90       :accessor font-options-subpixel-order
91       :type subpixel-order)
92      (hint-style
93       :allocation :virtual 
94       :getter "font_options_get_hint_style"
95       :setter "font_options_set_hint_style"
96       :accessor font-options-hint-style
97       :type hint-style)
98      (hint-metrics
99       :allocation :virtual 
100       :getter "font_options_get_hint_metrics"
101       :setter "font_options_set_hint_metrics"
102       :accessor font-options-hint-metrics
103       :type hint-metrics))
104     (:metaclass proxy-class)    
105     (:ref %font-options-reference)
106     (:unref %font-options-destroy))
107
108   (defclass scaled-font (proxy)
109     ()
110     (:metaclass proxy-class)
111     (:ref %scaled-font-reference)
112     (:unref %scaled-font-destroy))
113
114   (defclass matrix (struct)
115     ((xx :allocation :alien :initarg :xx :initform 1.0
116          :accessor matrix-xx :type double-float)
117      (yx :allocation :alien  :initarg :yx :initform 0.0
118          :accessor matrix-yx :type double-float)
119      (xy :allocation :alien  :initarg :xy :initform 1.0
120          :accessor matrix-xy :type double-float)
121      (yy :allocation :alien  :initarg :yy :initform 0.0
122          :accessor matrix-yy :type double-float)
123      (x0 :allocation :alien  :initarg :x0 :initform 0.0
124          :accessor matrix-x0 :type double-float)
125      (y0 :allocation :alien  :initarg :y0 :initform 0.0
126          :accessor matrix-y0 :type double-float))
127     (:metaclass struct-class))
128
129
130   (defclass text-extents (struct)
131     ((x-bearing :allocation :alien :reader text-extents-x-bearing :type double-float)
132      (y-bearing :allocation :alien :reader text-extents-y-bearing :type double-float)
133      (width :allocation :alien :reader text-extents-width :type double-float)
134      (height :allocation :alien :reader text-extents-height :type double-float)
135      (x-advance :allocation :alien :reader text-extents-x-advance :type double-float)
136      (y-advance :allocation :alien :reader text-extents-y-advance :type double-float))
137     (:metaclass struct-class))
138
139   (defclass pattern (proxy)
140     ((extend
141       :allocation :virtual 
142       :getter "cairo_pattern_get_extend"
143       :setter "cairo_pattern_set_extend"
144       :accessor pattern-extend
145       :type extend)
146      (filter
147       :allocation :virtual 
148       :getter "cairo_pattern_get_filter"
149       :setter "cairo_pattern_set_filter"
150       :accessor pattern-filter
151       :type filter)
152      (matrix
153       :allocation :virtual 
154       :getter "cairo_pattern_get_matrix"
155       :setter "cairo_pattern_set_matrix"
156       :accessor pattern-matrix
157       :type matrix))
158     (:metaclass proxy-class)
159     (:ref %pattern-reference)
160     (:unref %pattern-destroy))
161
162
163   (defclass surface (proxy)
164     ()
165     (:metaclass proxy-class)
166     (:ref %surface-reference)
167     (:unref %surface-destroy))
168
169   (defclass context (proxy)
170     ((target
171       :allocation :virtual 
172       :getter "cairo_get_target"
173       :reader target
174       :type surface)
175      (source
176       :allocation :virtual 
177       :getter "cairo_get_source"
178       :setter "cairo_set_source"
179       :accessor source
180       :type pattern)
181      (antialias
182       :allocation :virtual 
183       :getter "cairo_get_antialias"
184       :setter "cairo_set_antialias"
185       :accessor antialias
186       :type antialias)
187      (tolerance
188       :allocation :virtual 
189       :getter "cairo_get_tolerance"
190       :setter "cairo_set_tolerance"
191       :accessor tolerance
192       :type double-float)
193      (fill-rule
194       :allocation :virtual 
195       :getter "cairo_get_fill_rule"
196       :setter "cairo_set_fill_rule"
197       :accessor fill-rule
198       :type fill-rule)
199      (line-width
200       :allocation :virtual 
201       :getter "cairo_get_line_width"
202       :setter "cairo_set_line_width"
203       :accessor line-width
204       :type double-float)
205      (line-cap
206       :allocation :virtual 
207       :getter "cairo_get_line_cap"
208       :setter "cairo_set_line_cap"
209       :accessor line-cap
210       :type line-cap)
211      (line-join
212       :allocation :virtual 
213       :getter "cairo_get_line_join"
214       :setter "cairo_set_line_join"
215       :accessor line-join
216       :type line-join)
217      (miter-limit
218       :allocation :virtual 
219       :getter "cairo_get_miter_limit"
220       :setter "cairo_set_miter_limit"
221       :accessor miter-limit
222       :type double-float)
223      (font-matrix
224       :allocation :virtual 
225       :getter "cairo_get_font_matrix"
226       :setter "cairo_set_font_matrix"
227       :accessor font-matrix
228       :type matrix)
229      (font-options
230       :allocation :virtual 
231       :getter "cairo_get_font_options"
232       :setter "cairo_set_font_options"
233       :accessor font-options
234       :type font-options)
235      (font-face
236       :allocation :virtual 
237       :getter "cairo_get_font_face"
238       :setter "cairo_set_font_face"
239       :accessor font-face
240       :type font-face)
241      (operator
242       :allocation :virtual 
243       :getter "cairo_get_operator"
244       :setter "cairo_set_operator"
245       :accessor operator
246       :type operator)
247      (matrix
248       :allocation :virtual 
249       :getter matrix
250       :setter "cairo_set_matrix"
251       :writer (setf matrix)
252       :type matrix)
253      )
254     (:metaclass proxy-class)
255     (:ref %reference)
256     (:unref %destroy))
257
258   (defclass image-surface (surface)
259     ((width
260       :allocation :virtual 
261       :getter "cairo_image_surface_get_width"
262       :reader surface-width
263       :type int)
264      (height
265       :allocation :virtual 
266       :getter "cairo_image_surface_get_height"
267       :reader surface-height
268       :type int))
269     (:metaclass proxy-class)
270     (:ref %surface-reference)
271     (:unref %surface-destroy))
272
273
274 ;;   (defclass path (proxy)
275 ;;     ()
276 ;;     (:metaclass proxy-class))
277
278 )
279
280
281 ;;; Cairo context
282
283 (defbinding %reference () nil
284   (location pointer))
285
286 (defbinding %destroy () nil
287   (location pointer))
288
289 (defbinding (save-context "cairo_save") () nil
290   (cr context))
291
292 (defbinding (restore-context "cairo_restore") () nil
293   (cr context))
294
295 (defmacro with-context ((cr) &body body)
296   (let ((context (make-symbol "CONTEXT")))
297     `(let ((,context ,cr))
298        (save-context ,context)
299        (unwind-protect
300            (progn ,@body)
301          (restore-context ,context)))))
302
303 (defbinding status () status
304   (cr context))
305
306 (defun ensure-color-component (component)
307   (etypecase component
308     (float component)
309     (integer (/ component 256.0))))
310
311 (defbinding (set-source-color "cairo_set_source_rgba") (cr red green blue &optional (alpha 1.0)) nil
312   (cr context)
313   ((ensure-color-component red) double-float)
314   ((ensure-color-component green) double-float)
315   ((ensure-color-component blue) double-float)
316   ((ensure-color-component alpha) double-float))
317
318 (defbinding set-source-surface () nil
319   (cr context)
320   (surface surface)
321   (x double-float)
322   (y double-float))
323
324 (defbinding set-dash (cr dashes &optional (offset 0.0)) nil
325   (cr context)
326   (dashes (vector double-float))
327   ((length dashes) int)
328   (offset double-float))
329
330 (defbinding (paint "cairo_paint_with_alpha") (cr &optional (alpha 1.0)) nil
331   (cr context)
332   (alpha double-float))
333
334 (defbinding mask () nil
335   (cr context)
336   (pattern pattern))
337
338 (defbinding mask-surface () nil
339   (cr context)
340   (surface surface)
341   (surface-x double-float)
342   (surface-y double-float))
343
344 (defmacro defoperator (name &optional clip-p)
345   (let ((iname (intern (format nil "%~A" name)))
346         (pname (intern (format nil "%~A-PRESERVE" name))))
347     `(progn
348        (defbinding ,iname () nil
349          (cr context))
350        (defbinding ,pname () nil
351          (cr context))
352        (defun ,name (cr &optional preserve)
353          (if preserve
354              (,pname cr)
355            (,iname cr)))
356        ,(unless clip-p
357           (let ((tname (intern (format nil "IN-~A-P" name)))
358                 (ename (intern (format nil "~A-EXTENTS" name))))
359             `(progn
360                (defbinding ,tname () boolean
361                  (cr context)
362                  (x double-float)
363                  (y double-float))
364                (defbinding ,ename () boolean
365                  (cr context)
366                  (x1 double-float :out)
367                  (y1 double-float :out)
368                  (x2 double-float :out)
369                  (y2 double-float :out))))))))
370
371 (defoperator clip t)
372 (defoperator stroke)
373 (defoperator fill)
374
375 (defbinding reset-clip () nil
376   (cr context))
377
378 (defbinding copy-page () nil
379   (cr context))
380
381 (defbinding show-page () nil
382   (cr context))
383
384
385 ;;; Paths
386
387 (defbinding get-current-point () nil
388   (cr context)
389   (x double-float :out)
390   (y double-float :out))
391
392 (defbinding new-path () nil
393   (cr context))
394
395 #?(pkg-exists-p "cairo" :atleast-version "1.2")
396 (defbinding new-sub-path () nil
397   (cr context))
398
399 (defbinding close-path () nil
400   (cr context))
401
402 (defbinding arc () nil
403   (cr context)
404   (xc double-float)
405   (yc double-float)
406   (radius double-float)
407   (angle1 double-float)
408   (angle2 double-float))
409
410 (defbinding arc-negative () nil
411   (cr context)
412   (xc double-float)
413   (yc double-float)
414   (radius double-float)
415   (angle1 double-float)
416   (angle2 double-float))
417
418 (defun circle (cr x y radius)
419   (arc cr x y radius 0.0 (* pi 2)))
420
421 (defmacro defpath (name &rest args)
422   (let ((relname (intern (format nil "REL-~A" name))))
423     `(progn
424        (defbinding ,name () nil
425          (cr context)
426          ,@args)
427        (defbinding ,relname () nil
428          (cr context)
429          ,@args))))
430
431 (defpath curve-to
432   (x1 double-float)
433   (y1 double-float)
434   (x2 double-float)
435   (y2 double-float)
436   (x3 double-float)
437   (y3 double-float))
438
439 (defpath line-to
440   (x double-float)
441   (y double-float))
442
443 (defpath move-to
444   (x double-float)
445   (y double-float))
446
447 (defbinding rectangle () nil
448   (cr context)
449   (x double-float)
450   (y double-float)
451   (width double-float)
452   (height double-float))
453
454 (defbinding glyph-path (cr glyphs) nil
455   (cr context)
456   (glyphs (vector glyph))
457   ((length glyphs) int))
458
459 (defbinding text-path () nil
460   (cr context)
461   (text string))
462
463
464
465 ;;; Patterns
466
467 (defbinding (pattern-add-color-stop "cairo_pattern_add_color_stop_rgba")
468     (pattern offset red green blue &optional (alpha 1.0)) nil
469   (pattern pattern)
470   (offset double-float)
471   (red double-float)
472   (green double-float)
473   (blue double-float)
474   (alpha double-float))
475
476 (defbinding (pattern-create "cairo_pattern_create_rgba")
477     (red green blue &optional (alpha 1.0)) pattern   
478   (red double-float)
479   (green double-float)
480   (blue double-float)
481   (alpha double-float))
482
483 (defbinding pattern-create-for-surface () pattern
484   (surface surface))
485
486 (defbinding pattern-create-linear () pattern
487   (x0 double-float)
488   (y0 double-float)
489   (x1 double-float)
490   (y1 double-float))
491
492 (defbinding pattern-create-radial () pattern
493   (cx0 double-float)
494   (cy0 double-float)
495   (radius0 double-float)
496   (cx1 double-float)
497   (cy1 double-float)
498   (radius1 double-float))
499
500 (defbinding %pattern-reference () nil
501   (location pointer))
502
503 (defbinding %pattern-destroy () nil
504   (location pointer))
505
506 (defbinding pattern-status () status
507   (pattern pattern))
508
509
510
511 ;;; Transformations
512
513 (defbinding translate () nil
514   (cr context)
515   (tx double-float)
516   (ty double-float))
517
518 (defbinding scale () nil
519   (cr context)
520   (sx double-float)
521   (sy double-float))
522
523 (defbinding rotate () nil
524   (cr context)
525   (angle double-float))
526
527 (defbinding transform () nil
528   (cr context)
529   (matrix matrix))
530
531 (defbinding (matrix "cairo_get_matrix") () nil
532   (cr context)
533   ((make-instance 'matrix) matrix :in/return))
534
535 (defbinding identity-matrix () nil
536   (cr context))
537
538 (defbinding user-to-device () nil
539   (cr context)
540   (x double-float :in/out)
541   (y double-float :in/out))
542
543 (defbinding user-to-device-distance (cr dx &optional (dy 0.0)) nil
544   (cr context)
545   (dx double-float :in/out)
546   (dy double-float :in/out))
547
548 (defbinding device-to-user () nil
549   (cr context)
550   (x double-float :in/out)
551   (y double-float :in/out))
552
553 (defbinding device-to-user-distance (cr dx &optional (dy 0.0)) nil
554   (cr context)
555   (dx double-float :in/out)
556   (dy double-float :in/out))
557
558
559 ;;; Text
560
561 (defbinding select-font-face () nil
562   (cr context)
563   (family string)
564   (slant font-slant)
565   (weight font-weight))
566
567 (defbinding set-font-size () nil
568   (cr context)
569   (size double-float))
570
571 (defbinding show-text () nil
572   (cr context)
573   (text string))
574
575 (defbinding show-glyphs () nil
576   (cr context)
577   (glyphs (vector glyph))
578   ((length glyphs) int))
579
580 (defbinding font-extents () boolean
581   (cr context))
582
583 (defbinding text-extents (cr text &optional (extents (make-instance 'text-extents))) nil
584   (cr context)
585   (text string)
586   (extents text-extents :in/return))
587
588 (defbinding glyph-extents (cr glyphs &optional (extents (make-instance 'text-extents))) nil
589   (cr context)
590   (glyphs (vector glyph))
591   ((length glyphs) int)
592   (extents text-extents :in/return))
593
594
595 ;;; Fonts
596
597 (defbinding %font-face-reference () nil
598   (location pointer))
599
600 (defbinding %font-face-destroy () nil
601   (location pointer))
602
603 (defbinding font-face-status () status
604   (font-face font-face))
605
606
607
608 ;;; Scaled Fonts
609
610 (defbinding %scaled-font-reference () nil
611   (location pointer))
612
613 (defbinding %scaled-font-destroy () nil
614   (location pointer))
615
616 (defbinding scaled-font-status () status
617   (scaled-font scaled-font))
618
619 (defbinding scaled-font-extents (scaled-font &optional (extents (make-instance 'text-extents))) nil
620   (scaled-font scaled-font)
621   (extents text-extents :in/return))
622
623 (defbinding scaled-font-glyph-extents (scaled-font glyphs &optional (extents (make-instance 'text-extents))) nil
624   (scaled-font scaled-font)
625   (glyphs (vector glyph))
626   ((length glyphs) int)
627   (extents text-extents :in/return))
628
629 (defbinding %scaled-font-create () pointer
630   (font-face font-face)
631   (font-matrix matrix)
632   (ctm matrix)
633   (options font-options))
634
635 (defmethod allocate-foreign ((scaled-font scaled-font) &key font-face font-matrix cmt options)
636   (%scaled-font-create font-face font-matrix cmt options))
637
638
639
640 ;;; Font Options
641
642
643 (defbinding %font-options-copy () nil
644   (location pointer))
645
646 (defbinding %font-options-destroy () nil
647   (location pointer))
648
649 (defbinding font-options-status () status
650   (font-options font-options))
651
652 (defbinding %font-options-create () pointer)
653
654 (defmethod allocate-foreign ((font-options font-options) &rest initargs)
655   (declare (ignore initargs))
656   (%font-options-create))
657
658 (defbinding font-options-merge () nil
659   (options1 font-options :in/return)
660   (options2 font-options))
661
662 (defbinding font-options-hash () unsigned-int
663   (options font-options))
664
665 (defbinding font-options-equal-p () boolean
666   (options1 font-options)
667   (options2 font-options))
668
669
670
671 ;;; Surfaces
672
673 (defbinding %surface-reference () nil
674   (location pointer))
675
676 (defbinding %surface-destroy () nil
677   (location pointer))
678
679 (defbinding surface-create-similar () surface
680   (other surface)
681   (format surface-format )
682   (width int)
683   (height int))
684
685 (defbinding surface-finish () nil
686   (surface surface))
687
688 (defbinding surface-flush () nil
689   (surface surface))
690
691 (defbinding surface-get-font-options () nil
692   (surface surface)
693   ((make-instance 'font-options) font-options :in/return))
694
695 (defbinding surface-set-device-offset () nil
696   (surface surface)
697   (x-offset double-float)
698   (y-offset double-float))
699
700 (defbinding surface-status () status
701   (surface surface))
702
703 (defbinding %surface-mark-dirty () nil
704   (surface surface))
705
706 (defbinding %surface-mark-dirty-rectangle () nil
707   (surface surface)
708   (x int)
709   (y int)
710   (width int)
711   (height int))
712
713 (defun surface-mark-dirty (surface &optional x y width height)
714   (if x
715       (%surface-mark-dirty-rectangle surface x y width height)
716     (%surface-mark-dirty surface)))
717
718
719
720 ;; Image Surface
721
722 ;; Should data be automatically freed when the surface is GCed?
723 (defmethod allocate-foreign ((surface image-surface) 
724                              &key width height stride format data)
725   (if (not data)
726       (%image-surface-create format width height)
727     (%image-surface-create-for-data data format width height 
728      (or 
729       stride
730       (let ((element-size (cdr (assoc format '((:argb32 . 4) (:rgb24 . 4) (:a8 . 1) (:a1 1/8))))))
731         (ceiling (* width element-size)))))))
732
733
734 (defbinding %image-surface-create () image-surface
735   (format surface-format)
736   (width int)
737   (hegit int))
738
739 (defbinding %image-surface-create-for-data () image-surface
740   (data pointer)
741   (format surface-format)
742   (width int)
743   (hegit int)
744   (stride int))
745
746
747
748 ;;; PNG Surface
749
750 (defbinding image-surface-create-from-png (filename) image-surface
751   ((truename filename) pathname))
752
753
754
755
756 ;;; Matrices
757
758 (defbinding matrix-init () nil
759   (matrix matrix :in/return)
760   (xx double-float) (yx double-float) 
761   (xy double-float) (yy double-float) 
762   (x0 double-float) (y0 double-float))
763
764 (defbinding matrix-init-identity () nil
765   (matrix matrix :in/return))
766
767 (defbinding matrix-init-translate () nil
768   (matrix matrix :in/return)
769   (tx double-float)
770   (ty double-float))
771
772 (defbinding matrix-init-scale () nil
773   (matrix matrix :in/return)
774   (sx double-float)
775   (sy double-float))
776
777 (defbinding matrix-init-rotate () nil
778   (matrix matrix :in/return)
779   (radians double-float))
780
781 (defbinding matrix-translate () nil
782   (matrix matrix :in/return)
783   (tx double-float)
784   (ty double-float))
785
786 (defbinding matrix-scale () nil
787   (matrix matrix :in/return)
788   (sx double-float)
789   (sy double-float))
790
791 (defbinding matrix-rotate () nil
792   (matrix matrix :in/return)
793   (radians double-float))
794
795 (defbinding matrix-invert () nil
796   (matrix matrix :in/return))
797
798 (defbinding matrix-multiply () nil
799   (result matrix :out)
800   (a matrix)
801   (b matrix))
802
803 (defbinding matrix-transform-distance () nil
804   (matrix matrix :in/return)
805   (dx double-float)
806   (dy double-float))
807
808 (defbinding matrix-transform-point () nil
809   (matrix matrix :in/return)
810   (x double-float)
811   (y double-float))
812
813
814