]> git.donarmstrong.com Git - lilypond.git/commitdiff
patch::: 1.3.112.jcn1
authorJan Nieuwenhuizen <janneke@gnu.org>
Wed, 29 Nov 2000 10:12:40 +0000 (11:12 +0100)
committerJan Nieuwenhuizen <janneke@gnu.org>
Wed, 29 Nov 2000 10:12:40 +0000 (11:12 +0100)
1.3.112.jcn1
============

* Added forced slur direction (stemUp no longer implies slurUp) in
cross-staff slur example.

* Fixes to Glissando and line-spanner.  Behaves reasonably across line
breaks.

CHANGES
VERSION
input/test/slur-cross-staff.ly
lily/include/line-spanner.hh
lily/line-spanner.cc
lily/note-head-line-engraver.cc
scm/element-descriptions.scm
scm/interface.scm
scm/translator-description.scm

diff --git a/CHANGES b/CHANGES
index 86235a9b6fb315c11bad8ffb467be027f246b321..3ca97f927a7ed8bc00c6fc2ac57fffc46ebe0c85 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,13 @@
+1.3.112.jcn1
+============
+
+* Added forced slur direction (stemUp no longer implies slurUp) in
+cross-staff slur example.
+
+* Fixes to Glissando and line-spanner.  Behaves reasonably across line
+breaks.
+
+
 1.3.111.jcn3
 ============
 
diff --git a/VERSION b/VERSION
index bc5b6b1d0c030f6d4b8304ed1f23db91cc9473ef..7cadd3f2ddefa05488007ec05d5a3e38013b2aab 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -2,7 +2,7 @@ PACKAGE_NAME=LilyPond
 MAJOR_VERSION=1
 MINOR_VERSION=3
 PATCH_LEVEL=112
-MY_PATCH_LEVEL=
+MY_PATCH_LEVEL=jcn1
 
 # use the above to send patches: MY_PATCH_LEVEL is always empty for a
 # released version.
index 8e0b0e5325c813cacbc60b0e27a5d9f0a36f1ab3..2f1f8ed6af405f089d3b73a35f1961c39170ba15 100644 (file)
@@ -1,24 +1,36 @@
+
+
+       
 \score{
        \context PianoStaff <
        \context Staff=one \notes\relative c'{
-               \stemUp c4( c \translator Staff=two c )c |
+               \stemUp \slurUp
+                c4( c \translator Staff=two c )c |
                \translator Staff=one
-               \stemUp c4( c \translator Staff=two c )c |
-               \stemUp c4( c \translator Staff=one c )c |
+               \stemUp \slurUp
+                c4( c \translator Staff=two c )c |
+               \stemUp \slurUp
+                c4( c \translator Staff=one c )c |
                \translator Staff=two
-               \stemUp c4( c \translator Staff=one c )c |
+               \stemUp \slurUp
+                c4( c \translator Staff=one c )c |
                \translator Staff=two
-               \stemUp c4( \translator Staff=one c c )c |
+               \stemUp \slurUp
+                c4( \translator Staff=one c c )c |
                r2
                \translator Staff=two
-               \stemUp c4( \translator Staff=one c
+               \stemUp \slurUp
+                c4( \translator Staff=one c
                   \break
                c )c
                r2
-%              \stemDown c4( \translator Staff=two c c \translator Staff=one )c
-               \stemDown d4( \translator Staff=two c c \translator Staff=one )d
+%              \stemDown \slurDown
+%               c4( \translator Staff=two c c \translator Staff=one )c
+               \stemDown \slurDown
+                d4( \translator Staff=two c c \translator Staff=one )d
                \translator Staff=two
-               \stemUp c4( \translator Staff=one c c \translator Staff=two )c
+               \stemUp \slurUp
+                c4( \translator Staff=one c c \translator Staff=two )c
                r1
        }
        \context Staff=two \notes\relative c'{
index 3b9ac9545d50ffe9a9605f4695bf89f130bb7062..e125a12c02b104c259a12b79c9d6473e4c6ba40a 100644 (file)
@@ -17,6 +17,10 @@ class Line_spanner
 public:
   DECLARE_SCHEME_CALLBACK (brew_molecule, (SCM));
   static SCM line_atom (Grob* me, Real dx, Real dy);
+
+private:
+  static Offset get_broken_offset (Grob *me, Direction dir);
+  static Offset broken_trend_offset (Grob *me, Direction dir);
 };
 
 #endif /* LINE_SPANNER_HH */
