From b0ceb64701c0418fb074b6823cad1c682cefe76a Mon Sep 17 00:00:00 2001 From: Neil Puttock Date: Fri, 15 Jan 2010 00:02:23 +0000 Subject: [PATCH] Fix DynamicTextSpanner left alignment. When a DynamicTextSpanner directly follows a DynamicScript, padding is required to ensure the 'left 'text doesn't collide with the dynamic sign. Unfortunately, this default value skews the spanner's left bound to the right when no dynamic script is present. This patch caters for both situations by resetting 'left 'padding and 'left 'attach-dir as required, adding extra padding read from the property 'right-padding to fine-tune the space between the text elements. * add regtests demonstrating 'right-padding and correct alignment * remove hard-coded 'bound-details setting in New_dynamic_engraver, which prevented user override * add dynamic-text-interface with user property 'right-padding * add 'before-line-breaking callback dynamic-text-spanner::before-line-breaking which checks whether the left bound is a DynamicText; if this is true, set nested properties 'left 'attach-dir/'padding to prevent collision --- .../regression/dynamics-text-left-text-alignment.ly | 13 +++++++++++++ input/regression/dynamics-text-right-padding.ly | 12 ++++++++++++ lily/new-dynamic-engraver.cc | 11 +---------- scm/define-grob-interfaces.scm | 5 +++++ scm/define-grobs.scm | 7 +++++-- scm/output-lib.scm | 21 +++++++++++++++++++++ 6 files changed, 57 insertions(+), 12 deletions(-) create mode 100644 input/regression/dynamics-text-left-text-alignment.ly create mode 100644 input/regression/dynamics-text-right-padding.ly diff --git a/input/regression/dynamics-text-left-text-alignment.ly b/input/regression/dynamics-text-left-text-alignment.ly new file mode 100644 index 0000000000..03893c0896 --- /dev/null +++ b/input/regression/dynamics-text-left-text-alignment.ly @@ -0,0 +1,13 @@ +\version "2.13.11" +\header { + texidoc = "The left text of a @code{DynamicTextSpanner} is +left-aligned to its anchor note. +" +} + +\relative c' { + \crescTextCresc + \dimTextDim + c4\< c c c\! + c4\> c c c\! +} diff --git a/input/regression/dynamics-text-right-padding.ly b/input/regression/dynamics-text-right-padding.ly new file mode 100644 index 0000000000..e3c8a09604 --- /dev/null +++ b/input/regression/dynamics-text-right-padding.ly @@ -0,0 +1,12 @@ +\version "2.13.11" +\header { + texidoc = "The space between an absolute dynamic and a dynamic text +span can be changed using @code{'right-padding}. +" +} + +\relative c' { + \dimTextDim + \once \override DynamicText #'right-padding = #0 + c4\fff\> c c c\! +} diff --git a/lily/new-dynamic-engraver.cc b/lily/new-dynamic-engraver.cc index ea4c99d22a..af943c4aa8 100644 --- a/lily/new-dynamic-engraver.cc +++ b/lily/new-dynamic-engraver.cc @@ -166,16 +166,7 @@ New_dynamic_engraver::process_music () if (finished_spanner_) finished_spanner_->set_bound (RIGHT, script_); if (current_spanner_) - { - current_spanner_->set_bound (LEFT, script_); - - if (!Hairpin::has_interface (current_spanner_)) - set_nested_property (current_spanner_, - scm_list_3 (ly_symbol2scm ("bound-details"), - ly_symbol2scm ("left"), - ly_symbol2scm ("attach-dir")), - scm_from_int (RIGHT)); - } + current_spanner_->set_bound (LEFT, script_); } } diff --git a/scm/define-grob-interfaces.scm b/scm/define-grob-interfaces.scm index d0abebed7b..b068da91ad 100644 --- a/scm/define-grob-interfaces.scm +++ b/scm/define-grob-interfaces.scm @@ -57,6 +57,11 @@ note)." '(avoid-slur)) (ly:add-interface + 'dynamic-text-interface + "An absolute text dynamic." + '(right-padding)) + +(ly:add-interface 'dynamic-text-spanner-interface "Dynamic text spanner." '(text)) diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm index 7c459a0bca..781d3e0b03 100644 --- a/scm/define-grobs.scm +++ b/scm/define-grobs.scm @@ -660,6 +660,7 @@ (font-shape . italic) (outside-staff-priority . 250) (positioning-done . ,ly:script-interface::calc-positioning-done) + (right-padding . 0.5) (self-alignment-X . ,CENTER) (self-alignment-Y . ,CENTER) (stencil . ,ly:text-interface::print) @@ -667,6 +668,7 @@ (Y-offset . ,ly:self-alignment-interface::y-aligned-on-self) (meta . ((class . Item) (interfaces . (dynamic-interface + dynamic-text-interface font-interface script-interface self-alignment-interface @@ -674,6 +676,7 @@ (DynamicTextSpanner . ( + (before-line-breaking . ,dynamic-text-spanner::before-line-breaking) (bound-details . ((right . ((attach-dir . ,LEFT) (Y . 0) (padding . 0.75) @@ -684,8 +687,8 @@ (left . ((attach-dir . ,LEFT) (Y . 0) - (stencil-offset . (0 . -0.5)) - (padding . 0.5) + (stencil-offset . (-0.75 . -0.5)) + (padding . 0.75) )) (left-broken . ((attach-dir . ,RIGHT) )) diff --git a/scm/output-lib.scm b/scm/output-lib.scm index a7ba96b589..e98937e821 100644 --- a/scm/output-lib.scm +++ b/scm/output-lib.scm @@ -644,6 +644,27 @@ and duration-log @var{log}." START STOP)) +(define-public (dynamic-text-spanner::before-line-breaking grob) + "Monitor left bound of @code{DynamicTextSpanner} for absolute dynamics. +If found, ensure @code{DynamicText} does not collide with spanner text by +changing @code{'attach-dir} and @code{'padding}. Reads the +@code{'right-padding} property of @code{DynamicText} to fine tune space +between the two text elements." + (let ((left-bound (ly:spanner-bound grob LEFT))) + (if (grob::has-interface left-bound 'dynamic-text-interface) + (let* ((details (ly:grob-property grob 'bound-details)) + (left-details (ly:assoc-get 'left details)) + (my-padding (ly:assoc-get 'padding left-details)) + (script-padding (ly:grob-property left-bound 'right-padding 0))) + + (and (number? my-padding) + (ly:grob-set-nested-property! grob + '(bound-details left attach-dir) + RIGHT) + (ly:grob-set-nested-property! grob + '(bound-details left padding) + (+ my-padding script-padding))))))) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; lyrics -- 2.11.4.GIT