* input/regression/beam-single-stem.ly: new file.
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Mon, 22 May 2006 14:06:28 +0000 (14:06 +0000)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Mon, 22 May 2006 14:06:28 +0000 (14:06 +0000)
* lily/stem.cc (set_beaming): use #f as signaling value for
beamcount 0.

* lily/beam-engraver.cc (typeset_beam): set right bound if unset.

* lily/beam.cc (set_beaming): read clip-edges property.
(calc_direction): don't suicide for single stem.

* lily/beaming-info.cc (best_splitpoint_index): take bool*
argument, remove 1<<15 hack. Remove clip_edges()

* lily/hairpin.cc (print): only do padding for nonmusical bounds

12 files changed:
ChangeLog
input/regression/beam-single-stem.ly [new file with mode: 0644]
lily/auto-beam-engraver.cc
lily/beam-engraver.cc
lily/beam.cc
lily/beaming-info.cc
lily/hairpin.cc
lily/include/beaming.hh
lily/measure-grouping-engraver.cc
lily/stem.cc
scm/define-grob-properties.scm
scm/define-grobs.scm

index f62b454c901cd8603f76b9ae6777464fce6419d6..af201e791bbc9aef23fb2a2692f161a21cf0d238 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,18 @@
 2006-05-22  Han-Wen Nienhuys  <hanwen@lilypond.org>
 
+       * input/regression/beam-single-stem.ly: new file.
+
+       * lily/stem.cc (set_beaming): use #f as signaling value for
+       beamcount 0.
+
+       * lily/beam-engraver.cc (typeset_beam): set right bound if unset.
+
+       * lily/beam.cc (set_beaming): read clip-edges property.
+       (calc_direction): don't suicide for single stem.
+
+       * lily/beaming-info.cc (best_splitpoint_index): take bool*
+       argument, remove 1<<15 hack. Remove clip_edges() 
+
        * lily/hairpin.cc (print): only do padding for nonmusical bounds
 
 2006-05-21  Graham Percival  <gpermus@gmail.com>
diff --git a/input/regression/beam-single-stem.ly b/input/regression/beam-single-stem.ly
new file mode 100644 (file)
index 0000000..8749d41
--- /dev/null
@@ -0,0 +1,17 @@
+\header {
+
+  texidoc = "Single stem beams are also allowed. For such beams,
+  clip-edges is switched off automatically."
+
+}
+\version "2.9.6"
+
+\relative c' {
+  d16[]
+  \set stemRightBeamCount = #0
+  d32[]
+}
+
+\layout {
+  ragged-right = ##t
+}
index a70755bc33a1913944329b9d75a9bbc2205184e7..03795dc9a0e71a7c1035be20d9c7615370ea1219 100644 (file)
@@ -211,14 +211,12 @@ Auto_beam_engraver::begin_beam ()
     }
 
   stems_ = new vector<Item*>;
-  grouping_ = new Beaming_info_list;
+  grouping_ = make_beaming_info_list (context ());
   beam_settings_ = updated_grob_properties (context (), ly_symbol2scm ("Beam"));
 
   beam_start_moment_ = now_mom ();
   beam_start_location_
     = robust_scm2moment (get_property ("measurePosition"), Moment (0));
-  subdivide_beams_ = ly_scm2bool (get_property ("subdivideBeams"));
-  beat_length_ = robust_scm2moment (get_property ("beatLength"), Moment (1, 4));
 }
 
 void
@@ -260,7 +258,10 @@ Auto_beam_engraver::typeset_beam ()
 {
   if (finished_beam_)
     {
-      finished_grouping_->beamify (beat_length_, subdivide_beams_);
+      if (!finished_beam_->get_bound (RIGHT))
+       finished_beam_->set_bound (RIGHT, finished_beam_->get_bound (LEFT));
+      
+      finished_grouping_->beamify ();
       Beam::set_beaming (finished_beam_, finished_grouping_);
       finished_beam_ = 0;
 
index eb6284380a2627217ac9ce50ceb46f60177fedd0..7f89b9ed98802203dbafe3012be631be63cf1093 100644 (file)
@@ -145,8 +145,7 @@ Beam_engraver::process_music ()
       beam_start_location_ = mp;
       beam_start_mom_ = now_mom ();
 
-      beam_info_ = new Beaming_info_list;
-
+      beam_info_ = make_beaming_info_list (context ());
       /* urg, must copy to Auto_beam_engraver too */
     }
 }
