+ vector<Column_description> cols;
+ Simple_spacer spacer;
+ Column_x_positions ret;
+
+ ret.cols_.push_back (dynamic_cast<Item*> (columns[0])->find_prebroken_piece (RIGHT));
+ for (vsize i = 1; i < columns.size () - 1; i++)
+ {
+ if (is_loose (columns[i]))
+ ret.loose_cols_.push_back (columns[i]);
+ else
+ ret.cols_.push_back (columns[i]);
+ }
+ ret.cols_.push_back (dynamic_cast<Item*> (columns.back ())->find_prebroken_piece (LEFT));
+
+ /* since we've already put our line-ending column in the column list, we can ignore
+ the end_XXX_ fields of our column_description */
+ for (vsize i = 0; i < ret.cols_.size () - 1; i++)
+ {
+ cols.push_back (get_column_description (ret.cols_, i, i == 0));
+ spacer.add_spring (cols[i].ideal_, cols[i].inverse_hooke_);
+ }
+ for (vsize i = 0; i < cols.size (); i++)
+ {
+ for (vsize r = 0; r < cols[i].rods_.size (); r++)
+ spacer.add_rod (i, cols[i].rods_[r].r_, cols[i].rods_[r].dist_);
+
+ if (!cols[i].keep_inside_line_.is_empty ())
+ {
+ spacer.add_rod (i, cols.size (), cols[i].keep_inside_line_[RIGHT]);
+ spacer.add_rod (0, i, -cols[i].keep_inside_line_[LEFT]);
+ }
+ }
+
+ spacer.solve (line_len, ragged);
+ ret.force_ = spacer.force ();
+
+ /*
+ We used to have a penalty for compression, no matter what, but that
+ fucked up wtk1-fugue2 (taking 3 full pages.)
+ */
+ ret.config_ = spacer.spring_positions ();
+ for (vsize i = 0; i < ret.config_.size (); i++)
+ ret.config_[i] += indent;
+
+ ret.satisfies_constraints_ = spacer.fits ();
+
+ /*
+ Check if breaking constraints are met.
+ */
+ for (vsize i = 1; i < ret.cols_.size () - 1; i++)
+ {
+ SCM p = ret.cols_[i]->get_property ("line-break-permission");
+ if (p == ly_symbol2scm ("force"))
+ ret.satisfies_constraints_ = false;
+ }
+
+ return ret;