summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeil Puttock <n.puttock@gmail.com>2009-09-18 22:01:24 +0100
committerNeil Puttock <n.puttock@gmail.com>2009-09-18 22:01:24 +0100
commit001ad87ae4b9cccc9588557e4b944b11b8fe05f1 (patch)
treea79a231777242bde02daa55df7faf237f8f234ab
parent786083941557d40acf9ec1920e89e0e02f3981e6 (diff)
Fix collisions between hairpins and dynamic text spanner bounds.
* rename 'adjacent-hairpins to 'adjacent-spanners * add DynamicTextSpanner grobs to 'adjacent-spanners in New_dynamic_engraver * in Hairpin::print (), use renamed property to catch text spans and apply the appropriate amount of bound-padding * add regression test
-rw-r--r--input/regression/hairpin-neighboring-span-dynamics.ly27
-rw-r--r--lily/hairpin.cc74
-rw-r--r--lily/new-dynamic-engraver.cc68
-rw-r--r--scm/define-grob-properties.scm4
4 files changed, 105 insertions, 68 deletions
diff --git a/input/regression/hairpin-neighboring-span-dynamics.ly b/input/regression/hairpin-neighboring-span-dynamics.ly
new file mode 100644
index 0000000000..d969346e49
--- /dev/null
+++ b/input/regression/hairpin-neighboring-span-dynamics.ly
@@ -0,0 +1,27 @@
+\version "2.13.4"
+
+\header {
+ texidoc = "Bound padding for hairpins also works with neighboring
+@code{DynamicTextSpanner} grobs. In this case, @code{bound-padding}
+is not scaled down.
+"
+}
+
+\relative c' {
+ \override Hairpin #'to-barline = ##f
+ c2\>
+ \dimTextDim
+ c2\>
+ \dimHairpin
+ c\> c\! \break
+ \dimTextDim
+ c2\>
+ \override Hairpin #'bound-padding = #5
+ \dimHairpin
+ c2\>
+ \dimTextDim
+ c2\> c\! \break
+ \crescHairpin
+ c2\< c\<
+ c2\< c\!
+}
diff --git a/lily/hairpin.cc b/lily/hairpin.cc
index bb4fec084b..6403c62241 100644
--- a/lily/hairpin.cc
+++ b/lily/hairpin.cc
@@ -70,7 +70,7 @@ Hairpin::print (SCM smob)
broken[RIGHT] = broken[RIGHT] && me->broken_neighbor (RIGHT);
broken[RIGHT] = broken[RIGHT] && me->broken_neighbor (RIGHT)->is_live ();
-
+
if (broken[RIGHT])
{
Spanner *next = me->broken_neighbor (RIGHT);
@@ -86,8 +86,8 @@ Hairpin::print (SCM smob)
Use the height and thickness of the hairpin when making a circled tip
*/
bool circled_tip = ly_scm2bool (me->get_property ("circled-tip"));
- Real height = robust_scm2double (me->get_property ("height"), 0.2) *
- Staff_symbol_referencer::staff_space (me);
+ Real height = robust_scm2double (me->get_property ("height"), 0.2)
+ * Staff_symbol_referencer::staff_space (me);
/*
FIXME: 0.525 is still just a guess...
*/
@@ -95,7 +95,7 @@ Hairpin::print (SCM smob)
Real thick = 1.0;
if (circled_tip)
thick = robust_scm2double (me->get_property ("thickness"), 1.0)
- * Staff_symbol_referencer::line_thickness (me);
+ * Staff_symbol_referencer::line_thickness (me);
do
{
@@ -117,37 +117,47 @@ Hairpin::print (SCM smob)
else
{
bool neighbor_found = false;
- extract_grob_set (me, "adjacent-hairpins", pins);
- for (vsize i = 0; i < pins.size (); i++)
+ Spanner *adjacent;
+ extract_grob_set (me, "adjacent-spanners", neighbors);
+ for (vsize i = 0; i < neighbors.size (); i++)
{
/*
FIXME: this will fuck up in case of polyphonic
notes in other voices. Need to look at note-columns
in the current staff/voice.
*/
-
- Spanner *pin = dynamic_cast<Spanner *> (pins[i]);
- if (pin
- && (pin->get_bound (LEFT)->get_column () == b->get_column ()
- || pin->get_bound (RIGHT)->get_column () == b->get_column ()))
- neighbor_found = true;
+ adjacent = dynamic_cast<Spanner *> (neighbors[i]);
+ if (adjacent
+ && (adjacent->get_bound (-d)->get_column ()
+ == b->get_column ()))
+ {
+ neighbor_found = true;
+ break;
+ }
}
Interval e = robust_relative_extent (b, common, X_AXIS);
if (neighbor_found)
{
- /*
- Handle back-to-back hairpins with a circle in the middle
- */
- if (circled_tip && (grow_dir != d))
- x_points[d] = e.center () + d * (rad - thick / 2.0);
- /*
- If we're hung on a paper column, that means we're not
- adjacent to a text-dynamic, and we may move closer. We
- make the padding a little smaller, here.
- */
+ if (Hairpin::has_interface (adjacent))
+ {
+ /*
+ Handle back-to-back hairpins with a circle in the middle
+ */
+ if (circled_tip && (grow_dir != d))
+ x_points[d] = e.center () + d * (rad - thick / 2.0);
+ /*
+ If we're hung on a paper column, that means we're not
+ adjacent to a text-dynamic, and we may move closer. We
+ make the padding a little smaller, here.
+ */
+ else
+ x_points[d] = e.center () - d * padding / 3;
+ }
+ // Our neighbor is a dynamic text spanner, so add the
+ // same amount of padding as for text dynamics
else
- x_points[d] = e.center () - d * padding / 3;
+ x_points[d] = e[-d] - d * padding;
}
else
{
@@ -156,10 +166,10 @@ Hairpin::print (SCM smob)
x_points[d] = e[-d];
else
x_points[d] = e[d];
-
+
Item *bound = me->get_bound (d);
if (bound->is_non_musical (bound))
- x_points[d] -= d * padding;
+ x_points[d] -= d * padding;
}
}
}
@@ -218,16 +228,16 @@ Hairpin::print (SCM smob)
if (circled_tip)
{
Box extent (Interval (-rad, rad), Interval (-rad, rad));
-
+
/* Hmmm, perhaps we should have a Lookup::circle () method? */
Stencil circle (extent,
- scm_list_4 (ly_symbol2scm ("circle"),
- scm_from_double (rad),
- scm_from_double (thick),
- SCM_BOOL_F));
+ scm_list_4 (ly_symbol2scm ("circle"),
+ scm_from_double (rad),
+ scm_from_double (thick),
+ SCM_BOOL_F));
/*
- don't add another circle the hairpin is broken
+ don't add another circle if the hairpin is broken
*/
if (!broken[tip_dir])
mol.add_at_edge (X_AXIS, tip_dir, Stencil (circle), 0);
@@ -243,7 +253,7 @@ ADD_INTERFACE (Hairpin,
"A hairpin crescendo or decrescendo.",
/* properties */
- "adjacent-hairpins "
+ "adjacent-spanners "
"circled-tip "
"bound-padding "
"grow-direction "
diff --git a/lily/new-dynamic-engraver.cc b/lily/new-dynamic-engraver.cc
index 235dc178d9..489fcf5ea6 100644
--- a/lily/new-dynamic-engraver.cc
+++ b/lily/new-dynamic-engraver.cc
@@ -1,15 +1,12 @@
/*
new-dynamic-engraver.cc -- implement New_dynamic_engraver
-
+
source file of the GNU LilyPond music typesetter
-
+
(c) 2008--2009 Han-Wen Nienhuys <hanwen@lilypond.org>
-
*/
-
#include "engraver.hh"
-
#include "hairpin.hh"
#include "international.hh"
#include "item.hh"
@@ -35,13 +32,14 @@ protected:
virtual void finalize ();
private:
- SCM get_property_setting (Stream_event *evt, char const *evprop, char const *ctxprop);
+ SCM get_property_setting (Stream_event *evt, char const *evprop,
+ char const *ctxprop);
string get_spanner_type (Stream_event *ev);
Drul_array<Stream_event *> accepted_spanevents_drul_;
Spanner *current_spanner_;
Spanner *finished_spanner_;
-
+
Item *script_;
Stream_event *script_event_;
Stream_event *current_span_event_;
@@ -74,7 +72,9 @@ New_dynamic_engraver::listen_span_dynamic (Stream_event *ev)
}
SCM
-New_dynamic_engraver::get_property_setting (Stream_event *evt, char const *evprop, char const *ctxprop)
+New_dynamic_engraver::get_property_setting (Stream_event *evt,
+ char const *evprop,
+ char const *ctxprop)
{
SCM spanner_type = evt->get_property (evprop);
if (spanner_type == SCM_EOL)
@@ -86,7 +86,9 @@ void
New_dynamic_engraver::process_music ()
{
if (current_spanner_
- && (accepted_spanevents_drul_[STOP] || script_event_ || accepted_spanevents_drul_[START]))
+ && (accepted_spanevents_drul_[STOP]
+ || script_event_
+ || accepted_spanevents_drul_[START]))
{
Stream_event *ender = accepted_spanevents_drul_[STOP];
if (!ender)
@@ -94,7 +96,7 @@ New_dynamic_engraver::process_music ()
if (!ender)
ender = accepted_spanevents_drul_[START];
-
+
finished_spanner_ = current_spanner_;
announce_end_grob (finished_spanner_, ender->self_scm ());
current_spanner_ = 0;
@@ -107,7 +109,7 @@ New_dynamic_engraver::process_music ()
string start_type = get_spanner_type (current_span_event_);
SCM cresc_type = get_property_setting (current_span_event_, "span-type",
- (start_type + "Spanner").c_str ());
+ (start_type + "Spanner").c_str ());
if (cresc_type == ly_symbol2scm ("text"))
{
@@ -116,11 +118,9 @@ New_dynamic_engraver::process_music ()
accepted_spanevents_drul_[START]->self_scm ());
SCM text = get_property_setting (current_span_event_, "span-text",
- (start_type + "Text").c_str ());
+ (start_type + "Text").c_str ());
if (Text_interface::is_markup (text))
- {
- current_spanner_->set_property ("text", text);
- }
+ current_spanner_->set_property ("text", text);
}
else
{
@@ -132,16 +132,17 @@ New_dynamic_engraver::process_music ()
}
current_spanner_ = make_spanner ("Hairpin",
current_span_event_->self_scm ());
- if (finished_spanner_)
- {
- Pointer_group_interface::add_grob (finished_spanner_,
- ly_symbol2scm ("adjacent-hairpins"),
- current_spanner_);
-
- Pointer_group_interface::add_grob (current_spanner_,
- ly_symbol2scm ("adjacent-hairpins"),
- finished_spanner_);
- }
+ }
+ if (finished_spanner_)
+ {
+ if (Hairpin::has_interface (finished_spanner_))
+ Pointer_group_interface::add_grob (finished_spanner_,
+ ly_symbol2scm ("adjacent-spanners"),
+ current_spanner_);
+ if (Hairpin::has_interface (current_spanner_))
+ Pointer_group_interface::add_grob (current_spanner_,
+ ly_symbol2scm ("adjacent-spanners"),
+ finished_spanner_);
}
}
@@ -161,26 +162,24 @@ New_dynamic_engraver::process_music ()
set_nested_property (current_spanner_,
scm_list_3 (ly_symbol2scm ("bound-details"),
ly_symbol2scm ("left"),
- ly_symbol2scm ("attach-dir")
- ),
+ ly_symbol2scm ("attach-dir")),
scm_from_int (RIGHT));
-
}
}
}
-
-
void
New_dynamic_engraver::stop_translation_timestep ()
{
if (finished_spanner_ && !finished_spanner_->get_bound (RIGHT))
- finished_spanner_->set_bound (RIGHT,
- unsmob_grob (get_property ("currentMusicalColumn")));
+ finished_spanner_
+ ->set_bound (RIGHT,
+ unsmob_grob (get_property ("currentMusicalColumn")));
if (current_spanner_ && !current_spanner_->get_bound (LEFT))
- current_spanner_->set_bound (LEFT,
- unsmob_grob (get_property ("currentMusicalColumn")));
+ current_spanner_
+ ->set_bound (LEFT,
+ unsmob_grob (get_property ("currentMusicalColumn")));
script_ = 0;
script_event_ = 0;
accepted_spanevents_drul_.set (0, 0);
@@ -216,6 +215,7 @@ New_dynamic_engraver::get_spanner_type (Stream_event *ev)
type = "crescendo";
else
programming_error ("unknown dynamic spanner type");
+
return type;
}
diff --git a/scm/define-grob-properties.scm b/scm/define-grob-properties.scm
index 0ff4f7641a..b9cf4ed3a2 100644
--- a/scm/define-grob-properties.scm
+++ b/scm/define-grob-properties.scm
@@ -884,8 +884,8 @@ constructed from a whole number of squiggles.")
(accidental-grob ,ly:grob? "The accidental for this note.")
(accidental-grobs ,list? "An alist with @code{(@var{notename} .
@var{groblist})} entries.")
- (adjacent-hairpins ,ly:grob-array? "An array of directly neighboring
-hairpins.")
+ (adjacent-spanners ,ly:grob-array? "An array of directly neighboring
+dynamic spanners.")
(all-elements ,ly:grob-array? "An array of all grobs in this line. Its
function is to protect objects from being garbage collected.")
(arpeggio ,ly:grob? "A pointer to an @code{Arpeggio} object.")