source file of the GNU LilyPond music typesetter
- (c) 1999--2005 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+ (c) 1999--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
TODO:
- add support for different stretch/shrink constants?
*/
#include <cstdio>
-#include <math.h>
+#include "column-x-positions.hh"
+#include "dimensions.hh"
+#include "international.hh"
#include "libc-extension.hh" // isinf
-#include "simple-spacer.hh"
#include "paper-column.hh"
+#include "simple-spacer.hh"
+#include "spaceable-grob.hh"
#include "spring.hh"
#include "warn.hh"
-#include "column-x-positions.hh"
-#include "spaceable-grob.hh"
-#include "dimensions.hh"
/*
A simple spacing constraint solver. The approach:
{
if (isinf (dist) || isnan (dist))
{
- programming_error ("Weird minimum distance. Ignoring");
+ programming_error ("ignoring weird minimum distance");
return;
}
Real block_stretch = dist - d;
Real block_force = c * block_stretch;
- force_ = force_ >? block_force;
+ force_ = max (force_, block_force);
for (int i = l; i < r; i++)
- springs_[i].block_force_ = block_force >?
- springs_[i].block_force_;
+ springs_[i].block_force_ = max (block_force, springs_[i].block_force_);
}
Real
for (int i = l; i < r; i++)
{
if (springs_[i].is_active_)
- den += 1 / springs_[i].hooke_;
+ den += 1 * springs_[i].inverse_hooke_;
}
return 1 / den;
Simple_spacer::active_blocking_force () const
{
Real bf = -infinity_f;
- for (int i = 0; i < springs_.size (); i++)
+ for (vsize i = 0; i < springs_.size (); i++)
if (springs_[i].is_active_)
- {
- bf = bf >? springs_[i].block_force_;
- }
+ bf = max (bf, springs_[i].block_force_);
return bf;
}
Real max_block_force = -infinity_f;
int max_i = -1;
- for (int i = 0; i < springs_.size (); i++)
+ for (vsize i = 0; i < springs_.size (); i++)
{
if (springs_[i].block_force_ > max_block_force)
{
}
}
- stiff = springs_[max_i].hooke_;
+ stiff = 1/springs_[max_i].inverse_hooke_;
}
return stiff;
}
Simple_spacer::set_active_states ()
{
/* float comparison is safe, since force is only copied. */
- for (int i = 0; i < springs_.size (); i++)
+ for (vsize i = 0; i < springs_.size (); i++)
if (springs_[i].is_active_
&& springs_[i].block_force_ >= force_)
{
Simple_spacer::configuration_length () const
{
Real l = 0.;
- for (int i = 0; i < springs_.size (); i++)
+ for (vsize i = 0; i < springs_.size (); i++)
l += springs_[i].length (force_);
return l;
while (is_active ())
{
- force_ = active_blocking_force () >? 0.0;
+ force_ = max (active_blocking_force (), 0.0);
Real conf = configuration_length ();
if (conf < line_len_)
Spring_description::Spring_description ()
{
ideal_ = 0.0;
- hooke_ = 0.0;
+ inverse_hooke_ = 0.0;
is_active_ = true;
block_force_ = 0.0;
}
bool
Spring_description::is_sane () const
{
- return (hooke_ > 0)
+ return (inverse_hooke_ >= 0)
&& ideal_ > 0
&& !isinf (ideal_) && !isnan (ideal_);
}
{
if (!is_active_)
f = block_force_;
- return ideal_ + f / hooke_;
+ return ideal_ + f * inverse_hooke_;
}
/****************************************************************/
by constraints, eg.
- =====
- | |
- o|o| x ##x
-
+ . =====
+ . | |
+ .o|o|x ##x
+ .
The ## forces the notes apart; we shouldn't allow the O's to touch
this closely.
We used to have a penalty for compression, no matter what, but that
fucked up wtk1-fugue2 (taking 3 full pages.)
*/
- positions->config_.push (spacer_->indent_);
- for (int i = 0; i < spacer_->springs_.size (); i++)
+ positions->config_.push_back (spacer_->indent_);
+ for (vsize i = 0; i < spacer_->springs_.size (); i++)
{
Real l = spacer_->springs_[i].length ((ragged) ? 0.0 : spacer_->force_);
- positions->config_.push (positions->config_.top () + l);
+ positions->config_.push_back (positions->config_.back () + l);
/*
we have l>= 0 here, up to rounding errors
*/
if (ragged)
{
positions->satisfies_constraints_
- = positions->config_.top () < spacer_->line_len_;
+ = positions->config_.back () < spacer_->line_len_;
}
else
positions->satisfies_constraints_ = spacer_->is_active ();
}
void
-Simple_spacer::add_spring (Real ideal, Real hooke)
+Simple_spacer::add_spring (Real ideal, Real inverse_hooke)
{
Spring_description desc;
desc.ideal_ = ideal;
- desc.hooke_ = hooke;
+ desc.inverse_hooke_ = inverse_hooke;
if (!desc.is_sane ())
{
- programming_error ("Insane spring found. Setting to unit spring.");
+ programming_error ("insane spring found, setting to unit");
- desc.hooke_ = 1.0;
+ desc.inverse_hooke_ = 1.0;
desc.ideal_ = 1.0;
}
- if (isinf (hooke))
- {
- desc.is_active_ = false;
- }
+ if (!inverse_hooke)
+ desc.is_active_ = false;
else
{
/*
desc.is_active_ ?
*/
- desc.block_force_ = -desc.hooke_ * desc.ideal_; // block at distance 0
+ desc.block_force_ = -desc.ideal_ / desc.inverse_hooke_;
+ // block at distance 0
active_count_++;
}
- springs_.push (desc);
+ springs_.push_back (desc);
}
static int
}
void
-Simple_spacer_wrapper::add_columns (Link_array<Grob> const &icols)
+Simple_spacer_wrapper::add_columns (vector<Grob*> const &icols)
{
- Link_array<Grob> cols (icols);
+ vector<Grob*> cols (icols);
+ cols.clear ();
- for (int i = cols.size (); i--;)
- if (scm_is_pair (cols[i]->get_property ("between-cols")))
- {
- loose_cols_.push (cols[i]);
- cols.del (i);
- }
+ for (vsize i = 0; i < icols.size (); i++)
+ if (scm_is_pair (icols[i]->get_object ("between-cols")))
+ loose_cols_.push_back (icols[i]);
+ else
+ cols.push_back (icols[i]);
spaced_cols_ = cols;
- for (int i = 0; i < cols.size () - 1; i++)
+ for (vsize i = 0; i < cols.size () - 1; i++)
{
Spring_smob *spring = 0;
- for (SCM s = cols[i]->get_property ("ideal-distances");
+ for (SCM s = cols[i]->get_object ("ideal-distances");
!spring && scm_is_pair (s);
s = scm_cdr (s))
{
Paper_column::get_rank (cols[i])));
Real ideal = (spring) ? spring->distance_ : spacer_->default_space_;
- Real hooke = (spring) ? spring->strength_ : 1.0;
+ Real inverse_hooke = (spring) ? spring->inverse_strength_ : 1.0;
- spacer_->add_spring (ideal, hooke);
+ spacer_->add_spring (ideal, inverse_hooke);
}
- for (int i = 0; i < cols.size () - 1; i++)
+ for (vsize i = 0; i < cols.size () - 1; i++)
{
for (SCM s = Spaceable_grob::get_minimum_distances (cols[i]);
scm_is_pair (s); s = scm_cdr (s))
{
Grob *other = unsmob_grob (scm_caar (s));
- int oi = binsearch_links (cols, other, &compare_paper_column_rank);
- if (oi >= 0)
- {
- spacer_->add_rod (i, oi, scm_to_double (scm_cdar (s)));
- }
+ vsize j = binary_search (cols, other, &compare_paper_column_rank);
+ if (j != VPOS && cols[j] == other)
+ spacer_->add_rod (i, j, scm_to_double (scm_cdar (s)));
}
if (i
- && !to_boolean (cols[i]->get_property ("allow-outside-line")))
+ && to_boolean (cols[i]->get_property ("keep-inside-line")))
{
Interval e = cols[i]->extent (cols[i], X_AXIS);
if (!e.is_empty ())