@@ -156,7 +155,10 @@ Beam_engraver::typeset_beam ()
 {
   if (finished_beam_)
     {
-      finished_beam_info_->beamify (beat_length_, subdivide_beams_);
+      if (!finished_beam_->get_bound (RIGHT))
+       finished_beam_->set_bound (RIGHT, finished_beam_->get_bound (LEFT));
+         
+      finished_beam_info_->beamify ();
       Beam::set_beaming (finished_beam_, finished_beam_info_);
 
       delete finished_beam_info_;
@@ -173,9 +175,6 @@ Beam_engraver::start_translation_timestep ()
   if (beam_)
     {
       set_melisma (true);
-
-      subdivide_beams_ = to_boolean (get_property ("subdivideBeams"));
-      beat_length_ = robust_scm2moment (get_property ("beatLength"), Moment (1, 4));
     }
 }
 
@@ -277,12 +276,21 @@ ADD_ACKNOWLEDGER (Beam_engraver, stem);
 ADD_ACKNOWLEDGER (Beam_engraver, rest);
 
 ADD_TRANSLATOR (Beam_engraver,
-               /* doc */ "Handles Beam events by engraving Beams.    If omitted, then notes will be "
+               /* doc */
+
+               "Handles Beam events by engraving Beams.  If omitted, then notes will be "
                "printed with flags instead of beams.",
+               
                /* create */ "Beam",
                /* accept */ "beam-event",
-               /* read */ "beamMelismaBusy beatLength subdivideBeams",
-               /* write */ "forbidBreak");
+
+               /* read */
+               "beamMelismaBusy "
+               "beatLength "
+               "subdivideBeams "
+               ,
+               /* write */
+               "forbidBreak");
 
 class Grace_beam_engraver : public Beam_engraver
 {
@@ -314,12 +322,22 @@ Grace_beam_engraver::valid_end_point ()
 
 ADD_ACKNOWLEDGER (Grace_beam_engraver, stem);
 ADD_ACKNOWLEDGER (Grace_beam_engraver, rest);
+
 ADD_TRANSLATOR (Grace_beam_engraver,
-               /* doc */ "Handles Beam events by engraving Beams.  If omitted, then notes will "
+
+               /* doc */
+
+               "Handles Beam events by engraving Beams.  If omitted, then notes will "
                "be printed with flags instead of beams. Only engraves beams when we "
                " are at grace points in time. ",
+               
                /* create */ "Beam",
                /* accept */ "beam-event",
-               /* read */ "beamMelismaBusy beatLength allowBeamBreak subdivideBeams",
+               /* read */
+               "beamMelismaBusy "
+               "beatLength "
+               "allowBeamBreak "
+               "subdivideBeams "
+               ,
                /* write */ "");
 
index 1a4e0e36610b05d7fa4a0c1122c9c57ebae311f8..497957b465b9a101a04e91a5ebff19e6b1d28776 100644 (file)
@@ -133,24 +133,17 @@ Beam::calc_direction (SCM smob)
      For a beam that  only has one stem, we try to do some disappearance magic:
      we revert the flag, and move on to The Eternal Engraving Fields. */
 
-  Direction d = CENTER;
+  Direction dir = CENTER;
 
   int count = visible_stem_count (me);
   if (count < 2)
     {
       extract_grob_set (me, "stems", stems);
-      if (stems.size () == 1)
+      if (stems.size () == 0)
        {
-         me->warning (_ ("removing beam with less than two stems"));
-
-         stems[0]->set_object ("beam", SCM_EOL);
+         me->warning (_ ("removing beam with no stems"));
          me->suicide ();
 
-         return SCM_UNSPECIFIED;
-       }
-      else if (stems.size () == 0)
-       {
-         me->suicide ();
          return SCM_UNSPECIFIED;
        }
       else 
@@ -160,24 +153,24 @@ Beam::calc_direction (SCM smob)
          /*
            ugh: stems[0] case happens for chord tremolo.
          */
-         d = to_dir ((stem ? stem : stems[0])->get_property ("default-direction"));
+         dir = to_dir ((stem ? stem : stems[0])->get_property ("default-direction"));
        }
     }
 
   if (count >= 1)
     {
-      if (!d)
-       d = get_default_dir (me);
+      if (!dir)
+       dir = get_default_dir (me);
       
       consider_auto_knees (me);
     }
 
