2 This file is part of LilyPond, the GNU music typesetter.
4 Copyright (C) 1997--2011 Han-Wen Nienhuys <hanwen@xs4all.nl>
6 LilyPond is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 LilyPond is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
22 #include "directional-element-interface.hh"
24 #include "font-interface.hh"
25 #include "international.hh"
26 #include "output-def.hh"
27 #include "paper-score.hh"
28 #include "staff-symbol-referencer.hh"
33 MAKE_SCHEME_CALLBACK (Rest, y_offset_callback, 1);
35 Rest::y_offset_callback (SCM smob)
37 Grob *me = unsmob_grob (smob);
38 int duration_log = scm_to_int (me->get_property ("duration-log"));
39 int line_count = Staff_symbol_referencer::line_count (me);
40 Real ss = Staff_symbol_referencer::staff_space (me);
42 bool position_override = scm_is_number (me->get_property ("staff-position"));
45 if (position_override)
48 robust_scm2double (me->get_property ("staff-position"), 0) * 0.5 * ss;
50 trust the client on good positioning;
51 would be tempting to adjust position of rests longer than a quarter
52 to be properly aligned to staff lines,
53 but custom rest shapes may not need that sort of care.
58 amount = 2 * ss * get_grob_direction (me);
60 if (line_count % 2 == 0)
65 make a semibreve rest hang from the next line,
66 except for a single line staff
68 if (duration_log == 0 && line_count > 1)
71 return scm_from_double (amount);
74 /* A rest might lie under a beam, in which case it should be cross-staff if
75 the beam is cross-staff because the rest's position depends on the
76 formatting of the beam. */
77 MAKE_SCHEME_CALLBACK (Rest, calc_cross_staff, 1);
79 Rest::calc_cross_staff (SCM smob)
81 Grob *me = unsmob_grob (smob);
82 Grob *stem = unsmob_grob (me->get_object ("stem"));
87 return stem->get_property ("cross-staff");
91 make this function easily usable in C++
94 Rest::glyph_name (Grob *me, int balltype, string style, bool try_ledgers)
96 bool is_ledgered = false;
97 if (try_ledgers && (balltype == -1 || balltype == 0 || balltype == 1))
99 Real rad = Staff_symbol_referencer::staff_radius (me) * 2.0;
100 Real pos = Staff_symbol_referencer::get_position (me);
103 Figure out when the rest is far enough outside the staff. This
104 could bemore generic, but hey, we understand this even after
107 is_ledgered |= (balltype == -1) && (pos <= -rad - 3 || pos >= +rad + 1);
108 is_ledgered |= (balltype == 0) && (pos >= +rad + 2 || pos < -rad);
109 is_ledgered |= (balltype == 1) && (pos <= -rad - 2 || pos > +rad);
112 string actual_style (style.c_str ());
114 if ((style == "mensural") || (style == "neomensural"))
118 FIXME: Currently, ancient font does not provide ledgered rests;
119 hence the "o" suffix in the glyph name is bogus. But do we need
120 ledgered rests at all now that we can draw ledger lines with
121 variable width, length and blotdiameter? -- jr
126 There are no 32th/64th/128th mensural/neomensural rests. In
127 these cases, revert back to default style.
133 if ((style == "classical") && (balltype != 2))
136 classical style: revert back to default style for any rest other
142 if (style == "default")
145 Some parts of lily still prefer style "default" over "".
146 Correct this here. -- jr
151 return ("rests." + to_string (balltype) + (is_ledgered ? "o" : "")
155 MAKE_SCHEME_CALLBACK (Rest, print, 1);
157 Rest::brew_internal_stencil (Grob *me, bool ledgered)
159 SCM balltype_scm = me->get_property ("duration-log");
160 if (!scm_is_number (balltype_scm))
161 return Stencil ().smobbed_copy ();
163 int balltype = scm_to_int (balltype_scm);
165 string style = robust_symbol2string (me->get_property ("style"), "default");
167 Font_metric *fm = Font_interface::get_default_font (me);
168 string font_char = glyph_name (me, balltype, style, ledgered);
169 Stencil out = fm->find_by_name (font_char);
171 me->warning (_f ("rest `%s' not found", font_char.c_str ()));
173 return out.smobbed_copy ();
177 translate the rest vertically by amount DY, but only if
178 it doesn't have staff-position set.
181 Rest::translate (Grob *me, int dy)
183 if (!scm_is_number (me->get_property ("staff-position")))
185 me->translate_axis (dy * Staff_symbol_referencer::staff_space (me) / 2.0, Y_AXIS);
186 Grob *p = me->get_parent (Y_AXIS);
187 p->flush_extent_cache (Y_AXIS);
192 Rest::print (SCM smob)
194 return brew_internal_stencil (unsmob_grob (smob), true);
197 MAKE_SCHEME_CALLBACK (Rest, width, 1);
199 We need the callback. The real stencil has ledgers depending on
200 Y-position. The Y-position is known only after line breaking. */
202 Rest::width (SCM smob)
204 return generic_extent_callback (unsmob_grob (smob), X_AXIS);
207 MAKE_SCHEME_CALLBACK (Rest, height, 1);
209 Rest::height (SCM smob)
211 return generic_extent_callback (unsmob_grob (smob), Y_AXIS);
215 We need the callback. The real stencil has ledgers depending on
216 Y-position. The Y-position is known only after line breaking. */
218 Rest::generic_extent_callback (Grob *me, Axis a)
221 Don't want ledgers: ledgers depend on Y position, which depends on
222 rest collision, which depends on stem size which depends on beam
223 slop of opposite note column.
225 consequence: we get too small extents and potential collisions
228 SCM m = brew_internal_stencil (me, a != X_AXIS);
229 return ly_interval2scm (unsmob_stencil (m)->extent (a));
232 MAKE_SCHEME_CALLBACK (Rest, pure_height, 3);
234 Rest::pure_height (SCM smob,
238 Grob *me = unsmob_grob (smob);
239 SCM m = brew_internal_stencil (me, false);
240 return ly_interval2scm (unsmob_stencil (m)->extent (Y_AXIS));
244 "A rest symbol. The property @code{style} can be"
245 " @code{default}, @code{mensural}, @code{neomensural} or"
246 " @code{classical}.",