(c) 1999--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
*/
-#include <math.h>
+#include "spacing-spanner.hh"
+#include <math.h>
#include <cstdio>
using namespace std;
-#include "spacing-spanner.hh"
-#include "paper-column.hh"
-#include "output-def.hh"
-#include "paper-score.hh"
-#include "system.hh"
+#include "international.hh"
+#include "main.hh"
#include "moment.hh"
#include "note-spacing.hh"
-#include "main.hh"
-#include "warn.hh"
+#include "output-def.hh"
+#include "paper-column.hh"
+#include "paper-score.hh"
#include "pointer-group-interface.hh"
#include "spaceable-grob.hh"
-#include "staff-spacing.hh"
#include "spacing-interface.hh"
+#include "staff-spacing.hh"
+#include "system.hh"
+#include "warn.hh"
/*
*/
Rational
Spacing_spanner::effective_shortest_duration (Grob *me,
- Link_array<Grob> const &all)
+ vector<Grob*> const &all)
{
SCM preset_shortest = me->get_property ("common-shortest-duration");
Rational global_shortest;
SCM
Spacing_spanner::set_springs (SCM smob)
{
- Grob *me = unsmob_grob (smob);
+ Spanner *me = unsmob_spanner (smob);
/*
can't use get_system() ? --hwn.
*/
- Link_array<Grob> all (get_root_system (me)->columns ());
-
+ vector<Grob*> all (get_root_system (me)->columns ());
+ vsize start = binary_search (all, (Grob*)me->get_bound (LEFT),
+ &Paper_column::compare);
+ vsize end = binary_search (all, (Grob*) me->get_bound (RIGHT),
+ &Paper_column::compare);
+
+ all = vector<Grob*>::vector<Grob*> (all.begin () + start,
+ all.begin () + end + 1);
+
set_explicit_neighbor_columns (all);
Spacing_options options;
stuff, then.
*/
Rational
-Spacing_spanner::find_shortest (Grob *me, Link_array<Grob> const &cols)
+Spacing_spanner::find_shortest (Grob *me, vector<Grob*> const &cols)
{
/*
ascending in duration
*/
- Array<Rational> durations;
- Array<int> counts;
+ vector<Rational> durations;
+ vector<int> counts;
Rational shortest_in_measure;
shortest_in_measure.set_infinite (1);
- for (int i = 0; i < cols.size (); i++)
+ for (vsize i = 0; i < cols.size (); i++)
{
if (Paper_column::is_musical (cols[i]))
{
shortest_in_measure = min (shortest_in_measure, this_shortest.main_part_);
}
else if (!shortest_in_measure.is_infinity ()
- && Item::is_breakable (cols[i]))
+ && Paper_column::is_breakable (cols[i]))
{
- int j = 0;
+ vsize j = 0;
for (; j < durations.size (); j++)
{
if (durations[j] > shortest_in_measure)
{
- counts.insert (1, j);
- durations.insert (shortest_in_measure, j);
+ counts.insert (counts.begin () + j, 1);
+ durations.insert (durations.begin () + j, shortest_in_measure);
break;
}
else if (durations[j] == shortest_in_measure)
if (durations.size () == j)
{
- durations.push (shortest_in_measure);
- counts.push (1);
+ durations.push_back (shortest_in_measure);
+ counts.push_back (1);
}
shortest_in_measure.set_infinite (1);
int max_idx = -1;
int max_count = 0;
- for (int i = durations.size (); i--;)
+ for (vsize i = durations.size (); i--;)
{
if (counts[i] >= max_count)
{
void
Spacing_spanner::generate_springs (Grob *me,
- Link_array<Grob> const &cols,
+ vector<Grob*> const &cols,
Spacing_options const *options)
{
- Paper_column *next = 0;
- Paper_column *next_next = 0;
- for (int i = cols.size (); i--;)
+ Paper_column *prev = 0;
+ for (vsize i = 0; i < cols.size (); i++)
{
Paper_column *col = dynamic_cast<Paper_column *> (cols[i]);
- if (next)
- generate_pair_spacing (me, col, next, next_next, options);
+ Paper_column *next = (i < cols.size()-1) ? dynamic_cast<Paper_column *> (cols[i+1]) : 0;
+
+ if (i > 0)
+ generate_pair_spacing (me, prev, col, next, options);
- next_next = next;
- next = col;
+ prev = col;
}
}
Real compound_fixed_note_space = 0.0;
if (options->stretch_uniformly_)
- compound_note_space = base_note_space;
+ {
+ compound_note_space = base_note_space;
+
+ if (!Paper_column::is_musical (right_col))
+ {
+ /*
+ Crude fix for notes that lead up to barlines and time sigs.
+ */
+ Interval lext = right_col->extent (right_col, X_AXIS);
+ if (!lext.is_empty ())
+ compound_note_space += -lext[LEFT];
+ }
+
+ }
else
{
int wish_count = 0;
happens after the current note (this is set in the grob
property SPACING-SEQUENCE.
*/
- for (int i = 0; i < neighbors.size (); i++)
+ for (vsize i = 0; i < neighbors.size (); i++)
{
Grob *wish = neighbors[i];
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.
+
+ We used to have compound_fixed_note_space = options->increment_
+
+ but this can lead to numeric instability problems when we
+ do
+
+ inverse_strength = (compound_note_space - compound_fixed_note_space)
+
+ */
+
compound_note_space = base_note_space;
- compound_fixed_note_space = options->increment_;
+ compound_fixed_note_space = 0.0;
}
else if (to_boolean (me->get_property ("average-spacing-wishes")))
{
{
extract_grob_set (l, "spacing-wishes", wishes);
- for (int i = 0; i < wishes.size (); i++)
+ for (vsize i = 0; i < wishes.size (); i++)
{
Item *spacing_grob = dynamic_cast<Item *> (wishes[i]);
"head width) A 16th note is followed by 0.5 note head width. The\n"
"quarter note is followed by 3 NHW, the half by 4 NHW, etc.\n",
+
"average-spacing-wishes "
+ "base-shortest-duration "
+ "common-shortest-duration "
"grace-space-factor "
+ "packed-spacing "
+ "shortest-duration-space "
"spacing-increment "
- "base-shortest-duration "
"strict-note-spacing "
- "shortest-duration-space "
- "common-shortest-duration "
"uniform-stretching "
- "packed-spacing "
+
);
ADD_INTERFACE (Spacing_interface, "spacing-interface",