-  if (d)
+  if (dir)
     {
-      set_stem_directions (me, d);
+      set_stem_directions (me, dir);
     }
   
-  return scm_from_int (d);
+  return scm_from_int (dir);
 }
 
 
@@ -1217,6 +1210,12 @@ Beam::set_beaming (Grob *me, Beaming_info_list const *beaming)
                  && Stem::is_invisible (stem))
                count = min (count, beaming->infos_.at (i).beam_count_drul_[-d]);
 
+             if ( ((i == 0 && d == LEFT)
+                   || (i == stems.size ()-1 && d == RIGHT))
+                  && stems.size () > 1
+                  && to_boolean (me->get_property ("clip-edges")))
+               count = 0;
+
              Stem::set_beaming (stem, count, d);
            }
        }
@@ -1445,6 +1444,7 @@ ADD_INTERFACE (Beam,
               "beamed-stem-shorten "
               "beaming "
               "break-overshoot "
+              "clip-edges "
               "concaveness "
               "damping "
               "details "
index 417a20372c193de23bda8312f61b27930d7f9a94..0e66b2b68196b3f7f71846262b6e9724ff0eeca8 100644 (file)
@@ -7,6 +7,7 @@
 */
 
 #include "beaming.hh"
+#include "context.hh"
 
 Beaming_info::Beaming_info ()
 {
@@ -22,11 +23,10 @@ Beaming_info::Beaming_info (Moment m, int i)
   beam_count_drul_[RIGHT] = i;
 }
 
-const int at_beat = 1 << 15;   //  WTF is this.
-
 int
-Beaming_info_list::best_splitpoint_index (Moment &beat_length,
-                                         bool subdivide) const
+Beaming_info_list::best_splitpoint_index (Moment beat_length,
+                                         bool subdivide_beams,
+                                         bool *at_beat_subdivide) const
 {
   int min_denominator = INT_MAX;
   int min_index = -1;
@@ -37,7 +37,7 @@ Beaming_info_list::best_splitpoint_index (Moment &beat_length,
       beat_pos = infos_[i].start_moment_ / beat_length;
       int den = beat_pos.den ();
       if (infos_[i].beam_count_drul_[LEFT] == infos_[i - 1].beam_count_drul_[RIGHT]
-         && !subdivide)
+         && !subdivide_beams)
        den *= 2;
       
       if (den < min_denominator)
@@ -47,7 +47,9 @@ Beaming_info_list::best_splitpoint_index (Moment &beat_length,
        }
     }
 
-  return min_index | (min_denominator == 1 && subdivide ? at_beat : 0);
+  *at_beat_subdivide = (min_denominator == 1 && subdivide_beams);
+  
+  return min_index;
 }
 
 int
@@ -63,16 +65,37 @@ Beaming_info_list::beam_extend_count (Direction d) const
 }
 
 void
