]> git.donarmstrong.com Git - lilypond.git/blob - lily/breathing-sign.cc
* scm/music-functions.scm (has-request-chord): don't use
[lilypond.git] / lily / breathing-sign.cc
1 /*
2   breathing_sign.cc -- implement Breathing_sign
3
4   (c) 1999--2005 Michael Krause
5
6   written for the GNU LilyPond music typesetter
7
8   TODO: --> see breathing-sign-engraver.cc
9
10   Extensions for ancient notation (c) 2003--2005 by Juergen Reuter
11 */
12
13 #include "breathing-sign.hh"
14
15 #include "staff-symbol-referencer.hh"
16 #include "directional-element-interface.hh"
17 #include "output-def.hh"
18 #include "lookup.hh"
19 #include "dimensions.hh"
20 #include "direction.hh"
21 #include "text-item.hh"
22 #include "font-interface.hh"
23
24 /*
25   TODO: thickness should be a grob property (unit: linethickness)
26  rather than hardwired to (staff_space / 6).
27  */
28
29   
30
31 /*
32   UGH : this is full of C&P code. Consolidate!  --hwn
33 */
34
35 /*
36   Gregorian chant divisio minima.  (Actually, this was the original
37   breathing sign by Michael. -- jr)
38  */
39 MAKE_SCHEME_CALLBACK (Breathing_sign, divisio_minima, 1);
40 SCM 
41 Breathing_sign::divisio_minima (SCM smob)
42 {
43   Grob *me = unsmob_grob (smob);
44   Real staff_space = Staff_symbol_referencer::staff_space (me);
45   Real staff_size;
46
47   Real thickness = Staff_symbol_referencer::line_thickness (me);
48   thickness *= robust_scm2double (me->get_property ("thickness"), 1.0);
49   if (Staff_symbol_referencer::get_staff_symbol (me))
50     {
51       staff_size = (Staff_symbol_referencer::line_count (me) - 1) * staff_space;
52     }
53   else
54     staff_size = 0.0;
55
56   Real blotdiameter = me->get_layout ()->get_dimension (ly_symbol2scm ("blotdiameter"));
57
58   /*
59    * Draw a small vertical line through the uppermost (or, depending
60    * on direction, lowermost) staff line.
61    */
62   Interval xdim (0, thickness);
63   Interval ydim (-0.5 * staff_space, +0.5 * staff_space);
64   Box b (xdim, ydim);
65   Stencil out = Lookup::round_filled_box (b, blotdiameter);
66   return out.smobbed_copy ();
67 }
68
69 /*
70   Gregorian chant divisio maior.
71  */
72 MAKE_SCHEME_CALLBACK (Breathing_sign, divisio_maior, 1);
73 SCM 
74 Breathing_sign::divisio_maior (SCM smob)
75 {
76   Grob *me = unsmob_grob (smob);
77   Real staff_space = Staff_symbol_referencer::staff_space (me);
78   Real staff_size;
79   Real thickness = Staff_symbol_referencer::line_thickness (me);
80   thickness *= robust_scm2double (me->get_property ("thickness"), 1.0);
81
82   if (Staff_symbol_referencer::get_staff_symbol (me))
83     {
84       staff_size = (Staff_symbol_referencer::line_count (me) - 1) * staff_space;
85     }
86   else
87     staff_size = 0.0;
88
89   Real blotdiameter = me->get_layout ()->get_dimension (ly_symbol2scm ("blotdiameter"));
90
91   /*
92    * Draw a vertical line that is vertically centered in the staff
93    * (just like a bar).  The height of this line should be a little
94    * more than half the size of the staff, such that the endings of
95    * the line are in the middle of a staff space.
96    */
97   int lines = Staff_symbol_referencer::line_count (me);
98   int height = lines / 2; // little more than half of staff size
99   if ((lines & 1) != (height & 1))
100     height++; // ensure endings are centered in staff space
101
102   Interval xdim (0, thickness);
103   Interval ydim (-0.5 * height, +0.5 * height);
104   Box b (xdim, ydim);
105   Stencil out = Lookup::round_filled_box (b, blotdiameter);
106   return out.smobbed_copy ();
107 }
108
109 /*
110   Gregorian chant divisio maxima.
111  */
112 MAKE_SCHEME_CALLBACK (Breathing_sign, divisio_maxima, 1);
113 SCM 
114 Breathing_sign::divisio_maxima (SCM smob)
115 {
116   Grob *me = unsmob_grob (smob);
117   Real staff_space = Staff_symbol_referencer::staff_space (me);
118   Real staff_size;
119   Real thickness = Staff_symbol_referencer::line_thickness (me);
120   thickness *= robust_scm2double (me->get_property ("thickness"), 1.0);
121
122   if (Staff_symbol_referencer::get_staff_symbol (me))
123     {
124       staff_size = (Staff_symbol_referencer::line_count (me) - 1) * staff_space;
125     }
126   else
127     staff_size = 0.0;
128
129   Real blotdiameter = me->get_layout ()->get_dimension (ly_symbol2scm ("blotdiameter"));
130
131   // like a "|" type bar
132   Interval xdim (0, thickness);
133   Interval ydim (-0.5 * staff_size, +0.5 * staff_size);
134   Box b (xdim, ydim);
135   Stencil out = Lookup::round_filled_box (b, blotdiameter);
136   return out.smobbed_copy ();
137 }
138
139 /*
140   Gregorian chant finalis.
141  */
142 MAKE_SCHEME_CALLBACK (Breathing_sign, finalis, 1);
143 SCM 
144 Breathing_sign::finalis (SCM smob)
145 {
146   Grob *me = unsmob_grob (smob);
147   Real staff_space = Staff_symbol_referencer::staff_space (me);
148   Real staff_size;
149   Real thickness = Staff_symbol_referencer::line_thickness (me);
150   thickness *= robust_scm2double (me->get_property ("thickness"), 1.0);
151
152   if (Staff_symbol_referencer::get_staff_symbol (me))
153     {
154       staff_size = (Staff_symbol_referencer::line_count (me) - 1) * staff_space;
155     }
156   else
157     staff_size = 0.0;
158
159   Real blotdiameter = me->get_layout ()->get_dimension (ly_symbol2scm ("blotdiameter"));
160
161   // like a "||" type bar
162   Interval xdim (0, thickness);
163   Interval ydim (-0.5 * staff_size, +0.5 * staff_size);
164   Box b (xdim, ydim);
165   Stencil line1 = Lookup::round_filled_box (b, blotdiameter);
166   Stencil line2 (line1);
167   line2.translate_axis (0.5 * staff_space, X_AXIS);
168   line1.add_stencil (line2);
169
170   return line1.smobbed_copy ();
171 }
172
173 MAKE_SCHEME_CALLBACK (Breathing_sign, offset_callback, 2);
174 SCM
175 Breathing_sign::offset_callback (SCM element_smob, SCM)
176 {
177   Grob *me = unsmob_grob (element_smob);
178   
179   Direction d = get_grob_direction (me);
180   if (!d)
181     {
182       d = UP;
183       set_grob_direction (me, d);
184     }
185
186   Real inter_f = Staff_symbol_referencer::staff_space (me)/2;
187   int sz = Staff_symbol_referencer::line_count (me)-1;
188   return scm_make_real (inter_f * sz * d);
189 }
190
191 ADD_INTERFACE (Breathing_sign, "breathing-sign-interface",
192               "A breathing sign.",
193               "direction");