]> git.donarmstrong.com Git - lilypond.git/blob - lily/breathing-sign.cc
* lily/my-lily-lexer.cc (My_lily_lexer): don't crash
[lilypond.git] / lily / breathing-sign.cc
1 /*
2   breathing_sign.cc -- implement Breathing_sign
3
4   (c)  1999--2003 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: stafflinethickness)
28  rather than hardwired to (staff_space / 6).
29  */
30
31   
32
33 /*
34   Simplistic caesura.
35  */
36 MAKE_SCHEME_CALLBACK (Breathing_sign,railtracks,1);
37 SCM 
38 Breathing_sign::railtracks (SCM smob)
39 {
40   Grob * me = unsmob_grob (smob);
41   Real space = Staff_symbol_referencer::staff_space (me);
42   Real th = me->get_paper ()->get_realvar (ly_symbol2scm ("linethickness"));
43   SCM lt =  me->get_grob_property ("thickness");
44   if (gh_number_p (lt))
45     th *= gh_scm2double (lt);
46   
47   Offset x1 (0, -space);
48   Offset x2 (space / 3, space);
49   Molecule l1 (Lookup::line (th, x1, x2));
50   Molecule l2 (l1);
51   l2.translate_axis (space *0.6 , X_AXIS);
52   l1.add_molecule (l2);
53   return l1.smobbed_copy();
54 }
55
56 /*
57   Gregorian chant divisio minima.  (Actually, this was the original
58   breathing sign by Michael. -- jr)
59  */
60 MAKE_SCHEME_CALLBACK (Breathing_sign,divisio_minima,1);
61 SCM 
62 Breathing_sign::divisio_minima (SCM smob)
63 {
64   Grob *me = unsmob_grob (smob);
65   Real staff_space = Staff_symbol_referencer::staff_space (me);
66   Real staff_size;
67   Real thickness = me->get_paper ()->get_realvar (ly_symbol2scm ("linethickness"));
68   SCM lt =  me->get_grob_property ("thickness");
69   if (gh_number_p (lt))
70     thickness *= gh_scm2double (lt);
71   if (Staff_symbol_referencer::get_staff_symbol (me))
72     {
73       staff_size = (Staff_symbol_referencer::line_count (me) - 1) * staff_space;
74     }
75   else
76     staff_size = 0.0;
77
78   Real blotdiameter = me->get_paper ()->get_realvar (ly_symbol2scm ("blotdiameter"));
79
80   /*
81    * Draw a small vertical line through the uppermost (or, depending
82    * on direction, lowermost) staff line.
83    */
84   Interval xdim (0, thickness);
85   Interval ydim (-0.5 * staff_space, +0.5 * staff_space);
86   Box b (xdim, ydim);
87   Molecule out = Lookup::round_filled_box (b, blotdiameter);
88   return out.smobbed_copy ();
89 }
90
91 /*
92   Gregorian chant divisio maior.
93  */
94 MAKE_SCHEME_CALLBACK (Breathing_sign,divisio_maior,1);
95 SCM 
96 Breathing_sign::divisio_maior (SCM smob)
97 {
98   Grob *me = unsmob_grob (smob);
99   Real staff_space = Staff_symbol_referencer::staff_space (me);
100   Real staff_size;
101   Real thickness = me->get_paper ()->get_realvar (ly_symbol2scm ("linethickness"));
102   SCM lt =  me->get_grob_property ("thickness");
103   if (gh_number_p (lt))
104     thickness *= gh_scm2double (lt);
105   if (Staff_symbol_referencer::get_staff_symbol (me))
106     {
107       staff_size = (Staff_symbol_referencer::line_count (me) - 1) * staff_space;
108     }
109   else
110     staff_size = 0.0;
111
112   Real blotdiameter = me->get_paper ()->get_realvar (ly_symbol2scm ("blotdiameter"));
113
114   /*
115    * Draw a vertical line that is vertically centered in the staff
116    * (just like a bar).  The height of this line should be a little
117    * more than half the size of the staff, such that the endings of
118    * the line are in the middle of a staff space.
119    */
120   int lines = Staff_symbol_referencer::line_count (me);
121   int height = lines / 2; // little more than half of staff size
122   if ((lines & 1) != (height & 1))
123     height++; // ensure endings are centered in staff space
124
125   Interval xdim (0, thickness);
126   Interval ydim (-0.5 * height, +0.5 * height);
127   Box b (xdim, ydim);
128   Molecule out = Lookup::round_filled_box (b, blotdiameter);
129   return out.smobbed_copy ();
130 }
131
132 /*
133   Gregorian chant divisio maxima.
134  */
135 MAKE_SCHEME_CALLBACK (Breathing_sign,divisio_maxima,1);
136 SCM 
137 Breathing_sign::divisio_maxima (SCM smob)
138 {
139   Grob *me = unsmob_grob (smob);
140   Real staff_space = Staff_symbol_referencer::staff_space (me);
141   Real staff_size;
142   Real thickness = me->get_paper ()->get_realvar (ly_symbol2scm ("linethickness"));
143   SCM lt =  me->get_grob_property ("thickness");
144   if (gh_number_p (lt))
145     thickness *= gh_scm2double (lt);
146   if (Staff_symbol_referencer::get_staff_symbol (me))
147     {
148       staff_size = (Staff_symbol_referencer::line_count (me) - 1) * staff_space;
149     }
150   else
151     staff_size = 0.0;
152
153   Real blotdiameter = me->get_paper ()->get_realvar (ly_symbol2scm ("blotdiameter"));
154
155   // like a "|" type bar
156   Interval xdim (0, thickness);
157   Interval ydim (-0.5 * staff_size, +0.5 * staff_size);
158   Box b (xdim, ydim);
159   Molecule out = Lookup::round_filled_box (b, blotdiameter);
160   return out.smobbed_copy ();
161 }
162
163 /*
164   Gregorian chant finalis.
165  */
166 MAKE_SCHEME_CALLBACK (Breathing_sign,finalis,1);
167 SCM 
168 Breathing_sign::finalis (SCM smob)
169 {
170   Grob *me = unsmob_grob (smob);
171   Real staff_space = Staff_symbol_referencer::staff_space (me);
172   Real staff_size;
173   Real thickness = me->get_paper ()->get_realvar (ly_symbol2scm ("linethickness"));
174   SCM lt =  me->get_grob_property ("thickness");
175   if (gh_number_p (lt))
176     thickness *= gh_scm2double (lt);
177   if (Staff_symbol_referencer::get_staff_symbol (me))
178     {
179       staff_size = (Staff_symbol_referencer::line_count (me) - 1) * staff_space;
180     }
181   else
182     staff_size = 0.0;
183
184   Real blotdiameter = me->get_paper ()->get_realvar (ly_symbol2scm ("blotdiameter"));
185
186   // like a "||" type bar
187   Interval xdim (0, thickness);
188   Interval ydim (-0.5 * staff_size, +0.5 * staff_size);
189   Box b (xdim, ydim);
190   Molecule line1 = Lookup::round_filled_box (b, blotdiameter);
191   Molecule line2 (line1);
192   line2.translate_axis (0.5 * staff_space, X_AXIS);
193   line1.add_molecule (line2);
194
195   return line1.smobbed_copy ();
196 }
197
198 MAKE_SCHEME_CALLBACK (Breathing_sign,offset_callback,2);
199 SCM
200 Breathing_sign::offset_callback (SCM element_smob, SCM)
201 {
202   Grob *me = unsmob_grob (element_smob);
203   
204   Direction d = Directional_element_interface::get (me);
205   if (!d)
206     {
207       d = UP;
208       Directional_element_interface::set (me, d);
209     }
210
211   Real inter_f = Staff_symbol_referencer::staff_space (me)/2;
212   int sz = Staff_symbol_referencer::line_count (me)-1;
213   return gh_double2scm (inter_f * sz * d);
214 }
215
216 ADD_INTERFACE(Breathing_sign, "breathing-sign-interface",
217               "A breathing sign.",
218               "direction");