index bece984882c939e3373d3683f90a76c35c041a1b..38fa223dc09706194b3c653622ebdf4a8db24a80 100644 (file)
@@ -62,6 +62,56 @@ Line_spanner::line_atom (Grob* me, Real dx, Real dy)
   return list;
 }
 
+Offset
+Line_spanner::get_broken_offset (Grob *me, Direction dir)
+{
+  Spanner *spanner = dynamic_cast<Spanner*> (me);
+  Item* bound = spanner->get_bound (dir);
+  
+  if (!bound->break_status_dir ())
+    {
+      Grob *common[] = {
+       bound->common_refpoint (Staff_symbol_referencer::staff_symbol_l (me),
+                               X_AXIS),
+       bound->common_refpoint (Staff_symbol_referencer::staff_symbol_l (me),
+                               Y_AXIS)
+      };
+  
+      return Offset ( abs (bound->extent (common[X_AXIS], X_AXIS)[-dir]),
+                     bound->extent (common[Y_AXIS], Y_AXIS).center ());
+    }
+  return Offset ();
+}
+
+Offset
+Line_spanner::broken_trend_offset (Grob *me, Direction dir)
+{
+  /* A broken line-spaner should maintain the same vertical trend
+     the unbroken line-spanner would have had.
+     From slur */
+  Offset o;
+  if (Spanner *mother =  dynamic_cast<Spanner*> (me->original_l_))
+    {
+      for (int i = dir == LEFT ? 0 : mother->broken_into_l_arr_.size () - 1;
+          dir == LEFT ? i < mother->broken_into_l_arr_.size () : i > 0;
+          dir == LEFT ? i++ : i--)
+       {
+         if (mother->broken_into_l_arr_[i - dir] == me)
+           {
+             Grob *neighbour = mother->broken_into_l_arr_[i];
+             Offset neighbour_o = get_broken_offset (neighbour, dir);
+             Offset me_o = get_broken_offset (me, -dir);
+             // Hmm, why not return me_o[X], but recalc in brew_mol?
+             o = Offset (0,
+                         (neighbour_o[Y_AXIS]*me_o[X_AXIS]
+                          - me_o[Y_AXIS]*neighbour_o[X_AXIS]) * dir /
+                         (me_o[X_AXIS] + neighbour_o[X_AXIS]));
+             break;
+           }
+       }
+    }
+  return o;
+}
 
 
 /*
@@ -78,45 +128,72 @@ SCM
 Line_spanner::brew_molecule (SCM smob) 
 {
   Grob *me= unsmob_grob (smob);
+
   Spanner *spanner = dynamic_cast<Spanner*> (me);
+  Item* bound_drul[] = {
+    spanner->get_bound (LEFT),
+    0,
+    spanner->get_bound (RIGHT)
+  };
+  
+  Item** bound = bound_drul + 1;
 
   Grob *common[] = { 0, 0 };
-
-  Item *l = spanner->get_bound (LEFT);
-  Item *r = spanner->get_bound (RIGHT);  
-
-  /*
-    FIXME: should also do something sensible across line breaks.
-   */
-  if (l->break_status_dir () || r->break_status_dir ())
-    return SCM_EOL;
-  
   for (Axis a = X_AXIS;  a < NO_AXES; a = Axis (a + 1))
     {
-      common[a] = l->common_refpoint (r, a);
-  
-    if (!common[a])
-      return SCM_EOL;
+      common[a] = bound[LEFT]->common_refpoint (bound[RIGHT], a);
+      
+      if (!common[a])
+       return SCM_EOL;
     }
   
