source file of the GNU LilyPond music typesetter
- (c) 1999--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+ (c) 1999--2007 Han-Wen Nienhuys <hanwen@xs4all.nl>
*/
#include "spacing-spanner.hh"
#include <math.h>
#include <cstdio>
+
using namespace std;
+#include "spacing-options.hh"
#include "international.hh"
#include "main.hh"
#include "moment.hh"
#include "warn.hh"
vector<Grob*>
-Spacing_spanner::get_columns (Spanner *me)
+Spacing_spanner::get_columns (Grob *me_grob)
{
- vector<Grob*> all (get_root_system (me)->columns ());
+ Spanner *me = dynamic_cast<Spanner*> (me_grob);
+ vector<Grob*> all (get_root_system (me)->used_columns ());
vsize start = binary_search (all, (Grob*)me->get_bound (LEFT),
- &Paper_column::compare);
+ &Paper_column::less_than);
vsize end = binary_search (all, (Grob*) me->get_bound (RIGHT),
- &Paper_column::compare);
-
+ &Paper_column::less_than);
+
all = vector<Grob*>::vector<Grob*> (all.begin () + start,
all.begin () + end + 1);
return all;
/*
can't use get_system() ? --hwn.
*/
- vector<Grob*> all (get_columns (me));
- set_explicit_neighbor_columns (all);
-
Spacing_options options;
options.init_from_grob (me);
- options.global_shortest_ = robust_scm2moment (me->get_property ("common-shortest-duration"),
- Moment (Rational (1,8)).main_part_;
+ vector<Grob*> cols = Spacing_spanner::get_columns (me);
+ set_explicit_neighbor_columns (cols);
- prune_loose_columns (me, &all, &options);
- set_implicit_neighbor_columns (all);
- generate_springs (me, all, &options);
+ prune_loose_columns (me, &cols, &options);
+ set_implicit_neighbor_columns (cols);
+ generate_springs (me, cols, &options);
return SCM_UNSPECIFIED;
}
max_idx = i;
max_count = counts[i];
}
-
- // printf ("duration %d/%d, count %d\n",
- // durations[i].num (), durations[i].den (), counts[i]);
}
SCM bsd = me->get_property ("base-shortest-duration");
for (vsize i = 0; i < cols.size (); i++)
{
Paper_column *col = dynamic_cast<Paper_column *> (cols[i]);
- Paper_column *next = (i < cols.size()-1) ? dynamic_cast<Paper_column *> (cols[i+1]) : 0;
+ Paper_column *next = (i + 1 < cols.size ()) ? dynamic_cast<Paper_column *> (cols[i+1]) : 0;
if (i > 0)
generate_pair_spacing (me, prev, col, next, options);
if (!lext.is_empty ())
compound_note_space += -lext[LEFT];
}
-
}
else
{
int wish_count = 0;
-
+
extract_grob_set (left_col, "right-neighbors", neighbors);
/*
if (compound_note_space < 0 || wish_count == 0)
{
- /*
- Fixed should be 0.0. If there are no spacing wishes, we're
- likely dealing with polyphonic spacing of hemiolas.
+
+ if (!Paper_column::is_musical (right_col))
+ {
+ /*
+ reconsider this: breaks with wide marks/tempos/etc.
+ */
+ Real left_col_stick_out = robust_relative_extent (left_col, left_col, X_AXIS)[RIGHT];
+ compound_fixed_note_space = max (left_col_stick_out, options->increment_);
+
+ compound_note_space = max (base_note_space,
+ base_note_space - options->increment_ + left_col_stick_out);
+ }
+ else
+ {
+ /*
+ Fixed should be 0.0. If there are no spacing wishes, we're
+ likely dealing with polyphonic spacing of hemiolas.
- We used to have compound_fixed_note_space = options->increment_
+ We used to have compound_fixed_note_space = options->increment_
- but this can lead to numeric instability problems when we
- do
+ but this can lead to numeric instability problems when we
+ do
- inverse_strength = (compound_note_space - compound_fixed_note_space)
+ inverse_strength = (compound_note_space - compound_fixed_note_space)
- */
-
- compound_note_space = base_note_space;
- compound_fixed_note_space = 0.0;
+ */
+
+ compound_note_space = base_note_space;
+ compound_fixed_note_space = 0.0;
+ }
}
else if (to_boolean (me->get_property ("average-spacing-wishes")))
{
Spaceable_grob::add_spring (left_col, right_col, distance, inverse_strength);
}
+/*
+ Check if COL fills the whole measure.
+ */
+bool
+Spacing_spanner::fills_measure (Grob *me, Item *left, Item *col)
+{
+ System *sys = get_root_system (me);
+ Item *next = sys->column (col->get_column()->get_rank () + 1);
+ if (!next)
+ return false;
+
+ if (Paper_column::is_musical (next)
+ || Paper_column::is_musical (left)
+ || !Paper_column::is_musical (col)
+ || !Paper_column::is_used (next))
+ return false;
+
+ Moment dt =
+ Paper_column::when_mom (next) - Paper_column::when_mom (col);
+
+ Moment *len = unsmob_moment (left->get_property ("measure-length"));
+ if (!len)
+ return false;
+
+ /*
+ Don't check for exact measure length, since ending measures are
+ often shortened due to pickups.
+ */
+ if (dt.main_part_ > len->main_part_ / Rational (2)
+ && (next->is_broken ()
+ || next->break_status_dir ()))
+ return true;
+
+ return false;
+}
+
/*
Read hints from L and generate springs.
*/
if (!spacing_grob || !Staff_spacing::has_interface (spacing_grob))
continue;
- Real space;
- Real fixed_space;
+ Real space = 0.;
+ Real fixed_space = 0.;
/*
column for the left one settings should be ok due automatic
pointer munging.
-
*/
assert (spacing_grob->get_column () == l);
}
+ if (Paper_column::is_musical (r)
+ && l->break_status_dir () == CENTER
+ && fills_measure (me, l, r))
+ {
+ compound_space += 1.0;
+ }
+
if (options->stretch_uniformly_ && l->break_status_dir () != RIGHT)
compound_fixed = 0.0;
assert (!isinf (compound_space));
compound_space = max (compound_space, compound_fixed);
- /*
- There used to be code that changed spacing depending on
- raggedright setting. Ugh.
-
- Do it more cleanly, or rename the property.
-
- */
Real inverse_strength = (compound_space - compound_fixed);
Real distance = compound_space;
Spaceable_grob::add_spring (l, r, distance, inverse_strength);
}
-ADD_INTERFACE (Spacing_spanner, "spacing-spanner-interface",
+ADD_INTERFACE (Spacing_spanner,
"The space taken by a note is dependent on its duration. Doubling a\n"
"duration adds spacing-increment to the space. The most common shortest\n"
"note gets @code{shortest-duration-space}. Notes that are even shorter are\n"
"average-spacing-wishes "
"base-shortest-duration "
"common-shortest-duration "
- "grace-space-factor "
"packed-spacing "
"shortest-duration-space "
"spacing-increment "
+ "strict-grace-spacing "
"strict-note-spacing "
"uniform-stretching "
);
-ADD_INTERFACE (Spacing_interface, "spacing-interface",
- "Something to do with line breaking and spacing. "
- "Kill this one after determining line breaks.",
- "");
-