]> git.donarmstrong.com Git - lilypond.git/commitdiff
* lily/stem.cc (get_default_stem_end_position): lengthen stems for
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Mon, 15 Sep 2003 21:35:08 +0000 (21:35 +0000)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Mon, 15 Sep 2003 21:35:08 +0000 (21:35 +0000)
tremoloed stems.

* lily/stem-tremolo.cc (brew_molecule): position tremolo next to
head for flagged stems.

* lily/stem.cc (get_default_stem_end_position): futz with extra
stem length if there is a stem tremolo.

ChangeLog
lily/include/stem-tremolo.hh
lily/stem-engraver.cc
lily/stem-tremolo.cc
lily/stem.cc
scm/define-grob-properties.scm

index 898574255b75307dee1c92f94f95167af8d806e3..95269981500de7f272be153f71e32f94d40e6baa 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
 2003-09-15  Han-Wen Nienhuys  <hanwen@cs.uu.nl>
 
+       * lily/stem.cc (get_default_stem_end_position): lengthen stems for
+       tremoloed stems.
+
+       * lily/stem-tremolo.cc (brew_molecule): position tremolo next to
+       head for flagged stems.
+
+       * lily/stem.cc (get_default_stem_end_position): futz with extra
+       stem length if there is a stem tremolo.
+
        * lily/tuplet-bracket.cc (brew_molecule): don't print bracket when
        it would be too small.
 
index 6a54d95a39fdf652a00c5b0dc2bdeeb07f95c2b3..d214822688d626c372afa2a2bb43a2d8deaf3ab5 100644 (file)
@@ -22,6 +22,7 @@ public:
   DECLARE_SCHEME_CALLBACK (brew_molecule, (SCM ));
   DECLARE_SCHEME_CALLBACK (height, (SCM,SCM));
   static void set_stem (Grob*me, Grob *st);
+  static Molecule raw_molecule (Grob*);
 };
 
 #endif /* ABBREV_HH */
index 7535d3916286b5d5ac4c32f49b90655d61e9866d..4c7946af055b46e5e9bfdc18cbd0ec0957db00cb 100644 (file)
@@ -32,16 +32,16 @@ protected:
 private:
   Grob  *stem_;
   Grob *tremolo_;
-  Music *rhythmic_req_;
-  Music* tremolo_req_;
+  Music *rhythmic_ev_;
+  Music* tremolo_ev_;
 };
 
 Stem_engraver::Stem_engraver ()
 {
-  tremolo_req_ = 0;
+  tremolo_ev_ = 0;
   stem_ = 0;
   tremolo_ = 0;
-  rhythmic_req_ =0;
+  rhythmic_ev_ =0;
 }
 
 
@@ -68,48 +68,49 @@ Stem_engraver::acknowledge_grob (Grob_info i)
 
          stem_->set_grob_property ("duration-log", gh_int2scm (duration_log));
 
-         if (tremolo_req_)
+         if (tremolo_ev_)
            {
              /*
                Stem tremolo is never applied to a note by default,
-               is must me requested.  But there is a default for the
+               is must me evuested.  But there is a default for the
                tremolo value:
 
                   c4:8 c c:
 
                the first and last (quarter) note bothe get one tremolo flag.
               */
-             int requested_type = gh_scm2int (tremolo_req_->get_mus_property ("tremolo-type"));
+             int evuested_type = gh_scm2int (tremolo_ev_->get_mus_property ("tremolo-type"));
              SCM f = get_property ("tremoloFlags");
-             if (!requested_type)
+             if (!evuested_type)
                if (gh_number_p (f))
-                 requested_type = gh_scm2int (f);
+                 evuested_type = gh_scm2int (f);
                else
-                 requested_type = 8; 
+                 evuested_type = 8; 
              else
-               daddy_trans_->set_property ("tremoloFlags", gh_int2scm (requested_type));
+               daddy_trans_->set_property ("tremoloFlags", gh_int2scm (evuested_type));
 
-             int tremolo_flags = intlog2 (requested_type) - 2
+             int tremolo_flags = intlog2 (evuested_type) - 2
                - (duration_log > 2 ? duration_log - 2 : 0);
              if (tremolo_flags <= 0)
                {
-                 tremolo_req_->origin()->warning (_("tremolo duration is too long"));
+                 tremolo_ev_->origin()->warning (_("tremolo duration is too long"));
                  tremolo_flags = 0;
                }
 
              if (tremolo_flags)
                {
                  tremolo_ = new Item (get_property ("StemTremolo"));
-                 announce_grob(tremolo_, tremolo_req_->self_scm());
+                 announce_grob(tremolo_, tremolo_ev_->self_scm());
 
                  /*
                    The number of tremolo flags is the number of flags of
                    the tremolo-type minus the number of flags of the note
                    itself.
                   */
-                         tremolo_->set_grob_property ("flag-count",
-                                               gh_int2scm (tremolo_flags));
+                 tremolo_->set_grob_property ("flag-count",
+                                              gh_int2scm (tremolo_flags));
                  tremolo_->set_parent (stem_, X_AXIS);
+                 stem_->set_grob_property ("tremolo-flag", tremolo_->self_scm ());
                }
            }
 
