]> git.donarmstrong.com Git - lilypond.git/blob - scm/output-ps.scm
* scm/framework-ps.scm:
[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--2006 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             dashed-slur
25             char
26             setcolor
27             resetcolor
28             named-glyph
29             dashed-line
30             zigzag-line
31             comment
32             repeat-slash
33             placebox
34             bezier-sandwich
35             embedded-ps
36             round-filled-box
37             text
38             polygon
39             draw-line
40             no-origin))
41
42
43 (use-modules (guile)
44              (ice-9 regex)
45              (srfi srfi-1)
46              (srfi srfi-13)
47              (scm framework-ps)
48              (lily))
49
50 ;;; helper functions, not part of output interface
51 (define (escape-parentheses s)
52   (regexp-substitute/global #f "(^|[^\\])([\\(\\)])" s 'pre 1 "\\" 2 'post))
53
54 (define (ps-encoding text)
55   (escape-parentheses text))
56
57 (define (round2 num)
58   (/ (round (* 100 num)) 100))
59
60 (define (round4 num)
61   (/ (round (* 10000 num)) 10000))
62
63 (define (str4 num)
64   (format #f "~f" (round4 num)))
65
66 (define (number-pair->string4 numpair)
67   (format #f "~f ~f" (round4 (car numpair)) (round4 (cdr numpair))))
68
69 (define (numbers->string4 numlist)
70   (string-join (map str4 numlist) " "))
71
72 ;; FIXME: lily-def
73 (define-public (ps-string-def prefix key val)
74   (format #f "/ ~a~a (~a) def\n"
75           prefix
76           (symbol->string key)
77           (escape-parentheses val)))
78
79 (define (ps-number-def prefix key val)
80   (let ((s (if (integer? val)
81                (ly:number->string val)
82                (ly:number->string (exact->inexact val)))))
83     (format #f "/~a~a ~a def\n"
84             prefix
85             (symbol->string key) s)))
86
87
88 ;;;
89 ;;; Lily output interface, PostScript implementation --- cleanup and docme
90 ;;;
91
92 ;; two beziers
93 (define (bezier-sandwich lst thick)
94   (format #f "~a ~a draw_bezier_sandwich" 
95           (string-join (map number-pair->string4 lst) " ")
96           (str4 thick)))
97
98 (define (char font i)
99   (format #f "~a (\\~a) show"
100    (ps-font-command font)
101    (ly:inexact->string i 8)))
102
103 (define (circle radius thick fill)
104   (format #f
105    "~f ~f ~a draw_circle" (round4 radius) (round4 thick)
106    (if fill
107        "true "
108        "false ")))
109
110 (define (dashed-line thick on off dx dy)
111   (format #f "~a ~a ~a [ ~a ~a ] 0 draw_dashed_line"
112    (str4 dx)
113    (str4 dy)
114    (str4 thick)
115    (str4 on)
116    (str4 off)))
117
118 ;; what the heck is this interface ?
119 (define (dashed-slur thick on off l)
120   (format #f "~a ~a [ ~a ~a ] 0 draw_dashed_slur"
121           (string-join (map number-pair->string4 l) " ")
122           (str4 thick)
123           (str4 on)
124           (str4 off)))
125
126 (define (dot x y radius)
127   (format #f " ~a draw_dot"
128    (numbers->string4 (list x y radius))))
129
130 (define (draw-line thick x1 y1 x2 y2)
131   (format #f "1 setlinecap 1 setlinejoin ~a setlinewidth ~a ~a moveto ~a ~a lineto stroke"
132    (str4 thick)
133    (str4 x1)
134    (str4 y1)
135    (str4 x2)
136    (str4 y2)))
137
138 (define (embedded-ps string)
139   string)
140
141 (define (glyph-string postscript-font-name
142                       size
143                       cid?
144                       w-x-y-named-glyphs)
145
146   (format #f "gsave \n/~a ~a output-scale div selectfont\n~a grestore"
147           postscript-font-name
148           size
149           (string-append
150             (apply
151               string-append
152               (map (lambda  (item)
153                      (let*
154                        ((w (car item))
155                         (x (cadr item))
156                         (y (caddr item))
157                         (g (cadddr item))
158                         (prefix (if  (string? g) "/" "")))
159
160                        (format #f "~f ~f ~a~a\n" (round2 (+ w x))
161                                (round2 y) prefix g)
162                        ))
163                    w-x-y-named-glyphs))
164             (format #f "~a print_glyphs" (length w-x-y-named-glyphs)))
165           ))
166
167 (define (grob-cause offset grob)
168   (let* ((cause (ly:grob-property grob 'cause))
169          (music-origin (if (ly:music? cause)
170                            (ly:music-property cause 'origin))))
171     (if (not (ly:input-location? music-origin))
172         ""
173         (let* ((location (ly:input-file-line-char-column music-origin))
174                (raw-file (car location))
175                (file (if (is-absolute? raw-file)
176                          raw-file
177                          (string-append (ly-getcwd) "/" raw-file)))
178                (x-ext (ly:grob-extent grob grob X))
179                (y-ext (ly:grob-extent grob grob Y)))
180
181           (if (and (< 0 (interval-length x-ext))
182                    (< 0 (interval-length y-ext)))
183               (format #f "~$ ~$ ~$ ~$ (textedit://~a:~a:~a:~a) mark_URI\n"
184                       (+ (car offset) (car x-ext))
185                       (+ (cdr offset) (car y-ext))
186                       (+ (car offset) (cdr x-ext))
187                       (+ (cdr offset) (cdr y-ext))
188
189                       ;; TODO
190                       ;;full escaping.
191
192                       ;; backslash is interpreted by GS.
193                       (string-regexp-substitute "\\\\" "/" 
194                                       (string-regexp-substitute " " "%20" file))
195                       (cadr location)
196                       (caddr location)
197                       (cadddr location))
198               "")))))
199
200 (define (lily-def key val)
201   (let ((prefix "lilypondlayout"))
202     (if (string=?
203           (substring key 0 (min (string-length prefix) (string-length key)))
204           prefix)
205       (string-append "/" key " {" val "} bind def\n")
206       (string-append "/" key " (" val ") def\n"))))
207
208 (define (named-glyph font glyph)
209   (format #f "~a /~a glyphshow " ;;Why is there a space at the end?
210           (ps-font-command font)
211           glyph))
212
213 (define (no-origin)
214   "")
215
216 (define (placebox x y s) 
217   (format #f
218 "gsave ~a ~a translate
219 0 0 moveto
220 ~a
221 grestore\n"
222
223    (str4 x)
224    (str4 y)
225    s))
226
227 (define (polygon points blot-diameter filled?)
228   (format #f "~a ~a ~a ~a draw_polygon"
229           (numbers->string4 points)
230           (str4 (/ (length points) 2))
231           (str4 blot-diameter)
232           (if filled? "true" "false")))
233
234 (define (repeat-slash wid slope thick)
235   (format #f "~a draw_repeat_slash"
236    (numbers->string4 (list wid slope thick))))
237
238 ;; restore color from stack
239 (define (resetcolor) "setrgbcolor\n")
240
241 (define (round-filled-box x y width height blotdiam)
242   (format #f "~a draw_round_box"
243           (numbers->string4
244             (list x y width height blotdiam))))
245
246 ;; save current color on stack and set new color
247 (define (setcolor r g b)
248   (format #f "currentrgbcolor ~a setrgbcolor\n"
249           (numbers->string4 (list r g b))))
250
251 (define (text font s)
252   ;; (ly:warning (_ "TEXT backend-command encountered in Pango backend"))
253   ;; (ly:warning (_ "Arguments: ~a ~a"" font str))
254   
255   (let* ((space-length (cdar (ly:text-dimension font " ")))
256          (space-move (string-append (number->string space-length)
257                                     " 0.0 rmoveto "))
258          (out-vec (decode-byte-string s)))
259
260     (string-append
261      (ps-font-command font) " "
262      (string-join
263       (vector->list
264        (vector-for-each
265         
266         (lambda (sym)
267           (if (eq? sym 'space)
268               space-move
269               (string-append "/" (symbol->string sym) " glyphshow")))
270         out-vec))))))
271
272 (define (unknown) 
273   "\n unknown\n")
274
275 (define (url-link url x y)
276   (format #f "~$ ~$ ~$ ~$ (~a) mark_URI"
277           (car x)
278           (car y)
279           (cdr x)
280           (cdr y)
281           url))
282
283 (define (utf-8-string pango-font-description string)
284   (ly:warning (_ "utf-8-string encountered in PS backend")))
285
286
287 (define (zigzag-line centre? zzw zzh thick dx dy)
288   (format #f "~a ~a ~a ~a 0 0 ~a ~a draw_zigzag_line"
289    (if centre? "true" "false")
290    (str4 zzw)
291    (str4 zzh)
292    (str4 thick)
293    (str4 dx)
294    (str4 dy)))