]> git.donarmstrong.com Git - lilypond.git/blob - scm/output-ps.scm
Glossary: add German translation
[lilypond.git] / scm / output-ps.scm
1 ;;;; This file is part of LilyPond, the GNU music typesetter.
2 ;;;;
3 ;;;; Copyright (C) 1998--2012 Jan Nieuwenhuizen <janneke@gnu.org>
4 ;;;;                 Han-Wen Nienhuys <hanwen@xs4all.nl>
5 ;;;;
6 ;;;; LilyPond is free software: you can redistribute it and/or modify
7 ;;;; it under the terms of the GNU General Public License as published by
8 ;;;; the Free Software Foundation, either version 3 of the License, or
9 ;;;; (at your option) any later version.
10 ;;;;
11 ;;;; LilyPond is distributed in the hope that it will be useful,
12 ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 ;;;; GNU General Public License for more details.
15 ;;;;
16 ;;;; You should have received a copy of the GNU General Public License
17 ;;;; along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
18
19 ;;;; Note: currently misused as testbed for titles with markup, see
20 ;;;;       input/test/title-markup.ly
21 ;;;;
22 ;;;; TODO:
23 ;;;;   * %% Papersize in (header ...)
24 ;;;;   * text setting, kerning.
25 ;;;;   * document output-interface
26
27 (define-module (scm output-ps)
28   #:re-export (quote))
29
30 (use-modules (guile)
31              (ice-9 regex)
32              (ice-9 optargs)
33              (srfi srfi-1)
34              (srfi srfi-13)
35              (scm framework-ps)
36              (lily))
37
38 ;;; helper functions, not part of output interface
39 ;;;
40
41
42 ;; ice-9 format uses a lot of memory
43 ;; using simple-format almost halves lilypond cell usage
44
45 (define (str4 num)
46   (if (or (nan? num) (inf? num))
47       (begin
48         (ly:warning (_ "Found infinity or nan in output.  Substituting 0.0"))
49         (if (ly:get-option 'strict-infinity-checking)
50             (exit 1))
51         "0.0")
52       (ly:number->string num)))
53
54 (define (number-pair->string4 numpair)
55   (ly:format "~4l" numpair))
56
57 ;;;
58 ;;; Lily output interface, PostScript implementation --- cleanup and docme
59 ;;;
60
61 (define (char font i)
62   (ly:format "~a (\\~a) show"
63    (ps-font-command font)
64    (ly:inexact->string i 8)))
65
66 (define (circle radius thick fill)
67   (ly:format
68    "~a ~4f ~4f draw_circle"
69    (if fill
70      "true"
71      "false")
72    radius thick))
73
74 (define (start-enclosing-id-node s)
75   "")
76
77 (define (end-enclosing-id-node)
78   "")
79
80 (define (dashed-line thick on off dx dy phase)
81   (ly:format "~4f ~4f ~4f [ ~4f ~4f ] ~4f draw_dashed_line"
82    dx
83    dy
84    thick
85    on
86    off
87    phase))
88
89 (define (draw-line thick x1 y1 x2 y2)
90   (ly:format "~4f ~4f ~4f ~4f ~4f draw_line"
91           (- x2 x1) (- y2 y1)
92           x1 y1 thick))
93
94 (define (partial-ellipse x-radius y-radius start-angle end-angle thick connect fill)
95   (ly:format "~a ~a ~4f ~4f ~4f ~4f ~4f draw_partial_ellipse"
96         (if fill "true" "false")
97         (if connect "true" "false")
98         x-radius
99         y-radius
100         start-angle
101         end-angle
102         thick))
103
104 (define (ellipse x-radius y-radius thick fill)
105   (ly:format
106    "~a ~4f ~4f ~4f draw_ellipse"
107    (if fill
108      "true"
109      "false")
110    x-radius y-radius thick))
111
112 (define (embedded-ps string)
113   string)
114
115 (define (glyph-string postscript-font-name
116                       size
117                       cid?
118                       w-x-y-named-glyphs)
119
120   (define (glyph-spec w x y g)
121     (let ((prefix (if (string? g) "/" "")))
122       (ly:format "~4f ~4f ~4f ~a~a"
123                  w x y
124                  prefix g)))
125
126   (ly:format
127    (if cid?
128 "/~a /CIDFont findresource ~a output-scale div scalefont setfont
129 ~a
130 ~a print_glyphs"
131
132 "/~a ~a output-scale div selectfont
133 ~a
134 ~a print_glyphs")
135           postscript-font-name
136           size
137           (string-join (map (lambda (x) (apply glyph-spec x))
138                             (reverse w-x-y-named-glyphs)) "\n")
139           (length w-x-y-named-glyphs)))
140
141
142 (define (grob-cause offset grob)
143   (if (ly:get-option 'point-and-click)
144       (let* ((cause (ly:grob-property grob 'cause))
145              (music-origin (if (ly:stream-event? cause)
146                                (ly:event-property cause 'origin)))
147              (point-and-click (ly:get-option 'point-and-click)))
148         (if (and
149              (ly:input-location? music-origin)
150              (cond ((boolean? point-and-click) point-and-click)
151                    ((symbol? point-and-click)
152                     (ly:in-event-class? cause point-and-click))
153                    (else (any (lambda (t)
154                                 (ly:in-event-class? cause t))
155                               point-and-click))))
156             (let* ((location (ly:input-file-line-char-column music-origin))
157                    (raw-file (car location))
158                    (file (if (is-absolute? raw-file)
159                              raw-file
160                              (string-append (ly-getcwd) "/" raw-file)))
161                    (x-ext (ly:grob-extent grob grob X))
162                    (y-ext (ly:grob-extent grob grob Y)))
163
164               (if (and (< 0 (interval-length x-ext))
165                        (< 0 (interval-length y-ext)))
166                   (ly:format "~4f ~4f ~4f ~4f (textedit://~a:~a:~a:~a) mark_URI\n"
167                              (+ (car offset) (car x-ext))
168                              (+ (cdr offset) (car y-ext))
169                              (+ (car offset) (cdr x-ext))
170                              (+ (cdr offset) (cdr y-ext))
171
172                              ;; Backslashes are not valid
173                              ;; file URI path separators.
174                              (ly:string-percent-encode
175                                (ly:string-substitute "\\" "/" file))
176
177                              (cadr location)
178                              (caddr location)
179                              (cadddr location))
180                   ""))
181             ""))
182       ""))
183
184 (define (named-glyph font glyph)
185   (ly:format "~a /~a glyphshow " ;;Why is there a space at the end?
186              (ps-font-command font)
187              glyph))
188
189 (define (no-origin)
190   "")
191
192 (define (placebox x y s)
193   (if (not (string-null? s))
194       (ly:format "~4f ~4f moveto ~a\n" x y s)
195       ""))
196
197 (define (polygon points blot-diameter filled?)
198   (ly:format "~a ~4l ~a ~4f draw_polygon"
199              (if filled? "true" "false")
200              points
201              (- (/ (length points) 2) 1)
202              blot-diameter))
203
204 (define (round-filled-box left right bottom top blotdiam)
205   (let* ((halfblot (/ blotdiam 2))
206          (x (- halfblot left))
207          (width (- right (+ halfblot x)))
208          (y (- halfblot bottom))
209          (height (- top (+ halfblot y))))
210     (ly:format  "~4l draw_round_box"
211                 (list width height x y blotdiam))))
212
213 ;; save current color on stack and set new color
214 (define (setcolor r g b)
215   (ly:format "gsave ~4l setrgbcolor\n"
216               (list r g b)))
217
218 ;; restore color from stack
219 (define (resetcolor) "grestore\n")
220
221 ;; rotation around given point
222 (define (setrotation ang x y)
223   (ly:format "gsave ~4l translate ~a rotate ~4l translate\n"
224              (list x y)
225              ang
226              (list (* -1 x) (* -1 y))))
227
228 (define (resetrotation ang x y)
229   "grestore  ")
230
231 (define (unknown)
232   "\n unknown\n")
233
234 (define (url-link url x y)
235   (ly:format "~a ~a currentpoint vector_add  ~a ~a currentpoint vector_add (~a) mark_URI"
236              (car x)
237              (car y)
238              (cdr x)
239              (cdr y)
240              url))
241
242 (define (page-link page-no x y)
243   (if (number? page-no)
244     (ly:format "~a ~a currentpoint vector_add  ~a ~a currentpoint vector_add ~a mark_page_link"
245                (car x)
246                (car y)
247                (cdr x)
248                (cdr y)
249                page-no)
250     ""))
251
252 (define* (path thickness exps #:optional (cap 'round) (join 'round) (fill? #f))
253   (define (convert-path-exps exps)
254     (if (pair? exps)
255         (let*
256             ((head (car exps))
257              (rest (cdr exps))
258              (arity
259               (cond
260                ((memq head '(rmoveto rlineto lineto moveto)) 2)
261                ((memq head '(rcurveto curveto)) 6)
262                ((eq? head 'closepath) 0)
263                (else 1)))
264              (args (take rest arity))
265              )
266
267           ;; WARNING: this is a vulnerability: a user can output arbitrary PS code here.
268           (cons (ly:format
269                         "~l ~a "
270                         args
271                         head)
272                 (convert-path-exps (drop rest arity))))
273         '()))
274
275   (let ((cap-numeric (case cap ((butt) 0) ((round) 1) ((square) 2)
276                        (else (begin
277                                (ly:warning (_ "unknown line-cap-style: ~S")
278                                            (symbol->string cap))
279                                1))))
280         (join-numeric (case join ((miter) 0) ((round) 1) ((bevel) 2)
281                         (else (begin
282                                 (ly:warning (_ "unknown line-join-style: ~S")
283                                             (symbol->string join))
284                                 1)))))
285     (ly:format
286      "gsave currentpoint translate
287 ~a setlinecap ~a setlinejoin ~a setlinewidth
288 ~l gsave stroke grestore ~a grestore"
289      cap-numeric
290      join-numeric
291      thickness
292      (convert-path-exps exps)
293      (if fill? "fill" ""))))
294
295 (define (setscale x y)
296   (ly:format "gsave ~4l scale\n"
297               (list x y)))
298
299 (define (resetscale)
300   "grestore\n")