lilypond-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Makes parameters for hairpin rotation available in Scheme (issue4809051)


From: mtsolo
Subject: Makes parameters for hairpin rotation available in Scheme (issue4809051)
Date: Sat, 23 Jul 2011 14:48:01 +0000

Reviewers: ,

Message:
I think that this is sufficient to "fix" issue 36.  As Graham points out
in the tracker, it is difficult to imagine what a good solution is, and
I have a feeling that the solution likely depends upon the user's
preferences.  In certain situations I can see making the hairpin take up
less vertical space and using whiteout, in other situations I can see it
being rotated to follow the slope of the beam.  In either of these
cases, in order to know if an intersection occurs, the hairpin needs to
know:

a) The cross staff beams that happen during it.
b) The left and right Y-positions of the beams.
c) The left and right X-positions of the beams.
d) Its own left and right X/Y positions.

(a) is currently impossible to calculate in all circumstances, and (c)
would require a code dup.  I think by making these available as
properties, the user can then use this data to fix the problem.  In the
example given in Issue 36, I would personally rotate the stencil
downwards, and this patch would give me all the data necessary to create
an override for Beam #'rotation.

Cheers,
MS



Please review this at http://codereview.appspot.com/4809051/

Affected files:
  M lily/beam.cc
  M lily/hairpin.cc
  M lily/include/beam.hh
  M lily/new-dynamic-engraver.cc
  M scm/define-grob-properties.scm
  M scm/define-grobs.scm


Index: lily/beam.cc
diff --git a/lily/beam.cc b/lily/beam.cc
index 1bb0a209a859666c271dfed1c955d556723ecfa0..e27844c1bb61f0a5ad912e61060032eee7514ce0 100644
--- a/lily/beam.cc
+++ b/lily/beam.cc
@@ -548,6 +548,29 @@ Beam::get_beam_segments (Grob *me_grob, Grob **common)
   return segments;
 }

+MAKE_SCHEME_CALLBACK (Beam, calc_x_positions, 1);
+SCM
+Beam::calc_x_positions (SCM grob)
+{
+  Spanner *me = unsmob_spanner (grob);
+  Grob *commonx = 0;
+
+  Interval span;
+  if (normal_stem_count (me))
+    {
+ span[LEFT] = first_normal_stem (me)->relative_coordinate (commonx, X_AXIS); + span[RIGHT] = last_normal_stem (me)->relative_coordinate (commonx, X_AXIS);
+    }
+  else
+    {
+      extract_grob_set (me, "stems", stems);
+      span[LEFT] = stems[0]->relative_coordinate (commonx, X_AXIS);
+      span[RIGHT] = stems.back ()->relative_coordinate (commonx, X_AXIS);
+    }
+
+  return ly_interval2scm (span);
+}
+
 MAKE_SCHEME_CALLBACK (Beam, print, 1);
 SCM
 Beam::print (SCM grob)
@@ -558,7 +581,7 @@ Beam::print (SCM grob)
   if (!segments.size ())
     return SCM_EOL;

-  Interval span;
+ Interval span = robust_scm2interval (me->get_property ("X-positions"), Interval (0, 0));
   if (normal_stem_count (me))
     {
span[LEFT] = first_normal_stem (me)->relative_coordinate (commonx, X_AXIS);
@@ -1876,4 +1899,5 @@ ADD_INTERFACE (Beam,
               "quantized-positions "
               "shorten "
               "stems "
+              "X-positions "
               );
Index: lily/hairpin.cc
diff --git a/lily/hairpin.cc b/lily/hairpin.cc
index 399b5d995e8876f37aec2622a947435bcdc35507..139446a70d62501a1b65e097bec2fd6998733d25 100644
--- a/lily/hairpin.cc
+++ b/lily/hairpin.cc
@@ -250,6 +250,7 @@ Hairpin::print (SCM smob)
   mol.translate_axis (x_points[LEFT]
                      - bounds[LEFT]->relative_coordinate (common, X_AXIS),
                      X_AXIS);
+
   return mol.smobbed_copy ();
 }

@@ -259,6 +260,7 @@ ADD_INTERFACE (Hairpin,
               /* properties */
               "adjacent-spanners "
               "circled-tip "
+              "cross-staff-beams "
               "bound-padding "
               "grow-direction "
               "height "
Index: lily/include/beam.hh
diff --git a/lily/include/beam.hh b/lily/include/beam.hh
index f541a216be2966b4732eedc1ed7ceb838fb4458e..1be7d7fde98d91fc58586bb68680a4015966dc95 100644
--- a/lily/include/beam.hh
+++ b/lily/include/beam.hh
@@ -77,6 +77,7 @@ public:
   DECLARE_SCHEME_CALLBACK (calc_stem_shorten, (SCM));
   DECLARE_SCHEME_CALLBACK (calc_direction, (SCM));
   DECLARE_SCHEME_CALLBACK (calc_positions, (SCM));
+  DECLARE_SCHEME_CALLBACK (calc_x_positions, (SCM));
   DECLARE_SCHEME_CALLBACK (calc_least_squares_positions, (SCM, SCM));
   DECLARE_SCHEME_CALLBACK (calc_normal_stems, (SCM));
   DECLARE_SCHEME_CALLBACK (calc_concaveness, (SCM));
Index: lily/new-dynamic-engraver.cc
diff --git a/lily/new-dynamic-engraver.cc b/lily/new-dynamic-engraver.cc
index e225d97f1fd1bf4285988c27700839ebb3bca595..8d9ef01d087ea6216906fb74df4816e6f36a3f19 100644
--- a/lily/new-dynamic-engraver.cc
+++ b/lily/new-dynamic-engraver.cc
@@ -17,6 +17,7 @@
   along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
 */

+#include "beam.hh"
 #include "engraver.hh"
 #include "hairpin.hh"
 #include "international.hh"
@@ -34,6 +35,7 @@ class New_dynamic_engraver : public Engraver
 {
   TRANSLATOR_DECLARATIONS (New_dynamic_engraver);
   DECLARE_ACKNOWLEDGER (note_column);
+  DECLARE_ACKNOWLEDGER (beam);
   DECLARE_TRANSLATOR_LISTENER (absolute_dynamic);
   DECLARE_TRANSLATOR_LISTENER (span_dynamic);

@@ -54,6 +56,9 @@ private:
   Item *script_;
   Stream_event *script_event_;
   Stream_event *current_span_event_;
+
+  vector<Spanner *> cross_staff_beams_;
+  vector<Spanner *> hairpins_;
 };

 New_dynamic_engraver::New_dynamic_engraver ()
@@ -143,6 +148,7 @@ New_dynamic_engraver::process_music ()
            }
          current_spanner_ = make_spanner ("Hairpin",
                                           current_span_event_->self_scm ());
