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