]> git.donarmstrong.com Git - lilypond.git/commitdiff
release: 1.3.12 release/1.3.12
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Thu, 16 Dec 1999 12:06:01 +0000 (13:06 +0100)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Thu, 16 Dec 1999 12:06:01 +0000 (13:06 +0100)
23 files changed:
CHANGES
Documentation/programmer/regression-test.tely
TODO
VERSION
input/test/beam-pos.ly
input/test/harmonics.fly
input/test/noteheadstyle.ly
lily/beam.cc
lily/clef-engraver.cc
lily/clef-item.cc
lily/include/beam.hh
lily/include/bow.hh
lily/include/clef-item.hh
lily/include/stem.hh
lily/new-beaming.cc [deleted file]
lily/note-column.cc
lily/stem-tremolo.cc
lily/stem.cc
make/out/lilypond.lsm
make/out/lilypond.spec
mutopia/J.S.Bach/wtk1-fugue2.ly
scm/generic-property.scm
scm/lily.scm

diff --git a/CHANGES b/CHANGES
index c997cae9da449ade511ef002be922693efac7da0..537ec3f1c40afbf3b158dc0c325a7166cc96e3ee 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,7 +1,17 @@
+pl 11.jcn3
+       - small beam fixes (interstaff knees still broken)
+
 pl 11.hwn1
        - bf: dots
+       - bf: harmonic note heads
        - revise stem, notehead, rest
 
+pl 11.jcn2
+       - included missing scm,ly updates
+       - bf: urg to_dir () takes scm..
+       - bf's: if (Foo b = bar != 1)
+       - beam cleanup
+
 ************
 pl 10.uu1
        - various small bfs
index de989ac512c0489c87802262fcc253f5f6deb4eb..dab2cc587d9c7d7bfed37cc11177a33ccdb1c292 100644 (file)
@@ -29,14 +29,17 @@ Note head shapes are settable.  The stem endings should be adjusted
 per note head.  If you want different note head styles on one stem,
 you must create a special context called Thread.
 
+Harmonic notes have a different shape and different
+dimensions. Nevertheless, noteheads in both styles can be combined, on
+either up or down stems.
+
 @mudelafile{noteheadstyle.ly}
 
-Noteheads can have dots, and ---although this is bad style in duple
-meters--- rests can too.  Augmentation dots should never be printed on
-a staff line, but rather be shifted vertically. They should go up, but
-in case of multiple parts, the down stems have down shifted dots.
-(Wanske p. 186) In case of chords, all dots should be in a column.
-The dots go along as rests are shifted to avoid collisions.
+Noteheads can have dots, and rests can too.  Augmentation dots should
+never be printed on a staff line, but rather be shifted vertically. They
+should go up, but in case of multiple parts, the down stems have down
+shifted dots.  (Wanske p. 186) In case of chords, all dots should be in
+a column.  The dots go along as rests are shifted to avoid collisions.
 
 @mudelafile{dots.fly}
 
diff --git a/TODO b/TODO
index 5bf1c889c4336c4c748605122360e19c854820d7..a08d5cbf25dcc2948a721f9716f457485a113fb4 100644 (file)
--- a/TODO
+++ b/TODO
@@ -13,6 +13,8 @@ Grep -i for TODO, FIXME and ugh/ugr/urg.
 . * agressive type-checking for SCM stuff.
 . * use  "staff-space" and "half-space" iso interline,
     staff_line_leading () etc.
+. * why does Voice.beamQuantisation = #'none not work?
+    overriding in ly/params.ly works fine
 
 . * TODO^2:
 .  * make  a TODO.texi, like http://www.gnu.org/software/guile/ideas.html
diff --git a/VERSION b/VERSION
index a68f071212ca468a649636f6887a9d28e9607c67..04cb146bb1d4ebea0fc64db9bf1711a062a7f817 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1,8 +1,8 @@
 PACKAGE_NAME=LilyPond
 MAJOR_VERSION=1
 MINOR_VERSION=3
-PATCH_LEVEL=11
-MY_PATCH_LEVEL=hwn1
+PATCH_LEVEL=12
+MY_PATCH_LEVEL=
 
 # use the above to send patches: MY_PATCH_LEVEL is always empty for a
 # released version.
