(Which properties to
[lilypond.git] / lily / rest.cc
blob16b5032ec1baccb7d375167709f0d3b84e7f93ba
1 /*
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>
7 */
9 #include "stencil.hh"
10 #include "paper-def.hh"
11 #include "font-interface.hh"
12 #include "rest.hh"
13 #include "dots.hh"
14 #include "paper-score.hh"
15 #include "staff-symbol-referencer.hh"
16 #include "directional-element-interface.hh"
18 // -> offset callback
19 MAKE_SCHEME_CALLBACK (Rest,after_line_breaking,1);
20 SCM
21 Rest::after_line_breaking (SCM smob)
23 Grob *me = unsmob_grob (smob);
24 int bt = gh_scm2int (me->get_property ("duration-log"));
25 int lc = Staff_symbol_referencer::line_count (me);
26 Real ss = Staff_symbol_referencer::staff_space (me);
27 if (lc % 2)
29 if (bt == 0 && lc > 1)
31 me->translate_axis (ss , Y_AXIS);
34 else
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 gh_int2scm ((bt == 7) ? 4 : 3));
45 if (d && bt >= -1 && bt <= 1) // UGH again.
47 d->set_property ("staff-position",
48 gh_int2scm ((bt == 0) ? -1 : 1));
50 return SCM_UNSPECIFIED;
54 make this function easily usable in C++
56 String
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
69 dinner.
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
85 ledgered_b = 0;
88 There are no 32th/64th/128th mensural/neo_mensural rests. In
89 these cases, revert back to default style.
91 if (balltype > 4)
92 actual_style = "";
95 if ((style == "classical") && (balltype != 2)) {
97 classical style: revert back to default style for any rest other
98 than quarter rest
100 actual_style = "";
103 if (style == "default") {
105 Some parts of lily still prefer style "default" over "".
106 Correct this here. -- jr
108 actual_style = "";
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 (!gh_number_p (balltype_scm))
124 return Stencil ().smobbed_copy ();
126 int balltype = gh_scm2int (balltype_scm);
128 String style;
129 SCM style_scm = me->get_property ("style");
130 if (gh_symbol_p (style_scm))
132 style = ly_scm2string (scm_symbol_to_string (style_scm));
135 Font_metric *fm = Font_interface::get_default_font (me);
136 String font_char = glyph_name (me, balltype, style);
137 Stencil out = fm->find_by_name (font_char);
138 if (out.is_empty ())
140 me->warning (_f ("rest `%s' not found, ", font_char.to_str0 ()));
143 return out.smobbed_copy ();
146 SCM
147 Rest::print (SCM smob)
149 return brew_internal_stencil (smob);
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) gh_scm2int (ax);
159 SCM m = brew_internal_stencil (smob);
160 return ly_interval2scm (unsmob_stencil (m)->extent (a));
163 MAKE_SCHEME_CALLBACK (Rest,polyphonic_offset_callback,2);
165 Rest::polyphonic_offset_callback (SCM smob, SCM)
167 Grob* me = unsmob_grob (smob);
168 if (gh_number_p (me->get_property ("staff-position")))
169 return gh_double2scm (0);
171 Direction d = get_grob_direction (me);
172 Real off = 2* d ;
173 if (off)
174 off *= Staff_symbol_referencer::staff_space (me);
175 return gh_double2scm (off);
178 ADD_INTERFACE (Rest,"rest-interface",
179 "A rest symbol.",
180 "style minimum-distance");