-  Offset dxy ; 
-  for (Axis a = X_AXIS;  a < NO_AXES; a = Axis (a + 1))
+  Real gap = gh_scm2double (me->get_grob_property ("gap"));
+  
+  Offset dxy ;
+  Offset my_off;
+  Offset his_off;
+  
+  if (bound[LEFT]->break_status_dir () || bound[RIGHT]->break_status_dir ())
+    /* across line break */
     {
-      dxy[a] = r->extent (common[a], a)[LEFT] -
-       l->extent (common[a], a)[RIGHT];
+      Direction broken = bound[LEFT]->break_status_dir () ? LEFT : RIGHT;
+
+      dxy[X_AXIS] = bound[RIGHT]->extent (common[X_AXIS], X_AXIS)[LEFT]
+       - bound[LEFT]->extent (common[X_AXIS], X_AXIS)[RIGHT];
+      
+      dxy += broken_trend_offset (me, broken);
+      dxy[X_AXIS] -= 1 * gap;
+
+      my_off = Offset (0,
+                      me->relative_coordinate (common[Y_AXIS], Y_AXIS));
+
+      his_off = Offset (0, 
+                       bound[-broken]->relative_coordinate (common[Y_AXIS],
+                                                            Y_AXIS));
+
+      if (broken == LEFT)
+       {
+         my_off[Y_AXIS] += dxy[Y_AXIS];
+       }
     }
-  
+  else
+    {
+      dxy[X_AXIS] = bound[RIGHT]->extent (common[X_AXIS], X_AXIS)[LEFT]
+       - bound[LEFT]->extent (common[X_AXIS], X_AXIS)[RIGHT];
+      dxy[Y_AXIS] = bound[RIGHT]->extent (common[Y_AXIS], Y_AXIS).center ()
+       - bound[LEFT]->extent (common[Y_AXIS], Y_AXIS).center ();
+      dxy[X_AXIS] -= 2 * gap;
+
+      my_off = Offset (me->relative_coordinate (common[X_AXIS], X_AXIS),
+                      me->relative_coordinate (common[Y_AXIS], Y_AXIS)); 
+      
+      his_off = Offset (bound[LEFT]->relative_coordinate (common[X_AXIS],
+                                                         X_AXIS),
+                       bound[LEFT]->relative_coordinate (common[Y_AXIS],
+                                                         Y_AXIS)); 
+      
+      }
   Molecule line;
-  Real gap = gh_scm2double (me->get_grob_property ("gap"));
-
-  Offset my_off(me->relative_coordinate (common[X_AXIS], X_AXIS),
-               me->relative_coordinate (common[Y_AXIS], Y_AXIS) ); 
-  Offset his_off(l->relative_coordinate (common[X_AXIS], X_AXIS),
-                l->relative_coordinate (common[Y_AXIS], Y_AXIS) ); 
-  dxy *= (dxy.length () - 2 * gap) / dxy.length ();
-  
   SCM list = Line_spanner::line_atom (me, dxy[X_AXIS], dxy[Y_AXIS]);
     
   if (list == SCM_EOL)
@@ -125,10 +202,9 @@ Line_spanner::brew_molecule (SCM smob)
   Box b (Interval (0, dxy[X_AXIS]), Interval (0, dxy[Y_AXIS]));
   
   line = Molecule (b, list);
-  line.translate_axis (l->extent (l, X_AXIS).length (), X_AXIS); 
-  
-  
-  Offset g = dxy * (gap / dxy.length ());
+  line.translate_axis (bound[LEFT]->extent (bound[LEFT], X_AXIS).length (), X_AXIS); 
+
+  Offset g (gap, 0);
   line.translate (g - my_off + his_off);
       
   return line.smobbed_copy ();
index 57e62f5e6deee6632aa785aae11373aae1eb4a0b..cd45b77323562da35d5c0085647b154b4252f65c 100644 (file)
@@ -38,6 +38,7 @@ private:
   Request* req_;
   Request* last_req_;
   Translator* last_staff_;
+  bool follow_;
   Grob* head_;
   Grob* last_head_;
 };
@@ -47,6 +48,7 @@ Note_head_line_engraver::Note_head_line_engraver ()
   line_ = 0;
   req_ = 0;
   last_req_ = 0;
+  follow_ = false;
   head_ = 0;
   last_head_ = 0;
   last_staff_ = 0;
@@ -80,7 +82,7 @@ Note_head_line_engraver::acknowledge_grob (Grob_info info)
          if (staff != last_staff_)
            {
              if (last_head_)
-               last_req_ = (Request*)1; // ugh
+               follow_ = true;
              last_staff_ = staff;
            }
        }
