]> git.donarmstrong.com Git - lilypond.git/commitdiff
* lily/tuplet-bracket.cc (after_line_breaking): don't suicide if
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Fri, 5 Aug 2005 13:44:36 +0000 (13:44 +0000)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Fri, 5 Aug 2005 13:44:36 +0000 (13:44 +0000)
columns is empty

* lily/tuplet-engraver.cc (finalize): new function. Reset right
bounds to currentCommandColumn for the last step.
(start_translation_timestep): if tupletFullLength is set, set
bound to Paper Column

* lily/spacing-loose-columns.cc (set_loose_columns): space a whole
clique of loose columns, eg. a set of grace notes in strict
notespacing.

* input/regression/spacing-strict-spacing-grace.ly: new file.

* lily/spacing-determine-loose-columns.cc: new file.

* input/regression/spacing-strict-notespacing.ly: new file.

* lily/spacing-spanner.cc (generate_springs): rename from
do_measure.
(generate_pair_spacing): new function.
(init, generate_pair_spacing): set between-cols for floating
nonmusical columns.

* lily/tuplet-bracket.cc (print): on the left, the overshoot is
relative to the right edge of the prefatory matter.

15 files changed:
ChangeLog
Documentation/topdocs/NEWS.tely
input/regression/spacing-strict-notespacing.ly
input/regression/spacing-strict-spacing-grace.ly [new file with mode: 0644]
lily/include/paper-column.hh
lily/include/spacing-spanner.hh
lily/spacing-basic.cc
lily/spacing-determine-loose-columns.cc
lily/spacing-loose-columns.cc
lily/spacing-spanner.cc
lily/tuplet-bracket.cc
lily/tuplet-engraver.cc
ly/engraver-init.ly
scm/define-context-properties.scm
scm/define-grob-properties.scm

index b9b5f86a01607e1a222080c4c8e16da8a87a14f3..316d4e9cf7c8e790ae14045b8314cdb1d1a1668d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,21 @@
 2005-08-05  Han-Wen Nienhuys  <hanwen@xs4all.nl>
 
+       * lily/tuplet-bracket.cc (after_line_breaking): don't suicide if
+       columns is empty
+
+       * lily/tuplet-engraver.cc (finalize): new function. Reset right
+       bounds to currentCommandColumn for the last step.
+       (start_translation_timestep): if tupletFullLength is set, set
+       bound to Paper Column
+
+       * input/regression/tuplet-full-length.ly (indent): new file.
+
+       * lily/spacing-loose-columns.cc (set_loose_columns): space a whole
+       clique of loose columns, eg. a set of grace notes in strict
+       notespacing.
+
+       * input/regression/spacing-strict-spacing-grace.ly: new file.
+
        * lily/key-signature-interface.cc: change property name to
        alteration-alist
 
index 99622e13bf4be9cea865bba87a96df9ba211769a..64158ca328d0b6a0f823be6bae635232b4e75a81 100644 (file)
@@ -33,16 +33,32 @@ See user manual, \NAME\
 
 @itemize @bullet
 
+@item
+Tuplets can be made to reach the next non-tuplet note by setting the
+@code{tupletFullLength}  property,
+
+@lilypond[fragment]
+\new Voice \with {
+  \remove  Forbid_line_break_engraver
+  allowBeamBreak = ##t
+}
+{
+  \set tupletFullLength = ##t
+  \times 2/3 { c8[ c c] }
+  c4
+}
+@end lilypond  
+
+
 @item
 When @code{strict-note-spacing} is set, note are spaced without regard
-for clefs and bar lines. For example,
+for clefs, bar lines and grace notes. For example,
 
 @lilypond[fragment,verbatim,relative=2]
 \override Score.SpacingSpanner #'strict-note-spacing = ##t 
-\new Staff { c8[ c \clef alto c c c c]  c32 c32 }
+\new Staff { c8[ c \clef alto c \grace { c16[ c] } c8 c c]  c32[ c32] }
 @end lilypond
 
-
 This feature was sponsored by Trevor Baca. 
 
 @item
index 797a3a2edd5186a515b3dfeb6d7672e5e199937d..d88f8abb2c16419bfeaa04a214c920f193a9b629 100644 (file)
@@ -25,7 +25,14 @@ time.  This may cause collisions.  "
 <<
   \override Score.SpacingSpanner #'strict-note-spacing = ##t 
   \set Score.proportionalNotationDuration = #(ly:make-moment 1 16)
