2 rest.cc -- implement Rest
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--2006 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"
21 MAKE_SCHEME_CALLBACK (Rest
, y_offset_callback
, 1);
23 Rest::y_offset_callback (SCM smob
)
25 Grob
*me
= unsmob_grob (smob
);
26 int duration_log
= scm_to_int (me
->get_property ("duration-log"));
27 int line_count
= Staff_symbol_referencer::line_count (me
);
28 Real ss
= Staff_symbol_referencer::staff_space (me
);
30 bool position_override
= scm_is_number (me
->get_property ("staff-position"));
31 Real amount
= robust_scm2double (me
->get_property ("staff-position"), 0)
36 if (duration_log
== 0 && line_count
> 1)
42 Grob
*dot
= unsmob_grob (me
->get_object ("dot"));
43 if (dot
&& duration_log
> 4) // UGH.
45 dot
->set_property ("staff-position",
46 scm_from_int ((duration_log
== 7) ? 4 : 3));
48 if (dot
&& duration_log
>= -1 && duration_log
<= 1) // UGH again.
50 dot
->set_property ("staff-position",
51 scm_from_int ((duration_log
== 0) ? -1 : 1));
54 if (!position_override
)
55 amount
+= 2 * ss
* get_grob_direction (me
);;
57 return scm_from_double (amount
);
61 make this function easily usable in C++
64 Rest::glyph_name (Grob
*me
, int balltype
, string style
, bool try_ledgers
)
66 bool is_ledgered
= false;
67 if (try_ledgers
&& (balltype
== 0 || balltype
== 1))
69 Real rad
= Staff_symbol_referencer::staff_radius (me
) * 2.0;
70 Real pos
= Staff_symbol_referencer::get_position (me
);
73 Figure out when the rest is far enough outside the staff. This
74 could bemore generic, but hey, we understand this even after
77 is_ledgered
|= (balltype
== 0) && (pos
>= +rad
+ 2 || pos
< -rad
);
78 is_ledgered
|= (balltype
== 1) && (pos
<= -rad
- 2 || pos
> +rad
);
81 string
actual_style (style
.c_str ());
83 if ((style
== "mensural") || (style
== "neomensural"))
87 FIXME: Currently, ancient font does not provide ledgered rests;
88 hence the "o" suffix in the glyph name is bogus. But do we need
89 ledgered rests at all now that we can draw ledger lines with
90 variable width, length and blotdiameter? -- jr
95 There are no 32th/64th/128th mensural/neomensural rests. In
96 these cases, revert back to default style.
102 if ((style
== "classical") && (balltype
!= 2))
105 classical style: revert back to default style for any rest other
111 if (style
== "default")
114 Some parts of lily still prefer style "default" over "".
115 Correct this here. -- jr
120 return ("rests." + to_string (balltype
) + (is_ledgered
? "o" : "")
124 MAKE_SCHEME_CALLBACK (Rest
, print
, 1);
126 Rest::brew_internal_stencil (Grob
*me
, bool ledgered
)
128 SCM balltype_scm
= me
->get_property ("duration-log");
129 if (!scm_is_number (balltype_scm
))
130 return Stencil ().smobbed_copy ();
132 int balltype
= scm_to_int (balltype_scm
);
135 SCM style_scm
= me
->get_property ("style");
136 if (scm_is_symbol (style_scm
))
137 style
= ly_scm2string (scm_symbol_to_string (style_scm
));
139 Font_metric
*fm
= Font_interface::get_default_font (me
);
140 string font_char
= glyph_name (me
, balltype
, style
, ledgered
);
141 Stencil out
= fm
->find_by_name (font_char
);
143 me
->warning (_f ("rest `%s' not found", font_char
.c_str ()));
145 return out
.smobbed_copy ();
149 Rest::print (SCM smob
)
151 return brew_internal_stencil (unsmob_grob (smob
), true);
154 MAKE_SCHEME_CALLBACK (Rest
, width
, 1);
156 We need the callback. The real stencil has ledgers depending on
157 Y-position. The Y-position is known only after line breaking. */
159 Rest::width (SCM smob
)
161 return generic_extent_callback (unsmob_grob (smob
), X_AXIS
);
164 MAKE_SCHEME_CALLBACK (Rest
, height
, 1);
166 Rest::height (SCM smob
)
168 return generic_extent_callback (unsmob_grob (smob
), Y_AXIS
);
172 We need the callback. The real stencil has ledgers depending on
173 Y-position. The Y-position is known only after line breaking. */
175 Rest::generic_extent_callback (Grob
*me
, Axis a
)
178 Don't want ledgers: ledgers depend on Y position, which depends on
179 rest collision, which depends on stem size which depends on beam
180 slop of opposite note column.
182 consequence: we get too small extents and potential collisions
185 SCM m
= brew_internal_stencil (me
, a
!= X_AXIS
);
186 return ly_interval2scm (unsmob_stencil (m
)->extent (a
));
189 ADD_INTERFACE (Rest
, "rest-interface",