+ retval = scm_cons (scm_from_double (posns[i]), retval);
+ }
+
+ retval = scm_cons (force_return, retval);
+ return retval;
+}
+
+
+/****************************************************************/
+
+Spring_description::Spring_description ()
+{
+ ideal_ =0.0;
+ hooke_ =0.0;
+ is_active_ = true;
+ block_force_ = 0.0;
+}
+
+
+bool
+Spring_description::is_sane () const
+{
+ return (hooke_ > 0)
+ && ideal_ > 0
+ && !isinf (ideal_) && !isnan (ideal_);
+}
+
+Real
+Spring_description::length (Real f) const
+{
+ if (!is_active_)
+ f = block_force_;
+ return ideal_ + f / hooke_ ;
+}
+/****************************************************************/
+
+
+/*
+
+ TODO: should a add penalty for widely varying spring forces (caused
+ by constraints, eg.
+
+
+ =====
+ | |
+ o|o| x ##x
+
+
+ The ## forces the notes apart; we shouldn't allow the O's to touch
+ this closely.
+
+ */
+void
+Simple_spacer_wrapper::solve (Column_x_positions *positions, bool ragged)
+{
+ if (ragged)
+ spacer_->my_solve_natural_len ();
+ else
+ spacer_->my_solve_linelen ();
+
+ positions->force_ = spacer_->force_;
+
+ /*
+ 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++)
+ {
+ Real l = spacer_->springs_[i].length ((ragged) ? 0.0 : spacer_->force_);
+ positions->config_.push (positions->config_.top () + l);
+ /*
+ we have l>= 0 here, up to rounding errors
+ */
+ }
+
+ /*
+ For raggedright, we must have a measure of music density: this is
+ to prevent lots of short lines (which all have force = 0).
+ */
+ if (ragged)
+ {
+ Real len = positions->config_.top ();
+ if (spacer_->line_len_ - len >= 0)
+ positions->force_ = ((spacer_->line_len_ - len)
+ * spacer_->active_springs_stiffness ());
+ else