index edcd5e9253710c3d028cf9dbe5b103af6b7ab04e..2d6dcdfc1fe1c230bf48e9afd0aced7c0e49214a 100644 (file)
@@ -2,7 +2,7 @@
 
 \score{
        \notes\transpose c''{
-               \property Score.beamQuantisation = 'test
+               \property Score.beamQuantisation = 'test
 
                [c8 c] [c c] [c c] [c c]
                [a' a'] [a' a'] [a' a'] [a' a']
index 59d8925dc9220cbc6e30470faca3502254ed1443..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
@@ -1,8 +0,0 @@
-% this should be normal notes:
-c'1 | d2 d | e4 e 
-
-% and this should be harmonics:
-\property Voice.noteheadStyle = "harmonic"
-e8 e e16 e e e32 e
-
-
index d89e3655306aeba9553fb64675bb0b3ba824658a..2ea3c430255c9830ad80a9529d51d6e246b956ec 100644 (file)
@@ -20,6 +20,12 @@ c4 c2 c8  c16 c16  c1
       { \property Thread.noteHeadStyle = "harmonic" d16 }
     
   >
+ \context Voice <\context Thread = TA { c4 c4 }
+\context Thread = TB {
+  \property Thread.noteHeadStyle = "harmonic"
+  c'4 \stemdown c
+} >
+
 }
 
     \paper {
index 0c622458928a3a6a489a09e7119148bc7a25b7de..152e411cff1ec033224b004e1e96072067dc60be 100644 (file)
@@ -8,23 +8,21 @@
 
 */
 
-
 /*
   [TODO]
     * center beam symbol
     * less hairy code
+    * move paper vars to scm
 
     */
 
-#include <math.h>
+//#include <math.h>
 
 #include "beaming.hh"
-#include "proto.hh"
 #include "dimensions.hh"
 #include "beam.hh"
 #include "misc.hh"
 #include "debug.hh"
-#include "molecule.hh"
 #include "leastsquares.hh"
 #include "stem.hh"
 #include "paper-def.hh"
@@ -37,74 +35,6 @@ Beam::Beam ()
 {
   Group_interface g (this, "stems");
   g.set_interface ();
-  
-  slope_f_ = 0;
-  left_y_ = 0;
-}
-
-/*
-  TODO: Fix this class. This is wildly inefficient.
- */
-Stem *
-Beam::stem (int i)const
-{
-  return Group_interface__extract_elements ((Beam*) this, (Stem*) 0, "stems")[i];
-}
-
-int
-Beam::stem_count ()const
-{
-  Group_interface gi (this, "stems");
-  return gi.count ();
-}
-
-Stem*
-Beam::stem_top ()const
-{
-  return Group_interface__extract_elements ((Beam*) this, (Stem*) 0, "stems")[stem_count () - 1];
-}
-
-/* burp */
-int
-Beam::visible_stem_count () const
-{
-  int c = 0;
-  for (int i = 0; i < stem_count (); i++)
-    {
-      if (!stem (i)->invisible_b ())
-        c++;
-    }
-  return c;
-}
-
-Stem*
-Beam::first_visible_stem () const
-{
-  for (int i = 0; i < stem_count (); i++)
-    {
-      Stem* s = stem (i);
-      if (!s->invisible_b ())
-        return s;
-    }
-
-  assert (0);
-  // sigh
-  return 0;
-}
-
-Stem*
-Beam::last_visible_stem () const
-{
-  for (int i = stem_count (); i > 0; i--)
-    {
-      Stem* s = stem (i - 1);
-      if (!s->invisible_b ())
-        return s;
-    }
-
-  assert (0);
-  // sigh
-  return 0;
 }
 
 void
@@ -124,152 +54,52 @@ Beam::add_stem (Stem*s)
     set_bounds (RIGHT,s);
 }
 
-Molecule*
-Beam::do_brew_molecule_p () const
+int
+Beam::get_multiplicity () const
 {
-  Molecule *mol_p = new Molecule;
-  if (!stem_count ())
-    return mol_p;
-  
-  Real x0 = first_visible_stem ()->hpos_f ();
-  for (int j=0; j <stem_count (); j++)
+  int m = 0;
+  for (SCM s = get_elt_property ("stems"); gh_pair_p (s); s = gh_cdr (s))
     {
-      Stem *i = stem (j);
-      Stem * prev = (j > 0)? stem (j-1) : 0;
-      Stem * next = (j < stem_count ()-1) ? stem (j+1) :0;
+      Score_element * sc = unsmob_element (gh_car (s));
 
-      Molecule sb = stem_beams (i, next, prev);
-      Real  x = i->hpos_f ()-x0;
-      sb.translate (Offset (x, x * slope_f_ + left_y_));
-      mol_p->add_molecule (sb);
+      if (Stem * st = dynamic_cast<Stem*> (sc))
+       m = m >? st->beam_count (LEFT) >? st->beam_count (RIGHT);
     }
-  mol_p->translate_axis (x0 
-    - spanned_drul_[LEFT]->relative_coordinate (0, X_AXIS), X_AXIS);
-
-  return mol_p;
-}
-
-Offset
-Beam::center () const
-{
-  Real w = (first_visible_stem ()->note_delta_f () + extent (X_AXIS).length ())/2.0;
-  return Offset (w, w * slope_f_);
+  return m;
 }
 
 /*
-  Simplistic auto-knees; only consider vertical gap between two
-  adjacent chords
+  After pre-processing all directions should be set.
+  Several post-processing routines (stem, slur, script) need stem/beam
+  direction.
+  Currenly, this means that beam has set all stem's directions.
+  [Alternatively, stems could set its own directions, according to
+   their beam, during 'final-pre-processing'.]
  */
-bool
-Beam::auto_knee (SCM gap, bool interstaff_b)
-{
-  bool knee = false;
-  int knee_y = 0;
-  if (gap != SCM_UNDEFINED)
-    {
-      int auto_gap_i = gh_scm2int (gap);
-      for (int i=1; i < stem_count (); i++)
-        {
-         bool is_b = (bool)(calc_interstaff_dist (stem (i), this) 
-           - calc_interstaff_dist (stem (i-1), this));
-         int l_y = (int)(stem (i-1)->chord_start_f ())
-           + (int)calc_interstaff_dist (stem (i-1), this);
-         int r_y = (int)(stem (i)->chord_start_f ())
-           + (int)calc_interstaff_dist (stem (i), this);
-         int gap_i = r_y - l_y;
-
-         /*
-           Forced stem directions are ignored.  If you don't want auto-knees,
-           don't set, or unset autoKneeGap/autoInterstaffKneeGap.
-          */
-         if ((abs (gap_i) >= auto_gap_i) && (!interstaff_b || is_b))
-           {
-             knee_y = (r_y + l_y) / 2;
-             knee = true;
-             break;
-           }
-       }
-    }
-  if (knee)
-    {
-      for (int i=0; i < stem_count (); i++)
-        {
-         int y = (int)(stem (i)->chord_start_f ())
-           + (int)calc_interstaff_dist (stem (i), this);
-         stem (i)->set_direction ( y < knee_y ? UP : DOWN);
-         stem (i)->set_elt_property ("dir-forced", SCM_BOOL_T);
-       }
-    }
-  return knee;
-}
-
-bool
-Beam::auto_knees ()
-{
-  if (auto_knee (get_elt_property ("auto-interstaff-knee-gap"), true))
-    return true;
-  
-  return auto_knee (get_elt_property ("auto-knee-gap"), false);
-}
-
-
 void
 Beam::do_pre_processing ()
 {
-  /*
-    urg: it seems that info on whether beam (voice) dir was forced
-         is being junked here?
-  */
-  if (!get_direction ())
-    set_direction ( get_default_dir ());
-  
-  set_direction (get_direction ());
-}
-
-void
-Beam::do_print () const
-{
-#ifndef NPRINT
-  DEBUG_OUT << "slope_f_ " << slope_f_ << "left ypos " << left_y_;
-  Spanner::do_print ();
-#endif
-}
-
-void
-Beam::do_post_processing ()
-{
+  // Why?
   if (visible_stem_count () < 2)
     {
-      warning (_ ("beam with less than two stems"));
+      warning (_ ("beam has less than two stems"));
       set_elt_property ("transparent", SCM_BOOL_T);
-      return;
-    }
-  set_stem_shorten ();
-  if (auto_knees ())
-    {
-      /*
-       if auto-knee did its work, most probably stem directions
-       have changed, so we must recalculate all.
-       */
-      set_direction (get_default_dir ());
-      set_direction (get_direction ());
-
-      /* auto-knees used to only work for slope = 0
-        anyway, should be able to set slope per beam
-         set_elt_property ("damping", gh_int2scm(1000));
-      */
-
-      set_stem_shorten ();
     }
-  calculate_slope ();
-  set_stemlens ();
-}
 
+  if (!get_direction ())
+    set_direction (calc_default_dir ());
 
+  auto_knees ();
+  set_stem_directions ();
 
+  set_stem_shorten (); 
+}
 
+/*
+ FIXME
+ */
 Direction