+          hairpins_.push_back (current_spanner_);
        }
       if (finished_spanner_)
        {
@@ -203,6 +209,41 @@ New_dynamic_engraver::finalize ()
       current_spanner_->suicide ();
       current_spanner_ = 0;
     }
+
+  if (!cross_staff_beams_.size ())
+    return;
+
+  vector_sort (cross_staff_beams_, Grob::less);
+  vector_sort (hairpins_, Grob::less);
+  vsize start = 0;
+
+  for (vsize i = 0; i < hairpins_.size (); i++)
+    {
+      Grob *hairpin_grob = hairpins_[i];
+
+ Interval_t<int> hairpin_spanned_rank_ = hairpin_grob->spanned_rank_interval (); + // Start considering grobs at the first grob whose end falls at or after the hairpin's beginning. + while (cross_staff_beams_[start]->spanned_rank_interval ()[RIGHT] < hairpin_spanned_rank_[LEFT])
+        start++;
+
+      // Stop when the grob's beginning comes after the hairpin's end.
+      for (vsize j = start; j < cross_staff_beams_.size (); j++)
+        {
+          Grob *cross_staff_beam = cross_staff_beams_[j];
+
+ Interval_t<int> cross_staff_beam_spanned_rank = cross_staff_beam->spanned_rank_interval (); + if (cross_staff_beam_spanned_rank[LEFT] > hairpin_spanned_rank_[RIGHT])
+            break;
+          /*
+ Only consider grobs whose end falls at or after the hairpin's beginning.
+             If the grob is a hairpin, it cannot start before hairpins_[i].
+ Also, if the user wants to check for collisions only in the hairpin's voice, + then make sure the hairpin and the cross_staff_beam are in the same voice.
+          */
+ if (cross_staff_beam_spanned_rank[RIGHT] >= hairpin_spanned_rank_[LEFT]) + Pointer_group_interface::add_grob (hairpin_grob, ly_symbol2scm ("cross-staff-beams"), cross_staff_beam);
+        }
+    }
 }

 string
@@ -247,7 +288,15 @@ New_dynamic_engraver::acknowledge_note_column (Grob_info info)
     finished_spanner_->set_bound (RIGHT, info.grob ());
 }

+void
+New_dynamic_engraver::acknowledge_beam (Grob_info info)
+{
+  if (Beam::is_cross_staff (info.grob ()))
+    cross_staff_beams_.push_back (dynamic_cast<Spanner *> (info.grob ()));
+}
+
 ADD_ACKNOWLEDGER (New_dynamic_engraver, note_column);
+ADD_ACKNOWLEDGER (New_dynamic_engraver, beam);
 ADD_TRANSLATOR (New_dynamic_engraver,
                /* doc */
                "Create hairpins, dynamic texts and dynamic text spanners.",
Index: scm/define-grob-properties.scm
diff --git a/scm/define-grob-properties.scm b/scm/define-grob-properties.scm
index 40732d0e9d10997850ade1bc6b85a168fad765f8..9d4d65572aaf3dfc306577f4f82e0751ecb46110 100644
--- a/scm/define-grob-properties.scm
+++ b/scm/define-grob-properties.scm
@@ -937,6 +937,7 @@ texts.")
      (X-extent ,number-pair? "Hard coded extent in address@hidden")
      (X-offset ,number? "The horizontal amount that this object is
 moved relative to its X-parent.")
+     (X-positions ,number-pair? "The X axis positions of a beam.")


 ;;
@@ -1000,6 +1001,8 @@ bounds are spaced.")
      (conditional-elements ,ly:grob-array? "Internal use only.")
      (covered-grobs ,ly:grob-array? "Grobs that could potentially collide
 with a beam.")
+     (cross-staff-beams ,ly:grob-array? "Cross staff beams that potentially
+intersect with hairpins and other below-staff grobs.")

      (direction-source ,ly:grob? "In case @code{side-relative-direction} is
 set, which grob to get the direction from.")
Index: scm/define-grobs.scm
diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm
index a5c03a52755c7cc3bdfac07960833e799ba7730b..2f4854d97f7ec32ec9dafd903a6acaa776ed1758 100644
--- a/scm/define-grobs.scm
+++ b/scm/define-grobs.scm
@@ -396,7 +396,7 @@

        (shorten . ,ly:beam::calc-stem-shorten)
        (stencil . ,ly:beam::print)
-
+       (X-positions . ,ly:beam::calc-x-positions)
        (meta . ((class . Spanner)
                 (object-callbacks . ((normal-stems . 
,ly:beam::calc-normal-stems)))
                 (interfaces . (beam-interface





reply via email to

[Prev in Thread] Current Thread [Next in Thread]