]> git.donarmstrong.com Git - lilypond.git/commitdiff
lilypond-1.3.70
authorfred <fred>
Tue, 26 Mar 2002 23:24:28 +0000 (23:24 +0000)
committerfred <fred>
Tue, 26 Mar 2002 23:24:28 +0000 (23:24 +0000)
CHANGES
VERSION
input/bugs/auto-beam.ly [new file with mode: 0644]
input/bugs/f.ly [new file with mode: 0644]
lily/auto-beam-engraver.cc
lily/simple-spacer.cc
lily/spaceable-element.cc [new file with mode: 0644]
lily/spacing-spanner.cc

diff --git a/CHANGES b/CHANGES
index 36ed28852a67630a50c974a4ddb67440eac37e49..fd106120c2edc571ece2db4f8ef5e35b7e1b2610 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,18 @@
-1.3.68.hwn1
-===========
+* Fixed: long standing problem in optical-illusion code.
+
+* Fixed: stop beam if stem *has* a beam in auto-beam-engraver. 
+
+* Made interface of Multi_measure_rest, System_start_delimiter,
+Spacing_spanner, Separating_group_spanner, Beam, Slur and
+Rhythmic_head.
+
+* Use properties for minimum distances and spring parameters.  Move
+spacing related functions from Paper_column into Spaceable_element.
+
+* Removed most Paper_column typecasts.
+
+1.3.69
+======
 
 * Cleanup auto-beam-engraver: use properties for retrieving timing
 information.
@@ -32,8 +45,6 @@ callback for determining barsize.
 
 * Added test for repeats to trip.ly
 
-* 
-
 1.3.68
 ======
 
diff --git a/VERSION b/VERSION
index 9c8701a77f84fe42a7b5f215a4a3a7671dd7cde0..7da804129723ea48c53a6f66c346f762e7610ae5 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1,7 +1,7 @@
 PACKAGE_NAME=LilyPond
 MAJOR_VERSION=1
 MINOR_VERSION=3
-PATCH_LEVEL=69
+PATCH_LEVEL=70
 MY_PATCH_LEVEL=
 
 # use the above to send patches: MY_PATCH_LEVEL is always empty for a
diff --git a/input/bugs/auto-beam.ly b/input/bugs/auto-beam.ly
new file mode 100644 (file)
index 0000000..5acc702
--- /dev/null
@@ -0,0 +1,6 @@
+% bug or feature?
+\score { \notes { c8 c8
+  % needed to force auto-beam:
+  % c4
+
+}}
diff --git a/input/bugs/f.ly b/input/bugs/f.ly
new file mode 100644 (file)
index 0000000..5acc702
--- /dev/null
@@ -0,0 +1,6 @@
+% bug or feature?
+\score { \notes { c8 c8
+  % needed to force auto-beam:
+  % c4
+
+}}
index d912bb9585d17f8b6fe14b5a55cf1f2d0864ab44..316cc56f621593855cfd8049c3a30633c667020a 100644 (file)
@@ -16,6 +16,8 @@
 #include "bar.hh"
 #include "rest.hh"
 #include "engraver.hh"
+#include "item.hh"
+#include "spanner.hh"
 
 class Auto_beam_engraver : public Engraver
 {
@@ -34,14 +36,14 @@ protected:
 private:
   void begin_beam ();
   void consider_end_and_begin (Moment test_mom);
-  Beam* create_beam_p ();
+  Spanner* create_beam_p ();
   void end_beam ();
   void junk_beam ();
   bool same_grace_state_b (Score_element* e);
   void typeset_beam ();
 
   Moment shortest_mom_;
-  Beam *finished_beam_p_;
+  Spanner *finished_beam_p_;
   Link_array<Item>* stem_l_arr_p_;
   
   Moment last_add_mom_;
@@ -234,10 +236,11 @@ Auto_beam_engraver::begin_beam ()
   beam_start_location_ = *unsmob_moment (get_property ("measurePosition"));
 }
 
