Update from Francisco.
[lilypond.git] / lily / rest.cc
blob1abb770d7b307a7150e22ed90be2f746e5124400
1 /*
2 rest.cc -- implement Rest
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--2007 Han-Wen Nienhuys <hanwen@xs4all.nl>
7 */
9 #include "rest.hh"
11 #include "directional-element-interface.hh"
12 #include "dots.hh"
13 #include "font-interface.hh"
14 #include "international.hh"
15 #include "output-def.hh"
16 #include "paper-score.hh"
17 #include "staff-symbol-referencer.hh"
18 #include "stencil.hh"
19 #include "grob.hh"
21 // -> offset callback
22 MAKE_SCHEME_CALLBACK (Rest, y_offset_callback, 1);
23 SCM
24 Rest::y_offset_callback (SCM smob)
26 Grob *me = unsmob_grob (smob);
27 int duration_log = scm_to_int (me->get_property ("duration-log"));
28 int line_count = Staff_symbol_referencer::line_count (me);
29 Real ss = Staff_symbol_referencer::staff_space (me);
31 bool position_override = scm_is_number (me->get_property ("staff-position"));
32 Real amount = robust_scm2double (me->get_property ("staff-position"), 0)
33 * 0.5 * ss;
35 if (line_count % 2)
37 if (duration_log == 0 && line_count > 1)
38 amount += ss;
40 else
41 amount += ss / 2;
43 if (!position_override)
44 amount += 2 * ss * get_grob_direction (me);;
46 return scm_from_double (amount);
50 make this function easily usable in C++
52 string
53 Rest::glyph_name (Grob *me, int balltype, string style, bool try_ledgers)
55 bool is_ledgered = false;
56 if (try_ledgers && (balltype == 0 || balltype == 1))
58 Real rad = Staff_symbol_referencer::staff_radius (me) * 2.0;
59 Real pos = Staff_symbol_referencer::get_position (me);
62 Figure out when the rest is far enough outside the staff. This
63 could bemore generic, but hey, we understand this even after
64 dinner.
66 is_ledgered |= (balltype == 0) && (pos >= +rad + 2 || pos < -rad);
67 is_ledgered |= (balltype == 1) && (pos <= -rad - 2 || pos > +rad);
70 string actual_style (style.c_str ());
72 if ((style == "mensural") || (style == "neomensural"))
76 FIXME: Currently, ancient font does not provide ledgered rests;
77 hence the "o" suffix in the glyph name is bogus. But do we need
78 ledgered rests at all now that we can draw ledger lines with
79 variable width, length and blotdiameter? -- jr
81 is_ledgered = 0;
84 There are no 32th/64th/128th mensural/neomensural rests. In
85 these cases, revert back to default style.
87 if (balltype > 4)
88 actual_style = "";
91 if ((style == "classical") && (balltype != 2))
94 classical style: revert back to default style for any rest other
95 than quarter rest
97 actual_style = "";
100 if (style == "default")
103 Some parts of lily still prefer style "default" over "".
104 Correct this here. -- jr
106 actual_style = "";
109 return ("rests." + to_string (balltype) + (is_ledgered ? "o" : "")
110 + actual_style);
113 MAKE_SCHEME_CALLBACK (Rest, print, 1);
115 Rest::brew_internal_stencil (Grob *me, bool ledgered)
117 SCM balltype_scm = me->get_property ("duration-log");
118 if (!scm_is_number (balltype_scm))
119 return Stencil ().smobbed_copy ();
121 int balltype = scm_to_int (balltype_scm);
123 string style;
124 SCM style_scm = me->get_property ("style");
125 if (scm_is_symbol (style_scm))
126 style = ly_scm2string (scm_symbol_to_string (style_scm));
128 Font_metric *fm = Font_interface::get_default_font (me);
129 string font_char = glyph_name (me, balltype, style, ledgered);
130 Stencil out = fm->find_by_name (font_char);
131 if (out.is_empty ())
132 me->warning (_f ("rest `%s' not found", font_char.c_str ()));
134 return out.smobbed_copy ();
138 Rest::print (SCM smob)
140 return brew_internal_stencil (unsmob_grob (smob), true);
143 MAKE_SCHEME_CALLBACK (Rest, width, 1);
145 We need the callback. The real stencil has ledgers depending on
146 Y-position. The Y-position is known only after line breaking. */
148 Rest::width (SCM smob)
150 return generic_extent_callback (unsmob_grob (smob), X_AXIS);
153 MAKE_SCHEME_CALLBACK (Rest, height, 1);
155 Rest::height (SCM smob)
157 return generic_extent_callback (unsmob_grob (smob), Y_AXIS);
161 We need the callback. The real stencil has ledgers depending on
162 Y-position. The Y-position is known only after line breaking. */
164 Rest::generic_extent_callback (Grob *me, Axis a)
167 Don't want ledgers: ledgers depend on Y position, which depends on
168 rest collision, which depends on stem size which depends on beam
169 slop of opposite note column.
171 consequence: we get too small extents and potential collisions
172 with ledgered rests.
174 SCM m = brew_internal_stencil (me, a != X_AXIS);
175 return ly_interval2scm (unsmob_stencil (m)->extent (a));
178 MAKE_SCHEME_CALLBACK (Rest, pure_height, 3);
180 Rest::pure_height (SCM smob, SCM start, SCM end)
182 (void) start;
183 (void) end;
185 Grob *me = unsmob_grob (smob);
186 SCM m = brew_internal_stencil (me, false);
187 return ly_interval2scm (unsmob_stencil (m)->extent (Y_AXIS));
190 ADD_INTERFACE (Rest,
191 "A rest symbol. The property @code{style} can be"
192 " @code{default}, @code{mensural}, @code{neomensural} or"
193 " @code{classical}.",
195 /* properties */
196 "direction "
197 "minimum-distance "
198 "style "