]> git.donarmstrong.com Git - lilypond.git/blob - scm/output-ps.scm
* lily/stencil-scheme.cc (LY_DEFINE): ly:stencil-in-color
[lilypond.git] / scm / output-ps.scm
1 ;;;; output-ps.scm -- implement Scheme output interface for PostScript
2 ;;;;
3 ;;;;  source file of the GNU LilyPond music typesetter
4 ;;;; 
5 ;;;; (c) 1998--2005 Jan Nieuwenhuizen <janneke@gnu.org>
6 ;;;;                 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7
8 ;;;; Note: currently misused as testbed for titles with markup, see
9 ;;;;       input/test/title-markup.ly
10 ;;;; 
11 ;;;; TODO:
12 ;;;;   * %% Papersize in (header ...)
13 ;;;;   * text setting, kerning.
14 ;;;;   * document output-interface
15
16 (define-module (scm output-ps)
17   #:re-export (quote)
18
19   ;; JUNK this -- see lily.scm: ly:all-output-backend-commands
20   #:export (unknown
21             blank
22             circle
23             dot
24             white-dot
25             beam
26             dashed-slur
27             char
28             setcolor
29             resetcolor
30             named-glyph
31             dashed-line
32             zigzag-line
33             comment
34             repeat-slash
35             placebox
36             bezier-sandwich
37             embedded-ps
38             filledbox
39             round-filled-box
40             text
41             white-text
42             polygon
43             draw-line
44             no-origin))
45
46
47 (use-modules (guile)
48              (ice-9 regex)
49              (srfi srfi-1)
50              (srfi srfi-13)
51              (scm framework-ps)
52              (lily))
53
54
55 ;;(map export
56 ;;   (append (ly:all-stencil-expressions) (ly:all-output-backend-commands)))
57
58 ;; huh?
59 ;;(write (ly:all-output-backend-commands))
60 ;;(write (ly:all-stencil-expressions))
61
62 ;;; helper functions, not part of output interface
63 (define (escape-parentheses s)
64   (regexp-substitute/global #f "(^|[^\\])([\\(\\)])" s 'pre 1 "\\" 2 'post))
65
66 (define (ps-encoding text)
67   (escape-parentheses text))
68
69 ;; FIXME: lily-def
70 (define-public (ps-string-def prefix key val)
71   (string-append "/" prefix (symbol->string key) " ("
72                  (escape-parentheses val)
73                  ") def\n"))
74
75
76 (define (ps-number-def prefix key val)
77   (let ((s (if (integer? val)
78                (ly:number->string val)
79                (ly:number->string (exact->inexact val)))))
80     (string-append "/" prefix (symbol->string key) " " s " def\n")))
81
82
83 ;;;
84 ;;; Lily output interface, PostScript implementation --- cleanup and docme
85 ;;;
86
87 ;;; Output-interface functions
88 (define (beam width slope thick blot)
89   (string-append
90    (ly:numbers->string (list slope width thick blot)) " draw_beam" ))
91
92 ;; two beziers
93 (define (bezier-sandwich lst thick)
94   (string-append 
95    (string-join (map ly:number-pair->string lst) " ")
96    " "
97    (ly:number->string thick)
98    " draw_bezier_sandwich"))
99
100 (define (char font i)
101   (string-append 
102    (ps-font-command font) " setfont " 
103    "(\\" (ly:inexact->string i 8) ") show"))
104
105 (define (circle radius thick fill)
106   (format
107    "~a ~a ~a draw_circle" radius thick
108    (if fill
109        "true "
110        "false ")))
111
112 (define (dashed-line thick on off dx dy)
113   (string-append 
114    (ly:number->string dx) " "
115    (ly:number->string dy) " "
116    (ly:number->string thick)
117    " [ "
118    (ly:number->string on) " "
119    (ly:number->string off)
120    " ] 0 draw_dashed_line"))
121
122 ;; what the heck is this interface ?
123 (define (dashed-slur thick on off l)
124   (string-append 
125    (string-join (map ly:number-pair->string l) " ")
126    " "
127    (ly:number->string thick) 
128    " [ "
129    (ly:number->string on)
130    " "   
131    (ly:number->string off)
132    " ] 0 draw_dashed_slur"))
133
134 (define (dot x y radius)
135   (string-append
136    " "
137    (ly:numbers->string
138     (list x y radius)) " draw_dot"))
139
140 (define (draw-line thick x1 y1 x2 y2)
141   (string-append 
142    "1 setlinecap 1 setlinejoin "
143    (ly:number->string thick) " setlinewidth "
144    (ly:number->string x1) " "
145    (ly:number->string y1) " moveto "
146    (ly:number->string x2) " "
147    (ly:number->string y2) " lineto stroke"))
148
149 (define (embedded-ps string)
150   string)
151
152 ;; FIXME: use draw_round_box
153 (define (filledbox breapth width depth height)
154   (string-append (ly:numbers->string (list breapth width depth height))
155                  " draw_box"))
156
157 (define (glyph-string
158          postscript-font-name
159          size cid?
160          x-y-named-glyphs)
161
162   (format #f "gsave 1 output-scale div 1 output-scale div scale
163   /~a ~a ~a scalefont setfont\n~a grestore"
164           postscript-font-name
165           (if cid?
166               " /CIDFont findresource "
167               " findfont") 
168           
169           size
170           (apply
171            string-append
172            (map (lambda  (item)
173                   (let*
174                       ((x (car item))
175                        (y (cadr item))
176                        (g (caddr item))
177                        (prefix (if  (string? g) "/" "")))
178
179                     (if (and (= 0.0 x)
180                              (= 0.0 y))
181                         (format #f " ~a~a glyphshow\n" prefix g)
182                         (format #f " ~a ~a rmoveto ~a~a glyphshow\n"
183                                 x y
184                                 prefix
185                                 g))))
186                 x-y-named-glyphs))))
187
188 (define (grob-cause offset grob)
189   (let* ((cause (ly:grob-property grob 'cause))
190          (music-origin (if (ly:music? cause)
191                            (ly:music-property cause 'origin))))
192     (if (not (ly:input-location? music-origin))
193         ""
194         (let* ((location (ly:input-file-line-column music-origin))
195                (raw-file (car location))
196                (file (if (is-absolute? raw-file)
197                          raw-file
198                          (string-append (ly-getcwd) "/" raw-file)))
199                (x-ext (ly:grob-extent grob grob X))
200                (y-ext (ly:grob-extent grob grob Y)))
201
202           (if (and (< 0 (interval-length x-ext))
203                    (< 0 (interval-length y-ext)))
204               (format "~a ~a ~a ~a (textedit://~a:~a:~a) mark_URI\n"
205                       (+ (car offset) (car x-ext))
206                       (+ (cdr offset) (car y-ext))
207                       (+ (car offset) (cdr x-ext))
208                       (+ (cdr offset) (cdr y-ext))
209                       file
210                       (cadr location)
211                       (caddr location))
212               "")))))
213
214 (define (lily-def key val)
215   (let ((prefix "lilypondlayout"))
216     (if (string=?
217          (substring key 0 (min (string-length prefix) (string-length key)))
218          prefix)
219         (string-append "/" key " {" val "} bind def\n")
220         (string-append "/" key " (" val ") def\n"))))
221
222 (define (named-glyph font glyph)
223   (string-append 
224    (ps-font-command font) " setfont " 
225    "/" glyph " glyphshow "))
226
227 (define (no-origin)
228   "")
229
230 (define (placebox x y s) 
231   (string-append 
232    (ly:number->string x) " " (ly:number->string y) " { " s " } place-box\n"))
233
234 (define (polygon points blotdiameter filled?)
235   (string-append
236    (ly:numbers->string points) " "
237    (ly:number->string (/ (length points) 2)) " "
238    (ly:number->string blotdiameter)
239    (if filled? " true " " false ")
240    " draw_polygon"))
241
242 (define (repeat-slash wid slope thick)
243   (string-append
244    (ly:numbers->string (list wid slope thick))
245    " draw_repeat_slash"))
246
247 ;; restore color from stack
248 (define (resetcolor)
249   (string-append "setrgbcolor\n"))
250
251 (define (round-filled-box x y width height blotdiam)
252   (string-append
253    (ly:numbers->string
254     (list x y width height blotdiam)) " draw_round_box"))
255
256 ;; save current color on stack and set new color
257 (define (setcolor r g b)
258   (string-append "currentrgbcolor "
259   (ly:numbers->string (list r g b))
260   " setrgbcolor\n"))
261
262 (define (text font s)
263   ;; (ly:warning (_ "TEXT backend-command encountered in Pango backend"))
264   ;; (ly:warning (_ "Arguments: ~a ~a"" font str))
265   
266   (let* ((space-length (cdar (ly:text-dimension font " ")))
267          (space-move (string-append (number->string space-length)
268                                     " 0.0 rmoveto "))
269          (out-vec (decode-byte-string s)))
270
271     (string-append
272      (ps-font-command font) " setfont "
273      (string-join
274       (vector->list
275        (vector-for-each
276         
277         (lambda (sym)
278           (if (eq? sym 'space)
279               space-move
280               (string-append "/" (symbol->string sym) " glyphshow")))
281         out-vec))))))
282
283 (define (unknown) 
284   "\n unknown\n")
285
286 (define (url-link url x y)
287   (format "~a ~a ~a ~a (~a) mark_URI"
288           (car x)
289           (car y)
290           (cdr x)
291           (cdr y)
292           url))
293
294 (define (utf8-string pango-font-description string)
295   (ly:warning (_ "utf8-string encountered in PS backend")))
296
297
298 ;; TODO: FIX THIS.
299 ;;
300 (define (white-dot x y radius)
301   (string-append
302    " "
303    (ly:numbers->string
304     (list x y radius)) " draw_white_dot"))
305
306 (define (white-text scale s)
307   (let ((mystring (string-append
308                    "(" s  ") " (number->string scale)
309                    " /Helvetica-Bold "
310                    " draw_white_text")))
311     mystring
312     ))
313
314 (define (zigzag-line centre? zzw zzh thick dx dy)
315   (string-append
316    (if centre? "true" "false") " "
317    (ly:number->string zzw) " "
318    (ly:number->string zzh) " "
319    (ly:number->string thick) " "
320    "0 0 "
321    (ly:number->string dx) " "
322    (ly:number->string dy)
323    " draw_zigzag_line"))