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" : "")
119 MAKE_SCHEME_CALLBACK (Rest, print, 1);
122 Rest::brew_internal_stencil (SCM smob, bool ledgered)
124 Grob* me = unsmob_grob (smob);
126 SCM balltype_scm = me->get_property ("duration-log");
127 if (!scm_is_number (balltype_scm))
128 return Stencil ().smobbed_copy ();
130 int balltype = scm_to_int (balltype_scm);
133 SCM style_scm = me->get_property ("style");
134 if (scm_is_symbol (style_scm))
135 style = ly_scm2string (scm_symbol_to_string (style_scm));
137 Font_metric *fm = Font_interface::get_default_font (me);
138 String font_char = glyph_name (me, balltype, style, ledgered);
139 Stencil out = fm->find_by_name (font_char);
141 me->warning (_f ("rest `%s' not found", font_char.to_str0 ()));
143 return out.smobbed_copy ();
147 Rest::print (SCM smob)
149 return brew_internal_stencil (smob, true);
152 MAKE_SCHEME_CALLBACK (Rest, extent_callback, 2);
154 We need the callback. The real stencil has ledgers depending on
155 Y-position. The Y-position is known only after line breaking. */
157 Rest::extent_callback (SCM smob, SCM ax)
159 Axis a = (Axis) scm_to_int (ax);
162 Don't want ledgers: ledgers depend on Y position, which depends on
163 rest collision, which depends on stem size which depends on beam
164 slop of opposite note column.
166 consequence: we get too small extents and potential collisions
169 SCM m = brew_internal_stencil (smob, a != X_AXIS);
170 return ly_interval2scm (unsmob_stencil (m)->extent (a));
173 MAKE_SCHEME_CALLBACK (Rest, polyphonic_offset_callback, 2);
175 Rest::polyphonic_offset_callback (SCM smob, SCM)
177 Grob* me = unsmob_grob (smob);
178 if (scm_is_number (me->get_property ("staff-position")))
179 return scm_make_real (0);
181 Direction d = get_grob_direction (me);
184 off *= Staff_symbol_referencer::staff_space (me);
186 return scm_make_real (off);
189 ADD_INTERFACE (Rest, "rest-interface",
191 "style direction minimum-distance");