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