2 rest.cc -- implement Rest
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--2006 Han-Wen Nienhuys <hanwen@xs4all.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);
29 Real amount = robust_scm2double (me->get_property ("staff-position"), 0)
33 if (duration_log == 0 && line_count > 1)
39 Grob *dot = unsmob_grob (me->get_object ("dot"));
40 if (dot && duration_log > 4) // UGH.
42 dot->set_property ("staff-position",
43 scm_from_int ((duration_log == 7) ? 4 : 3));
45 if (dot && duration_log >= -1 && duration_log <= 1) // UGH again.
47 dot->set_property ("staff-position",
48 scm_from_int ((duration_log == 0) ? -1 : 1));
51 amount += 2 * ss * get_grob_direction (me);;
53 return scm_from_double (amount);
57 make this function easily usable in C++
60 Rest::glyph_name (Grob *me, int balltype, String style, bool try_ledgers)
62 bool is_ledgered = false;
63 if (try_ledgers && (balltype == 0 || balltype == 1))
65 Real rad = Staff_symbol_referencer::staff_radius (me) * 2.0;
66 Real pos = Staff_symbol_referencer::get_position (me);
69 Figure out when the rest is far enough outside the staff. This
70 could bemore generic, but hey, we understand this even after
73 is_ledgered |= (balltype == 0) && (pos >= +rad + 2 || pos < -rad);
74 is_ledgered |= (balltype == 1) && (pos <= -rad - 2 || pos > +rad);
77 String actual_style (style.to_str0 ());
79 if ((style == "mensural") || (style == "neomensural"))
83 FIXME: Currently, ancient font does not provide ledgered rests;
84 hence the "o" suffix in the glyph name is bogus. But do we need
85 ledgered rests at all now that we can draw ledger lines with
86 variable width, length and blotdiameter? -- jr
91 There are no 32th/64th/128th mensural/neomensural rests. In
92 these cases, revert back to default style.
98 if ((style == "classical") && (balltype != 2))
101 classical style: revert back to default style for any rest other
107 if (style == "default")
110 Some parts of lily still prefer style "default" over "".
111 Correct this here. -- jr
116 return ("rests." + to_string (balltype) + (is_ledgered ? "o" : "")
120 MAKE_SCHEME_CALLBACK (Rest, print, 1);
122 Rest::brew_internal_stencil (Grob *me, bool ledgered)
124 SCM balltype_scm = me->get_property ("duration-log");
125 if (!scm_is_number (balltype_scm))
126 return Stencil ().smobbed_copy ();
128 int balltype = scm_to_int (balltype_scm);
131 SCM style_scm = me->get_property ("style");
132 if (scm_is_symbol (style_scm))
133 style = ly_scm2string (scm_symbol_to_string (style_scm));
135 Font_metric *fm = Font_interface::get_default_font (me);
136 String font_char = glyph_name (me, balltype, style, ledgered);
137 Stencil out = fm->find_by_name (font_char);
139 me->warning (_f ("rest `%s' not found", font_char.to_str0 ()));
141 return out.smobbed_copy ();
145 Rest::print (SCM smob)
147 return brew_internal_stencil (unsmob_grob (smob), true);
150 MAKE_SCHEME_CALLBACK (Rest, width, 1);
152 We need the callback. The real stencil has ledgers depending on
153 Y-position. The Y-position is known only after line breaking. */
155 Rest::width (SCM smob)
157 return generic_extent_callback (unsmob_grob (smob), X_AXIS);
160 MAKE_SCHEME_CALLBACK (Rest, height, 1);
162 Rest::height (SCM smob)
164 return generic_extent_callback (unsmob_grob (smob), Y_AXIS);
168 We need the callback. The real stencil has ledgers depending on
169 Y-position. The Y-position is known only after line breaking. */
171 Rest::generic_extent_callback (Grob *me, Axis a)
174 Don't want ledgers: ledgers depend on Y position, which depends on
175 rest collision, which depends on stem size which depends on beam
176 slop of opposite note column.
178 consequence: we get too small extents and potential collisions
181 SCM m = brew_internal_stencil (me, a != X_AXIS);
182 return ly_interval2scm (unsmob_stencil (m)->extent (a));
185 ADD_INTERFACE (Rest, "rest-interface",