]> git.donarmstrong.com Git - lilypond.git/blob - ps/music-drawing-routines.ps
Add '-dcrop' option to ps and svg backends
[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             currentstrokeadjust {
142                 currentlinewidth 2 div
143                 0 0 2 index 180 270 arc
144                 2 index 0 2 index 270 360 arc
145                 3 copy 0 90 arc
146                 0 2 index 3 -1 roll 90 180 arc
147                 closepath
148                 2 copy 2 mul gt
149                 { % horizontal
150                     2 copy add currentlinewidth add 10 add % large enough
151                     0 1 index neg moveto
152                     2 index 1 index neg lineto
153                     2 index 1 index lineto
154                     0 exch lineto closepath
155                     gsave clip newpath
156                     0 1 index 2 div moveto
157                     currentlinewidth add setlinewidth
158                     0 rlineto
159                     2 setlinecap
160                     stroke
161                     grestore
162                 }
163                 {
164                     2 copy exch 2 mul gt
165                     { % vertical
166                         2 copy add currentlinewidth add 10 add % large enough
167                         dup neg 0 moveto
168                         dup 0 lineto
169                         dup 2 index lineto
170                         neg 1 index lineto closepath
171                         gsave clip newpath
172                         1 index 2 div 0 moveto
173                         exch currentlinewidth add setlinewidth
174                         0 exch rlineto
175                         2 setlinecap
176                         stroke
177                         grestore
178                     }
179                     {
180                         pop pop
181                         fill
182                     }
183                     ifelse
184                 }
185                 ifelse
186                 newpath
187             }
188             {
189                 1 setlinejoin
190                 0 0 4 2 roll 4 copy rectstroke rectfill
191             }
192             ifelse
193         }
194         ifelse
195     }
196     ifelse
197     setmatrix
198 } bind def
199
200 /draw_polygon % fill? x(n) y(n) x(n-1) y(n-1) ... x(0) y(0) n blot
201 {
202         setlinewidth %set to blot
203
204         0 setlinecap
205         1 setlinejoin
206
207         3 1 roll
208         /polygon_x
209         currentpoint
210         /polygon_y exch def
211         def
212         rmoveto % x(0) y(0)
213         { polygon_x polygon_y vector_add lineto } repeat % n times
214         closepath
215         stroke_and_fill?
216 } bind def
217
218 /draw_circle % filled? radius thickness draw_circle
219 {
220         setlinewidth    % f? r
221         currentpoint    % f? r x0 y0
222         3 2 roll        % f? x0 y0 r
223         dup 0 rmoveto
224         0 360 arc closepath
225         stroke_and_fill?
226 } bind def
227
228 /draw_ellipse % filled? x-radius y-radius thickness draw_ellipse
229 {
230   setlinewidth % f? x-r y-r
231   /savematrix matrix currentmatrix def
232   scale % f?
233   currentpoint
234   1 0 rmoveto
235   1 0 360  arc closepath
236   savematrix setmatrix
237   stroke_and_fill?
238 } bind def
239
240 /draw_partial_ellipse % filled connect x-radius y-radius startangle endangle thickness draw_partial_ellipse
241 % Note that filled is not boolean to permit for different graylevels (ie for trill keys)
242 {
243   gsave
244   currentpoint translate
245   /thickness exch def
246   /endangle exch def
247   /startangle exch def
248   /y_radius exch def
249   /x_radius exch def
250   /endrad x_radius y_radius mul
251     x_radius x_radius mul
252     endangle cos endangle cos mul mul
253     y_radius y_radius mul
254     endangle sin endangle sin mul mul add sqrt div def
255   /endangle endangle sin endrad mul y_radius div
256     endangle cos endrad mul x_radius div atan def
257   /startrad x_radius y_radius mul
258     x_radius x_radius mul
259       startangle cos startangle cos mul mul
260     y_radius y_radius mul
261       startangle sin startangle sin mul mul add sqrt div def
262   /startangle startangle sin startrad mul y_radius div
263     startangle cos startrad mul x_radius div atan def
264   /connect exch def
265   /filled exch def
266   /savematrix matrix currentmatrix def
267   thickness setlinewidth
268   x_radius y_radius scale
269   startangle cos startangle sin moveto
270   0 0 1 startangle
271     startangle endangle eq { endangle 360 add } { endangle } ifelse
272     arc
273   connect {
274     startangle cos startangle sin moveto endangle cos endangle sin lineto }
275     if
276   savematrix setmatrix filled stroke_and_fill?
277   grestore
278 } bind def
279
280 /draw_line % dx dy x1 y1 thickness draw_line
281 {
282         setlinewidth % dx dy x1 y1
283         1 setlinecap
284         rmoveto % dx dy
285         rlineto
286         stroke
287 } bind def
288
289 /draw_dashed_line % dx dy thickness dashpattern offset draw_dashed_line
290 {
291         1 setlinecap
292         setdash % dx dy thickness
293         setlinewidth %dx dy
294         rlineto
295         stroke
296         [] 0 setdash % reset dash pattern
297 } bind def
298
299 /print_glyphs % w dx dy glyph print_glyphs
300 {
301         {
302                 currentpoint %w dx dy glyph x0 y0
303                 5 2 roll %w x0 y0 dx dy glyph
304                 3 1 roll %w x0 y0 glyph dx dy
305                 rmoveto %w x0 y0 glyph
306                 glyphshow %w x0 y0
307                 moveto %w
308                 0 rmoveto
309         }repeat
310 }bind def
311 %end music-drawing-routines.ps