-Beam*
+Spanner*
 Auto_beam_engraver::create_beam_p ()
 {
-  Beam* beam_p = new Beam (get_property ("basicBeamProperties"));
+  Spanner* beam_p = new Spanner (get_property ("basicBeamProperties"));
+  Beam::set_interface (beam_p);
 
   for (int i = 0; i < stem_l_arr_p_->size (); i++)
     {
@@ -248,7 +251,7 @@ Auto_beam_engraver::create_beam_p ()
        {
          return 0;
        }
-      beam_p->add_stem ((*stem_l_arr_p_)[i]);
+      Beam::add_stem (beam_p,(*stem_l_arr_p_)[i]);
     }
   
   announce_element (Score_element_info (beam_p, 0));
@@ -281,7 +284,7 @@ Auto_beam_engraver::typeset_beam ()
   if (finished_beam_p_)
     {
       finished_grouping_p_->beamify ();
-      finished_beam_p_->set_beaming (finished_grouping_p_);
+      Beam::set_beaming (finished_beam_p_, finished_grouping_p_);
       typeset_element (finished_beam_p_);
       finished_beam_p_ = 0;
     
@@ -338,7 +341,7 @@ Auto_beam_engraver::acknowledge_element (Score_element_info info)
   
   if (stem_l_arr_p_)
     {
-      if (Beam *b = dynamic_cast<Beam *> (info.elem_l_))
+      if (Beam::has_interface (info.elem_l_))
        {
          end_beam ();
        }
@@ -373,7 +376,7 @@ Auto_beam_engraver::acknowledge_element (Score_element_info info)
          return;
        }
 
-      if (!Stem::beam_l (stem_l))
+      if (Stem::beam_l (stem_l))
        {
          if (stem_l_arr_p_)
            junk_beam ();
index e11b6c1dd6cb5f26abde9701a10eefa1762185d7..36971396df3c7229b3a83ae974a157992818ff9a 100644 (file)
@@ -19,6 +19,7 @@
 #include "rod.hh"
 #include "warn.hh"
 #include "column-x-positions.hh"
+#include "spaceable-element.hh"
 #include "dimensions.hh"
 
 Simple_spacer::Simple_spacer ()
@@ -164,26 +165,27 @@ Simple_spacer::my_solve_natural_len ()
 }
 
 void
-Simple_spacer::add_columns (Link_array<Paper_column> cols)
+Simple_spacer::add_columns (Link_array<Score_element> cols)
 {
   for (int i=0; i < cols.size () - 1; i++)
     {
-      Paper_column * c = cols [i];
-      Column_spring *to_next = 0;
-      for (int j =0; !to_next && j < c->springs_.size( ); j++)
+      SCM spring_params = SCM_UNDEFINED;
+      for (SCM s = Spaceable_element::get_ideal_distances (cols[i]);
+          spring_params == SCM_UNDEFINED && gh_pair_p (s);
+          s = gh_cdr (s))
        {
-         Column_spring &sp = c->springs_ [j];
-         if (sp.other_l_ != cols[i+1])
+         Score_element *other = unsmob_element (gh_caar (s));
+         if (other != cols[i+1])
            continue;
 
-         to_next = &sp;
+         spring_params = gh_cdar (s);
        }
 
       Spring_description desc;
-      if (to_next)
+      if (spring_params != SCM_UNDEFINED)
        {
-         desc.hooke_f_ = to_next->strength_f_;
-         desc.ideal_f_ = to_next->distance_f_;
+         desc.ideal_f_ = gh_scm2double (gh_car (spring_params));
+         desc.hooke_f_ = gh_scm2double (gh_cdr (spring_params));
        }
       else
        {
@@ -204,13 +206,14 @@ Simple_spacer::add_columns (Link_array<Paper_column> cols)
   
   for (int i=0; i < cols.size () - 1; i++)
     {
-      Array<Column_rod> * rods = &cols [i]->minimal_dists_;
-      for (int j =0; j < rods->size( ); j++)
+      for (SCM s = Spaceable_element::get_minimum_distances (cols[i]);
+          gh_pair_p (s); s = gh_cdr (s))
        {
-         int oi = cols.find_i (rods->elem (j).other_l_ );
+         Score_element * other = unsmob_element (gh_caar (s));
+         int oi = cols.find_i (other);
          if (oi >= 0)
            {
-             add_rod (i, oi, rods->elem (j).distance_f_);
+             add_rod (i, oi, gh_scm2double (gh_cdar (s)));
            }
        }
     }
diff --git a/lily/spaceable-element.cc b/lily/spaceable-element.cc
new file mode 100644 (file)
index 0000000..7f746ee
--- /dev/null
@@ -0,0 +1,84 @@
+/*   
+  spaceable-element.cc --  implement Spaceable_element
+  
+  source file of the GNU LilyPond music typesetter
+  
+  (c) 2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+  
+ */
+
+#include "spaceable-element.hh"
+#include "score-element.hh"
+#include "warn.hh"
+
+SCM
+Spaceable_element::get_minimum_distances ( Score_element*me)
+{
+  return me->get_elt_property ("minimum-distances");
+}
+
+void
+Spaceable_element::add_rod (Score_element *me , Score_element * p, Real d)
+{
+  SCM mins = get_minimum_distances (me);
+  SCM newdist=                        gh_double2scm (d);
+  for (; gh_pair_p (mins); mins = gh_cdr (mins))
+    {
+      SCM dist = gh_car (mins);
+      if (gh_car (dist) == p->self_scm_)
+       {
+         gh_set_cdr_x (dist, scm_max (gh_cdr (dist),
+                                      newdist));
+         return ;
+       }
+    }
+
+  mins = gh_cons (gh_cons (p->self_scm_, newdist), mins);
+  me->set_elt_property ("minimum-distances", mins);
+}
+
+SCM
+Spaceable_element::get_ideal_distances (Score_element*me)
+{
+  return me->get_elt_property ("ideal-distances");
+}
+
+void
+Spaceable_element::add_spring (Score_element*me, Score_element * p, Real d, Real s)
+{
+  SCM mins = get_ideal_distances (me);
+  SCM newdist= gh_double2scm (d);
+  for (; gh_pair_p (mins); mins = gh_cdr (mins))
+    {
+      SCM dist = gh_car (mins);
+      if (gh_car (dist) == p->self_scm_)
+       {
+         programming_error("already have that spring");
+         /*      gh_set_car_x (gh_cdr (dist), scm_max (gh_cadr (dist),
+                 newdist));*/
+         return ;
+       }
+    }
+  SCM newstrength= gh_double2scm (s);  
+  
+  mins = gh_cons (gh_cons (p->self_scm_, gh_cons (newdist, newstrength)), mins);
+  me->set_elt_property ("ideal-distances", mins);
+}
+
+
+void
+Spaceable_element::remove_interface (Score_element*me)
+{
+  me->remove_elt_property ("minimum-distances");
+  me->remove_elt_property ("ideal-distances");
+  me->remove_elt_property ("dir-list");
+}
+
+
+void
+Spaceable_element::set_interface (Score_element*me)
+{
+  me->set_elt_property ("minimum-distances", SCM_EOL);
+  me->set_elt_property ("ideal-distances", SCM_EOL);
+  me->set_elt_property ("dir-list",SCM_EOL) ;  
+}
index 827213d9fd089b1046a4a5d2f614c6576a89fa6a..9ba71190341dc939b9675c05bdfcd3d6e339f49d 100644 (file)
 #include "line-of-score.hh"
 #include "misc.hh"
 
-Spacing_spanner::Spacing_spanner (SCM s)
-  : Spanner (s)
+void
+Spacing_spanner::set_interface (Score_element*me)
 {
-  set_extent_callback (0, X_AXIS);
-  set_extent_callback (0, Y_AXIS);  
+  me->set_extent_callback (0, X_AXIS);
+  me->set_extent_callback (0, Y_AXIS);  
 }
 
 /*
@@ -36,8 +36,8 @@ Spacing_spanner::Spacing_spanner (SCM s)
   TODO: write comments 
   
  */
-Array<Spring>
-Spacing_spanner::do_measure (Link_array<Paper_column> cols) const
+void
+Spacing_spanner::do_measure (Score_element*me, Link_array<Score_element> cols) 
 {
   Moment shortest;
   Moment mean_shortest;
@@ -46,7 +46,7 @@ Spacing_spanner::do_measure (Link_array<Paper_column> cols) const
   int n = 0;
   for (int i =0 ; i < cols.size (); i++)  
     {
-      if (cols[i]->musical_b ())
+      if (dynamic_cast<Paper_column*> (cols[i])->musical_b ())
        {
          SCM  st = cols[i]->get_elt_property ("shortest-starter-duration");
          Moment this_shortest = (*SMOB_TO_TYPE(Moment, st));
@@ -60,15 +60,13 @@ Spacing_spanner::do_measure (Link_array<Paper_column> cols) const
     }
   mean_shortest /= n;
 
-  Array<Spring> meas_springs;
-
-  Real non_musical_space_strength = paper_l ()->get_var ("breakable_column_space_strength");
+  Real non_musical_space_strength = me->paper_l ()->get_var ("breakable_column_space_strength");
   for (int i= 0; i < cols.size () - 1; i++)
     {
-      Item * l = cols[i];
-      Item * r = cols[i+1];
-      Item * lb = l->find_prebroken_piece (RIGHT);
-      Item * rb = r->find_prebroken_piece (LEFT);      
+      Item * l = dynamic_cast<Item*> (cols[i]);
+      Item * r =  dynamic_cast<Item*> (cols[i+1]);
+      Item * lb = dynamic_cast<Item*> ( l->find_prebroken_piece (RIGHT));
+      Item * rb = dynamic_cast<Item*> ( r->find_prebroken_piece (LEFT));
 
       Item* combinations[4][2]={{l,r}, {lb,r}, {l,rb},{lb,rb}};
 
@@ -96,11 +94,11 @@ Spacing_spanner::do_measure (Link_array<Paper_column> cols) const
           // 2nd condition should be (i+1 < col_count()), ie. not the last column in score.  FIXME
          else if (!lc->musical_b() && i+1 < cols.size ()) 
            {
-             left_distance= default_bar_spacing (lc,rc,shortest);
+             left_distance= default_bar_spacing (me,lc,rc,shortest);
            }
          else if (lc->musical_b())
            {
-             left_distance  = note_spacing (lc, rc, shortest);
+             left_distance  = note_spacing (me,lc, rc, shortest);
            }
 
          s.distance_f_ = left_distance;
@@ -112,10 +110,10 @@ Spacing_spanner::do_measure (Link_array<Paper_column> cols) const
            We want the space before barline to be like the note
            spacing in the measure.
          */
-         if (lc->breakable_b () || lc->original_l_)
+         if (Item::breakable_b (lc) || lc->original_l_)
            s.strength_f_ = non_musical_space_strength;
          else if (!lc->musical_b ())
-           left_distance *= paper_l ()->get_var ("decrease_nonmus_spacing_factor");
+           left_distance *= me->paper_l ()->get_var ("decrease_nonmus_spacing_factor");
 
          
          Real right_dist = 0.0;
@@ -135,11 +133,11 @@ Spacing_spanner::do_measure (Link_array<Paper_column> cols) const
          if (lc->musical_b () && rc->musical_b ())
            {
              if (!to_boolean (rc->get_elt_property ("contains-grace")))
-               right_dist *= paper_l ()->get_var ("musical_to_musical_left_spacing_factor");
+               right_dist *= me->paper_l ()->get_var ("musical_to_musical_left_spacing_factor");
            }
 
          if (rc->musical_b () && to_boolean (rc->get_elt_property ("contains-grace")))
-           right_dist *= paper_l ()->get_var ("before_grace_spacing_factor");
+           right_dist *= me->paper_l ()->get_var ("before_grace_spacing_factor");
  
          s.distance_f_ = left_distance + right_dist;
            
@@ -170,30 +168,29 @@ Spacing_spanner::do_measure (Link_array<Paper_column> cols) const
          else
            s.strength_f_ /= stretch_dist;
          
-         meas_springs.push (s);        
+         s.add_to_cols ();
        }
     }
-
-  return meas_springs;
+  
 }
 
 /**
    Do something if breakable column has no spacing hints set.
  */
 Real
-Spacing_spanner::default_bar_spacing (Paper_column *lc, Paper_column *rc,
-                                     Moment shortest) const
+Spacing_spanner::default_bar_spacing (Score_element*me, Score_element *lc, Score_element *rc,
+                                     Moment shortest) 
 {
   Real symbol_distance = lc->extent (X_AXIS)[RIGHT] ;
   Real durational_distance = 0;
-  Moment delta_t =  rc->when_mom () - lc->when_mom () ;
+  Moment delta_t = Paper_column::when_mom (rc) - Paper_column::when_mom (lc);
 
   /*
                ugh should use shortest_playing distance
   */
   if (delta_t)
     {
-      durational_distance =  get_duration_space (delta_t, shortest);
+      durational_distance =  get_duration_space (me, delta_t, shortest);
     }
 
   return  symbol_distance >? durational_distance;
@@ -201,7 +198,7 @@ Spacing_spanner::default_bar_spacing (Paper_column *lc, Paper_column *rc,
 
 
 /**
-  Get the measure wide constant for arithmetic spacing.
+  Get the measure wide ant for arithmetic spacing.
 
   @see
   John S. Gourlay. ``Spacing a Line of Music,'' Technical Report
@@ -210,42 +207,47 @@ Spacing_spanner::default_bar_spacing (Paper_column *lc, Paper_column *rc,
 
   */
 Real
-Spacing_spanner::get_duration_space (Moment d, Moment shortest) const
+Spacing_spanner::get_duration_space (Score_element*me, Moment d, Moment shortest) 
 {
   Real log = log_2 (Moment (1,8) <? shortest);
-  Real k=   paper_l ()->get_var ("arithmetic_basicspace")
+  Real k=   me->paper_l ()->get_var ("arithmetic_basicspace")
     - log;
   
-  return (log_2 (d) + k) * paper_l ()->get_var ("arithmetic_multiplier");
+  return (log_2 (d) + k) * me->paper_l ()->get_var ("arithmetic_multiplier");
 }
 
 
 Real
-Spacing_spanner::note_spacing (Paper_column *lc, Paper_column *rc, Moment shortest) const
+Spacing_spanner::note_spacing (Score_element*me, Score_element *lc, Score_element *rc, Moment shortest) 
 {
   Moment shortest_playing_len = 0;
   SCM s = lc->get_elt_property ("shortest-playing-duration");
-  //  SCM s = lc->get_elt_property ("mean-playing-duration");  
-  if (SMOB_IS_TYPE_B(Moment, s))
-    shortest_playing_len = *SMOB_TO_TYPE (Moment, s);
 
+  //  SCM s = lc->get_elt_property ("mean-playing-duration");  
+  if (unsmob_moment (s))
+    shortest_playing_len = *unsmob_moment(s);
   
   if (! shortest_playing_len)
     {
-      programming_error ("can't find a ruling note at " + lc->when_mom ().str ());
+      programming_error ("can't find a ruling note at " + Paper_column::when_mom (lc).str ());
       shortest_playing_len = 1;
     }
   
   if (! shortest)
     {
-      programming_error ("no minimum in measure at " + lc->when_mom ().str ());
+      programming_error ("no minimum in measure at " + Paper_column::when_mom (lc).str ());
       shortest = 1;
     }
-  Moment delta_t = rc->when_mom () - lc->when_mom ();
-  Real dist = get_duration_space (shortest_playing_len, shortest);
+  Moment delta_t = Paper_column::when_mom (rc) - Paper_column::when_mom (lc);
+  Real dist = get_duration_space (me, shortest_playing_len, shortest);
   dist *= (double)(delta_t / shortest_playing_len);
 
-  dist += stem_dir_correction (lc,rc);
+  /*
+    UGH: KLUDGE!
+  */
+  
+  if (delta_t > Moment (1,32))
+    dist += stem_dir_correction (me, lc,rc);
   return dist;
 }
 
@@ -264,17 +266,16 @@ Spacing_spanner::note_spacing (Paper_column *lc, Paper_column *rc, Moment shorte
    TODO: lookup correction distances?  More advanced correction?
    Possibly turn this off?
 
+   TODO: have to check wether the stems are in the same staff.
+
    This routine reads the DIR-LIST property of both its L and R arguments.  */
 Real
-Spacing_spanner::stem_dir_correction (Paper_column*l, Paper_column*r) const
+Spacing_spanner::stem_dir_correction (Score_element*me, Score_element*l, Score_element*r) 
 {
   SCM dl = l->get_elt_property ("dir-list");
   SCM dr = r->get_elt_property ("dir-list");
-  if (dl == SCM_UNDEFINED || dr == SCM_UNDEFINED)
-    return 0.0;
-
-
-  if (scm_ilength (dl) != 1 && scm_ilength (dr) != 1)
+  
+  if (scm_ilength (dl) != 1 || scm_ilength (dr) != 1)
     return 0.;
 
   dl = gh_car (dl);
@@ -289,44 +290,35 @@ Spacing_spanner::stem_dir_correction (Paper_column*l, Paper_column*r) const
 
   bool err = false;
   Real correction = 0.0;
-  Real ssc = paper_l ()->get_var("stemSpacingCorrection");
+  Real ssc = me->paper_l ()->get_var("stemSpacingCorrection");
 
 
-  if (d1 && d2)
+  if (d1 && d2 && d1 * d2 == -1)
     {
-      if (d1 == 1 && d2 == -1)
-       correction = ssc;
-      else if (d1 == -1 && d2 == 1)
-       correction = -ssc;
-      else
-       err = true;
+      correction = d1 * ssc;
     }
-  
   else
-    err = true;
-
-  if (err)
     programming_error ("Stem directions not set correctly for optical correction");
   return correction;
 }
   
 
-Array<Spring>
-Spacing_spanner::get_springs () const
+MAKE_SCHEME_CALLBACK(Spacing_spanner, set_springs);
+SCM
+Spacing_spanner::set_springs (SCM smob)
 {
-  Array<Spring> springs;
-
-  Link_array<Paper_column> all (pscore_l_->line_l_->column_l_arr ()) ;
+  Score_element *me = unsmob_element (smob);
+  Link_array<Score_element> all (me->pscore_l_->line_l_->column_l_arr ()) ;
 
   int j = 0;
 
   for (int i = 1; i < all.size (); i++)
     {
-      Paper_column* sc = dynamic_cast<Paper_column*> (all[i]);
-      if (sc->breakable_b ())
+      Score_element *sc = all[i];
+      if (Item::breakable_b (sc))
         {
-         Link_array<Paper_column> measure (all.slice (j, i+1));          
-          springs.concat (do_measure (measure));
+         Link_array<Score_element> measure (all.slice (j, i+1));         
+          do_measure (me, measure);
          j = i;
         }
     }
@@ -334,9 +326,8 @@ Spacing_spanner::get_springs () const
   /*
     farewell, cruel world
    */
-  ((Spacing_spanner*)this)->suicide ();
-  
-  return springs;
+  me->suicide ();
+  return SCM_UNDEFINED;
 }