2 rest.cc -- implement Rest
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
10 #include "output-def.hh"
11 #include "font-interface.hh"
14 #include "paper-score.hh"
15 #include "staff-symbol-referencer.hh"
16 #include "directional-element-interface.hh"
19 MAKE_SCHEME_CALLBACK (Rest,after_line_breaking,1);
21 Rest::after_line_breaking (SCM smob)
23 Grob *me = unsmob_grob (smob);
24 int bt = ly_scm2int (me->get_property ("duration-log"));
25 int lc = Staff_symbol_referencer::line_count (me);
26 Real ss = Staff_symbol_referencer::staff_space (me);
29 if (bt == 0 && lc > 1)
31 me->translate_axis (ss , Y_AXIS);
36 me->translate_axis (ss/2 , Y_AXIS);
39 Grob * d = unsmob_grob (me->get_property ("dot"));
40 if (d && bt > 4) // UGH.
42 d->set_property ("staff-position",
43 scm_int2num ((bt == 7) ? 4 : 3));
45 if (d && bt >= -1 && bt <= 1) // UGH again.
47 d->set_property ("staff-position",
48 scm_int2num ((bt == 0) ? -1 : 1));
50 return SCM_UNSPECIFIED;
54 make this function easily usable in C++
57 Rest::glyph_name (Grob *me, int balltype, String style)
59 bool ledgered_b = false;
61 if (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 == "neo_mensural")) {
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/neo_mensural 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" : "") + actual_style;
115 MAKE_SCHEME_CALLBACK (Rest,print,1);
118 Rest::brew_internal_stencil (SCM smob)
120 Grob* me = unsmob_grob (smob);
122 SCM balltype_scm = me->get_property ("duration-log");
123 if (!ly_c_number_p (balltype_scm))
124 return Stencil ().smobbed_copy ();
126 int balltype = ly_scm2int (balltype_scm);
129 SCM style_scm = me->get_property ("style");
130 if (ly_c_symbol_p (style_scm))
131 style = ly_scm2string (scm_symbol_to_string (style_scm));
133 Font_metric *fm = Font_interface::get_default_font (me);
134 String font_char = glyph_name (me, balltype, style);
135 Stencil out = fm->find_by_name (font_char);
137 me->warning (_f ("rest `%s' not found", font_char.to_str0 ()));
139 return out.smobbed_copy ();
143 Rest::print (SCM smob)
145 return brew_internal_stencil (smob);
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) ly_scm2int (ax);
155 SCM m = brew_internal_stencil (smob);
156 return ly_interval2scm (unsmob_stencil (m)->extent (a));
159 MAKE_SCHEME_CALLBACK (Rest,polyphonic_offset_callback,2);
161 Rest::polyphonic_offset_callback (SCM smob, SCM)
163 Grob* me = unsmob_grob (smob);
164 if (ly_c_number_p (me->get_property ("staff-position")))
165 return scm_make_real (0);
167 Direction d = get_grob_direction (me);
170 off *= Staff_symbol_referencer::staff_space (me);
171 return scm_make_real (off);
174 ADD_INTERFACE (Rest,"rest-interface",
176 "style direction minimum-distance");