From: Han-Wen Nienhuys Date: Mon, 20 Mar 2006 14:26:26 +0000 (+0000) Subject: * lily/break-align-interface.cc (self_align_callback): new X-Git-Tag: release/2.7.40~15 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=bc1519b07df5412a825989a5fc2d9455f7a9e6c1;p=lilypond.git * lily/break-align-interface.cc (self_align_callback): new interface, new function. Look at complete alignment. This handles tunable break alignments in case break-align-symbols are missing. * lily/bar-number-engraver.cc (acknowledge_break_alignment): new function * lily/mark-engraver.cc (acknowledge_break_alignment): new function. * python/convertrules.py (conv): mark/bar number alignment rule. * lily/break-align-interface.cc (calc_positioning_done): also store offset from last visible break-alignment to its neighbor. This makes alignment on non-visible objects more reliable. --- diff --git a/ChangeLog b/ChangeLog index 23d9fec2b4..79995b2296 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,19 @@ 2006-03-20 Han-Wen Nienhuys + * lily/break-align-interface.cc (self_align_callback): new + interface, new function. Look at complete alignment. This handles + tunable break alignments in case break-align-symbols are missing. + + * lily/bar-number-engraver.cc (acknowledge_break_alignment): new function + + * lily/mark-engraver.cc (acknowledge_break_alignment): new function. + + * python/convertrules.py (conv): mark/bar number alignment rule. + + * lily/break-align-interface.cc (calc_positioning_done): also + store offset from last visible break-alignment to its + neighbor. This makes alignment on non-visible objects more reliable. + * po/lilypond.pot (Module): ran po-replace. * input/regression/tie-single-manual.ly (Module): new file. diff --git a/input/regression/rehearsal-mark-align.ly b/input/regression/rehearsal-mark-align.ly index 49012b6fd8..6f36ebee2b 100644 --- a/input/regression/rehearsal-mark-align.ly +++ b/input/regression/rehearsal-mark-align.ly @@ -2,7 +2,8 @@ \header { texidoc = "The rehearsal mark is put on top a breakable symbol, - according to the value of @code{rehearsalMarkAlignSymbol}." + according to the value of @code{break-align-symbol} value of the + @code{RehearsalMark}. The same holds for @code{BarNumber} grobs." } @@ -12,11 +13,11 @@ c1 \mark "foo" \key cis \major \clef alto - \set Score.rehearsalMarkAlignSymbol = #'key-signature + \override Score.RehearsalMark #'break-align-symbol = #'key-signature \mark "on-key" cis - \key ces \major - \set Score.rehearsalMarkAlignSymbol = #'clef + \key ces \major + \override Score.RehearsalMark #'break-align-symbol = #'clef \clef treble \mark "on clef" ces diff --git a/lily/bar-number-engraver.cc b/lily/bar-number-engraver.cc index 8a57a72135..f4cc5e66eb 100644 --- a/lily/bar-number-engraver.cc +++ b/lily/bar-number-engraver.cc @@ -28,6 +28,7 @@ protected: protected: void stop_translation_timestep (); DECLARE_ACKNOWLEDGER (break_aligned); + DECLARE_ACKNOWLEDGER (break_alignment); void process_music (); void create_items (); TRANSLATOR_DECLARATIONS (Bar_number_engraver); @@ -64,13 +65,19 @@ Bar_number_engraver::Bar_number_engraver () text_ = 0; } + +/* + see rehearsal mark comments. + */ void Bar_number_engraver::acknowledge_break_aligned (Grob_info inf) { Grob *s = inf.grob (); if (text_ + && !text_->get_parent (X_AXIS) && dynamic_cast (s) - && s->get_property ("break-align-symbol") == get_property ("barNumberAlignSymbol")) + && (s->get_property_data (ly_symbol2scm ("break-align-symbol")) + == text_->get_property_data (ly_symbol2scm ("break-align-symbol")))) { /* By default this would land on the Paper_column -- so why @@ -79,6 +86,18 @@ Bar_number_engraver::acknowledge_break_aligned (Grob_info inf) } } + +void +Bar_number_engraver::acknowledge_break_alignment (Grob_info inf) +{ + Grob *s = inf.grob (); + if (text_ + && dynamic_cast (s)) + { + text_->set_parent (s, X_AXIS); + } +} + void Bar_number_engraver::stop_translation_timestep () { @@ -101,6 +120,7 @@ Bar_number_engraver::create_items () ADD_ACKNOWLEDGER(Bar_number_engraver,break_aligned); +ADD_ACKNOWLEDGER(Bar_number_engraver,break_alignment); ADD_TRANSLATOR (Bar_number_engraver, /* doc */ "A bar number is created whenever measurePosition " @@ -113,7 +133,6 @@ ADD_TRANSLATOR (Bar_number_engraver, /* create */ "BarNumber", /* accept */ "", /* read */ - "barNumberAlignSymbol " "currentBarNumber " "whichBar " "stavesFound " diff --git a/lily/break-align-interface.cc b/lily/break-align-interface.cc index 7e494de706..e5c0765d4f 100644 --- a/lily/break-align-interface.cc +++ b/lily/break-align-interface.cc @@ -45,22 +45,36 @@ Break_align_interface::self_align_callback (SCM smob) So we return the correct order as an array. */ -vector -Break_align_interface::ordered_elements (Grob *grob) +SCM +Break_align_interface::break_align_order (Item *me) { - Item *me = dynamic_cast (grob); - extract_grob_set (me, "elements", elts); - SCM order_vec = me->get_property ("break-align-orders"); if (!scm_is_vector (order_vec) || scm_c_vector_length (order_vec) < 3) - return elts; + return SCM_BOOL_F; - vector writable_elts (elts); SCM order = scm_vector_ref (order_vec, scm_from_int (me->break_status_dir () + 1)); - /* + + return order; +} + + +vector +Break_align_interface::ordered_elements (Grob *grob) +{ + Item *me = dynamic_cast (grob); + extract_grob_set (me, "elements", elts); + + + SCM order = break_align_order (me); + + if (order == SCM_BOOL_F) + return elts; + + vector writable_elts (elts); + /* Copy in order specified in BREAK-ALIGN-ORDER. */ vector new_elts; @@ -143,8 +157,8 @@ Break_align_interface::calc_positioning_done (SCM smob) Grob *elt = elts[i]; if (edge_idx == VPOS - && elt->get_property ("break-align-symbol") - == ly_symbol2scm ("left-edge")) + && (elt->get_property ("break-align-symbol") + == ly_symbol2scm ("left-edge"))) edge_idx = idx; SCM l = elt->get_property ("space-alist"); @@ -217,7 +231,11 @@ Break_align_interface::calc_positioning_done (SCM smob) offsets[next_idx] = max (extents[idx][RIGHT], distance); } else - extra_right_space = distance; + { + extra_right_space = distance; + if (idx < offsets.size() - 1) + offsets[idx+1] = extents[idx][RIGHT] + distance; + } idx = next_idx; } @@ -288,3 +306,55 @@ ADD_INTERFACE (Break_align_interface, "break-alignment-interface", "positioning-done " "break-align-orders"); + +MAKE_SCHEME_CALLBACK(Break_alignment_align_interface, self_align_callback, 1) +SCM +Break_alignment_align_interface::self_align_callback (SCM grob) +{ + Grob *me = unsmob_grob (grob); + Item *alignment = dynamic_cast (me->get_parent (X_AXIS)); + if (!Break_align_interface::has_interface (alignment)) + return scm_from_int (0); + + SCM my_align = me->get_property ("break-align-symbol"); + SCM order = Break_align_interface::break_align_order (alignment); + + vector elements = Break_align_interface::ordered_elements (alignment); + if (elements.size () == 0) + return scm_from_int (0); + + int last_idx_found = -1; + vsize i = 0; + for (SCM s = order; scm_is_pair (order); s = scm_cdr (s)) + { + if (i < elements.size () + && elements[i]->get_property ("break-align-symbol") == scm_car (s)) + { + last_idx_found = i; + i ++; + } + + if (scm_car (s) == my_align) + break ; + } + + Direction which_edge = LEFT; + if (vsize (last_idx_found + 1) < elements.size()) + last_idx_found ++; + else + which_edge = RIGHT; + + Grob *common = me->common_refpoint (elements[last_idx_found], X_AXIS); + + return scm_from_double (robust_relative_extent (elements[last_idx_found], common, X_AXIS)[which_edge] + - me->relative_coordinate (common, X_AXIS)); +} + +ADD_INTERFACE (Break_alignment_align_interface, "break-alignment-align-interface", + "Object that is aligned on a break aligment. ", + + /* properties */ + "break-align-symbol " + ) + + diff --git a/lily/include/break-align-interface.hh b/lily/include/break-align-interface.hh index 7fc83f3e83..41972c83a5 100644 --- a/lily/include/break-align-interface.hh +++ b/lily/include/break-align-interface.hh @@ -17,12 +17,20 @@ public: static vector ordered_elements (Grob *me); static bool has_interface (Grob *); static void add_element (Grob *me, Grob *add); + static SCM break_align_order (Item *me); DECLARE_SCHEME_CALLBACK (calc_positioning_done, (SCM element)); DECLARE_SCHEME_CALLBACK (self_align_callback, (SCM element)); }; + struct Break_aligned_interface { static bool has_interface (Grob *); }; +struct Break_alignment_align_interface +{ + DECLARE_SCHEME_CALLBACK (self_align_callback, (SCM element)); + static bool has_interface (Grob *); +}; + #endif // BREAK_ALIGN_INTERFACE_HH diff --git a/lily/mark-engraver.cc b/lily/mark-engraver.cc index 2a4fbe3510..244404334e 100644 --- a/lily/mark-engraver.cc +++ b/lily/mark-engraver.cc @@ -39,6 +39,7 @@ protected: void process_music (); void stop_translation_timestep (); + DECLARE_ACKNOWLEDGER (break_alignment); DECLARE_ACKNOWLEDGER (break_aligned); }; @@ -48,13 +49,20 @@ Mark_engraver::Mark_engraver () mark_ev_ = 0; } +/* + This is a flawed approach, since various break-aligned objects may + not appear depending on key signature etc. + + We keep it in case someone puts the engraver in a lower context than score. + */ void Mark_engraver::acknowledge_break_aligned (Grob_info inf) { Grob *s = inf.grob (); if (text_ - && (get_property ("rehearsalMarkAlignSymbol") - == s->get_property ("break-align-symbol")) + && !text_->get_parent (X_AXIS) + && (text_->get_property_data (ly_symbol2scm ("break-align-symbol")) + == s->get_property_data (ly_symbol2scm ("break-align-symbol"))) && Axis_group_interface::has_interface (s)) { /* @@ -65,6 +73,18 @@ Mark_engraver::acknowledge_break_aligned (Grob_info inf) } } +void +Mark_engraver::acknowledge_break_alignment (Grob_info inf) +{ + Grob *s = inf.grob (); + if (text_ + && dynamic_cast (s)) + { + text_->set_parent (s, X_AXIS); + } +} + + void Mark_engraver::stop_translation_timestep () { @@ -141,6 +161,7 @@ Mark_engraver::process_music () #include "translator.icc" ADD_ACKNOWLEDGER (Mark_engraver, break_aligned); +ADD_ACKNOWLEDGER (Mark_engraver, break_alignment); ADD_TRANSLATOR (Mark_engraver, /* doc */ "This engraver will create RehearsalMark objects. " diff --git a/ly/engraver-init.ly b/ly/engraver-init.ly index 2ff22a1452..2f6df50f7a 100644 --- a/ly/engraver-init.ly +++ b/ly/engraver-init.ly @@ -524,8 +524,6 @@ AncientRemoveEmptyStaffContext = \context { tupletNumberFormatFunction = #denominator-tuplet-formatter markFormatter = #format-mark-letters rehearsalMark = #1 - rehearsalMarkAlignSymbol = #'staff-bar - barNumberAlignSymbol = #'staff-bar subdivideBeams = ##f allowBeamBreak = ##f extraNatural = ##t diff --git a/python/convertrules.py b/python/convertrules.py index 0fa0cdae7b..ffee8295d5 100644 --- a/python/convertrules.py +++ b/python/convertrules.py @@ -2770,5 +2770,13 @@ conversions.append (((2, 7, 36), conv, """def-(music-function|markup-command) -> define-(music-function|markup-command)""")) -conversions.append (((2, 7, 39), lambda x: x, - "Minimum version for 2.8")) + +def conv (str): + str = re.sub (r'\\set\s+Score\s*\.\s*barNumberAlignSymbol\s*=', + r"\\override Score.BarNumber #'break-align-symbol = ", str) + str = re.sub (r'\\set\s*Score\s*\.\s*rehearsalMarkAlignSymbol\s*=', + r"\\override Score.RehearsalMark #'break-align-symbol = ", str) + return str + +conversions.append (((2, 7, 40), conv, + "rehearsalMarkAlignSymbol/barNumberAlignSymbol -> break-align-symbol")) diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm index 8fd355b269..d2c5408bb1 100644 --- a/scm/define-grobs.scm +++ b/scm/define-grobs.scm @@ -185,16 +185,23 @@ (font-size . -2) (Y-offset . ,ly:side-position-interface::y-aligned-side) (side-axis . ,Y) - (X-offset . ,ly:self-alignment-interface::x-aligned-on-self) - (self-alignment-X . 1) + (X-offset . ,(ly:make-simple-closure + `(,+ + ,(ly:make-simple-closure + (list ly:break-alignment-align-interface::self-align-callback)) + ,(ly:make-simple-closure + (list ly:self-alignment-interface::x-aligned-on-self))))) + (self-alignment-X . 1) + (break-align-symbol . left-edge) (meta . ((class . Item) (interfaces . (side-position-interface text-interface + break-alignment-align-interface self-alignment-interface font-interface - break-aligned-interface)))) + )))) )) (BassFigure @@ -1156,11 +1163,12 @@ . ( (stencil . ,ly:text-interface::print) (X-offset . ,(ly:make-simple-closure - `(,+ ,(ly:make-simple-closure - `(,ly:self-alignment-interface::x-aligned-on-self)) - ,(ly:make-simple-closure - `(,ly:self-alignment-interface::centered-on-x-parent))) - )) + `(,+ + ,(ly:make-simple-closure + (list ly:break-alignment-align-interface::self-align-callback)) + ,(ly:make-simple-closure + (list ly:self-alignment-interface::x-aligned-on-self))))) + (Y-offset . ,ly:side-position-interface::y-aligned-side) (self-alignment-X . 0) (direction . ,UP) @@ -1168,10 +1176,12 @@ (font-size . 2) (baseline-skip . 2) (break-visibility . ,end-of-line-invisible) + (break-align-symbol . staff-bar) (padding . 0.8) (meta . ((class . Item) (interfaces . (text-interface side-position-interface + break-alignment-align-interface font-interface mark-interface self-alignment-interface))))))