X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fstaff-symbol.cc;h=0697085e114b7fb7811c65a71947e6c61052d9c3;hb=a6a51abfd0195a3cf7d6ea095cf69808852f21ce;hp=e2ea43a570a37bc5452fec3232bf262233a0ab80;hpb=d61cf3bbdb1c6670a127ba3baddf2f04d3e34fd3;p=lilypond.git diff --git a/lily/staff-symbol.cc b/lily/staff-symbol.cc index e2ea43a570..0697085e11 100644 --- a/lily/staff-symbol.cc +++ b/lily/staff-symbol.cc @@ -1,7 +1,7 @@ /* This file is part of LilyPond, the GNU music typesetter. - Copyright (C) 1997--2012 Han-Wen Nienhuys + Copyright (C) 1997--2015 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 @@ -33,7 +33,7 @@ MAKE_SCHEME_CALLBACK (Staff_symbol, print, 1); SCM Staff_symbol::print (SCM smob) { - Grob *me = unsmob_grob (smob); + Grob *me = unsmob (smob); Spanner *sp = dynamic_cast (me); Grob *common = sp->get_bound (LEFT)->common_refpoint (sp->get_bound (RIGHT), X_AXIS); @@ -50,8 +50,7 @@ Staff_symbol::print (SCM smob) Real t = me->layout ()->get_dimension (ly_symbol2scm ("line-thickness")); t *= robust_scm2double (me->get_property ("thickness"), 1.0); - Direction d = LEFT; - do + for (LEFT_and_RIGHT (d)) { SCM width_scm = me->get_property ("width"); if (d == RIGHT && scm_is_number (width_scm)) @@ -66,21 +65,27 @@ Staff_symbol::print (SCM smob) else { Item *x = sp->get_bound (d); - - span_points[d] = ((!x->break_status_dir () - && !x->extent (x, X_AXIS).is_empty ()) - ? Paper_column::break_align_width (x, ly_symbol2scm ("break-alignment"))[d] - : x->relative_coordinate (common, X_AXIS)); + if (x->extent (x, X_AXIS).is_empty () + || (x->break_status_dir () && sp->broken_neighbor (d))) + span_points[d] = x->relative_coordinate (common, X_AXIS); + // What the default implementation of to-barline does for + // spanners is not really in usefully recognizable shape by + // now, so we just reimplement. + else + { + SCM where = (d == RIGHT + ? me->get_property ("break-align-symbols") + : ly_symbol2scm ("break-alignment")); + span_points[d] = Paper_column::break_align_width (x, where)[d]; + } } span_points[d] -= d * t / 2; } - while (flip (&d) != LEFT); Stencil m; vector line_positions = Staff_symbol::line_positions (me); - int line_count = line_positions.size (); Stencil line = Lookup::horizontal_line (span_points @@ -88,10 +93,13 @@ Staff_symbol::print (SCM smob) t); Real space = staff_space (me); - for (int i = 0; i < line_count; i++) + for (vector::const_iterator i = line_positions.begin (), + e = line_positions.end (); + i != e; + ++i) { Stencil b (line); - b.translate_axis (line_positions[i] * 0.5 * space, Y_AXIS); + b.translate_axis (*i * 0.5 * space, Y_AXIS); m.add_stencil (b); } return m.smobbed_copy (); @@ -127,8 +135,27 @@ Staff_symbol::line_positions (Grob *me) } vector -Staff_symbol::ledger_positions (Grob *me, int pos) +Staff_symbol::ledger_positions (Grob *me, int pos, Item const *head) { + // allow override of ledger positions via note head grob... + if (head) + { + SCM posns = head->get_property ("ledger-positions"); + if (scm_is_pair (posns)) + return ly_scm2floatvector (posns); + } + + // ...or via custom ledger positions function + SCM lp_function = me->get_property ("ledger-positions-function"); + if (scm_is_pair (lp_function)) + { + SCM func = scm_eval (lp_function, scm_interaction_environment ()); + if (ly_is_procedure (func)) + return ly_scm2floatvector (scm_call_2 (func, + me->self_scm (), + scm_from_int (pos))); + } + SCM ledger_positions = me->get_property ("ledger-positions"); Real ledger_extra = robust_scm2double (me->get_property ("ledger-extra"), 0); vector line_positions = Staff_symbol::line_positions (me); @@ -137,17 +164,18 @@ Staff_symbol::ledger_positions (Grob *me, int pos) if (line_positions.empty ()) return values; - int line_count = line_positions.size (); - // find the staff line nearest to note position Real nearest_line = line_positions[0]; Real line_dist = abs (line_positions[0] - pos); - for (int i = 1; i < line_count; i++) + for (vector::const_iterator i = line_positions.begin (), + e = line_positions.end (); + i != e; + ++i) { - if (abs (line_positions[i] - pos) < line_dist) + if (abs (*i - pos) < line_dist) { - nearest_line = line_positions[i]; - line_dist = abs (line_positions[i] - pos); + nearest_line = *i; + line_dist = abs (*i - pos); } } @@ -157,7 +185,7 @@ Staff_symbol::ledger_positions (Grob *me, int pos) Direction dir = (Direction)sign (pos - nearest_line); if (scm_is_pair (ledger_positions)) - // custom ledger line positions + // custom ledger positions via StaffSymbol.ledger-positions { Real min_pos = HUGE_VAL; Real max_pos = -HUGE_VAL; @@ -238,7 +266,20 @@ Staff_symbol::ledger_positions (Grob *me, int pos) values[i] = nearest_line + dir * (ledger_count - i) * 2; } } - return values; + // remove any ledger lines that would fall on staff lines, + // which can happen when ledger-extra > 0 + vector final_values; + for (vector::const_iterator i = values.begin (), + e = values.end (); + i != e; + ++i) + { + if (find (line_positions.begin (), line_positions.end (), *i) == line_positions.end ()) + { + final_values.push_back (*i); + } + } + return final_values; } int @@ -254,7 +295,9 @@ Staff_symbol::line_count (Grob *me) Real Staff_symbol::staff_space (Grob *me) { - return robust_scm2double (me->get_property ("staff-space"), 1.0); + Real ss = me->layout ()->get_dimension (ly_symbol2scm ("staff-space")); + + return robust_scm2double (me->get_property ("staff-space"), 1.0) * ss; } Real @@ -278,7 +321,7 @@ MAKE_SCHEME_CALLBACK (Staff_symbol, height, 1); SCM Staff_symbol::height (SCM smob) { - Grob *me = unsmob_grob (smob); + Grob *me = unsmob (smob); Real t = me->layout ()->get_dimension (ly_symbol2scm ("line-thickness")); t *= robust_scm2double (me->get_property ("thickness"), 1.0); @@ -303,33 +346,48 @@ Staff_symbol::height (SCM smob) } bool -Staff_symbol::on_line (Grob *me, int pos) +Staff_symbol::on_line (Grob *me, int pos, bool allow_ledger) { - SCM line_positions = me->get_property ("line-positions"); - if (scm_is_pair (line_positions)) + // standard staff lines (any line count) and standard ledger lines + if (!scm_is_pair (me->get_property ("line-positions")) + && !scm_is_pair (me->get_property ("ledger-positions"))) { - Real min_line = HUGE_VAL; - Real max_line = -HUGE_VAL; - for (SCM s = line_positions; scm_is_pair (s); s = scm_cdr (s)) + int const line_cnt = line_count (me); + bool result = abs (pos + line_cnt) % 2 == 1; + if (result && !allow_ledger) { - Real current_line = scm_to_double (scm_car (s)); - if (pos == current_line) - return true; - if (current_line > max_line) - max_line = current_line; - if (current_line < min_line) - min_line = current_line; - + result = -line_cnt < pos && pos < line_cnt; } - if (pos < min_line) - return (( (int) (rint (pos - min_line)) % 2) == 0); - if (pos > max_line) - return (( (int) (rint (pos - max_line)) % 2) == 0); + return result; + } + + // staff lines (custom or standard) + vector lines = Staff_symbol::line_positions (me); + for (vector::const_iterator i = lines.begin (), + e = lines.end (); + i != e; + ++i) + { + if (pos == *i) + return true; + } - return false; + // ledger lines (custom or standard) + if (allow_ledger) + { + vector ledgers = Staff_symbol::ledger_positions (me, pos); + if (ledgers.empty ()) + return false; + for (vector::const_iterator i = ledgers.begin (), + e = ledgers.end (); + i != e; + ++i) + { + if (pos == *i) + return true; + } } - else - return ((abs (pos + line_count (me)) % 2) == 1); + return false; } Interval @@ -359,9 +417,11 @@ ADD_INTERFACE (Staff_symbol, " @code{width} property.", /* properties */ + "break-align-symbols " "ledger-extra " "ledger-line-thickness " "ledger-positions " + "ledger-positions-function " "line-count " "line-positions " "staff-space "