@@ -160,7 +161,7 @@ Stem_engraver::stop_translation_timestep ()
     }
 
 
-  tremolo_req_ = 0;
+  tremolo_ev_ = 0;
 }
 
 bool
@@ -168,7 +169,7 @@ Stem_engraver::try_music (Music* r)
 {
   if (r->is_mus_type ("tremolo-event"))
     {
-      tremolo_req_ = r;
+      tremolo_ev_ = r;
       return true;
     }
   return false;
index cac78d7e8a87fece3f20a600f7218b9d1e61a3b8..dba612fc70e295df81104bcde2b90564dac14a63 100644 (file)
@@ -55,23 +55,22 @@ Stem_tremolo::height (SCM smob, SCM ax)
 }
 
 
-MAKE_SCHEME_CALLBACK (Stem_tremolo,brew_molecule,1);
-SCM
-Stem_tremolo::brew_molecule (SCM smob)
+Molecule
+Stem_tremolo::raw_molecule (Grob *me)
 {
-  Grob *me= unsmob_grob (smob);
-  Grob * stem = unsmob_grob (me->get_grob_property ("stem"));
-  Grob * beam = Stem::get_beam (stem);
+  Grob *stem = unsmob_grob (me->get_grob_property ("stem"));
+  Grob *beam = Stem::get_beam (stem);
   
   Real dydx;
   if (beam)
     {
       Real dy = 0;
       SCM s = beam->get_grob_property ("positions");
-      if (gh_pair_p (s))
+      if (ly_number_pair_p (s))
        {
          dy = -gh_scm2double (gh_car (s)) +gh_scm2double (gh_cdr (s));
        }
+      
       Real dx = Beam::last_visible_stem (beam)->relative_coordinate (0, X_AXIS)
        - Beam::first_visible_stem (beam)->relative_coordinate (0, X_AXIS);
       dydx = dx ? dy/dx : 0;
@@ -80,7 +79,7 @@ Stem_tremolo::brew_molecule (SCM smob)
     // urg
     dydx = 0.25;
 
-  Real ss = Staff_symbol_referencer::staff_space (stem);
+  Real ss = Staff_symbol_referencer::staff_space (me);
   Real thick = gh_scm2double (me->get_grob_property ("beam-thickness"));
   Real width = gh_scm2double (me->get_grob_property ("beam-width"));
   width *= ss;
@@ -99,7 +98,7 @@ Stem_tremolo::brew_molecule (SCM smob)
       programming_error ("No tremolo flags?");
 
       me->suicide();
-      return SCM_EOL;
+      return Molecule ();
     }
 
   /*
@@ -116,11 +115,26 @@ Stem_tremolo::brew_molecule (SCM smob)
       b.translate_axis (beam_translation * i, Y_AXIS);
       mol.add_molecule (b);
     }
+  return mol;
+}
+
+
+MAKE_SCHEME_CALLBACK (Stem_tremolo,brew_molecule,1);
+SCM
+Stem_tremolo::brew_molecule (SCM grob) 
+{
+  Grob *me = unsmob_grob (grob);
+  Grob *stem = unsmob_grob (me->get_grob_property ("stem"));
+  Grob *beam = Stem::get_beam (stem);
   Direction stemdir = Stem::get_direction (stem);
+  Real beam_translation = beam ? Beam::get_beam_translation (beam) : 0.81;
+
+  Molecule mol = raw_molecule (me);
   Interval mol_ext = mol.extent (Y_AXIS);
+  Real ss = Staff_symbol_referencer::staff_space (me);
 
   // ugh, rather calc from Stem_tremolo_req
-  int beams_i = (beam) ? (Stem::beam_multiplicity (stem).length ()+ 1): 0;
+  int beam_count = (beam) ? (Stem::beam_multiplicity (stem).length ()+ 1): 0;
 
   /*
     TODO.
@@ -136,8 +150,8 @@ Stem_tremolo::brew_molecule (SCM smob)
 
   Real end_y
     = Stem::stem_end_position (stem) *ss/2 
-    - stemdir * (beams_i * beamthickness
-                + ((beams_i -1) >? 0) * beam_translation);
+    - stemdir * (beam_count * beamthickness
+                + ((beam_count -1) >? 0) * beam_translation);
 
   /*
     the 0.33 ss is to compensate for the size of the note head
@@ -148,12 +162,18 @@ Stem_tremolo::brew_molecule (SCM smob)
   Real padding = beam_translation;
 
   /*
+    if there is a flag, just above/below the notehead.
     if there is not enough space, center on remaining space,
     else one beamspace away from stem end.
    */
-  if (stemdir * (end_y - chord_start_y) - 2*padding - mol_ext.length ()  < 0.0)
+  if (!beam && Stem::duration_log (stem) >= 3)
+    {
+      mol.align_to (Y_AXIS, -stemdir);
+      mol.translate_axis (chord_start_y + .5 * stemdir, Y_AXIS);
+    }
+  else if (stemdir * (end_y - chord_start_y) - 2*padding - mol_ext.length ()  < 0.0)
     {
-      mol.translate_axis ((end_y + chord_start_y) /2.0  - mol_ext.center (),Y_AXIS);
+      mol.translate_axis (0.5 * (end_y + chord_start_y)  - mol_ext.center (),Y_AXIS);
     }
   else
     {
index f0f30ea6855f0358ff4cd1cca85a5c3e8b8c039b..45cd45ce21e2ba4f327dda0ad3c58e169afd585c 100644 (file)
@@ -33,6 +33,7 @@
 #include "spanner.hh"
 #include "side-position-interface.hh"
 #include "dot-column.hh"
+#include "stem-tremolo.hh"
 
 void
 Stem::set_beaming (Grob*me, int beam_count,  Direction d)
@@ -229,7 +230,7 @@ Stem::note_head_positions (Grob *me)
 
       ps.push (p);
     }
-
+  
   ps.sort (icmp);
   return ps; 
 }