-Beaming_info_list::beamify (Moment &beat_length, bool subdivide)
+Beaming_info_list::beamify ()
+{
+  bool subdivide_beams = to_boolean (context_->get_property ("subdivideBeams"));
+  Moment beat_length = robust_scm2moment (context_->get_property ("beatLength"), Moment (1, 4));
+
+  beamify (beat_length, subdivide_beams);
+}
+
+
+
+Beaming_info_list *
+make_beaming_info_list (Context *context)
+{
+  Beaming_info_list *l = new Beaming_info_list;
+  l->context_ = context;
+  return l;
+}  
+
+
+void
+Beaming_info_list::beamify (Moment beat_length,
+                           bool subdivide_beams)
 {
   if (infos_.size () <= 1)
     return;
 
-  Drul_array<Beaming_info_list> splits;
+  
+  Drul_array<Beaming_info_list> splits (*this, *this);
 
-  int m = best_splitpoint_index (beat_length, subdivide);
-  bool split = subdivide && (m & at_beat);
-  m = m & ~at_beat;
+  bool split = false;
+  int m = best_splitpoint_index (beat_length, subdivide_beams, &split);
 
   splits[LEFT].infos_ = vector<Beaming_info> (infos_.begin (),
                                              infos_.begin () + m);
@@ -83,7 +106,7 @@ Beaming_info_list::beamify (Moment &beat_length, bool subdivide)
 
   do
     {
-      splits[d].beamify (beat_length, subdivide);
+      splits[d].beamify (beat_length, subdivide_beams);
     }
   while (flip (&d) != LEFT);
 
@@ -102,22 +125,20 @@ Beaming_info_list::beamify (Moment &beat_length, bool subdivide)
   infos_.insert (infos_.end (),
                 splits[RIGHT].infos_.begin (),
                 splits[RIGHT].infos_.end ());
-
-  clip_edges ();
 }
 
+
+
 void
 Beaming_info_list::add_stem (Moment m, int b)
 {
   infos_.push_back (Beaming_info (m, b));
 }
 
-void
-Beaming_info_list::clip_edges ()
+
+Beaming_info_list::Beaming_info_list ()
 {
-  if (infos_.size ())
-    {
-      infos_[0].beam_count_drul_[LEFT] = 0;
-      infos_.back ().beam_count_drul_[RIGHT] = 0;
-    }
+  context_ = 0;
 }
+
+
index 37337d45bc77aadd9f75da0eef79c343b9730d5a..4b9c215e2e9b7cbd4936a7262653ee0f06baa72f 100644 (file)
@@ -164,7 +164,8 @@ Hairpin::print (SCM smob)
              else
                {
                  x_points[d] = e[d];
-                 if (me->get_bound (d)->is_non_musical ())
+                 Item *bound = me->get_bound (d);
+                 if (bound->is_non_musical (bound))
                    x_points[d] -=  d * padding;
                }
            }
index 32a9ed4c821fdfd1f77fce761ae8f1bc87e86591..bb4bc7e1c0a3bf417789271df2bb32e5f0baef52 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "std-vector.hh"
 #include "moment.hh"
+#include "lily-proto.hh"
 
 struct Beaming_info
 {
@@ -18,8 +19,9 @@ struct Beaming_info
   Drul_array<int> beam_count_drul_;
 
   Beaming_info (Moment, int);
-  int count (Direction d);
   Beaming_info ();
+
+  int count (Direction d);
 };
 
 /*
@@ -29,12 +31,17 @@ struct Beaming_info
 struct Beaming_info_list
 {
   vector<Beaming_info> infos_;
+  Context *context_; 
 
+  Beaming_info_list ();
+  
   int beam_extend_count (Direction) const;
-  int best_splitpoint_index (Moment &beat_length, bool subdivide) const;
-  void beamify (Moment &beat_length, bool subdivide);
+  int best_splitpoint_index (Moment, bool, bool *split) const;
+  void beamify ();
+  void beamify (Moment, bool);
   void add_stem (Moment d, int beams);
-  void clip_edges ();
 };
 
+Beaming_info_list *make_beaming_info_list (Context *);
+
 #endif /* BEAMING_HH */
index fc6e2ed7eee9fb3956268d27b3427811b896e65c..126e32ec5f99b19df3e04d22d40b89c7a847910f 100644 (file)
@@ -66,12 +66,12 @@ Measure_grouping_engraver::process_music ()
       Moment *measpos = unsmob_moment (get_property ("measurePosition"));
       Rational mp = measpos->main_part_;
 