@@ -90,26 +92,34 @@ Note_head_line_engraver::acknowledge_grob (Grob_info info)
 void
 Note_head_line_engraver::create_grobs ()
 {
-  if (!line_ && last_req_ && last_head_ && head_)
+  if (!line_ && (follow_ || last_req_) && last_head_ && head_
+      && (last_head_ != head_))
     {
       /* type Glissando? */
-      line_ = new Spanner (get_property ("NoteHeadLine"));
-      line_->set_bound (RIGHT, head_);
+      if (follow_)
+       line_ = new Spanner (get_property ("FollowThread"));
+      else
+       line_ = new Spanner (get_property ("Glissando"));
+       
       line_->set_bound (LEFT, last_head_);
+      line_->set_bound (RIGHT, head_);
 
-      line_->set_parent (head_, X_AXIS);
-      line_->set_parent (head_, Y_AXIS);
-
-      line_->set_parent (last_head_, X_AXIS);
-      line_->set_parent (last_head_, Y_AXIS);
+      /*
+       Note, mustn't set y-parent of breakable symbol to simple item:
+       one of the two broken parts won't have an y-parent!
+       
+       line_->set_parent (head_, Y_AXIS);
+       line_->set_parent (last_head_, Y_AXIS);
+       
+      */
+      /* X parent is set by set_bound */
+      line_->set_parent (Staff_symbol_referencer::staff_symbol_l (last_head_),
+                        Y_AXIS);
 
-      if ((int)last_req_ == 1) // ugh
-       last_req_ = 0;
-      
       announce_grob (line_, last_req_);
       last_req_ = 0;
-      last_head_ = head_;
-      head_ = 0;
+      follow_ = false;
+      last_head_ = 0;
     }
 }
 
@@ -121,8 +131,7 @@ Note_head_line_engraver::stop_translation_timestep ()
       typeset_grob (line_);
       line_ = 0;
     }
-  if (req_)
-    last_req_ = req_;
+  last_req_ = req_;
   req_ = 0;
 }
 
index 5ab89e84dfdf44b8d800dd7c810b86d0a730f03d..f656d5b1971389392db50511426763e2bc94dbcd 100644 (file)
                        rhythmic-head-interface font-interface 
                        note-head-interface ))
        ))
-       (NoteHeadLine . (
+       (Glissando . (
                         (type . line)
                         (gap . 0.5)
+                        (breakable . #t)
                         (X-extent-callback . #f)
                         (Y-extent-callback . #f)                        
                         (molecule-callback . ,Line_spanner::brew_molecule)
-                        (meta . ,(element-description "NoteHeadLine"
+                        (meta . ,(element-description "Glissando"
+                                                      line-spanner-interface))
+                        ))
+       (FollowThread . (
+                        (type . line)
+                        (gap . 0.5)
+                        (breakable . #t)
+                        (X-extent-callback . #f)
+                        (Y-extent-callback . #f)                        
+                        (molecule-callback . ,Line_spanner::brew_molecule)
+                        (meta . ,(element-description "FollowThread"
                                                       line-spanner-interface))
                         ))
 
index f8e19e52ce73566863116e820400162ed621bbbd..38cacd00fd0c956b1eb55ce469269c244f55080e 100644 (file)
@@ -476,7 +476,7 @@ font-point-size font-relative-size)
   (lily-interface
    'line-spanner-interface
    "Generic line drawn between two objects, eg. for use with glissandi.
-gap is relative to the total length of the line.   "
+gap is measured in staff-spaces.   "
 
    '(gap 
     dash-period 
index 82a2f02236c02398c056a3ac8be99bac0db9cebd..bf132b61c570c1a90b2bad528a92a04f4ba0ccb5 100644 (file)
@@ -409,7 +409,6 @@ measurePosition and currentBarNumber to determine what number to print over the
      '(
       )))
 
-
    (cons
     'Note_heads_engraver
     (engraver-description
@@ -419,6 +418,14 @@ measurePosition and currentBarNumber to determine what number to print over the
      '(
       )))
 
+   (cons
+    'Note_head_line_engraver
+    (engraver-description
+     "Note_head_line_engraver"
+     "Engrave a line between two note heads."
+     '(Glissando FollowThread)
+     '(
+      )))
 
    (cons
     'Note_name_engraver