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)
32 me->translate_axis (ss, Y_AXIS);
37 me->translate_axis (ss / 2, Y_AXIS);
40 Grob *d = unsmob_grob (me->get_property ("dot"));
41 if (d && bt > 4) // UGH.
43 d->set_property ("staff-position",
44 scm_int2num ((bt == 7) ? 4 : 3));
46 if (d && bt >= -1 && bt <= 1) // UGH again.
48 d->set_property ("staff-position",
49 scm_int2num ((bt == 0) ? -1 : 1));
51 return SCM_UNSPECIFIED;
55 make this function easily usable in C++
58 Rest::glyph_name (Grob *me, int balltype, String style, bool try_ledgers)
60 bool ledgered_b = false;
61 if (try_ledgers && (balltype == 0 || balltype == 1))
63 Real rad = Staff_symbol_referencer::staff_radius (me) * 2.0;
64 Real pos = Staff_symbol_referencer::get_position (me);
67 Figure out when the rest is far enough outside the staff. This
68 could bemore generic, but hey, we understand this even after
71 ledgered_b |= (balltype == 0) && (pos >= +rad + 2 || pos < -rad);
72 ledgered_b |= (balltype == 1) && (pos <= -rad - 2 || pos > +rad);
75 String actual_style (style.to_str0 ());
77 if ((style == "mensural") || (style == "neomensural"))
81 FIXME: Currently, ancient font does not provide ledgered rests;
82 hence the "o" suffix in the glyph name is bogus. But do we need
83 ledgered rests at all now that we can draw ledger lines with
84 variable width, length and blotdiameter? -- jr
89 There are no 32th/64th/128th mensural/neomensural rests. In
90 these cases, revert back to default style.
96 if ((style == "classical") && (balltype != 2))
99 classical style: revert back to default style for any rest other
105 if (style == "default")
108 Some parts of lily still prefer style "default" over "".
109 Correct this here. -- jr
114 return ("rests." + to_string (balltype) + (ledgered_b ? "o" : "")
118 MAKE_SCHEME_CALLBACK (Rest, print, 1);
121 Rest::brew_internal_stencil (SCM smob, bool ledgered)
123 Grob *me = unsmob_grob (smob);
125 SCM balltype_scm = me->get_property ("duration-log");
126 if (!scm_is_number (balltype_scm))
127 return Stencil ().smobbed_copy ();
129 int balltype = scm_to_int (balltype_scm);
132 SCM style_scm = me->get_property ("style");
133 if (scm_is_symbol (style_scm))
134 style = ly_scm2string (scm_symbol_to_string (style_scm));
136 Font_metric *fm = Font_interface::get_default_font (me);
137 String font_char = glyph_name (me, balltype, style, ledgered);
138 Stencil out = fm->find_by_name (font_char);
140 me->warning (_f ("rest `%s' not found", font_char.to_str0 ()));
142 return out.smobbed_copy ();
146 Rest::print (SCM smob)
148 return brew_internal_stencil (smob, true);
151 MAKE_SCHEME_CALLBACK (Rest, extent_callback, 2);
153 We need the callback. The real stencil has ledgers depending on
154 Y-position. The Y-position is known only after line breaking. */
156 Rest::extent_callback (SCM smob, SCM ax)
158 Axis a = (Axis) scm_to_int (ax);
161 Don't want ledgers: ledgers depend on Y position, which depends on
162 rest collision, which depends on stem size which depends on beam
163 slop of opposite note column.
165 consequence: we get too small extents and potential collisions
168 SCM m = brew_internal_stencil (smob, a != X_AXIS);
169 return ly_interval2scm (unsmob_stencil (m)->extent (a));
172 MAKE_SCHEME_CALLBACK (Rest, polyphonic_offset_callback, 2);
174 Rest::polyphonic_offset_callback (SCM smob, SCM)
176 Grob *me = unsmob_grob (smob);
177 if (scm_is_number (me->get_property ("staff-position")))
178 return scm_make_real (0);
180 Direction d = get_grob_direction (me);
183 off *= Staff_symbol_referencer::staff_space (me);
185 return scm_make_real (off);
188 ADD_INTERFACE (Rest, "rest-interface",
190 "style direction minimum-distance");