2 rest.cc -- implement Rest
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--2007 Han-Wen Nienhuys <hanwen@xs4all.nl>
11 #include "directional-element-interface.hh"
13 #include "font-interface.hh"
14 #include "international.hh"
15 #include "output-def.hh"
16 #include "paper-score.hh"
17 #include "staff-symbol-referencer.hh"
22 MAKE_SCHEME_CALLBACK (Rest
, y_offset_callback
, 1);
24 Rest::y_offset_callback (SCM smob
)
26 Grob
*me
= unsmob_grob (smob
);
27 int duration_log
= scm_to_int (me
->get_property ("duration-log"));
28 int line_count
= Staff_symbol_referencer::line_count (me
);
29 Real ss
= Staff_symbol_referencer::staff_space (me
);
31 bool position_override
= scm_is_number (me
->get_property ("staff-position"));
32 Real amount
= robust_scm2double (me
->get_property ("staff-position"), 0)
37 if (duration_log
== 0 && line_count
> 1)
43 if (!position_override
)
44 amount
+= 2 * ss
* get_grob_direction (me
);;
46 return scm_from_double (amount
);
49 /* A rest might lie under a beam, in which case it should be cross-staff if
50 the beam is cross-staff because the rest's position depends on the
51 formatting of the beam. */
52 MAKE_SCHEME_CALLBACK (Rest
, calc_cross_staff
, 1);
54 Rest::calc_cross_staff (SCM smob
)
56 Grob
*me
= unsmob_grob (smob
);
57 Grob
*stem
= unsmob_grob (me
->get_object ("stem"));
62 return stem
->get_property ("cross-staff");
66 make this function easily usable in C++
69 Rest::glyph_name (Grob
*me
, int balltype
, string style
, bool try_ledgers
)
71 bool is_ledgered
= false;
72 if (try_ledgers
&& (balltype
== 0 || balltype
== 1))
74 Real rad
= Staff_symbol_referencer::staff_radius (me
) * 2.0;
75 Real pos
= Staff_symbol_referencer::get_position (me
);
78 Figure out when the rest is far enough outside the staff. This
79 could bemore generic, but hey, we understand this even after
82 is_ledgered
|= (balltype
== 0) && (pos
>= +rad
+ 2 || pos
< -rad
);
83 is_ledgered
|= (balltype
== 1) && (pos
<= -rad
- 2 || pos
> +rad
);
86 string
actual_style (style
.c_str ());
88 if ((style
== "mensural") || (style
== "neomensural"))
92 FIXME: Currently, ancient font does not provide ledgered rests;
93 hence the "o" suffix in the glyph name is bogus. But do we need
94 ledgered rests at all now that we can draw ledger lines with
95 variable width, length and blotdiameter? -- jr
100 There are no 32th/64th/128th mensural/neomensural rests. In
101 these cases, revert back to default style.
107 if ((style
== "classical") && (balltype
!= 2))
110 classical style: revert back to default style for any rest other
116 if (style
== "default")
119 Some parts of lily still prefer style "default" over "".
120 Correct this here. -- jr
125 return ("rests." + to_string (balltype
) + (is_ledgered
? "o" : "")
129 MAKE_SCHEME_CALLBACK (Rest
, print
, 1);
131 Rest::brew_internal_stencil (Grob
*me
, bool ledgered
)
133 SCM balltype_scm
= me
->get_property ("duration-log");
134 if (!scm_is_number (balltype_scm
))
135 return Stencil ().smobbed_copy ();
137 int balltype
= scm_to_int (balltype_scm
);
140 SCM style_scm
= me
->get_property ("style");
141 if (scm_is_symbol (style_scm
))
142 style
= ly_scm2string (scm_symbol_to_string (style_scm
));
144 Font_metric
*fm
= Font_interface::get_default_font (me
);
145 string font_char
= glyph_name (me
, balltype
, style
, ledgered
);
146 Stencil out
= fm
->find_by_name (font_char
);
148 me
->warning (_f ("rest `%s' not found", font_char
.c_str ()));
150 return out
.smobbed_copy ();
154 Rest::print (SCM smob
)
156 return brew_internal_stencil (unsmob_grob (smob
), true);
159 MAKE_SCHEME_CALLBACK (Rest
, width
, 1);
161 We need the callback. The real stencil has ledgers depending on
162 Y-position. The Y-position is known only after line breaking. */
164 Rest::width (SCM smob
)
166 return generic_extent_callback (unsmob_grob (smob
), X_AXIS
);
169 MAKE_SCHEME_CALLBACK (Rest
, height
, 1);
171 Rest::height (SCM smob
)
173 return generic_extent_callback (unsmob_grob (smob
), Y_AXIS
);
177 We need the callback. The real stencil has ledgers depending on
178 Y-position. The Y-position is known only after line breaking. */
180 Rest::generic_extent_callback (Grob
*me
, Axis a
)
183 Don't want ledgers: ledgers depend on Y position, which depends on
184 rest collision, which depends on stem size which depends on beam
185 slop of opposite note column.
187 consequence: we get too small extents and potential collisions
190 SCM m
= brew_internal_stencil (me
, a
!= X_AXIS
);
191 return ly_interval2scm (unsmob_stencil (m
)->extent (a
));
194 MAKE_SCHEME_CALLBACK (Rest
, pure_height
, 3);
196 Rest::pure_height (SCM smob
, SCM start
, SCM end
)
201 Grob
*me
= unsmob_grob (smob
);
202 SCM m
= brew_internal_stencil (me
, false);
203 return ly_interval2scm (unsmob_stencil (m
)->extent (Y_AXIS
));
207 "A rest symbol. The property @code{style} can be"
208 " @code{default}, @code{mensural}, @code{neomensural} or"
209 " @code{classical}.",