X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Frest.cc;h=9057e45af1bd90deaf29c0419ac2a2b2233ee8a9;hb=0b5d0acdc14a073f9cf763c8b596ba02f2a8f08d;hp=97deba3f8fc93b41cce9767f0a17b851bcafe301;hpb=4a401ca1c60f428daa242dbdd102fdb3f327ebfb;p=lilypond.git diff --git a/lily/rest.cc b/lily/rest.cc index 97deba3f8f..9057e45af1 100644 --- a/lily/rest.cc +++ b/lily/rest.cc @@ -1,7 +1,7 @@ /* This file is part of LilyPond, the GNU music typesetter. - Copyright (C) 1997--2011 Han-Wen Nienhuys + Copyright (C) 1997--2012 Han-Wen Nienhuys LilyPond is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -26,6 +26,7 @@ #include "output-def.hh" #include "paper-score.hh" #include "staff-symbol-referencer.hh" +#include "staff-symbol.hh" #include "stencil.hh" #include "grob.hh" @@ -40,19 +41,54 @@ Rest::y_offset_callback (SCM smob) Real ss = Staff_symbol_referencer::staff_space (me); bool position_override = scm_is_number (me->get_property ("staff-position")); - Real amount = robust_scm2double (me->get_property ("staff-position"), 0) - * 0.5 * ss; + Real amount; - if (line_count % 2) + if (position_override) { - if (duration_log == 0 && line_count > 1) + 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 - amount += ss / 2; + { + int pos = 4 * get_grob_direction (me); - if (!position_override) - amount += 2 * ss * get_grob_direction (me);; + /* + make a semibreve rest hang from the next line, + except for a single line staff + */ + if (duration_log == 0 && line_count > 1) + pos += 2; + + /* + make sure rest is aligned to a staff line + */ + if (Grob *staff = Staff_symbol_referencer::get_staff_symbol (me)) + { + std::vector linepos = Staff_symbol::line_positions (staff); + std::sort (linepos.begin (), linepos.end ()); + std::vector::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); } @@ -77,22 +113,22 @@ Rest::calc_cross_staff (SCM smob) make this function easily usable in C++ */ string -Rest::glyph_name (Grob *me, int balltype, string style, bool try_ledgers) +Rest::glyph_name (Grob *me, int durlog, string style, bool try_ledgers) { bool is_ledgered = false; - if (try_ledgers && (balltype == -1 || balltype == 0 || balltype == 1)) + if (try_ledgers && (durlog == -1 || durlog == 0 || durlog == 1)) { - Real rad = Staff_symbol_referencer::staff_radius (me) * 2.0; - Real pos = Staff_symbol_referencer::get_position (me); + int const pos = int (Staff_symbol_referencer::get_position (me)); /* - Figure out when the rest is far enough outside the staff. This - could bemore generic, but hey, we understand this even after - dinner. + 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 */ - is_ledgered |= (balltype == -1) && (pos <= -rad - 3 || pos >= +rad + 1); - is_ledgered |= (balltype == 0) && (pos >= +rad + 2 || pos < -rad); - is_ledgered |= (balltype == 1) && (pos <= -rad - 2 || pos > +rad); + 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 ()); @@ -112,11 +148,11 @@ Rest::glyph_name (Grob *me, int balltype, string style, bool try_ledgers) There are no 32th/64th/128th mensural/neomensural rests. In these cases, revert back to default style. */ - if (balltype > 4) + if (durlog > 4) actual_style = ""; } - if ((style == "classical") && (balltype != 2)) + if ((style == "classical") && (durlog != 2)) { /* classical style: revert back to default style for any rest other @@ -134,7 +170,7 @@ Rest::glyph_name (Grob *me, int balltype, string style, bool try_ledgers) actual_style = ""; } - return ("rests." + to_string (balltype) + (is_ledgered ? "o" : "") + return ("rests." + to_string (durlog) + (is_ledgered ? "o" : "") + actual_style); } @@ -142,19 +178,16 @@ MAKE_SCHEME_CALLBACK (Rest, print, 1); SCM Rest::brew_internal_stencil (Grob *me, bool ledgered) { - SCM balltype_scm = me->get_property ("duration-log"); - if (!scm_is_number (balltype_scm)) + SCM durlog_scm = me->get_property ("duration-log"); + if (!scm_is_number (durlog_scm)) return Stencil ().smobbed_copy (); - int balltype = scm_to_int (balltype_scm); + int durlog = scm_to_int (durlog_scm); - string style; - SCM style_scm = me->get_property ("style"); - if (scm_is_symbol (style_scm)) - style = ly_scm2string (scm_symbol_to_string (style_scm)); + string style = robust_symbol2string (me->get_property ("style"), "default"); Font_metric *fm = Font_interface::get_default_font (me); - string font_char = glyph_name (me, balltype, style, ledgered); + string font_char = glyph_name (me, durlog, style, ledgered); Stencil out = fm->find_by_name (font_char); if (out.is_empty ()) me->warning (_f ("rest `%s' not found", font_char.c_str ())); @@ -239,4 +272,3 @@ ADD_INTERFACE (Rest, "minimum-distance " "style " ); -