-  \new Staff { c8[ c \clef alto c c c c]  c4 c2 r2 }
-  \new Staff { c2  \times 2/3 { c8 \clef bass cis,, c } c4 c1 }
+  \new Staff {
+    c8[ c \clef alto c c \grace { d16 }  c8 c]  c4 c2
+    \grace { c16[ c16] }
+    c2 }
+  \new Staff {
+    c2  \times 2/3 { c8 \clef bass cis,, c } 
+    c4
+    c1
+  }
 >>
   
diff --git a/input/regression/spacing-strict-spacing-grace.ly b/input/regression/spacing-strict-spacing-grace.ly
new file mode 100644 (file)
index 0000000..4af57d8
--- /dev/null
@@ -0,0 +1,21 @@
+\header {
+
+  texidoc = "With @code{strict-note-spacing} spacing for grace notes
+(even multiple ones), is floating as well."
+
+}
+
+\version "2.7.4"
+
+\paper {
+  raggedright = ##t
+  indent = 0
+}
+
+\relative c''
+{
+  \override Score.SpacingSpanner #'strict-note-spacing = ##t 
+  \set Score.proportionalNotationDuration = #(ly:make-moment 1 12)
+  c8[ \grace { c16[ c] } c8 c8 c8] 
+  c2 
+}  
index 70c1d178238b5a0c05b997ce45d0e4ec97308bdd..ff6d642fba7cfd7a2ca885ab8b1cc57481a48f13 100644 (file)
@@ -27,23 +27,21 @@ public:
   Paper_column (Paper_column const &, int count);
 
   virtual Grob *clone (int count) const;
-
-  static bool has_interface (Grob *);
   virtual void do_break_processing ();
   virtual Paper_column *get_column () const;
   virtual System *get_system () const;
 
-  static int get_rank (Grob *);
   int get_rank () const { return rank_; }
+  void set_rank (int);
   
   DECLARE_SCHEME_CALLBACK (print, (SCM));
   DECLARE_SCHEME_CALLBACK (before_line_breaking, (SCM));
 
+  static bool has_interface (Grob *);
+  static int get_rank (Grob *);
   static bool is_musical (Grob *);
   static Moment when_mom (Grob *);
-
   static bool is_used (Grob *);
-  void set_rank (int);
 };
 
 #endif // PAPER_COLUMN_HH
index 73fffccadd4b180b5531881f300056ac0af0531a..7dbfdfc8b4ea90b221d3a8fa22163658f475d166 100644 (file)
@@ -19,11 +19,13 @@ struct Spacing_options
   bool packed_;
   bool stretch_uniformly_;
   bool float_nonmusical_columns_;
-  
   Rational global_shortest_;
   Real increment_;
+  Real shortest_duration_space_; 
   
-  void init (Grob *me);
+  void init ();
+  void init_from_grob (Grob *me);
+  Real get_duration_space (Moment d, bool*) const;
 };
 
 /*
@@ -41,7 +43,7 @@ public:
                                                 Spacing_options const*);
   static Real default_bar_spacing (Grob *, Grob *, Grob *, Moment);
   static Real note_spacing (Grob *, Grob *, Grob *, Spacing_options const*, bool *);
-  static Real get_duration_space (Grob *, Moment dur, Rational shortest, bool *);
+  static Real get_duration_space (Moment dur, Spacing_options const*,  bool *);
   static Rational find_shortest (Grob *, Link_array<Grob> const &);
   static Rational effective_shortest_duration (Grob *me, Link_array<Grob> const &all);
   static void breakable_column_spacing (Grob *, Item *l, Item *r, Spacing_options const*);
index 7f4a4930b0a9f4b425cb00737a52e6082403b8ec..49453e8494b6486f7b4a8100b3ec63f0221a9fd5 100644 (file)
    Get the measure wide ant for arithmetic spacing.
 */
 Real
-Spacing_spanner::get_duration_space (Grob *me,
-                                    Moment d,
-                                    Rational shortest, bool *expand_only)
+Spacing_options::get_duration_space (Moment d,
+                                    bool *expand_only) const
 {
-  Real k = robust_scm2double (me->get_property ("shortest-duration-space"), 1);
-  Real incr = robust_scm2double (me->get_property ("spacing-increment"), 1);
+  Real k = shortest_duration_space_;
 
-  if (d < shortest)
+  if (d < global_shortest_)
     {
       /*
        We don't space really short notes using the log of the
@@ -49,9 +47,9 @@ Spacing_spanner::get_duration_space (Grob *me,
 
 
       */
-      Rational ratio = d.main_part_ / shortest;
+      Rational ratio = d.main_part_ / global_shortest_;
 
-      return ((k - 1) + double (ratio)) * incr;
+      return ((k - 1) + double (ratio)) * increment_;
     }
   else
     {
@@ -60,12 +58,12 @@ Spacing_spanner::get_duration_space (Grob *me,
        Report OSU-CISRC-10/87-TR35, Department of Computer and
        Information Science, The Ohio State University, 1987.
       */
-      Real log = log_2 (shortest);
+      Real log = log_2 (global_shortest_);
       k -= log;
       Rational compdur = d.main_part_ + d.grace_part_ / Rational (3);
       *expand_only = false;
 
-      return (log_2 (compdur) + k) * incr;
+      return (log_2 (compdur) + k) * increment_;
     }
 }
 
@@ -124,7 +122,7 @@ Spacing_spanner::standard_breakable_column_spacing (Grob *me, Item *l, Item *r,
       else
        {
          bool dummy;
-         *space = *fixed + get_duration_space (me, dt, options->global_shortest_, &dummy);
+         *space = *fixed + options->get_duration_space (dt, &dummy);
        }
     }
 }
