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")) {
80 FIXME: Currently, ancient font does not provide ledgered rests;
81 hence the "o" suffix in the glyph name is bogus. But do we need
82 ledgered rests at all now that we can draw ledger lines with
83 variable width, length and blotdiameter? -- jr
88 There are no 32th/64th/128th mensural/neomensural rests. In
89 these cases, revert back to default style.
95 if ((style == "classical") && (balltype != 2)) {
97 classical style: revert back to default style for any rest other
103 if (style == "default") {
105 Some parts of lily still prefer style "default" over "".
106 Correct this here. -- jr
111 return ("rests." + to_string (balltype) + (ledgered_b ? "o" : "")
116 MAKE_SCHEME_CALLBACK (Rest,print,1);
119 Rest::brew_internal_stencil (SCM smob, bool ledgered)
121 Grob* me = unsmob_grob (smob);
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 (smob, true);
148 MAKE_SCHEME_CALLBACK (Rest,extent_callback,2);
150 We need the callback. The real stencil has ledgers depending on
151 Y-position. The Y-position is known only after line breaking. */
153 Rest::extent_callback (SCM smob, SCM ax)
155 Axis a = (Axis) scm_to_int (ax);
158 Don't want ledgers: ledgers depend on Y position, which depends on
159 rest collision, which depends on stem size which depends on beam
160 slop of opposite note column.
162 consequence: we get too small extents and potential collisions
165 SCM m = brew_internal_stencil (smob, a != X_AXIS);
166 return ly_interval2scm (unsmob_stencil (m)->extent (a));
169 MAKE_SCHEME_CALLBACK (Rest,polyphonic_offset_callback,2);
171 Rest::polyphonic_offset_callback (SCM smob, SCM)
173 Grob* me = unsmob_grob (smob);
174 if (scm_is_number (me->get_property ("staff-position")))
175 return scm_make_real (0);
177 Direction d = get_grob_direction (me);
180 off *= Staff_symbol_referencer::staff_space (me);
181 return scm_make_real (off);
184 ADD_INTERFACE (Rest,"rest-interface",
186 "style direction minimum-distance");