@@ -284,12 +285,16 @@ Stem::get_default_stem_end_position (Grob*me)
       Direction dir = get_direction (me);
       return dir * (line_count + 3.5);
     }
-  
+  Real ss = Staff_symbol_referencer::staff_space (me); 
+
+  int durlog = duration_log (me);
+    
   bool grace_b = to_boolean (me->get_grob_property ("grace"));
   SCM s;
   Array<Real> a;
 
-  Real length = 3.5;
+  
+  Real length = 7;             // WARNING: IN HALF SPACES
   SCM scm_len = me->get_grob_property ("length");
   if (gh_number_p (scm_len))
     {
@@ -300,20 +305,10 @@ Stem::get_default_stem_end_position (Grob*me)
       s = me->get_grob_property ("lengths");
       if (gh_pair_p (s))
        {
-         length = 2* gh_scm2double (robust_list_ref (duration_log(me) -2, s));
+         length = 2* gh_scm2double (robust_list_ref (durlog -2, s));
        }
     }
 
-  Real shorten = 0.0;
-  
-  SCM sshorten = me->get_grob_property ("stem-shorten");
-  SCM scm_shorten = gh_pair_p (sshorten) ?
-    robust_list_ref ((duration_log (me) - 2) >? 0, sshorten): SCM_EOL;
-  if (gh_number_p (scm_shorten))
-    {
-      shorten = 2* gh_scm2double (scm_shorten);
-    }
-
 
 
   /* URGURGURG
@@ -326,16 +321,65 @@ Stem::get_default_stem_end_position (Grob*me)
       Directional_element_interface::set (me, dir);
     }
 
-  /* On boundary: shorten only half */
-  if (abs (head_positions (me)[get_direction (me)]) <= 1)
-    shorten *= 0.5;
-  
+
   /* stems in unnatural (forced) direction should be shortened, 
     according to [Roush & Gourlay] */
   if (!chord_start_y (me)
       || (get_direction (me) != get_default_dir (me)))