@@ -174,8 +172,8 @@ Spacing_spanner::note_spacing (Grob *me, Grob *lc, Grob *rc,
   Real dist = 0.0;
   if (delta_t.main_part_ && !lwhen.grace_part_)
     {
-      dist = get_duration_space (me, shortest_playing_len,
-                                options->global_shortest_, expand_only);
+      dist = options->get_duration_space (shortest_playing_len,
+                                 expand_only);
       dist *= double (delta_t.main_part_ / shortest_playing_len.main_part_);
     }
   else if (delta_t.grace_part_)
@@ -185,8 +183,7 @@ Spacing_spanner::note_spacing (Grob *me, Grob *lc, Grob *rc,
        available (namely the space for the global shortest note), and
        multiply that by grace-space-factor
       */
-      dist = get_duration_space (me, options->global_shortest_,
-                                options->global_shortest_, expand_only);
+      dist = options->get_duration_space (options->global_shortest_, expand_only);
 
       Real grace_fact
        = robust_scm2double (me->get_property ("grace-space-factor"), 1);
@@ -196,3 +193,31 @@ Spacing_spanner::note_spacing (Grob *me, Grob *lc, Grob *rc,
 
   return dist;
 }
+
+
+/****************************************************************/
+
+void
+Spacing_options::init_from_grob (Grob *me)
+{
+  increment_ = robust_scm2double (me->get_property ("spacing-increment"), 1);
+
+  packed_ = to_boolean (me->get_property ("packed-spacing"));
+  stretch_uniformly_ = to_boolean (me->get_property ("uniform-stretching"));
+  float_nonmusical_columns_
+    = to_boolean (me->get_property ("strict-note-spacing"));
+  shortest_duration_space_ = robust_scm2double (me->get_property ("shortest-duration-space"), 1);
+}
+
+
+void
+Spacing_options::init ()
+{
+  increment_ = 1.2;
+  packed_ = false;
+  stretch_uniformly_ = false;
+  float_nonmusical_columns_ = false;
+  shortest_duration_space_ = 2.0;
+
+  global_shortest_ = Rational (1,8);
+}
index 610b96b32081074d8c78ef1db6afd682b42dc2e8..f406425c3db82557387612f6ffeebafcf704ec4a 100644 (file)
@@ -8,17 +8,17 @@
 
 */
 
-
+#include "staff-spacing.hh"
 
 #include "system.hh"
 #include "paper-column.hh"
 #include "column-x-positions.hh"
-#include "staff-spacing.hh"
 #include "pointer-group-interface.hh"
 #include "spacing-spanner.hh"
 #include "note-spacing.hh"
-
+#include "moment.hh"
 #include "break-align-interface.hh"
+#include "warn.hh"
 
 /*
   Return whether COL is fixed to its neighbors by some kind of spacing
   (Otherwise, we might risk core dumps, and other weird stuff.)
 */
 static bool
-is_loose_column (Grob *l, Grob *c, Grob *r)
+is_loose_column (Grob *l, Grob *c, Grob *r, Spacing_options const *options)
 {
+  if (options->float_nonmusical_columns_
+      && Paper_column::when_mom (c).grace_part_)
+    return true;
+
+  if (Paper_column::is_musical (c)
+      || Item::is_breakable (c))
+    return false;
+      
   extract_grob_set (c, "right-neighbors", rns);
   extract_grob_set (c, "left-neighbors", lns);
   
@@ -125,18 +133,16 @@ Spacing_spanner::prune_loose_columns (Grob *me, Link_array<Grob> *cols,
                                      Spacing_options const *options)
 {
   Link_array<Grob> newcols;
-  Real increment = robust_scm2double (me->get_property ("spacing-increment"), 1.2);
+  
   for (int i = 0; i < cols->size (); i++)
     {
-      if (Item::is_breakable (cols->elem (i))
-         || Paper_column::is_musical (cols->elem (i)))
-       {
-         newcols.push (cols->elem (i));
-         continue;
-       }
-
       Grob *c = cols->elem (i);
-      if (is_loose_column (cols->elem (i - 1), c, cols->elem (i + 1)))
+
+      bool loose = (i > 0 && i < cols->size()-1)
+       && is_loose_column (cols->elem (i - 1), c, cols->elem (i + 1), options);
+       
+      
+      if (loose)
        {
          extract_grob_set (c, "right-neighbors", rns_arr);
          extract_grob_set (c, "left-neighbors", lns_arr);
@@ -168,7 +174,6 @@ Spacing_spanner::prune_loose_columns (Grob *me, Link_array<Grob> *cols,
              Item *lc = dynamic_cast<Item *> ((d == LEFT) ? next_door[LEFT] : c);
              Item *rc = dynamic_cast<Item *> (d == LEFT ? c : next_door[RIGHT]);
 
-
              extract_grob_set (lc, "spacing-wishes", wishes);
              for (int k = wishes.size(); k--;)
                {
@@ -181,7 +186,7 @@ Spacing_spanner::prune_loose_columns (Grob *me, Link_array<Grob> *cols,
                  fixed = 0.0;
                  bool dummy;
 
-                 if (d == LEFT)
+                 if (Note_spacing::has_interface (sp))
                    {
                      /*
                        The note spacing should be taken from the musical
@@ -189,13 +194,13 @@ Spacing_spanner::prune_loose_columns (Grob *me, Link_array<Grob> *cols,
 
                      */
                      Real base = note_spacing (me, lc, rc, options, &dummy);
-                     Note_spacing::get_spacing (sp, rc, base, increment, &space, &fixed);
+                     Note_spacing::get_spacing (sp, rc, base, options->increment_, &space, &fixed);
 
-                     space -= increment;
+                     space -= options->increment_;
 
                      dists[d] = max (dists[d], space);
                    }
-                 else
+                 else if (Staff_spacing::has_interface (sp))
                    {
                      Real space, fixed_space;
                      Staff_spacing::get_spacing_params (sp,
@@ -203,6 +208,10 @@ Spacing_spanner::prune_loose_columns (Grob *me, Link_array<Grob> *cols,
 
                      dists[d] = max (dists[d], fixed_space);
                    }
+                 else
+                   {
+                     programming_error ("Subversive spacing wish");
+                   }
                }
            }
          while (flip (&d) != LEFT);
index a2f87ba6bf91a2682525026effe15284b1cb31e4..9eda23b1a1dff2379b0deadd41cd094fd01bb0e5 100644 (file)
 #include "column-x-positions.hh"
 #include "pointer-group-interface.hh"
 #include "staff-spacing.hh"
+#include "note-spacing.hh"
+#include "spacing-spanner.hh"
+
+#include "moment.hh"
 
 /* Find the loose columns in POSNS, and drape them around the columns
    specified in BETWEEN-COLS.  */
@@ -34,6 +38,8 @@ set_loose_columns (System *which, Column_x_positions const *posns)
 
       Item *left = 0;
       Item *right = 0;
+
+      Link_array<Item> clique;
       while (1)
        {
          SCM between = loose->get_object ("between-cols");
@@ -51,7 +57,11 @@ set_loose_columns (System *which, Column_x_positions const *posns)
              left = le->get_column ();
              if (!left->get_system ())
                left = left->find_prebroken_piece (RIGHT);
+
+             clique.push (left);
            }
+         
+         clique.push (loose);
 
          divide_over++;
          loose = right = re->get_column ();
@@ -60,49 +70,77 @@ set_loose_columns (System *which, Column_x_positions const *posns)
       if (!right->get_system ())
        right = right->find_prebroken_piece (LEFT);
 
-      Grob *common = right->common_refpoint (left, X_AXIS);
-
-      int count = 0;
-      Real total_space = 0.0;
-      Real total_fixed = 0.0;
+      clique.push (right);
 
-      extract_grob_set (col, "spacing-wishes", wishes);
-      for (int i = 0; i < wishes.size (); i++)
+      Grob *common = right->common_refpoint (left, X_AXIS);
+      Item *finished_right_column = clique.top();
+      
+      for (int j = clique.size() - 2; j > 0; j--)
        {
-         Grob *spacing = wishes[i];
-         if (Staff_spacing::has_interface (spacing))
+         int count = 0;
+         Real total_space = 0.0;
+         Real total_fixed = 0.0;
+
+         extract_grob_set (col, "spacing-wishes", wishes);
+         for (int i = 0; i < wishes.size (); i++)
            {
+             Grob *spacing = wishes[i];
              Real space = 0.0;
              Real fixed = 0.0;
-             Staff_spacing::get_spacing_params (spacing, &space, &fixed);
 
-             total_fixed += fixed;
-             total_space += space;
+             if (Staff_spacing::has_interface (spacing))
+               {
+                 Staff_spacing::get_spacing_params (spacing, &space, &fixed);
+               }
+             else if (Note_spacing::has_interface (spacing))
+               {
+                 Spacing_options options;
+                 options.init ();
+
+                 fixed = robust_relative_extent (col, col, X_AXIS)[RIGHT];
+
+                 Moment dt = Paper_column::when_mom (right) - Paper_column::when_mom (col);
+                 bool expand;
+                 space = options.get_duration_space (dt, &expand);
+                 Note_spacing::get_spacing (spacing, right, space, options.increment_,
+                                            &space, &fixed);
+               }
+             else
+               {
+                 continue;
+               }
+         
              count++;
+
+             total_space += space;
+             total_fixed += fixed;
            }
-       }
 
-      Real right_point = 0.0;
-      Real distance_to_next = 0.0;
-      if (count)
-       {
-         total_space /= count;
-         total_fixed /= count;
+         Real distance_to_next = 0.0;
+         Real right_point = 0.0;  
+         if (count)
+           {
+             total_space /= count;
+             total_fixed /= count;
 
-         distance_to_next = total_space;
-         right_point = right->relative_coordinate (common, X_AXIS);
-       }
-      else
-       {
-         Interval my_extent = col->extent (col, X_AXIS);
-         distance_to_next = my_extent[RIGHT] + default_padding;
-         right_point = right->extent (common, X_AXIS)[LEFT];
-       }
+             distance_to_next = total_space;
+             right_point
+               = finished_right_column->relative_coordinate (common, X_AXIS);
+           }
+         else
+           {
+             Interval my_extent = col->extent (col, X_AXIS);
+             distance_to_next = my_extent[RIGHT] + default_padding;
+             right_point = finished_right_column->extent (common, X_AXIS)[LEFT];
+           }
 
-      Real my_offset = right_point - distance_to_next;
+         Real my_offset = right_point - distance_to_next;
+         
+         col->system_ = which;
+         col->translate_axis (my_offset - col->relative_coordinate (common, X_AXIS), X_AXIS);
 
-      col->system_ = which;
-      col->translate_axis (my_offset - col->relative_coordinate (common, X_AXIS), X_AXIS);
+         finished_right_column = col;
+       }
     }
 }
 
index 703337bd0bd46dbd6030783e0758089490e6db04..861522122eb5d7f75b7dd9da975b7da7b73ff290 100644 (file)
 
 
 
-void
-Spacing_options::init (Grob *me)
-{
-  increment_ = robust_scm2double (me->get_property ("spacing-increment"), 1);
-  packed_ = to_boolean (me->get_layout ()->c_variable ("packed"));
-  stretch_uniformly_ = to_boolean (me->get_property ("uniform-stretching"));
-  float_nonmusical_columns_
-    = to_boolean (me->get_property ("strict-note-spacing"));
-}
-
-
 Rational
 Spacing_spanner::effective_shortest_duration (Grob *me, Link_array<Grob> const &all)
 {
@@ -70,7 +59,7 @@ Spacing_spanner::set_springs (SCM smob)
   set_explicit_neighbor_columns (all);
 
   Spacing_options options;
-  options.init (me);
+  options.init_from_grob (me);
   options.global_shortest_ = effective_shortest_duration (me, all);
   
   prune_loose_columns (me, &all, &options);
@@ -462,7 +451,8 @@ ADD_INTERFACE (Spacing_spanner, "spacing-spanner-interface",
               "quarter note is followed by  3 NHW, the half by 4 NHW, etc.\n",
               
               "grace-space-factor spacing-increment base-shortest-duration strict-note-spacing "
-              "shortest-duration-space common-shortest-duration uniform-stretching"
+              "shortest-duration-space common-shortest-duration uniform-stretching "
+              "packed-spacing "
 
               );
 
index 3f435d637694d55c7661f8e95b06c4abf28e3bd9..194044cf004316fbe12d595fd993bf2912addc09 100644 (file)
@@ -57,16 +57,13 @@ get_x_bound_item (Grob *me_grob, Direction hdir, Direction my_dir)
     {
       g = Note_column::get_stem (g);
     }
-  
+
   return g;
 }
 
 Grob *
 Tuplet_bracket::parallel_beam (Grob *me_grob, Link_array<Grob> const &cols, bool *equally_long)
 {
-  /*
-    ugh: code dup.
-  */
   Spanner *me = dynamic_cast<Spanner *> (me_grob);
   
   if (me->get_bound (LEFT)->break_status_dir ()
@@ -76,6 +73,10 @@ Tuplet_bracket::parallel_beam (Grob *me_grob, Link_array<Grob> const &cols, bool
   Grob *s1 = Note_column::get_stem (cols[0]);
   Grob *s2 = Note_column::get_stem (cols.top ());
 
+
+  if (s2 != me->get_bound (RIGHT))
+    return 0;
+
   Grob *b1 = s1 ? Stem::get_beam (s1) : 0;
   Grob *b2 = s2 ? Stem::get_beam (s2) : 0;
 
@@ -106,13 +107,10 @@ MAKE_SCHEME_CALLBACK (Tuplet_bracket, print, 1);
 SCM
 Tuplet_bracket::print (SCM smob)
 {
-  Grob *me = unsmob_grob (smob);
+  Spanner *me = unsmob_spanner (smob);
   Stencil mol;
   extract_grob_set (me, "note-columns", columns);
 
-  if (!columns.size ())
-    return mol.smobbed_copy ();
-
   {
     SCM lp = me->get_property ("left-position");
     SCM rp = me->get_property ("right-position");
@@ -160,9 +158,7 @@ Tuplet_bracket::print (SCM smob)
   else if (numb == ly_symbol2scm ("if-no-beam"))
     number_visibility = !par_beam;
 
-  Grob *commonx = columns[0]->common_refpoint (columns.top (), X_AXIS);
-
-  
+  Grob *commonx = common_refpoint_of_array (columns, me, X_AXIS);
   commonx = commonx->common_refpoint (sp->get_bound (LEFT), X_AXIS);
   commonx = commonx->common_refpoint (sp->get_bound (RIGHT), X_AXIS);
 
@@ -172,13 +168,18 @@ Tuplet_bracket::print (SCM smob)
   bounds[LEFT] = get_x_bound_item (me, LEFT, dir);
   bounds[RIGHT] = get_x_bound_item (me, RIGHT, dir);
 
+  Drul_array<bool> connect_to_other; 
   Interval x_span;
   Direction d = LEFT;
   do
     {
       x_span[d] = robust_relative_extent (bounds[d], commonx, X_AXIS)[d];
-
-      if (bounds[d]->break_status_dir())
+      Direction break_dir = bounds[d]->break_status_dir ();
+      connect_to_other[d]
+       = (break_dir
+          && (me->get_break_index() - break_dir < me->broken_intos_.size()));
+      
+      if (connect_to_other[d])
        {
          Interval overshoot (robust_scm2drul (me->get_property ("break-overshoot"),
                                               Interval (-0.5, 1.0)));
@@ -189,6 +190,16 @@ Tuplet_bracket::print (SCM smob)
            x_span[d] = robust_relative_extent(bounds[d], commonx, X_AXIS)[RIGHT]
              - overshoot[LEFT];
        }
+      else if (d == RIGHT &&
+              (columns.is_empty ()
+               || bounds[d] != columns.top()))
+              
+       {
+         /*
+           TODO: make padding tunable? 
+          */
+         x_span[d] = robust_relative_extent (bounds[d], commonx, X_AXIS) [LEFT] - 1.0;
+       }
     }
   while (flip (&d) != LEFT);
 
@@ -237,19 +248,32 @@ Tuplet_bracket::print (SCM smob)
        = robust_scm2drul (me->get_property ("bracket-flare"), zero);
       Drul_array<Real> shorten
        = robust_scm2drul (me->get_property ("shorten-pair"), zero);
-
+      Drul_array<Stencil> edge_stencils;
+      
       scale_drul (&height, -ss * dir);
       scale_drul (&flare, ss);
       scale_drul (&shorten, ss);
-
-      
       do
        {
-         if (bounds[d]->break_status_dir ())
+         if (connect_to_other[d])
            {
              height[d] = 0.0;
              flare[d] = 0.0;
              shorten[d] = 0.0;
+             
+             SCM properties = Font_interface::text_font_alist_chain (me);
+             SCM edge_text = me->get_property ("edge-text");
+             
+             SCM text = index_get_cell (edge_text, d);
+             if (Text_interface::is_markup (text))
+               {
+                 SCM t = Text_interface::interpret_markup (pap->self_scm (), properties,
+                                                           text);
+                 
+                 Stencil *edge_text = unsmob_stencil (t);
+                 edge_text->translate_axis (x_span[d] - x_span[LEFT], X_AXIS);
+                 edge_stencils[d] = *edge_text;
+               }
            }
        }
       while (flip (&d) != LEFT);
@@ -267,22 +291,8 @@ Tuplet_bracket::print (SCM smob)
 
       do
        {
-         if (bounds[d]->break_status_dir ())
-           {
-             SCM properties = Font_interface::text_font_alist_chain (me);
-             SCM edge_text = me->get_property ("edge-text");
-             
-             SCM text = index_get_cell (edge_text, d);
-             if (Text_interface::is_markup (text))
-               {
-                 SCM t = Text_interface::interpret_markup (pap->self_scm (), properties,
-                                                           text);
-                 
-                 Stencil *edge_text = unsmob_stencil (t);
-                 edge_text->translate_axis (x_span[d] - x_span[LEFT], X_AXIS);
-                 mol.add_stencil (*edge_text);
-               }
-           }
+         if (!edge_stencils[d].is_empty ())
+           brack.add_stencil (edge_stencils[d]);
        }
       while (flip (&d) != LEFT);
 
@@ -393,12 +403,16 @@ Tuplet_bracket::calc_position_and_height (Grob *me_grob, Real *offset, Real *dy)
   
   Grob *commony = common_refpoint_of_array (columns, me, Y_AXIS);
   commony = common_refpoint_of_array (tuplets, commony, Y_AXIS);
+  if (Grob *st = Staff_symbol_referencer::get_staff_symbol (me))
+    {
+      commony = st->common_refpoint (commony, Y_AXIS); 
+    }
+
   Grob *commonx = common_refpoint_of_array (columns, me, X_AXIS);
   commonx = common_refpoint_of_array (tuplets, commonx, Y_AXIS);
   commonx = commonx->common_refpoint (me->get_bound (LEFT), X_AXIS);
   commonx = commonx->common_refpoint (me->get_bound (RIGHT), X_AXIS);
 
-
   Interval staff;
   if (Grob *st = Staff_symbol_referencer::get_staff_symbol (me))
     staff = st->extent (commony, Y_AXIS);
@@ -437,9 +451,6 @@ Tuplet_bracket::calc_position_and_height (Grob *me_grob, Real *offset, Real *dy)
 
   *offset = -dir * infinity_f;
 
-  if (!columns.size ())
-    return;
-
   Item *lgr = get_x_bound_item (me, LEFT, dir);
   Item *rgr = get_x_bound_item (me, RIGHT, dir);
   Real x0 = robust_relative_extent (lgr, commonx, X_AXIS)[LEFT];
@@ -451,10 +462,12 @@ Tuplet_bracket::calc_position_and_height (Grob *me_grob, Real *offset, Real *dy)
   Real factor = columns.size () > 1 ? 1 / (x1 - x0) : 1.0;
 
   Array<Offset> points;
+  points.push (Offset (x0, staff[dir]));
+  points.push (Offset (x1, staff[dir]));
+  
   for (int i = 0; i < columns.size (); i++)
     {
       Interval note_ext = columns[i]->extent (commony, Y_AXIS);
-      note_ext.unite (staff);
       Real notey = note_ext[dir] - me->relative_coordinate (commony, Y_AXIS);
 
       Real x = columns[i]->relative_coordinate (commonx, X_AXIS) - x0;
@@ -467,7 +480,6 @@ Tuplet_bracket::calc_position_and_height (Grob *me_grob, Real *offset, Real *dy)
     
     We assume that the smaller bracket is 1.0 space high.
   */
-  
   Real ss = Staff_symbol_referencer::staff_space (me);
   for (int i = 0; i < tuplets.size (); i++)
     {
@@ -564,18 +576,6 @@ Tuplet_bracket::after_line_breaking (SCM smob)
   Grob *me = unsmob_grob (smob);
   extract_grob_set (me, "note-columns", columns);
 
-  if (!columns.size ())
-    {
-      me->suicide ();
-      return SCM_UNSPECIFIED;
-    }
-  if (dynamic_cast<Spanner *> (me)->is_broken ())
-    {
-      me->warning (_ ("removing tuplet bracket across linebreak"));
-      me->suicide ();
-      return SCM_UNSPECIFIED;
-    }
-
   Direction dir = get_grob_direction (me);
   if (!dir)
     {
index 84299d2662f655690432d962b4b2df3dc2d6b64d..f5628975eed5510a48277e5d804d06fe1975d5b5 100644 (file)
@@ -41,9 +41,10 @@ public:
 
 protected:
   Array<Tuplet_description> tuplets_;
-
+  Link_array<Spanner> last_tuplets_;
   DECLARE_ACKNOWLEDGER (note_column);
   virtual bool try_music (Music *r);
+  virtual void finalize ();
   void start_translation_timestep ();
   void process_music ();
 };
@@ -118,19 +119,32 @@ Tuplet_engraver::start_translation_timestep ()
 {
   Moment now = now_mom ();
 
+  if (tuplets_.is_empty())
+    return;
+
+  Moment tsdmom = robust_scm2moment (get_property ("tupletSpannerDuration"), Moment (0));
+  bool full_length = to_boolean (get_property ("tupletFullLength"));
+
+  last_tuplets_.clear ();
   for (int i = tuplets_.size (); i--;)
     {
-      Moment tsdmom = robust_scm2moment (get_property ("tupletSpannerDuration"), Moment (0));
-
       Rational tsd = tsdmom.main_part_;
 
       if (now.main_part_ >= tuplets_[i].span_stop_)
        {
-         if (Spanner *sp = tuplets_[i].spanner_)
+         if (tuplets_[i].spanner_)
            {
-             if (!sp->get_bound (RIGHT))
-               sp->set_bound (RIGHT, sp->get_bound (LEFT));
-
+             if (full_length )
+               {
+                 Item * col = unsmob_item (get_property ("currentMusicalColumn"));
+             
+                 tuplets_[i].spanner_->set_bound (RIGHT, col);
+               }
+             else if (!tuplets_[i].spanner_->get_bound (RIGHT))
+               tuplets_[i].spanner_->set_bound (RIGHT,
+                                                tuplets_[i].spanner_->get_bound (LEFT));
+
+             last_tuplets_.push (tuplets_[i].spanner_);
              tuplets_[i].spanner_ = 0;
            }
 
@@ -145,6 +159,19 @@ Tuplet_engraver::start_translation_timestep ()
     }
 }
 
+void
+Tuplet_engraver::finalize ()
+{
+  if (to_boolean (get_property ("tupletFullLength")))
+    {
+      for (int i = 0; i < last_tuplets_.size (); i++)
+       {
+         Item * col = unsmob_item (get_property ("currentCommandColumn"));
+         last_tuplets_[i]->set_bound (RIGHT, col);
+       }
+    }
+}
+
 Tuplet_engraver::Tuplet_engraver ()
 {
 }
@@ -154,5 +181,5 @@ ADD_TRANSLATOR (Tuplet_engraver,
                /* descr */ "Catch Time_scaled_music and generate appropriate bracket  ",
                /* creats*/ "TupletBracket",
                /* accepts */ "time-scaled-music",
-               /* reads */ "tupletNumberFormatFunction tupletSpannerDuration",
+               /* reads */ "tupletNumberFormatFunction tupletSpannerDuration tupletFullLength" ,
                /* write */ "");
index 3cb645460e666abac97ce1b728e77eae0f2909d2..4189c9aca3978cb09b4838c4efc5db4145430774 100644 (file)
@@ -518,7 +518,7 @@ AncientRemoveEmptyStaffContext = \context {
   autoCautionaries = #'()  
 
   printKeyCancellation = ##t
-  keyAccidentalOrder = #`(
+  keyAlterationOrder = #`(
     (6 . ,FLAT) (2  . ,FLAT) (5 . ,FLAT ) (1  . ,FLAT) (4  . ,FLAT) (0  . ,FLAT) (3  . ,FLAT)
     (3  . ,SHARP) (0 . ,SHARP) (4 . ,SHARP) (1 . ,SHARP) (5 . ,SHARP) (2 . ,SHARP) (6 . ,SHARP)
     (6 . ,DOUBLE-FLAT) (2  . ,DOUBLE-FLAT) (5 . ,DOUBLE-FLAT ) (1  . ,DOUBLE-FLAT) (4  . ,DOUBLE-FLAT) (0  . ,DOUBLE-FLAT) (3 . ,DOUBLE-FLAT)
index 75bd2e9916f049a84bbc5eefd1af27334d233997..da0bbfd9f92eb1728f65110a398aa32404edf863 100644 (file)
@@ -382,6 +382,8 @@ Switch off for cadenzas.")
      (tremoloFlags ,integer? "Number of tremolo flags to add if no
 number is specified.")
 
+     (tupletFullLength ,boolean? "If set, the tuplet is printed upto
+the start of the next note.")
      (tupletNumberFormatFunction
       ,procedure?
       "Function taking a music as input, producing a string. This function
index 5a285980b638e62330e60413bad4685286050651..446000b50981071e29f38312d4eba26529508eb6 100644 (file)
@@ -348,7 +348,9 @@ spacing constraints.")
 get stems extending to the middle staff line.")
      (number-type ,symbol? "Type of numbers to use in label.  Choices
 include @code{roman-lower}, @code{roman-upper}, and @code{arabic}.")
-     
+
+     (packed-spacing ,boolean? "If set, the notes are spaced as
+tightly as possible.")
      (padding ,ly:dimension? "Add this much extra space between
 objects that are next to each other.")
      (page-penalty ,number? "Penalty for page break at