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, after_line_breaking, 1);
22 Rest::after_line_breaking (SCM smob)
24 Grob *me = unsmob_grob (smob);
25 int bt = scm_to_int (me->get_property ("duration-log"));
26 int lc = Staff_symbol_referencer::line_count (me);
27 Real ss = Staff_symbol_referencer::staff_space (me);
30 if (bt == 0 && lc > 1)
31 me->translate_axis (ss, Y_AXIS);
34 me->translate_axis (ss / 2, Y_AXIS);
36 Grob *d = unsmob_grob (me->get_object ("dot"));
37 if (d && bt > 4) // UGH.
39 d->set_property ("staff-position",
40 scm_from_int ((bt == 7) ? 4 : 3));
42 if (d && bt >= -1 && bt <= 1) // UGH again.
44 d->set_property ("staff-position",
45 scm_from_int ((bt == 0) ? -1 : 1));
47 return SCM_UNSPECIFIED;
51 make this function easily usable in C++
54 Rest::glyph_name (Grob *me, int balltype, String style, bool try_ledgers)
56 bool ledgered_b = false;
57 if (try_ledgers && (balltype == 0 || balltype == 1))
59 Real rad = Staff_symbol_referencer::staff_radius (me) * 2.0;
60 Real pos = Staff_symbol_referencer::get_position (me);
63 Figure out when the rest is far enough outside the staff. This
64 could bemore generic, but hey, we understand this even after
67 ledgered_b |= (balltype == 0) && (pos >= +rad + 2 || pos < -rad);
68 ledgered_b |= (balltype == 1) && (pos <= -rad - 2 || pos > +rad);
71 String actual_style (style.to_str0 ());
73 if ((style == "mensural") || (style == "neomensural"))
77 FIXME: Currently, ancient font does not provide ledgered rests;
78 hence the "o" suffix in the glyph name is bogus. But do we need
79 ledgered rests at all now that we can draw ledger lines with
80 variable width, length and blotdiameter? -- jr
85 There are no 32th/64th/128th mensural/neomensural rests. In
86 these cases, revert back to default style.
92 if ((style == "classical") && (balltype != 2))
95 classical style: revert back to default style for any rest other
101 if (style == "default")
104 Some parts of lily still prefer style "default" over "".
105 Correct this here. -- jr
110 return ("rests." + to_string (balltype) + (ledgered_b ? "o" : "")
114 MAKE_SCHEME_CALLBACK (Rest, print, 1);
117 Rest::brew_internal_stencil (SCM smob, bool ledgered)
119 Grob *me = unsmob_grob (smob);
121 SCM balltype_scm = me->get_property ("duration-log");
122 if (!scm_is_number (balltype_scm))
123 return Stencil ().smobbed_copy ();
125 int balltype = scm_to_int (balltype_scm);
128 SCM style_scm = me->get_property ("style");
129 if (scm_is_symbol (style_scm))
130 style = ly_scm2string (scm_symbol_to_string (style_scm));
132 Font_metric *fm = Font_interface::get_default_font (me);
133 String font_char = glyph_name (me, balltype, style, ledgered);
134 Stencil out = fm->find_by_name (font_char);
136 me->warning (_f ("rest `%s' not found", font_char.to_str0 ()));
138 return out.smobbed_copy ();
142 Rest::print (SCM smob)
144 return brew_internal_stencil (smob, true);
147 MAKE_SCHEME_CALLBACK (Rest, extent_callback, 2);
149 We need the callback. The real stencil has ledgers depending on
150 Y-position. The Y-position is known only after line breaking. */
152 Rest::extent_callback (SCM smob, SCM ax)
154 Axis a = (Axis) scm_to_int (ax);
157 Don't want ledgers: ledgers depend on Y position, which depends on
158 rest collision, which depends on stem size which depends on beam
159 slop of opposite note column.
161 consequence: we get too small extents and potential collisions
164 SCM m = brew_internal_stencil (smob, a != X_AXIS);
165 return ly_interval2scm (unsmob_stencil (m)->extent (a));
168 MAKE_SCHEME_CALLBACK (Rest, polyphonic_offset_callback, 2);
170 Rest::polyphonic_offset_callback (SCM smob, SCM)
172 Grob *me = unsmob_grob (smob);
173 if (scm_is_number (me->get_property ("staff-position")))
174 return scm_from_double (0);
176 Direction d = get_grob_direction (me);
179 off *= Staff_symbol_referencer::staff_space (me);
181 return scm_from_double (off);
184 ADD_INTERFACE (Rest, "rest-interface",
186 "style direction minimum-distance");