-    length -= shorten;
+    {
+      
+      Real shorten = 0.0;
+  
+      SCM sshorten = me->get_grob_property ("stem-shorten");
+      SCM scm_shorten = gh_pair_p (sshorten) ?
+       robust_list_ref ((duration_log (me) - 2) >? 0, sshorten): SCM_EOL;
+      if (gh_number_p (scm_shorten))
+       {
+         shorten = 2* gh_scm2double (scm_shorten);
+       }
+  
+      /* On boundary: shorten only half */
+      if (abs (head_positions (me)[get_direction (me)]) <= 1)
+       shorten *= 0.5;
+  
+      length -= shorten;
+    }
+
+  /*
+    Tremolo stuff: 
+  */
+  Grob * trem = unsmob_grob (me->get_grob_property ("tremolo-flag"));
+  if (trem &&  !unsmob_grob (me->get_grob_property ("beam")))
+    {
+      /*
+       Crude hack: add extra space if tremolo flag is there.
+
+       We can't do this for the beam, since we get into a loop
+       (Stem_tremolo::raw_molecule() looks at the beam.)
+       
+        --hwn 
+      */
+      
+      Real minlen =
+       1.0 + 2 * Stem_tremolo::raw_molecule (trem).extent (Y_AXIS).length  () / ss;
+      
+      if (durlog >= 3)
+       {
+         Interval flag_ext = flag (me).extent (Y_AXIS) ;
+         if (!flag_ext.empty_b())
+           minlen += 2 * flag_ext.length () / ss ;
 
+         /*
+           The clash is smaller for down stems (since the tremolo is
+           angled up.)
+          */
+         if (dir == DOWN)
+           minlen -= 1.0;
+       }
+      
+      length = length >? (minlen + 1.0);
+    }
+   
   Interval hp = head_positions (me);  
   Real st = hp[dir] + dir * length;
 
@@ -353,7 +397,7 @@ Stem::get_default_stem_end_position (Grob*me)
     
   */
   if (!get_beam (me) && dir == UP
-      && duration_log (me) > 2)
+      && durlog > 2)
     {
       Grob * closest_to_flag = extremal_heads (me)[dir];
       Grob * dots = closest_to_flag
@@ -363,7 +407,7 @@ Stem::get_default_stem_end_position (Grob*me)
        {
          Real dp = Staff_symbol_referencer::get_position (dots);
          Real flagy =  flag (me).extent (Y_AXIS)[-dir] * 2
-           / Staff_symbol_referencer::staff_space (me); 
+           / ss;
 
          /*
            Very gory: add myself to the X-support of the parent,
@@ -579,7 +623,8 @@ Stem::flag (Grob*me)
             flag's shape accordingly.  In the worst case, the shape
             looks slightly misplaced, but that will usually be the
             programmer's fault (e.g. when trying to attach multiple
-            note heads to a single stem in mensural notation).  */
+            note heads to a single stem in mensural notation).
+         */
 
          /*
            perhaps the detection whether this correction is needed should
@@ -806,6 +851,10 @@ Stem::get_stem_info (Grob *me)
   return si;
 }
 
+
+/*
+  TODO: add extra space for tremolos!
+ */
 void
 Stem::calc_stem_info (Grob *me)
 {
@@ -921,7 +970,7 @@ Stem::calc_stem_info (Grob *me)
     /* stem only extends to center of beam */
     - 0.5 * beam_thickness;
 
 Real minimum_y = note_start + minimum_length;
+ Real minimum_y = note_start + minimum_length;
   
   
   ideal_y *= my_dir;
index c7a821c437b8409ef44988fdb1121881961d23b9..6bcb585d5336385d450bbe3c44e2ba42794d34a9 100644 (file)
@@ -447,6 +447,7 @@ notation manual for more information.")
 same as setting molecule-callback to #f, but this retains the
 dimensions of this grob, which means that you can erase grobs
 individually. .")
+(grob-property-description 'tremolo-flag ly:grob? "The tremolo object on a stem.")
 (grob-property-description 'bracket-visibility boolean-or-symbol? "
 This controls the visibility of the tuplet bracket.
 Setting it to false will prevent printing of the