root/trunk/thirdparty/cl-gd-0.5.6/strings.lisp

Revision 2428, 10.2 kB (checked in by hhubner, 1 year ago)

Update cl-gd.

Line 
1 ;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: CL-GD; Base: 10 -*-
2 ;;; $Header: /usr/local/cvsrep/gd/strings.lisp,v 1.23 2007/04/24 09:01:39 edi Exp $
3
4 ;;; Copyright (c) 2003-2007, Dr. Edmund Weitz.  All rights reserved.
5
6 ;;; Redistribution and use in source and binary forms, with or without
7 ;;; modification, are permitted provided that the following conditions
8 ;;; are met:
9
10 ;;;   * Redistributions of source code must retain the above copyright
11 ;;;     notice, this list of conditions and the following disclaimer.
12
13 ;;;   * Redistributions in binary form must reproduce the above
14 ;;;     copyright notice, this list of conditions and the following
15 ;;;     disclaimer in the documentation and/or other materials
16 ;;;     provided with the distribution.
17
18 ;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
19 ;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 ;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 ;;; ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
22 ;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 ;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
24 ;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 ;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 ;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 ;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 ;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30 (in-package :cl-gd)
31
32 (defmacro with-default-font ((font) &body body)
33   "Execute BODY with *DEFAULT-FONT* bound to FONT so that you
34 don't have to provide the FONT keyword/optional argument to
35 string functions. But note that the fonts used for
36 DRAW-STRING/DRAW-CHARACTER and DRAW-FREETYPE-STRING are
37 incompatible."
38   `(let ((*default-font* ,font))
39     ,@body))
40
41 (defun draw-character (x y char &key up (font *default-font*) (color *default-color*) (image *default-image*))
42   "Draws the character CHAR from font FONT in color COLOR at position
43 \(X,Y). If UP is true the character will be drawn from bottom to top
44 \(rotated 90 degrees). FONT must be one of :TINY, :SMALL, :MEDIUM,
45 :LARGE, :GIANT."
46   (check-type char character)
47   (check-type image image)
48   (with-color-argument
49     (with-transformed-alternative
50         ((x x-transformer)
51          (y y-transformer))
52       (if up
53         (gd-image-char-up (img image) (ecase font
54                                         ((:tiny) +gd-font-tiny+)
55                                         ((:small) +gd-font-small+)
56                                         ((:medium :medium-bold) +gd-font-medium-bold+)
57                                         ((:large) +gd-font-large+)
58                                         ((:giant) +gd-font-giant+))
59                           x y (char-code char) color)
60         (gd-image-char (img image) (ecase font
61                                      ((:tiny) +gd-font-tiny+)
62                                      ((:small) +gd-font-small+)
63                                      ((:medium :medium-bold) +gd-font-medium-bold+)
64                                      ((:large) +gd-font-large+)
65                                      ((:giant) +gd-font-giant+))
66                        x y (char-code char) color))))
67   char)
68
69 (defun draw-string (x y string &key up (font *default-font*) (color *default-color*) (image *default-image*))
70   "Draws the string STRING in color COLOR at position \(X,Y). If UP is
71 true the character will be drawn from bottom to top \(rotated 90
72 degrees). FONT must be one of :TINY, :SMALL, :MEDIUM, :LARGE, :GIANT."
73   (check-type string string)
74   (check-type image image)
75   (with-color-argument
76     (with-transformed-alternative
77         ((x x-transformer)
78          (y y-transformer))
79       (with-cstring (c-string string)
80         (if up
81           (gd-image-string-up (img image) (ecase font
82                                             ((:tiny) +gd-font-tiny+)
83                                             ((:small) +gd-font-small+)
84                                             ((:medium :medium-bold) +gd-font-medium-bold+)
85                                             ((:large) +gd-font-large+)
86                                             ((:giant) +gd-font-giant+))
87                               x y c-string color)
88           (gd-image-string (img image) (ecase font
89                                          ((:tiny) +gd-font-tiny+)
90                                          ((:small) +gd-font-small+)
91                                          ((:medium :medium-bold) +gd-font-medium-bold+)
92                                          ((:large) +gd-font-large+)
93                                          ((:giant) +gd-font-giant+))
94                            x y c-string color)))))
95   string)
96
97 (defun draw-freetype-string (x y string
98                              &key (anti-aliased t)
99                                   (point-size 12.0d0)
100                                   (angle 0.0d0)
101                                   (convert-chars t)
102                                   line-spacing
103                                   (font-name *default-font*)
104                                   do-not-draw
105                                   (color *default-color*)
106                                   (image *default-image*))
107   "Draws the string STRING in color COLOR at position \(X,Y) using the
108 FreeType library. FONT-NAME is the full path \(a pathname or a string)
109 to a TrueType font file, or a font face name if the GDFONTPATH
110 environment variable or FreeType's DEFAULT_FONTPATH variable have been
111 set intelligently. The string may be arbitrarily scaled \(POINT-SIZE)
112 and rotated \(ANGLE in radians). The direction of rotation is
113 counter-clockwise, with 0 radians \(0 degrees) at 3 o'clock and PI/2
114 radians \(90 degrees) at 12 o'clock. Note that the ANGLE argument is
115 purposefully _not_ affected by WITH-TRANSFORMATION. If ANTI-ALIASED if
116 false, anti-aliasing is disabled. It is enabled by default. To output
117 multiline text with a specific line spacing, provide a value for
118 LINE-SPACING, expressed as a multiple of the font height. The default
119 is to use 1.05. The string may contain XML character entity references
120 like \"À\". If CONVERT-CHARS is true \(which is the default)
121 characters of STRING with CHAR-CODE greater than 127 are converted
122 accordingly. This of course pre-supposes that your Lisp's CHAR-CODE
123 function returns ISO/IEC 10646 (Unicode) character codes.
124
125 The return value is an array containing 8 elements representing the 4
126 corner coordinates \(lower left, lower right, upper right, upper left)
127 of the bounding rectangle around the string that was drawn. The points
128 are relative to the text regardless of the angle, so \"upper left\"
129 means in the top left-hand corner seeing the text horizontally. Set
130 DO-NOT-DRAW to true to get the bounding rectangle without
131 rendering. This is a relatively cheap operation if followed by a
132 rendering of the same string, because of the caching of the partial
133 rendering during bounding rectangle calculation."
134   (check-type string string)
135   (check-type font-name (or pathname string))
136   (unless do-not-draw
137     (check-type color integer)
138     (check-type image image))
139   (with-transformed-alternative
140       ((x x-transformer)
141        (y y-transformer)
142        ((deref-array c-bounding-rectangle '(:array :int) i) x-inv-transformer)
143        ((deref-array c-bounding-rectangle '(:array :int) (1+ i)) y-inv-transformer))
144     (when do-not-draw
145       (setq color 0
146             image *null-image*))
147     (when (pathnamep font-name)
148       (setq font-name (namestring font-name)))
149     (when convert-chars
150       (setq string (convert-to-char-references string)))
151     (with-cstring (c-font-name font-name)
152       (with-cstring (c-string string)
153         (with-safe-alloc (c-bounding-rectangle
154                           (allocate-foreign-object :int 8)
155                           (free-foreign-object c-bounding-rectangle))
156           (let ((msg (convert-from-cstring
157                       (cond (line-spacing
158                              (with-foreign-object (strex 'gd-ft-string-extra)
159                                (setf (get-slot-value strex
160                                                      'gd-ft-string-extra
161                                                      'flags)
162                                      +gd-ftex-linespace+
163                                      (get-slot-value strex
164                                                      'gd-ft-string-extra
165                                                      'line-spacing)
166                                          (coerce line-spacing 'double-float))
167                                (gd-image-string-ft-ex (img image)
168                                                       c-bounding-rectangle
169                                                       (if anti-aliased color (- color))
170                                                       c-font-name
171                                                       (coerce point-size 'double-float)
172                                                       (coerce angle 'double-float)
173                                                       x y
174                                                       c-string
175                                                       strex)))
176                             (t
177                              (gd-image-string-ft (img image)
178                                                  c-bounding-rectangle
179                                                  (if anti-aliased color (- color))
180                                                  c-font-name
181                                                  (coerce point-size 'double-float)
182                                                  (coerce angle 'double-float)
183                                                  x y
184                                                  c-string))))))
185             (when msg
186               (error "Error in FreeType library: ~A" msg))
187             (let ((bounding-rectangle (make-array 8)))
188               ;; strange iteration due to WITH-TRANSFORMED-ALTERNATIVE
189               (loop for i below 8 by 2 do
190                     (setf (aref bounding-rectangle i)
191                           (deref-array c-bounding-rectangle '(:array :int) i))
192                     (setf (aref bounding-rectangle (1+ i))
193                           (deref-array c-bounding-rectangle '(:array :int) (1+ i))))
194               bounding-rectangle)))))))
Note: See TracBrowser for help on using the browser.