1 ;;;; sodipodi.scm -- implement Scheme output routines for PostScript
3 ;;;; source file of the GNU LilyPond music typesetter
5 ;;;; (c) 1998--2002 Jan Nieuwenhuizen <janneke@gnu.org>
9 ;;;; * Get mftrace 1.0.12 or newer
11 ;;;; * Get sodipodi-cvs from 2002-11-23 or newer
13 ;;;; * Link/copy mf/out/private-fonts to ~/.sodipodi/private-fonts
17 (debug-enable 'backtrace)
20 (define-module (scm sodipodi))
21 (define this-module (current-module))
30 ;;; Lily output interface --- cleanup and docme
32 ;;; Bare minimum interface for \score { \notes c } }
35 ;;; xx-output-expression
40 ;;; and should intercept:
56 ;;(define-public (sodipodi-output-expression expr port)
57 ;; (display (eval expr this-module) port))
59 (define-public (sodipodi-output-expression expr port)
60 (display (dispatch expr) port))
63 (define (dispatch expr)
64 (let ((keyword (car expr)))
66 ((eq? keyword 'some-func) "")
67 ;;((eq? keyword 'placebox) (dispatch (cadddr expr)))
68 ;;((eq? keyword 'fontify) (dispatch (caddr expr)))
70 (if (module-defined? this-module keyword)
71 (apply (eval keyword this-module) (cdr expr))
74 (string-append "undefined: " (symbol->string keyword) "\n"))
80 (define output-scale 1)
83 (define line-thickness 0.1)
84 (define half-lt (/ line-thickness 2))
89 ((equal? (ly:unit) "mm") (/ 72.0 25.4))
90 ((equal? (ly:unit) "pt") (/ 72.0 72.27))
91 (else (error "unknown unit" (ly:unit)))))
93 ;; alist containing fontname -> fontcommand assoc (both strings)
94 ;;(define font-name-alist '())
99 (define (tagify tag string . attribute-alist)
102 (apply string-append (map (lambda (x) (string-append
104 (symbol->string (car x))
110 string "\n</" tag ">\n"))
113 (define (ascii->string i) (make-string 1 (integer->char i)))
114 (define (ascii->upm-string i)
117 (u2 (+ #x80 (quotient i+1 #x40)))
118 (u3 (+ #x80 (modulo i+1 #x40))))
123 (define (control->list c)
124 (list (car c) (cdr c)))
126 (define (control->string c)
128 (number->string (* output-scale (car c))) ","
129 (number->string (* -1 (* output-scale (cdr c)))) " "))
131 (define (control-flip-y c)
132 (cons (car c) (* -1 (cdr c))))
134 (define (numbers->string l)
136 (number->string (car l))
139 (string-append "," (numbers->string (cdr l))))))
141 (define (svg-bezier l)
142 (let* ((c0 (car (list-tail l 3)))
143 (c123 (list-head l 3)))
145 "M " (control->string c0)
146 "C " (apply string-append (map control->string c123)))))
150 "<?xml version='1.0' standalone='no'?>
151 <!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 20010904//EN'
152 'http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd'
155 xmlns:xlink CDATA #FIXED 'http://www.w3.org/1999/xlink'>
164 sodipodi:version='0.26'
165 xmlns='http://www.w3.org/2000/svg'
166 xmlns:sodipodi='http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd'
167 xmlns:xlink='http://www.w3.org/1999/xlink'
170 sodipodi:docbase='/tmp/'
171 sodipodi:docname='/tmp/x'>
176 <g tranform='translate(50,-250)'>
181 ;; Interface functions
186 (define (beam width slope thick)
189 (z (sqrt (+ (sqr x) (sqr y)))))
192 '(style . "fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-opacity:1;stroke-width:1pt;stroke-linejoin:miter;stroke-linecap:butt;")
193 `(x . ,(number->string (* output-scale half-lt)))
194 `(y . ,(number->string (* output-scale (- half-lt (/ thick 2)))))
195 `(width . ,(number->string (* output-scale width)))
196 `(height . ,(number->string (* output-scale thick)))
197 ;; `(ry . ,(number->string (* output-scale half-lt)))
198 `(ry . ,(number->string line-thickness))
199 `(transform . ,(format #f "matrix(~f,~f,0,1,0,0)"
203 ;; TODO: bezier-ending, see ps.scm
204 (define (bezier-bow l thick)
205 (bezier-sandwich l thick))
207 (define (bezier-sandwich l thick)
208 (let* ((urg (eval l this-module))
209 (first (list-tail urg 4))
210 (second (list-head urg 4)))
213 "style='stroke-width:"
214 (number->string (* output-scale line-thickness)) ";'\n"
222 ;;(tagify "tspan" (format #f "à~2,'0x;" i))
223 (tagify "tspan" (ascii->upm-string i))
225 (format #t "can't display char: ~x\n" i)
230 (string-append "<!-- " s " -->\n"))
232 (define (define-fonts internal-external-name-mag-pairs)
233 (comment (format #f "Fonts used: ~S" internal-external-name-mag-pairs)))
238 (define (filledbox breapth width depth height)
239 (roundfilledbox breapth width depth height line-thickness))
242 "fill:black;stroke:none;font-style:normal;font-weight:normal;text-anchor:start;writing-mode:lr;")
247 ("cmr8" . ,(string-append
249 "font-family:cmr;font-size:8;"))
250 ("feta13" . ,(string-append
252 "font-family:LilyPond-Feta;font-size:13;"))
253 ("feta-nummer10" . ,(string-append
255 "font-family:LilyPond-Feta-nummer;font-size:10;"))
256 ("feta20" . ,(string-append
258 "font-family:LilyPond-Feta;font-size:20;"))
259 ("parmesan20" . ,(string-append
261 "font-family:LilyPond-Parmesan;font-size:20;"))))
263 (define (get-font name-mag-pair)
264 ;; name-mag-pair: (quote ("feta20" . 0.569055118110236))"feta20"(quote ("feta20" . 0.569055118110236))
265 (let ((f (assoc (caadr name-mag-pair) font-alist)))
269 (format #t "font not found: ~s\n" (caadr name-mag-pair))
270 (cdr (assoc "feta20" font-alist))))))
272 (define (fontify name-mag-pair expr)
274 (tagify "text" (dispatch expr) (cons 'style (get-font name-mag-pair)))))
277 (comment "header-end"))
279 (define (header creator generate)
287 (define (lily-def key val)
288 (if (equal? key "lilypondpaperoutputscale")
290 (set! output-scale (* scale-to-unit (string->number val))))
297 (define (placebox x y expr)
298 (tagify "g" (dispatch expr)
303 ;; (number->string (* output-scale x))
304 (number->string (* output-scale (+ system-x x)))
307 ;; (number->string (- 0 (* output-scale y)))
308 (number->string (* output-scale (- system-y y)))
311 (define (roundfilledbox breapth width depth height blot-diameter)
314 '(style . "fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-opacity:1;stroke-width:1pt;stroke-linejoin:miter;stroke-linecap:butt;")
315 `(x . ,(number->string (* output-scale (- 0 breapth))))
316 `(y . ,(number->string (* output-scale (- 0 height))))
317 `(width . ,(number->string (* output-scale (+ breapth width))))
318 `(height . ,(number->string (* output-scale (+ depth height))))
319 ;;`(ry . ,(number->string (* output-scale half-lt)))
320 `(ry . ,(number->string blot-diameter))))
324 ;; TODO: use height, set scaling?
325 (define (start-system width height)
327 ;;"<g tranform='translate(50,-250)'>
328 (set! system-y (+ system-y height))
329 ;;(format #f "<g tranform='translate(0,~1,'~f)'>" y)))
332 (comment "start-system")
333 (comment "URG, transform does not work!")
334 (format #f "<g tranform='translate(0.0,~f)'>\n" (* output-scale y)))))
336 (define (stop-system)
339 (comment "stop-system")
342 (define stop-last-system stop-system)
345 ;; to unicode or not?
349 (apply string-appendb
350 (map (lambda (x) (ascii->upm-string (char->integer x)))
351 (string->list s))))))