-      Moment *beatlen = unsmob_moment (get_property ("beatLength"));
-      Rational bl = beatlen->main_part_;
+      Moment *beatlen_mom = unsmob_moment (get_property ("beatLength"));
+      Rational beat_length = beatlen_mom->main_part_;
 
       Rational where (0);
       for (SCM s = grouping; scm_is_pair (s);
-          where += Rational ((int) scm_to_int (scm_car (s))) * bl,
+          where += Rational ((int) scm_to_int (scm_car (s))) * beat_length,
             s = scm_cdr (s))
        {
          int grouplen = scm_to_int (scm_car (s));
@@ -86,7 +86,7 @@ Measure_grouping_engraver::process_music ()
              grouping_ = make_spanner ("MeasureGrouping", SCM_EOL);
              grouping_->set_bound (LEFT, unsmob_grob (get_property ("currentMusicalColumn")));
 
-             stop_grouping_mom_ = now.main_part_ + Rational (grouplen - 1) * bl;
+             stop_grouping_mom_ = now.main_part_ + Rational (grouplen - 1) * beat_length;
              get_global_context ()->add_moment_to_process (Moment (stop_grouping_mom_));
 
              if (grouplen == 3)
@@ -107,8 +107,17 @@ Measure_grouping_engraver::Measure_grouping_engraver ()
 
 ADD_ACKNOWLEDGER (Measure_grouping_engraver, note_column);
 ADD_TRANSLATOR (Measure_grouping_engraver,
-               /* doc */ "Creates MeasureGrouping to indicate beat subdivision.",
-               /* create */ "MeasureGrouping",
-               /* accept */ "",
-               /* read */ "beatGrouping beatLength measurePosition currentMusicalColumn",
-               /* write */ "");
+               /* doc */
+               "Creates MeasureGrouping to indicate beat subdivision.",
+               /* create */
+               "MeasureGrouping",
+               /* accept */
+               "",
+               /* read */
+               "beatLength "
+               "currentMusicalColumn "
+               "measurePosition "
+               "beatGrouping "
+               ,
+               /* write */
+               "");
index 1be8f5985544c1ea1f6413ad37479655e992c6dd..3b00da28cff37c956ee2f4a9d78c4b704d88440c 100644 (file)
@@ -48,8 +48,12 @@ Stem::set_beaming (Grob *me, int beam_count, Direction d)
     }
 
   SCM lst = index_get_cell (pair, d);
-  for (int i = 0; i < beam_count; i++)
-    lst = scm_cons (scm_from_int (i), lst);
+  if (beam_count)
+    for (int i = 0; i < beam_count; i++)
+      lst = scm_cons (scm_from_int (i), lst);
+  else
+    lst = SCM_BOOL_F;
+  
   index_set_cell (pair, d, lst);
 }
 
index d59d4661c92466beb9bafb8c3507435954c828a9..5bcffdd929f3cacebdcdf844a30fd8e9959f0b9f 100644 (file)
@@ -368,6 +368,7 @@ Y axis.")
 
      (shorten-pair ,number-pair? "The lengths to shorten a
 text-spanner on both sides, for example a pedal bracket")
+     (clip-edges ,boolean? "Allow outward pointing beamlets at the edges of beams?")
      (common-shortest-duration ,ly:moment?
                               "The most common shortest note length.
 This is used in spacing. Enlarging this will set the score tighter.")
index 128849f988de2ea9e2fa9ecff7841885f89eb69d..304360f4f110c14a0c9dea08bc58ac2b039e0190 100644 (file)
        (shorten . ,ly:beam::calc-stem-shorten)
        (beaming . ,ly:beam::calc-beaming)
        (stencil . ,ly:beam::print)
-
+       (clip-edges . #t)
+       
        ;; TODO: should be in SLT.
        (thickness . 0.48) ; in staff-space
        (neutral-direction . ,DOWN)