2 rest.cc -- implement Rest
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--2005 Han-Wen Nienhuys <hanwen@cs.uu.nl>
12 #include "output-def.hh"
13 #include "font-interface.hh"
15 #include "paper-score.hh"
16 #include "staff-symbol-referencer.hh"
17 #include "directional-element-interface.hh"
20 MAKE_SCHEME_CALLBACK (Rest, y_offset_callback, 1);
22 Rest::y_offset_callback (SCM smob)
24 Grob *me = unsmob_grob (smob);
25 int duration_log = scm_to_int (me->get_property ("duration-log"));
26 int line_count = Staff_symbol_referencer::line_count (me);
27 Real ss = Staff_symbol_referencer::staff_space (me);
32 if (duration_log == 0 && line_count > 1)
38 Grob *dot = unsmob_grob (me->get_object ("dot"));
39 if (dot && duration_log > 4) // UGH.
41 dot->set_property ("staff-position",
42 scm_from_int ((duration_log == 7) ? 4 : 3));
44 if (dot && duration_log >= -1 && duration_log <= 1) // UGH again.
46 dot->set_property ("staff-position",
47 scm_from_int ((duration_log == 0) ? -1 : 1));
50 amount += 2 * ss * get_grob_direction (me);;
52 return scm_from_double (amount);
56 make this function easily usable in C++
59 Rest::glyph_name (Grob *me, int balltype, String style, bool try_ledgers)
61 bool is_ledgered = false;
62 if (try_ledgers && (balltype == 0 || balltype == 1))
64 Real rad = Staff_symbol_referencer::staff_radius (me) * 2.0;
65 Real pos = Staff_symbol_referencer::get_position (me);
68 Figure out when the rest is far enough outside the staff. This
69 could bemore generic, but hey, we understand this even after
72 is_ledgered |= (balltype == 0) && (pos >= +rad + 2 || pos < -rad);
73 is_ledgered |= (balltype == 1) && (pos <= -rad - 2 || pos > +rad);
76 String actual_style (style.to_str0 ());
78 if ((style == "mensural") || (style == "neomensural"))
82 FIXME: Currently, ancient font does not provide ledgered rests;
83 hence the "o" suffix in the glyph name is bogus. But do we need
84 ledgered rests at all now that we can draw ledger lines with
85 variable width, length and blotdiameter? -- jr
90 There are no 32th/64th/128th mensural/neomensural rests. In
91 these cases, revert back to default style.
97 if ((style == "classical") && (balltype != 2))
100 classical style: revert back to default style for any rest other
106 if (style == "default")
109 Some parts of lily still prefer style "default" over "".
110 Correct this here. -- jr
115 return ("rests." + to_string (balltype) + (is_ledgered ? "o" : "")
119 MAKE_SCHEME_CALLBACK (Rest, print, 1);
121 Rest::brew_internal_stencil (Grob *me, bool ledgered)
123 SCM balltype_scm = me->get_property ("duration-log");
124 if (!scm_is_number (balltype_scm))
125 return Stencil ().smobbed_copy ();
127 int balltype = scm_to_int (balltype_scm);
130 SCM style_scm = me->get_property ("style");
131 if (scm_is_symbol (style_scm))
132 style = ly_scm2string (scm_symbol_to_string (style_scm));
134 Font_metric *fm = Font_interface::get_default_font (me);
135 String font_char = glyph_name (me, balltype, style, ledgered);
136 Stencil out = fm->find_by_name (font_char);
138 me->warning (_f ("rest `%s' not found", font_char.to_str0 ()));
140 return out.smobbed_copy ();
144 Rest::print (SCM smob)
146 return brew_internal_stencil (unsmob_grob (smob), true);
149 MAKE_SCHEME_CALLBACK (Rest, width, 1);
151 We need the callback. The real stencil has ledgers depending on
152 Y-position. The Y-position is known only after line breaking. */
154 Rest::width (SCM smob)
156 return generic_extent_callback (unsmob_grob (smob), X_AXIS);
159 MAKE_SCHEME_CALLBACK (Rest, height, 1);
161 Rest::height (SCM smob)
163 return generic_extent_callback (unsmob_grob (smob), Y_AXIS);
167 We need the callback. The real stencil has ledgers depending on
168 Y-position. The Y-position is known only after line breaking. */
170 Rest::generic_extent_callback (Grob *me, Axis a)
173 Don't want ledgers: ledgers depend on Y position, which depends on
174 rest collision, which depends on stem size which depends on beam
175 slop of opposite note column.
177 consequence: we get too small extents and potential collisions
180 SCM m = brew_internal_stencil (me, a != X_AXIS);
181 return ly_interval2scm (unsmob_stencil (m)->extent (a));
184 ADD_INTERFACE (Rest, "rest-interface",