-Beam::get_default_dir () const
+Beam::calc_default_dir () const
 {
   Drul_array<int> total;
   total[UP]  = total[DOWN] = 0;
@@ -278,7 +108,7 @@ Beam::get_default_dir () const
   Direction d = DOWN;
 
   for (int i=0; i <stem_count (); i++)
-    do {
+    do { // HUH -- waar slaat dit op?
       Stem *s = stem (i);
       int current = s->get_direction () 
        ? (1 + d * s->get_direction ())/2
@@ -334,229 +164,359 @@ Beam::get_default_dir () const
   return beam_dir;
 }
 
+
+/*
+  Set all stems with non-forced direction to beam direction.
+  Urg: non-forced should become `without/with unforced' direction,
+       once stem gets cleaned-up.
+ */
 void
-Beam::set_direction (Direction d)
+Beam::set_stem_directions ()
 {
-  Directional_spanner::set_direction (d);
+  Direction d = get_direction ();
   for (int i=0; i <stem_count (); i++)
     {
       Stem *s = stem (i);
-      s->set_elt_property ("beam-dir", gh_int2scm (d));
-
-      SCM force = s->get_elt_property ("dir-forced"); // remove_prop?
+      SCM force = s->remove_elt_property ("dir-forced");
       if (force == SCM_UNDEFINED)
-       s->set_direction ( d);
+       s->set_direction (d);
     }
+} 
+
+void
+Beam::auto_knees ()
+{
+  if (!auto_knee ("auto-interstaff-knee-gap", true))
+    auto_knee ("auto-knee-gap", false);
 }
 
 /*
-  See Documentation/tex/fonts.doc
+  Simplistic auto-knees; only consider vertical gap between two
+  adjacent chords.
+
+  `Forced' stem directions are ignored.  If you don't want auto-knees,
+  don't set, or unset autoKneeGap/autoInterstaffKneeGap.
  */
+bool
+Beam::auto_knee (String gap_str, bool interstaff_b)
+{
+  bool knee_b = false;
+  int knee_y = 0;
+  SCM gap = get_elt_property (gap_str);
+  if (gap != SCM_UNDEFINED)
+    {
+      int auto_gap_i = gh_scm2int (gap);
+      for (int i=1; i < stem_count (); i++)
+        {
+         bool is_b = (bool)(calc_interstaff_dist (stem (i), this) 
+           - calc_interstaff_dist (stem (i-1), this));
+         int l_y = (int)(stem (i-1)->chord_start_f ())
+           + (int)calc_interstaff_dist (stem (i-1), this);
+         int r_y = (int)(stem (i)->chord_start_f ())
+           + (int)calc_interstaff_dist (stem (i), this);
+         int gap_i = r_y - l_y;
 
+         if ((abs (gap_i) >= auto_gap_i) && (!interstaff_b || is_b))
+           {
+             knee_y = (r_y + l_y) / 2;
+             knee_b = true;
+             break;
+           }
+       }
+    }
+  if (knee_b)
+    {
+      for (int i=0; i < stem_count (); i++)
+        {
+         int y = (int)(stem (i)->chord_start_f ())
+           + (int)calc_interstaff_dist (stem (i), this);
+         stem (i)->set_direction (y < knee_y ? UP : DOWN);
+         stem (i)->set_elt_property ("dir-forced", SCM_BOOL_T);
+       }
+    }
+  return knee_b;
+}
+
+/*
+ Set stem's shorten property if unset.
+ TODO: take some y-position (nearest?) into account
+ */
 void
-Beam::solve_slope ()
+Beam::set_stem_shorten ()
 {
-  assert (visible_stem_count () > 1);
+  if (!visible_stem_count ())
+    return;
+
+  Real forced_fraction = forced_stem_count () / visible_stem_count ();
+  if (forced_fraction < 0.5)
+    return;
+
+  int multiplicity = get_multiplicity ();
+  SCM shorten = scm_eval (scm_listify (
+    ly_symbol2scm ("beamed-stem-shorten"),
+    gh_int2scm (multiplicity), 
+    SCM_UNDEFINED));
+  Real shorten_f = gh_scm2double (shorten) 
+    * Staff_symbol_referencer_interface (this).staff_line_leading_f ();
+
+  /* cute, but who invented this -- how to customise ? */
+  if (forced_fraction < 1)
+    shorten_f /= 2;
 
-  Least_squares l;
-  Real x0 = first_visible_stem ()->hpos_f ();
   for (int i=0; i < stem_count (); i++)
     {
       Stem* s = stem (i);
       if (s->invisible_b ())
         continue;
-      l.input.push (Offset (s->hpos_f () - x0, s->calc_stem_info ().idealy_f_));
+      if (s->get_elt_property ("shorten") == SCM_UNDEFINED)
+       s->set_elt_property ("shorten", gh_double2scm (shorten_f));
     }
-  l.minimise (slope_f_, left_y_);
 }
-
 /*
-  ugh. Naming: this doesn't check, but sets as well.
+  Set elt properties height and y-position if not set.
+  Adjust stem lengths to reach beam.
  */
-Real
-Beam::check_stemlengths_f (bool set_b)
+void
+Beam::do_post_processing ()
 {
-  int multiplicity = multiplicity_i ();
+  /* first, calculate y, dy */
+  Real y, dy;
+  calc_position_and_height (&y, &dy);
+  if (suspect_slope_b (y, dy))
+    dy = 0;
 
-  Real interbeam_f = paper_l ()->interbeam_f (multiplicity);
+  Real damped_dy = calc_slope_damping_f (dy);
+  Real quantised_dy = quantise_dy_f (damped_dy);
 
-  Real beam_f = gh_scm2double (get_elt_property ("beam-thickness"));
-  Real staffline_f = paper_l ()-> get_var ("stafflinethickness");
-  Real epsilon_f = staffline_f / 8;
-  Real dy_f = 0.0;
-  Real x0 = first_visible_stem ()->hpos_f ();
-  Real internote_f = paper_l ()->get_var ("interline");
-  for (int i=0; i < stem_count (); i++)
-    {
-      Stem* s = stem (i);
-      if (s->invisible_b ())
-       continue;
-      Real y = (s->hpos_f () - x0) * slope_f_ + left_y_;
-      Stem_info info = s->calc_stem_info ();
+  y += (dy - quantised_dy) / 2;
+  dy = quantised_dy;
+  
+  /*
+    until here, we used only stem_info, which acts as if dir=up
+   */
+  y *= get_direction ();
+  dy *= get_direction ();
 
-      // correct for knee
-      if (get_direction () != s->get_direction ())
-       {
-         y -= get_direction () * (beam_f / 2
-           + (multiplicity - 1) * interbeam_f);
+  /* set or read dy as necessary */
+  SCM s = get_elt_property ("height");
+  if (s != SCM_UNDEFINED)
+    dy = gh_scm2double (s);
+  else
+    set_elt_property ("height", gh_double2scm (dy));
 
+  /* set or read y as necessary */
+  s = get_elt_property ("y-position");
+  if (s != SCM_UNDEFINED)
+    {
+      y = gh_scm2double (s);
+      set_stem_length (y, dy);
+    }
+  else
+    { 
+      /* we can modify y, so we should quantise y */
+      Real y_shift = check_stem_length_f (y, dy);
+      y += y_shift;
+      y = quantise_y_f (y, dy, 0);
+      set_stem_length (y, dy);
+      y_shift = check_stem_length_f (y, dy);
+
+      Real internote_f = paper_l ()->get_var ("interline") / 2;
+      if (y_shift > internote_f / 4)
+       {
+         y += y_shift;
 
-         Staff_symbol_referencer_interface s1 (s);
-         Staff_symbol_referencer_interface s2 (stem_top ());
-         
-         if (!i
-           && s1.staff_symbol_l () != s2.staff_symbol_l ())
-           y += get_direction () * (multiplicity - (s->flag_i () - 2) >? 0)
-             * interbeam_f;
+         /*
+           for significantly lengthened or shortened stems,
+           request quanting the other way.
+         */
+         int quant_dir = 0;
+         if (abs (y_shift) > internote_f / 2)
+           quant_dir = sign (y_shift) * get_direction ();
+         y = quantise_y_f (y, dy, quant_dir);
+         set_stem_length (y, dy);
        }
 
-      /* caution: stem measures in staff-positions */
-      if (set_b)
-       s->set_stemend ((y - calc_interstaff_dist (s, this))
-                              / internote_f);
-       
-      y *= get_direction ();
-      if (y > info.maxy_f_)
-       dy_f = dy_f <? info.maxy_f_ - y;
-      if (y < info.miny_f_)
-       { 
-         // when all too short, normal stems win..
-         if (dy_f < -epsilon_f)
-           warning (_ ("weird beam vertical offset"));
-         dy_f = dy_f >? info.miny_f_ - y; 
-       }
+      set_elt_property ("y-position", gh_double2scm (y));
     }
-  return dy_f;
 }
 
+/*
+  See Documentation/tex/fonts.doc
+ */
 void
-Beam::set_stem_shorten ()
+Beam::calc_position_and_height (Real* y, Real* dy) const
 {
-  if(!stem_count ())
+  *y = *dy = 0;
+  if (visible_stem_count () <= 1)
     return;
 
-  int multiplicity = multiplicity_i();
-
-  if  (multiplicity <= 0)
+  Real first_ideal = first_visible_stem ()->calc_stem_info ().idealy_f_;
+  if (first_ideal == last_visible_stem ()->calc_stem_info ().idealy_f_)
     {
-      programming_error ("Singular beam");
+      *dy = 0;
+      *y = first_ideal;
       return;
     }
-  
-  int total_count_i = 0;
-  int forced_count_i = 0;
+
+  Least_squares ls;
+  Real x0 = first_visible_stem ()->hpos_f ();
   for (int i=0; i < stem_count (); i++)
     {
-      Stem *s = stem (i);
-
-      s->set_default_extents ();
+      Stem* s = stem (i);
       if (s->invisible_b ())
-       continue;
-      if (((int)s->chord_start_f ()) && (s->get_direction () != s->get_default_dir ()))
-        forced_count_i++;
-      total_count_i++;
+        continue;
+      ls.input.push (Offset (s->hpos_f () - x0, 
+        s->calc_stem_info ().idealy_f_));
     }
+  Real dydx;
+  ls.minimise (dydx, *y); // duh, takes references
 
-  Real internote_f = paper_l ()->get_var ("interline");
-  bool grace_b = get_elt_property ("grace") == SCM_BOOL_T;
-  String type_str = grace_b ? "grace_" : "";
-  int stem_max = (int)rint(paper_l ()->get_var ("stem_max"));
-  Real shorten_f = paper_l ()->get_var (type_str + "forced_stem_shorten"
-    + to_str (multiplicity <? stem_max)) * internote_f;
-    
-  for (int i=0; i < stem_count (); i++)
-    {
-      Stem *s = stem (i);
-      /*
-       Chord tremolo needs to beam over invisible stems of wholes
-      */
-      SCM trem = get_elt_property ("chord-tremolo");
-      if (gh_boolean_p (trem) && gh_scm2bool (trem))
-       {
-         if (s->invisible_b ())
-           continue;
-       }
+  Real dx = last_visible_stem ()->hpos_f () - x0;
+  *dy = dydx * dx;
+}
 
-      if (s->get_direction () == get_direction ())
-        {
-         if (forced_count_i == total_count_i)
-           s->set_real ("shorten", shorten_f);
-         else if (forced_count_i > total_count_i / 2)
-           s->set_real ("shorten", shorten_f/2);
-       }
+bool
+Beam::suspect_slope_b (Real y, Real dy) const
+{
+  /*
+    steep slope running against lengthened stem is suspect
+  */
+  Real first_ideal = first_visible_stem ()->calc_stem_info ().idealy_f_;
+  Real last_ideal = last_visible_stem ()->calc_stem_info ().idealy_f_;
+  Real lengthened = paper_l ()->get_var ("beam_lengthened");
+  Real steep = paper_l ()->get_var ("beam_steep_slope");
+
+  Real dx = last_visible_stem ()->hpos_f () - first_visible_stem ()->hpos_f ();
+  Real dydx = dy/dx;
+
+  if (((y - first_ideal > lengthened) && (dydx > steep))
+      || ((y + dy - last_ideal > lengthened) && (dydx < -steep)))
+    {
+      return true;
     }
+  return false;
 }
 
-void
-Beam::calculate_slope ()
+/*
+  This neat trick is by Werner Lemberg,
+  damped = tanh (slope)
+  corresponds with some tables in [Wanske]
+*/
+Real
+Beam::calc_slope_damping_f (Real dy) const
 {
-  if (!stem_count ())
-    slope_f_ = left_y_ = 0;
-  else if (first_visible_stem ()->calc_stem_info ().idealy_f_ == last_visible_stem ()->calc_stem_info ().idealy_f_)
+  SCM damp = get_elt_property ("damping"); // remove?
+  int damping = 1;             // ugh.
+  if (damp != SCM_UNDEFINED)
+    damping = gh_scm2int (damp);
+
+  if (damping)
     {
-      slope_f_ = 0;
-      left_y_ = first_visible_stem ()->calc_stem_info ().idealy_f_;
-      left_y_ *= get_direction ();
+      Real dx = last_visible_stem ()->hpos_f ()
+       - first_visible_stem ()->hpos_f ();
+      Real dydx = dy/dx;
+      dydx = 0.6 * tanh (dydx) / damping;
+      return dydx * dx;
     }
-  else
-    {
-      solve_slope ();
-      Real solved_slope_f = slope_f_;
+  return dy;
+}
 
-      /*
-       steep slope running against lengthened stem is suspect
-      */
-      Real dx_f = stem (stem_count () -1)->hpos_f () - first_visible_stem ()->hpos_f ();
-
-      Real lengthened = paper_l ()->get_var ("beam_lengthened");
-      Real steep = paper_l ()->get_var ("beam_steep_slope");
-      if (((left_y_ - first_visible_stem ()->calc_stem_info ().idealy_f_ > lengthened)
-          && (slope_f_ > steep))
-         || ((left_y_ + slope_f_ * dx_f - last_visible_stem ()->calc_stem_info ().idealy_f_ > lengthened)
-             && (slope_f_ < -steep)))
-       {
-         slope_f_ = 0;
-       }
+Real
+Beam::calc_stem_y_f (Stem* s, Real y, Real dy) const
+{
+  Real beam_f = gh_scm2double (get_elt_property ("beam-thickness"));
+  int   multiplicity = get_multiplicity ();
 
-      /*
-       This neat trick is by Werner Lemberg,
-       damped = tanh (slope_f_)
-       corresponds with some tables in [Wanske]
-      */
-      SCM damp = remove_elt_property ("damping");
-      int damping = 1;         // ugh.
-      if (damp!= SCM_UNDEFINED)
-       damping = gh_int2scm (damp);
-
-      if (damping)
-       slope_f_ = 0.6 * tanh (slope_f_) / damping;
+
+  Real interbeam_f = paper_l ()->interbeam_f (multiplicity);
+  Real x0 = first_visible_stem ()->hpos_f ();
+  Real dx = last_visible_stem ()->hpos_f () - x0;
+  Real stem_y = (s->hpos_f () - x0) / dx * dy + y;
+
+  /* knee */
+  if (get_direction () != s->get_direction ())
+    {
+      stem_y -= get_direction () * (beam_f / 2
+       + (multiplicity - 1) * interbeam_f);
+
+      Staff_symbol_referencer_interface me (s);
+      Staff_symbol_referencer_interface last (last_visible_stem ());
       
-      quantise_dy ();
+      if ((s != first_visible_stem ())
+         && me.staff_symbol_l () != last.staff_symbol_l ())
+       stem_y += get_direction () 
+                 * (multiplicity - (s->flag_i () - 2) >? 0) * interbeam_f;
+    }
+  return stem_y;
+}
 
-      Real damped_slope_dy_f = (solved_slope_f - slope_f_) * dx_f / 2;
-      left_y_ += damped_slope_dy_f;
+Real
+Beam::check_stem_length_f (Real y, Real dy) const
+{
+  Real shorten = 0;
+  Real lengthen = 0;
+  for (int i=0; i < stem_count (); i++)
+    {
+      Stem* s = stem (i);
+      if (s->invisible_b ())
+       continue;
 
-      left_y_ *= get_direction ();
-      slope_f_ *= get_direction ();
+      Real stem_y = calc_stem_y_f (s, y, dy);
+       
+      stem_y *= get_direction ();
+      Stem_info info = s->calc_stem_info ();
+
+      if (stem_y > info.maxy_f_)
+       shorten = shorten <? info.maxy_f_ - stem_y;
+
+      if (stem_y < info.miny_f_)
+        lengthen = lengthen >? info.miny_f_ - stem_y; 
     }
+
+  if (lengthen && shorten)
+    warning (_ ("weird beam vertical offset"));
+
+  /* when all stems are too short, normal stems win */
+  if (shorten)
+    return shorten * get_direction ();
+  else
+    return lengthen * get_direction ();
 }
 
 void
-Beam::quantise_dy ()
+Beam::set_stem_length (Real y, Real dy)
 {
-  /*
-    [Ross] (simplification of)
-    Try to set slope_f_ complying with y-span of:
-      - zero
-      - beam_f / 2 + staffline_f / 2
-      - beam_f + staffline_f
-    + n * interline
-    */
+  Real internote_f = paper_l ()->get_var ("interline") / 2;
+  for (int i=0; i < stem_count (); i++)
+    {
+      Stem* s = stem (i);
+      if (s->invisible_b ())
+       continue;
 
-  SCM q = get_elt_property ("slope-quantisation");
+      Real stem_y = calc_stem_y_f (s, y, dy);
+
+      /* caution: stem measures in staff-positions */
+      s->set_stemend ((stem_y - calc_interstaff_dist (s, this)) / internote_f);
+    }
+}
+
+/*
+  [Ross] (simplification of)
+  Try to set dy complying with:
+    - zero
+    - beam_f / 2 + staffline_f / 2
+    - beam_f + staffline_f
+  + n * interline
+
+  TODO: get allowed-positions as scm list (aarg: from paper block)
+*/
+Real
+Beam::quantise_dy_f (Real dy) const
+{
+  SCM s = get_elt_property ("slope-quantisation");
   
-  if (q == ly_symbol2scm ("none"))
-    return;
+  if (s == ly_symbol2scm ("none"))
+    return dy;
 
   Staff_symbol_referencer_interface st (this);
   Real interline_f = st.staff_line_leading_f ();
@@ -564,39 +524,36 @@ Beam::quantise_dy ()
   Real staffline_f = paper_l ()->get_var ("stafflinethickness");
   Real beam_f = gh_scm2double (get_elt_property ("beam-thickness"));;
 
-  Real dx_f = stem (stem_count () -1 )->hpos_f () - first_visible_stem ()->hpos_f ();
-
-  Real dy_f = dx_f * abs (slope_f_);
-  
-  Real quanty_f = 0.0;
-
   Array<Real> allowed_fraction (3);
   allowed_fraction[0] = 0;
   allowed_fraction[1] = (beam_f / 2 + staffline_f / 2);
   allowed_fraction[2] = (beam_f + staffline_f);
 
-  Interval iv = quantise_iv (allowed_fraction, interline_f, dy_f);
-  quanty_f = (dy_f - iv[SMALLER] <= iv[BIGGER] - dy_f)
+  Interval iv = quantise_iv (allowed_fraction, interline_f, abs (dy));
+  Real q = (abs (dy) - iv[SMALLER] <= iv[BIGGER] - abs (dy))
     ? iv[SMALLER]
     : iv[BIGGER];
 
-  slope_f_ = (quanty_f / dx_f) * sign (slope_f_);
+  return q * sign (dy);
 }
 
 /*
-  
-  Prevent interference from stafflines and beams.  See Documentation/tex/fonts.doc
-  
+  Prevent interference from stafflines and beams.
+  See Documentation/tex/fonts.doc
+
+  TODO: get allowed-positions as scm list (aarg: from paper block)
  */
-void
-Beam::quantise_left_y (bool extend_b)
+Real
+Beam::quantise_y_f (Real y, Real dy, int quant_dir)
 {
    /*
-    we only need to quantise the start of the beam as dy is quantised too
-   if extend_b then stems must *not* get shorter
+    We only need to quantise the (left) y-position of the beam,
+    since dy is quantised too.
+    if extend_b then stems must *not* get shorter
    */
-  SCM q = get_elt_property ("slope-quantisation");
-
+  SCM s = get_elt_property ("slope-quantisation");
+  if (s == ly_symbol2scm ("none"))
+    return y;
 
   /*
     ----------------------------------------------------------
@@ -614,12 +571,6 @@ Beam::quantise_left_y (bool extend_b)
   Real staffline_f = paper_l ()->get_var ("stafflinethickness");
   Real beam_f = gh_scm2double (get_elt_property ("beam-thickness"));;
 
-  /*
-    [TODO]
-    it would be nice to have all allowed positions in a runtime matrix:
-    (multiplicity, minimum_beam_dy, maximum_beam_dy)
-   */
-
   Real straddle = 0;
   Real sit = beam_f / 2 - staffline_f / 2;
   Real hang = space - beam_f / 2 + staffline_f / 2;
@@ -632,65 +583,39 @@ Beam::quantise_left_y (bool extend_b)
     For simplicity, we'll assume dir = UP and correct if 
     dir = DOWN afterwards.
    */
-  // isn't this asymmetric ? --hwn
   
-  Real dy_f = get_direction () * left_y_;
-
-  Real beamdx_f = stem (stem_count () -1)->hpos_f () - first_visible_stem ()->hpos_f ();
-  Real beamdy_f = beamdx_f * slope_f_;
+  int multiplicity = get_multiplicity ();
 
-  int multiplicity = multiplicity_i ();
 
   Array<Real> allowed_position;
-  if (q == ly_symbol2scm ("normal"))
+  if (s == ly_symbol2scm ("normal"))
     {
-      if ((multiplicity <= 2) || (abs (beamdy_f) >= staffline_f / 2))
+      if ((multiplicity <= 2) || (abs (dy) >= staffline_f / 2))
        allowed_position.push (straddle);
-      if ((multiplicity <= 1) || (abs (beamdy_f) >= staffline_f / 2))
+      if ((multiplicity <= 1) || (abs (dy) >= staffline_f / 2))
        allowed_position.push (sit);
       allowed_position.push (hang);
     }
-  else if (q == ly_symbol2scm ("traditional"))
+  else if (s == ly_symbol2scm ("traditional"))
     {
       // TODO: check and fix TRADITIONAL
-      if ((multiplicity <= 2) || (abs (beamdy_f) >= staffline_f / 2))
+      if ((multiplicity <= 2) || (abs (dy) >= staffline_f / 2))
        allowed_position.push (straddle);
-      if ((multiplicity <= 1) && (beamdy_f <= staffline_f / 2))
+      if ((multiplicity <= 1) && (dy <= staffline_f / 2))
        allowed_position.push (sit);
-      if (beamdy_f >= -staffline_f / 2)
+      if (dy >= -staffline_f / 2)
        allowed_position.push (hang);
     }
 
+  Real up_y = get_direction () * y;
+  Interval iv = quantise_iv (allowed_position, space, up_y);
 
-  Interval iv = quantise_iv (allowed_position, space, dy_f);
-
-  Real quanty_f = dy_f - iv[SMALLER] <= iv[BIGGER] - dy_f ? iv[SMALLER] : iv[BIGGER];
-  if (extend_b)
-    quanty_f = iv[BIGGER];
-
-  left_y_ = get_direction () * quanty_f;
-}
-
-void
-Beam::set_stemlens ()
-{
-  Real staffline_f = paper_l ()->get_var ("stafflinethickness");
-  // enge floots
-  Real epsilon_f = staffline_f / 8;
-
+  Real q = up_y - iv[SMALLER] <= iv[BIGGER] - up_y 
+    ? iv[SMALLER] : iv[BIGGER];
+  if (quant_dir)
+    q = iv[(Direction)quant_dir];
 
-  // je bent zelf eng --hwn.
-  Real dy_f = check_stemlengths_f (false);
-  for (int i = 0; i < 2; i++)  // 2 ?
-    { 
-      left_y_ += dy_f * get_direction ();
-      quantise_left_y (dy_f);
-      dy_f = check_stemlengths_f (true);
-      if (abs (dy_f) <= epsilon_f)
-        {
-         break;
-       }
-    }
+  return q * get_direction ();
 }
 
 void
@@ -701,8 +626,8 @@ Beam::set_beaming (Beaming_info_list *beaming)
     {
       do
        {
-         if (stem (i)->beam_count (d) < 0)
-           stem (i)->set_beaming (beaming->infos_.elem (i).beams_i_drul_[d], d);
+         if (stem (i)->beam_count (d) == 0)
+           stem (i)->set_beaming ( beaming->infos_.elem (i).beams_i_drul_[d],d);
        }
       while (flip (&d) != LEFT);
     }
@@ -710,23 +635,10 @@ Beam::set_beaming (Beaming_info_list *beaming)
 
 
 
-int
-Beam::multiplicity_i () const 
-{
-  int m = 0;
-  for (SCM s = get_elt_property ("stems"); gh_pair_p (s); s = gh_cdr (s))
-    {
-      Score_element * sc = unsmob_element (gh_car (s));
-
-      if (Stem * st = dynamic_cast<Stem*> (sc))
-       m = m >? st->beam_count (LEFT) >? st->beam_count (RIGHT);
-    }
-  return m;
-}
-
 /*
   beams to go with one stem.
 
+  BURP
   clean  me up.
   */
 Molecule
@@ -736,17 +648,18 @@ Beam::stem_beams (Stem *here, Stem *next, Stem *prev) const
       (prev && !(prev->hpos_f () < here->hpos_f ())))
       programming_error ("Beams are not left-to-right");
 
+  Real staffline_f = paper_l ()->get_var ("stafflinethickness");
+  int   multiplicity = get_multiplicity ();
 
-  int multiplicity = multiplicity_i();
 
-  Real staffline_f = paper_l ()->get_var ("stafflinethickness");
   Real interbeam_f = paper_l ()->interbeam_f (multiplicity);
-  
   Real beam_f = gh_scm2double (get_elt_property ("beam-thickness"));;
 
   Real dy = interbeam_f;
   Real stemdx = staffline_f;
-  Real sl = slope_f_;
+
+  Real dx = last_visible_stem ()->hpos_f () - first_visible_stem ()->hpos_f ();
+  Real dydx = get_real ("height")/dx;
 
   Molecule leftbeams;
   Molecule rightbeams;
@@ -765,9 +678,8 @@ Beam::stem_beams (Stem *here, Stem *next, Stem *prev) const
   /* half beams extending to the left. */
   if (prev)
     {
-      int lhalfs= lhalfs = here->beam_count (LEFT)
-       - prev->beam_count (RIGHT);
-      int lwholebeams= here->beam_count (LEFT) <? prev->beam_count (RIGHT);
+      int lhalfs= lhalfs = here->beam_count (LEFT) - prev->beam_count (RIGHT);
+      int lwholebeams= here->beam_count (LEFT) <? prev->beam_count (RIGHT) ;
       /*
        Half beam should be one note-width, 
        but let's make sure two half-beams never touch
@@ -776,8 +688,8 @@ Beam::stem_beams (Stem *here, Stem *next, Stem *prev) const
       w = w/2 <? nw_f;
       Molecule a;
       if (lhalfs)              // generates warnings if not
-       a =  lookup_l ()->beam (sl, w, beam_f);
-      a.translate (Offset (-w, -w * sl));
+       a =  lookup_l ()->beam (dydx, w, beam_f);
+      a.translate (Offset (-w, -w * dydx));
       for (int j = 0; j  < lhalfs; j++)
        {
          Molecule b (a);
@@ -788,11 +700,11 @@ Beam::stem_beams (Stem *here, Stem *next, Stem *prev) const
 
   if (next)
     {
-      int rhalfs = here->beam_count (RIGHT) - next->beam_count (LEFT);
-      int rwholebeams = here->beam_count(RIGHT) <? next->beam_count (LEFT);
+      int rhalfs  = here->beam_count (RIGHT) - next->beam_count (LEFT);
+      int rwholebeams= here->beam_count (RIGHT) <? next->beam_count (LEFT) ;
 
       Real w = next->hpos_f () - here->hpos_f ();
-      Molecule a = lookup_l ()->beam (sl, w + stemdx, beam_f);
+      Molecule a = lookup_l ()->beam (dydx, w + stemdx, beam_f);
       a.translate_axis( - stemdx/2, X_AXIS);
       int j = 0;
       Real gap_f = 0;
@@ -812,7 +724,7 @@ Beam::stem_beams (Stem *here, Stem *next, Stem *prev) const
          // TODO: notehead widths differ for different types
          gap_f = nw_f / 2;
          w -= 2 * gap_f;
-         a = lookup_l ()->beam (sl, w + stemdx, beam_f);
+         a = lookup_l ()->beam (dydx, w + stemdx, beam_f);
        }
 
       for (; j  < rwholebeams; j++)
@@ -827,7 +739,7 @@ Beam::stem_beams (Stem *here, Stem *next, Stem *prev) const
 
       w = w/2 <? nw_f;
       if (rhalfs)
-       a = lookup_l ()->beam (sl, w, beam_f);
+       a = lookup_l ()->beam (dydx, w, beam_f);
 
       for (; j  < rwholebeams + rhalfs; j++)
        {
@@ -847,3 +759,120 @@ Beam::stem_beams (Stem *here, Stem *next, Stem *prev) const
 }
 
 
+Molecule*
+Beam::do_brew_molecule_p () const
+{
+  Molecule *mol_p = new Molecule;
+  if (!stem_count ())
+    return mol_p;
+  
+  Real x0 = first_visible_stem ()->hpos_f ();
+  Real dx = last_visible_stem ()->hpos_f () - x0;
+  Real dydx = get_real ("height")/dx;
+  Real y = get_real ("y-position");
+  for (int j=0; j <stem_count (); j++)
+    {
+      Stem *i = stem (j);
+      Stem * prev = (j > 0)? stem (j-1) : 0;
+      Stem * next = (j < stem_count ()-1) ? stem (j+1) :0;
+
+      Molecule sb = stem_beams (i, next, prev);
+      Real x = i->hpos_f ()-x0;
+      sb.translate (Offset (x, x * dydx + y));
+      mol_p->add_molecule (sb);
+    }
+  mol_p->translate_axis (x0 
+    - spanned_drul_[LEFT]->relative_coordinate (0, X_AXIS), X_AXIS);
+
+  return mol_p;
+}
+
+int
+Beam::forced_stem_count () const
+{
+  int f = 0;
+  for (int i=0; i < stem_count (); i++)
+    {
+      Stem *s = stem (i);
+
+      if (s->invisible_b ())
+       continue;
+
+      if (((int)s->chord_start_f ()) 
+        && (s->get_direction () != s->get_default_dir ()))
+        f++;
+    }
+  return f;
+}
+
+
+
+/*
+  TODO: Fix this class. This is wildly inefficient.
+  And it sux.  Yet another array/list 'interface'.
+ */
+Stem *
+Beam::stem (int i) const
+{
+  return Group_interface__extract_elements ((Beam*) this, (Stem*) 0, "stems")[i];
+}
+
+int
+Beam::stem_count () const
+{
+  Group_interface gi (this, "stems");
+  return gi.count ();
+}
+
+Stem*
+Beam::stem_top () const
+{
+  SCM s = get_elt_property ("stems");
+  
+  return gh_pair_p (s) ? dynamic_cast<Stem*> (unsmob_element (gh_car (s))) : 0;
+    
+  //Group_interface__extract_elements ((Beam*) this, (Stem*) 0, "stems")[stem_count () - 1];
+}
+
+/* burp */
+int
+Beam::visible_stem_count () const
+{
+  int c = 0;
+  for (int i = 0; i < stem_count (); i++)
+    {
+      if (!stem (i)->invisible_b ())
+        c++;
+    }
+  return c;
+}
+
+Stem*
+Beam::first_visible_stem () const
+{
+  for (int i = 0; i < stem_count (); i++)
+    {
+      Stem* s = stem (i);
+      if (!s->invisible_b ())
+        return s;
+    }
+
+  assert (0);
+
+  return 0;
+}
+
+Stem*
+Beam::last_visible_stem () const
+{
+  for (int i = stem_count (); i > 0; i--)
+    {
+      Stem* s = stem (i - 1);
+      if (!s->invisible_b ())
+        return s;
+    }
+
+  assert (0);
+  // sigh
+  return 0;
+}
index 226e7adaa4785249eee5957cd010dcf14e489892..5de0c8e5495bce25e17f9853bb2e24c14567a73b 100644 (file)
@@ -178,6 +178,7 @@ Clef_engraver::create_clef()
   if (!clef_p_)
     {
       Clef_item *c= new Clef_item;
+      c->set_elt_property ("breakable", SCM_BOOL_T);
       c->set_elt_property ("break-aligned", SCM_BOOL_T);
       announce_element (Score_element_info (c, clef_req_l_));
 
index c98c188f7cc4c09da9d5e33c34462832d8e1d861..644735e28822797a5cb91e2602bbbaf367a4770b 100644 (file)
@@ -22,12 +22,13 @@ Clef_item::do_pre_processing()
 {
   SCM style_sym =get_elt_property ("style");
   String style;
-  if (style_sym != SCM_UNDEFINED)
+  if (gh_string_p (style_sym))
     style = ly_scm2string (style_sym);
   
   if (break_status_dir() != RIGHT && style != "fullSizeChanges")
     symbol_ += "_change";
-  if (style == "transparent")
+  
+  if (style == "transparent")  // UGH. JUNKME
     {
       set_elt_property ("transparent", SCM_BOOL_T);
       set_empty (X_AXIS);
@@ -35,12 +36,10 @@ Clef_item::do_pre_processing()
 }
 
 /*
-  FIXME
+  JUNKME
 */
 Clef_item::Clef_item()
 {
-  set_elt_property ("breakable", SCM_BOOL_T);
-
   symbol_ = "treble";
 }
 
index 258c538d9db3a93f56fd4ab905d4f68b0ee9e9c0..ff53282f52661eaf11fa9b0d8e2507c15a89f6e7 100644 (file)
@@ -14,7 +14,7 @@
 /** a beam connects multiple stems.
 
   Beam adjusts the stems its owns to make sure that they reach the
-  beam and that point in the correct direction
+  beam and that point in the correct direction (urg?)
 
 elt property:
 
@@ -25,7 +25,8 @@ should beam slope be damped? 0: no, 1: yes, 100000: horizontal beams
 slope_quantisation: 'none, 'normal or 'traditional
 
 */
-class Beam : public Directional_spanner  {
+class Beam : public Directional_spanner
+{
 public:
 
   int stem_count () const;
@@ -36,48 +37,44 @@ public:
   Stem* last_visible_stem () const;
 
   /**
-     the slope of the beam in (staffpositions) per (X-dimension, in PT).
-     UGH. standardise this for once and for all.
+     the slope of the beam in dy/dx
    */
-  Real slope_f_;
+  Real dydx_f_;
 
   /// position of leftmost end of beam  
   Real left_y_;
 
-  /** 
-   */
-
   Beam ();
   void add_stem (Stem*);
-
   void set_grouping (Rhythmic_grouping def, Rhythmic_grouping current);
   void set_beaming (Beaming_info_list *);
   void set_stemlens ();
   VIRTUAL_COPY_CONS(Score_element);
-  int multiplicity_i () const;
+
+  int get_multiplicity () const;
 
 protected:
-  Offset center () const;
-  Direction get_default_dir () const;
-  void set_direction (Direction);
-  void set_stem_shorten ();
-  bool auto_knee (SCM gap, bool interstaff_b);
-  bool auto_knees ();
-  
   virtual void do_pre_processing ();
   virtual void do_post_processing ();
-  virtual void do_print() const;
   virtual Molecule*do_brew_molecule_p () const;
 
   Molecule stem_beams (Stem *here, Stem *next, Stem *prev) const;
-
 private:
-  void calculate_slope ();
-  Real check_stemlengths_f (bool set_b);
-  void solve_slope ();
-
-  void quantise_left_y (bool extend_b);
-  void quantise_dy ();
+  Direction calc_default_dir () const;
+  void set_stem_directions ();
+  void auto_knees ();
+  bool auto_knee (String gap_str, bool interstaff_b);
+  void set_stem_shorten ();
+  void calc_position_and_height (Real* y, Real* dy) const;
+  bool suspect_slope_b (Real y, Real dy) const;
+  Real calc_slope_damping_f (Real dy) const;
+  Real calc_stem_y_f (Stem* s, Real y, Real dy) const;
+  Real check_stem_length_f (Real y, Real dy) const;
+  void set_stem_length (Real y, Real dy);
+  Real quantise_dy_f (Real dy) const;
+  Real quantise_y_f (Real y, Real dy, int quant_dir);
+  int forced_stem_count () const;
 
 };
 
index da2e7a3f1dde7273dee23b66f49a1bde966d9635..132ae263a69141fffb6e252a4624382e54ea3cf3 100644 (file)
@@ -30,7 +30,6 @@ public:
 
 protected:
   virtual Molecule* do_brew_molecule_p () const;
-  //  virtual Interval do_width () const;    
   Array<Offset> get_controls () const;
   virtual Array<Offset> get_encompass_offset_arr () const;
   static Interval dim_callback (Dimension_cache const*);
index e35b20c9c0f10df922c2fe78165ec363eae43f0b..68ed2dc5e274c54fe60c8ff6430b3eefcd247b6c 100644 (file)
@@ -30,7 +30,6 @@ protected:
   virtual Molecule* do_brew_molecule_p() const;
   virtual void do_add_processing ();
 public:
-  
   String symbol_;
 
   VIRTUAL_COPY_CONS(Score_element);
index 6ca04e807977e62e81086a3d951c7980ecc99d0f..7da90a36493009e90690d4a1ab0b6d3943364217 100644 (file)
@@ -62,7 +62,8 @@ public:
    */
   Beam* beam_l () const;
   Note_head * first_head () const;
-    
+  Score_element * support_head () const;
+  Stem ();
   /// ensure that this Stem also encompasses the Notehead #n#
   void add_head (Rhythmic_head*n);
 
diff --git a/lily/new-beaming.cc b/lily/new-beaming.cc
deleted file mode 100644 (file)
index e69de29..0000000
index 439cb08186489148f0122f2f96e2a8ae27a1b7b2..7ed9936d149ea28b56f03432600942683d5c0a03 100644 (file)
@@ -156,11 +156,26 @@ Note_column::do_post_processing ()
   if (!b || !b->stem_count ())
     return;
   
-  /* ugh. Should be done by beam. */
+  /* ugh. Should be done by beam.
+     (what? should be done --jcn)
+    scary too?: height is calculated during post_processing
+   */
+  Real dy = 0;
+  Real y = 0;
+  SCM s = b->get_elt_property ("height");
+  if (s != SCM_UNDEFINED)
+    dy = gh_scm2double (s);
+    s = b->get_elt_property ("y-position");
+  if (s != SCM_UNDEFINED)
+    y = gh_scm2double (s);
+
+  Real x0 = b->first_visible_stem ()->hpos_f ();
+  Real dydx = b->last_visible_stem ()->hpos_f () - x0;
+
   Direction d = stem_l ()->get_direction ();
-  Real beamy = (stem_l ()->hpos_f () - b->stem(0)->hpos_f ()) * b->slope_f_ + b->left_y_;
+  Real beamy = (stem_l ()->hpos_f () - x0) * dydx + y;
 
-  SCM s = get_elt_property ("rests");
+  s = get_elt_property ("rests");
   Score_element * se = unsmob_element (gh_car (s));
   Staff_symbol_referencer_interface si (se);
 
index 0a984d5d685be64f61a32312fba5235c30a39c91..700a491854e5410cff2a20177f142a08cb7cb6f7 100644 (file)
@@ -55,7 +55,7 @@ Stem_tremolo::do_brew_molecule_p () const
   int mult =0;
   if (Beam * b = st->beam_l ())
     {
-      mult = b->multiplicity_i ();
+      mult = b->get_multiplicity ();
     }
   
   Real interbeam_f = paper_l ()->interbeam_f (mult);
@@ -65,16 +65,25 @@ Stem_tremolo::do_brew_molecule_p () const
   Real beam_f = gh_scm2double (get_elt_property ("beam-thickness"));
 
   int beams_i = 0;
-  Real slope_f = 0.25;
-
-  if (st && st->beam_l ()) {
-    slope_f = st->beam_l ()->slope_f_;
-    // ugh, rather calc from Stem_tremolo_req
-    beams_i = st->beam_count (RIGHT) >? st->beam_count (LEFT);
-  } 
+  Real dydx = 0.25;
+  
+  if (st && st->beam_l ())
+    {
+      Real dy = 0;
+      SCM s = st->beam_l ()->get_elt_property ("height");
+      if (s != SCM_UNDEFINED)
+       dy = gh_scm2double (s);
+      Real dx = st->beam_l ()->last_visible_stem ()->hpos_f ()
+       - st->beam_l ()->first_visible_stem ()->hpos_f ();
+      dydx = dy/dx;
+  
+      // ugh, rather calc from Stem_tremolo_req
+      beams_i = st->beam_count(RIGHT) >? st->beam_count (LEFT);
+    } 
 
-  Molecule a (lookup_l ()->beam (slope_f, w, beam_f));
-  a.translate (Offset (-w/2, w / 2 * slope_f));
+  Molecule a (lookup_l ()->beam (dydx, w, beam_f));
+  a.translate (Offset (-w/2, w / 2 * dydx));
+  
 
   Molecule *beams= new Molecule; 
   for (int i = 0; i < abbrev_flags_i_; i++)
index 507772b54e6c52ae277a38a8f5f3502a88576fbc..232caf5aed7ac5caddd77103835aa5f983d725f4 100644 (file)
@@ -31,8 +31,10 @@ Stem::set_beaming (int i,  Direction d )
   SCM pair = get_elt_property ("beaming");
   
   if (!gh_pair_p (pair))
-    pair = gh_cons (gh_int2scm (0),gh_int2scm (0));
-
+    {
+      pair = gh_cons (gh_int2scm (0),gh_int2scm (0));
+      set_elt_property ("beaming", pair);
+    }
   index_set_cell (pair, d, gh_int2scm (i));
 }
 
@@ -110,16 +112,47 @@ Stem::type_i () const
   return first_head () ?  first_head ()->balltype_i () : 2;
 }
 
+
+
+/*
+  Note head that determines hshift for upstems
+ */ 
+Score_element*
+Stem::support_head ()const
+{
+  SCM h = get_elt_property ("support-head");
+  Score_element * nh = unsmob_element (h);
+  if (nh)
+    return nh;
+  else
+    return first_head ();
+}
+
+
+/*
+  The note head which forms one end of the stem.  
+ */
 Note_head*
 Stem::first_head () const
 {
-  SCM h =get_elt_property ("heads");
-  if (!gh_pair_p (h))
-    return 0;
+  const int inf = 1000000;
+  int pos = -inf;              
+  Direction dir = get_direction ();
+
 
-  Score_element * sc = unsmob_element (gh_car (h));
+  Note_head *nh =0;
+  for (SCM s = get_elt_property ("heads"); gh_pair_p (s); s = gh_cdr (s))
+    {
+      Note_head * n = dynamic_cast<Note_head*> (unsmob_element (gh_car (s)));
+      Staff_symbol_referencer_interface si (n);
+      int p = dir * int(si.position_f ());
+      if (p > pos)
+       {
+         nh = n;
+       }
+    }
 
-  return dynamic_cast<Note_head*> (sc);
+  return nh;
 }
 
 void
@@ -138,6 +171,12 @@ Stem::add_head (Rhythmic_head *n)
   gi.add_element (n);
 }
 
+Stem::Stem ()
+{
+  set_elt_property ("heads", SCM_EOL);
+  set_elt_property ("rests", SCM_EOL);
+}
+
 bool
 Stem::invisible_b () const
 {
@@ -181,6 +220,9 @@ Stem::set_default_stemlen ()
 
   Real shorten_f = paper_l ()->get_var (type_str + "forced_stem_shorten0");
 
+  /* URGURGURG
+     'set-default-stemlen' sets direction too
+   */ 
   if (!get_direction ())
     set_direction (get_default_dir ());
 
@@ -226,31 +268,35 @@ Stem::set_noteheads ()
   if (!first_head ())
     return;
   
-  Link_array<Score_element> head_l_arr =
+  Link_array<Score_element> heads =
     Group_interface__extract_elements (this, (Score_element*)0, "heads");
 
-  head_l_arr.sort (compare_position);
-  if (get_direction () < 0)
-    head_l_arr.reverse ();
+  heads.sort (compare_position);
+  Direction dir =get_direction ();
+  
+  if (dir < 0)
+    heads.reverse ();
 
-  Score_element * beginhead =   head_l_arr[0];
-  beginhead->set_elt_property ("extremal", SCM_BOOL_T);
-  if  (beginhead !=   head_l_arr.top ())
-    head_l_arr.top ()->set_elt_property ("extremal", SCM_BOOL_T);
+
+  Real w = support_head ()->extent (X_AXIS)[dir];
+  for (int i=0; i < heads.size (); i++)
+    {
+      heads[i]->translate_axis (w - heads[i]->extent (X_AXIS)[dir], X_AXIS);
+    }
   
   bool parity= true;
-  int lastpos = int (Staff_symbol_referencer_interface (beginhead).position_f ());
-  for (int i=1; i < head_l_arr.size (); i ++)
+  int lastpos = int (Staff_symbol_referencer_interface (heads[0]).position_f ());
+  for (int i=1; i < heads.size (); i ++)
     {
-      Real p = Staff_symbol_referencer_interface (head_l_arr[i]).position_f ();
+      Real p = Staff_symbol_referencer_interface (heads[i]).position_f ();
       int dy =abs (lastpos- (int)p);
 
       if (dy <= 1)
        {
          if (parity)
            {
-             Real l  = head_l_arr[i]->extent (X_AXIS).length ();
-             head_l_arr[i]->translate_axis (l * get_direction (), X_AXIS);
+             Real l  = heads[i]->extent (X_AXIS).length ();
+             heads[i]->translate_axis (l * get_direction (), X_AXIS);
            }
          parity = !parity;
        }
@@ -352,8 +398,8 @@ Stem::do_brew_molecule_p () const
     .staff_line_leading_f ()/2.0;
 
   Real head_wid = 0;
-  if (first_head ())
-    head_wid = first_head ()->extent (X_AXIS).length ();
+  if (support_head ())
+    head_wid = support_head ()->extent (X_AXIS).length ();
   stem_y[Direction(-get_direction ())] += get_direction () * head_wid * tan(ANGLE)/(2*dy);
   
   if (!invisible_b ())
@@ -417,24 +463,17 @@ Stem::calc_stem_info () const
 {
   assert (beam_l ());
 
-  SCM bd = get_elt_property ("beam-dir");
-  Real internote_f
-    = staff_symbol_referencer_interface (this).staff_line_leading_f ()/2;
-  
-  Direction beam_dir;
-  Stem_info info; 
-
-  if (isdir_b (bd))
+  Direction beam_dir = beam_l ()->get_direction ();
+  if (!beam_dir)
     {
-      beam_dir = to_dir (bd);
+      programming_error ("Beam dir not set.");
+      beam_dir = UP;
     }
-  else
-    {
-      programming_error ("Beam direction not set."); 
-      beam_dir = UP;           //  GURAUGRNAGURAGU! urg !
-    }
-  
-  Real interbeam_f = paper_l ()->interbeam_f (beam_l ()->multiplicity_i ());
+    
+  Stem_info info; 
+  Real internote_f
+     = staff_symbol_referencer_interface (this).staff_line_leading_f ()/2;
+   Real interbeam_f = paper_l ()->interbeam_f (beam_l ()->get_multiplicity ());
   Real beam_f = gh_scm2double (beam_l ()->get_elt_property ("beam-thickness"));
          
   info.idealy_f_ = chord_start_f ();
@@ -448,17 +487,17 @@ Stem::calc_stem_info () const
   int stem_max = (int)rint(paper_l ()->get_var ("stem_max"));
   String type_str = grace_b ? "grace_" : "";
   Real min_stem_f = paper_l ()->get_var (type_str + "minimum_stem_length"
-    + to_str (beam_l ()->multiplicity_i () <? stem_max)) * internote_f;
+    + to_str (beam_l ()->get_multiplicity () <? stem_max)) * internote_f;
   Real stem_f = paper_l ()->get_var (type_str + "stem_length"
-    + to_str (beam_l ()->multiplicity_i () <? stem_max)) * internote_f;
+    + to_str (beam_l ()->get_multiplicity () <? stem_max)) * internote_f;
 
   if (!beam_dir || (beam_dir == get_direction ()))
     /* normal beamed stem */
     {
-      if (beam_l ()->multiplicity_i ())
+      if (beam_l ()->get_multiplicity ())
        {
          info.idealy_f_ += beam_f;
-         info.idealy_f_ += (beam_l ()->multiplicity_i () - 1) * interbeam_f;
+         info.idealy_f_ += (beam_l ()->get_multiplicity () - 1) * interbeam_f;
        }
       info.miny_f_ = info.idealy_f_;
       info.maxy_f_ = INT_MAX;
@@ -482,7 +521,7 @@ Stem::calc_stem_info () const
          info.miny_f_ = info.miny_f_ >? 0;
          //lowest beam of (UP) beam must never be lower than second staffline
          info.miny_f_ = info.miny_f_ >? (- 2 * internote_f - beam_f
-                               + (beam_l ()->multiplicity_i () > 0) * beam_f + interbeam_f * (beam_l ()->multiplicity_i () - 1));
+                               + (beam_l ()->get_multiplicity () > 0) * beam_f + interbeam_f * (beam_l ()->get_multiplicity () - 1));
        }
     }
   else
@@ -500,11 +539,12 @@ Stem::calc_stem_info () const
   info.idealy_f_ = info.miny_f_ >? info.idealy_f_;
 
   Real interstaff_f = calc_interstaff_dist (this, beam_l ());
-  info.idealy_f_ += interstaff_f * beam_dir;
 
-  SCM s = get_elt_property ("shorten");
+  SCM s = beam_l ()->get_elt_property ("shorten");
   if (s != SCM_UNDEFINED)
     info.idealy_f_ -= gh_double2scm (s);
+
+  info.idealy_f_ += interstaff_f * beam_dir;
   info.miny_f_ += interstaff_f * beam_dir;
   info.maxy_f_ += interstaff_f * beam_dir;
 
index 777677986c5d56efa92f7f6ec5b8b80e994a2e2b..08483c3b3b4cda40ab9f0781c46efa1ac7cafc71 100644 (file)
@@ -1,15 +1,15 @@
 Begin3
 Title: LilyPond
-Version: 1.3.11
-Entered-date: 14DEC99
+Version: 1.3.12
+Entered-date: 16DEC99
 Description: 
 Keywords: music notation typesetting midi fonts engraving
 Author: hanwen@cs.uu.nl (Han-Wen Nienhuys)
        janneke@gnu.org (Jan Nieuwenhuizen)
 Maintained-by: hanwen@stack.nl (Han-Wen Nienhuys)
 Primary-site: sunsite.unc.edu /pub/Linux/apps/sound/convert
-       1000k lilypond-1.3.11.tar.gz 
+       1000k lilypond-1.3.12.tar.gz 
 Original-site: ftp.cs.uu.nl /pub/GNU/LilyPond/development/
-       1000k lilypond-1.3.11.tar.gz 
+       1000k lilypond-1.3.12.tar.gz 
 Copying-policy: GPL
 End
index 0ece23f2da966b7730d1a72fa2a4c2081e98267d..6215ec84ad0776ed6ac8df8739a7baa9c1c6fc54 100644 (file)
@@ -1,9 +1,9 @@
 Name: lilypond
-Version: 1.3.11
+Version: 1.3.12
 Release: 1
 Copyright: GPL
 Group: Applications/Publishing
-Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.3.11.tar.gz
+Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.3.12.tar.gz
 Summary: A program for printing sheet music.
 URL: http://www.cs.uu.nl/~hanwen/lilypond
 # get Packager from (undocumented?) ~/.rpmmacros!
index 9cd22ceb7de4c40a9f030cc7887576872ca0bcb6..665d44f0a70f794390b8d787c4595f56e4194a0f 100644 (file)
@@ -21,9 +21,6 @@
 
 \version "1.3.4";
 
-global = \notes {
-  \key c \minor;
-}
   
 dux = \context Voice=two \notes \relative c''{
   \voicetwo
@@ -163,15 +160,16 @@ bassdux = \context Voice=three \notes \relative c' {
 
 \score {
  
-    \context PianoStaff < 
-       \context Staff = treble < 
+    \notes \context PianoStaff < 
+       \context Staff = treble <
+           \key C \minor;
            \dux
            { \comes \bar "|."; }
              \time 4/4;
              \property Score.timeSignatureStyle = "C"
          >
        \context Staff = bass <
-           \global
+           \key C \minor;
            \bassdux
        >
     >
index 867d71e6248bb46e579dcde3a834254228f08dca..c6104e21d7c2e3c5f6cb1c399ebb0884934a47b4 100644 (file)
@@ -7,6 +7,8 @@
         (list 'autoInterstaffKneeGap number? 'auto-interstaff-knee-gap)
         (list 'beamQuantisation symbol? 'slope-quantisation)
         (list 'beamDirAlgorithm symbol? 'beam-dir-algorithm)
+        (list 'beamSlope number? 'height)
+        (list 'beamVerticalPosition number? 'y-position)
         )
        )
   )
@@ -20,6 +22,7 @@
         (list 'stemLength number? 'length)
         (list 'stemStyle string? 'style)
         (list 'noStemExtend boolean? 'no-stem-extend)
+        (list 'stemShorten number? 'shorten)
         ))
   )
 
index 34a370175d6d0c82ae6b5c608c1a4d76b2f723d1..ce8c9eec87cfed6aaaebd5ba314fbecce86af2a1 100644 (file)
 ;;
 ;;
 
+;; (Measured in interlines? -- jcn)
 (define space-alist
  '(
    (("" "Clef_item") . (minimum-space 1.0))
        (begin (ly-warn (string-append "Unknown spacing pair `" this "', `" next "'"))
               '(minimum-space 0.0)))))
   
-       
+
+;; Measured in interlines (urg: how to say #interline?)
+(define (stem-shorten flags) 0.5)
+(define (beamed-stem-shorten multiplicity) 0.5)
+
 
 ;;;;;;;; TeX