+// -> offset callback
+MAKE_SCHEME_CALLBACK (Rest, y_offset_callback, 1);
+SCM
+Rest::y_offset_callback (SCM smob)
+{
+ Grob *me = unsmob_grob (smob);
+ int duration_log = scm_to_int (me->get_property ("duration-log"));
+ Real ss = Staff_symbol_referencer::staff_space (me);
+
+ bool position_override = scm_is_number (me->get_property ("staff-position"));
+ Real amount;
+
+ if (position_override)
+ {
+ amount
+ = robust_scm2double (me->get_property ("staff-position"), 0) * 0.5 * ss;
+
+ /*
+ semibreve rests are positioned one staff line off
+ */
+ if (duration_log == 0)
+ amount += ss;
+
+ /*
+ trust the client on good positioning;
+ would be tempting to adjust position of rests longer than a quarter
+ to be properly aligned to staff lines,
+ but custom rest shapes may not need that sort of care.
+ */
+ }
+ else
+ {
+ int pos = 4 * get_grob_direction (me);
+
+ /*
+ make a semibreve rest hang from the next line,
+ except for a single line staff
+ */
+ if (duration_log == 0 && Staff_symbol_referencer::line_count (me) > 1)
+ pos += 2;
+
+ /*
+ make sure rest is aligned to a staff line
+ */
+ if (Grob *staff = Staff_symbol_referencer::get_staff_symbol (me))
+ {
+ std::vector<Real> linepos = Staff_symbol::line_positions (staff);
+ std::sort (linepos.begin (), linepos.end ());
+ std::vector<Real>::const_iterator it
+ = std::lower_bound (linepos.begin (), linepos.end (), pos);
+ if (it != linepos.end ())
+ {
+ pos = (int)ceil (*it);
+ }
+ }
+
+ amount = ss * 0.5 * pos;
+ }
+
+ return scm_from_double (amount);
+}
+
+/* A rest might lie under a beam, in which case it should be cross-staff if
+ the beam is cross-staff because the rest's position depends on the
+ formatting of the beam. */
+MAKE_SCHEME_CALLBACK (Rest, calc_cross_staff, 1);
+SCM
+Rest::calc_cross_staff (SCM smob)
+{
+ Grob *me = unsmob_grob (smob);
+ Grob *stem = unsmob_grob (me->get_object ("stem"));
+
+ if (!stem)
+ return SCM_BOOL_F;
+
+ return stem->get_property ("cross-staff");
+}
+
+/*
+ make this function easily usable in C++
+*/
+string
+Rest::glyph_name (Grob *me, int durlog, string style, bool try_ledgers)
+{
+ bool is_ledgered = false;
+ if (try_ledgers && (durlog == -1 || durlog == 0 || durlog == 1))
+ {
+ int const pos = int (Staff_symbol_referencer::get_position (me));
+
+ /*
+ half rests need ledger if not lying on a staff line,
+ whole rests need ledger if not hanging from a staff line,
+ breve rests need ledger if neither lying on nor hanging from a staff line
+ */
+ if (-1 <= durlog && durlog <= 1)
+ is_ledgered = !Staff_symbol_referencer::on_staff_line (me, pos)
+ && !(durlog == -1
+ && Staff_symbol_referencer::on_staff_line (me, pos + 2));
+ }
+
+ string actual_style (style.c_str ());
+
+ if ((style == "mensural") || (style == "neomensural"))
+ {
+
+ /*
+ FIXME: Currently, ancient font does not provide ledgered rests;
+ hence the "o" suffix in the glyph name is bogus. But do we need
+ ledgered rests at all now that we can draw ledger lines with
+ variable width, length and blotdiameter? -- jr
+ */
+ is_ledgered = 0;
+
+ /*
+ There are no 32th/64th/128th mensural/neomensural rests. In
+ these cases, revert back to default style.
+ */
+ if (durlog > 4)
+ actual_style = "";
+ }
+
+ if ((style == "classical") && (durlog != 2))
+ {
+ /*
+ classical style: revert back to default style for any rest other
+ than quarter rest
+ */
+ actual_style = "";
+ }
+
+ if (style == "default")
+ {
+ /*
+ Some parts of lily still prefer style "default" over "".
+ Correct this here. -- jr
+ */
+ actual_style = "";
+ }
+
+ return ("rests." + to_string (durlog) + (is_ledgered ? "o" : "")
+ + actual_style);
+}
+
+MAKE_SCHEME_CALLBACK (Rest, print, 1);
+SCM
+Rest::brew_internal_stencil (Grob *me, bool ledgered)