]> git.donarmstrong.com Git - lilypond.git/blob - ps/music-drawing-routines.ps
121897a0218682dbb339f76beeb6eea6156e596a
[lilypond.git] / ps / music-drawing-routines.ps
1 %!PS-Adobe-2.0
2 %
3 % Functions for direct and embedded PostScript
4
5 % Careful with double % as comment prefix.
6 % Any %%X comment is interpreted as DSC comments.
7
8 % TODO: use dicts or prefixes to prevent namespace pollution.
9
10 /pdfmark where
11 {pop} {userdict /pdfmark /cleartomark load put} ifelse
12
13
14 % llx lly urx ury URI
15 /mark_URI
16 {
17     /uri exch def
18     /ury exch def
19     /urx exch def
20     /lly exch def
21     /llx exch def
22     [
23         /Rect [ llx lly urx ury ]
24         
25         /Border [ 0 0 0 ]
26
27         /Action
28             <<
29                 /Subtype /URI
30                 /URI uri
31             >>
32         /Subtype /Link
33     /ANN
34     pdfmark
35 }
36 bind def
37
38 % llx lly urx ury page
39 /mark_page_link
40 {
41     /page exch def
42     /ury exch def
43     /urx exch def
44     /lly exch def
45     /llx exch def
46     [
47         /Rect [ llx lly urx ury ]
48         /Border [ 0 0 0 ]
49         /Page page
50         /Subtype /Link
51     /ANN
52     pdfmark
53 }
54 bind def
55
56 % from adobe tech note 5002.
57 /BeginEPSF { %def
58     /b4_Inc_state save def % Save state for cleanup
59     /dict_count countdictstack def % Count objects on dict stack
60     /op_count count 1 sub def % Count objects on operand stack
61     userdict begin % Push userdict on dict stack
62     /showpage { } def % Redefine showpage, { } = null proc
63     0 setgray 0 setlinecap % Prepare graphics state
64     1 setlinewidth 0 setlinejoin
65     10 setmiterlimit [ ] 0 setdash newpath
66     false setoverprint
67 } bind def
68
69 /EndEPSF { %def
70   count op_count sub {pop} repeat % Clean up stacks
71   countdictstack dict_count sub {end} repeat
72   b4_Inc_state restore
73 } bind def
74
75 /stroke_and_fill? {
76     {
77         gsave
78             false setstrokeadjust
79             stroke
80         grestore
81         fill
82     }
83     {
84         stroke
85     }
86     ifelse
87 } bind def
88
89 /vector_add { % x1 y1 x2 y2 vector_add x1+x2 y1+y2
90         exch
91         4 1 roll
92         add
93         3 1 roll
94         add
95         exch
96 } bind def
97
98 /draw_round_box % width height x y blot
99 {
100     0 max setlinewidth
101     matrix currentmatrix 5 1 roll
102     currentpoint translate newpath translate
103     2 copy 0 min exch 0 min exch translate
104     abs exch abs exch
105     currentlinewidth 0 eq
106     { % straight corners
107         2 copy 2 mul gt
108         { % horizontal
109             0 1 index 2 div moveto
110             setlinewidth
111             0 rlineto
112             0 setlinecap
113             stroke
114         }
115         {
116             2 copy exch 2 mul gt
117             { % vertical
118                 1 index 2 div 0 moveto
119                 exch setlinewidth
120                 0 exch rlineto
121                 0 setlinecap
122                 stroke
123             }
124             {
125                 0 0 4 2 roll rectfill
126             }
127             ifelse
128         }
129         ifelse
130     }
131     { % rounded corners
132         2 copy 0 eq exch 0 eq or
133         { % line shape
134             0 0 moveto
135             rlineto
136             1 setlinecap
137             stroke
138             0 setlinecap
139         }
140         { % full shape
141             currentlinewidth 2 div
142             0 0 2 index 180 270 arc
143             2 index 0 2 index 270 360 arc
144             3 copy 0 90 arc
145             0 2 index 3 -1 roll 90 180 arc
146             closepath
147             2 copy 2 mul gt
148             { % horizontal
149                 2 copy add currentlinewidth add 10 add % large enough
150                 0 1 index neg moveto
151                 2 index 1 index neg lineto
152                 2 index 1 index lineto
153                 0 exch lineto closepath
154                 gsave clip newpath
155                 0 1 index 2 div moveto
156                 currentlinewidth add setlinewidth
157                 0 rlineto
158                 2 setlinecap
159                 stroke
160                 grestore
161             }
162             {
163                 2 copy exch 2 mul gt
164                 { % vertical
165                     2 copy add currentlinewidth add 10 add % large enough
166                     dup neg 0 moveto
167                     dup 0 lineto
168                     dup 2 index lineto
169                     neg 1 index lineto closepath
170                     gsave clip newpath
171                     1 index 2 div 0 moveto
172                     exch currentlinewidth add setlinewidth
173                     0 exch rlineto
174                     2 setlinecap
175                     stroke
176                     grestore
177                 }
178                 {
179                     pop pop
180                     fill
181                 }
182                 ifelse
183             }
184             ifelse
185             newpath
186         }
187         ifelse
188     }
189     ifelse
190     setmatrix
191 } bind def
192
193 /draw_polygon % fill? x(n) y(n) x(n-1) y(n-1) ... x(0) y(0) n blot
194 {
195         setlinewidth %set to blot
196
197         0 setlinecap
198         1 setlinejoin
199
200         3 1 roll
201         /polygon_x
202         currentpoint
203         /polygon_y exch def
204         def
205         rmoveto % x(0) y(0)
206         { polygon_x polygon_y vector_add lineto } repeat % n times
207         closepath
208         stroke_and_fill?
209 } bind def
210
211 /draw_circle % filled? radius thickness draw_circle
212 {
213         setlinewidth    % f? r
214         currentpoint    % f? r x0 y0
215         3 2 roll        % f? x0 y0 r
216         dup 0 rmoveto
217         0 360 arc closepath
218         stroke_and_fill?
219 } bind def
220
221 /draw_ellipse % filled? x-radius y-radius thickness draw_ellipse
222 {
223   setlinewidth % f? x-r y-r
224   /savematrix matrix currentmatrix def
225   scale % f?
226   currentpoint
227   1 0 rmoveto
228   1 0 360  arc closepath
229   savematrix setmatrix
230   stroke_and_fill?
231 } bind def
232
233 /draw_partial_ellipse % filled connect x-radius y-radius startangle endangle thickness draw_partial_ellipse
234 % Note that filled is not boolean to permit for different graylevels (ie for trill keys)
235 {
236   gsave
237   currentpoint translate
238   /thickness exch def
239   /endangle exch def
240   /startangle exch def
241   /y_radius exch def
242   /x_radius exch def
243   /endrad x_radius y_radius mul
244     x_radius x_radius mul
245     endangle cos endangle cos mul mul
246     y_radius y_radius mul
247     endangle sin endangle sin mul mul add sqrt div def
248   /endangle endangle sin endrad mul y_radius div
249     endangle cos endrad mul x_radius div atan def
250   /startrad x_radius y_radius mul
251     x_radius x_radius mul
252       startangle cos startangle cos mul mul
253     y_radius y_radius mul
254       startangle sin startangle sin mul mul add sqrt div def
255   /startangle startangle sin startrad mul y_radius div
256     startangle cos startrad mul x_radius div atan def
257   /connect exch def
258   /filled exch def
259   /savematrix matrix currentmatrix def
260   thickness setlinewidth
261   x_radius y_radius scale
262   startangle cos startangle sin moveto
263   0 0 1 startangle
264     startangle endangle eq { endangle 360 add } { endangle } ifelse
265     arc
266   connect {
267     startangle cos startangle sin moveto endangle cos endangle sin lineto }
268     if
269   savematrix setmatrix filled stroke_and_fill?
270   grestore
271 } bind def
272
273 /draw_line % dx dy x1 y1 thickness draw_line
274 {
275         setlinewidth % dx dy x1 y1
276         1 setlinecap
277         rmoveto % dx dy
278         rlineto
279         stroke
280 } bind def
281
282 /draw_dashed_line % dx dy thickness dashpattern offset draw_dashed_line
283 {
284         1 setlinecap
285         setdash % dx dy thickness
286         setlinewidth %dx dy
287         rlineto
288         stroke
289         [] 0 setdash % reset dash pattern
290 } bind def
291
292 /print_glyphs % w dx dy glyph print_glyphs
293 {
294         {
295                 currentpoint %w dx dy glyph x0 y0
296                 5 2 roll %w x0 y0 dx dy glyph
297                 3 1 roll %w x0 y0 glyph dx dy
298                 rmoveto %w x0 y0 glyph
299                 glyphshow %w x0 y0
300                 moveto %w
301                 0 rmoveto
302         }repeat
303 }bind def
304 %end music-drawing-routines.ps