source file of the GNU LilyPond music typesetter
- (c) 2006--2007 Joe Neeman <joeneeman@gmail.com>
+ (c) 2006--2009 Joe Neeman <joeneeman@gmail.com>
*/
#include "constrained-breaking.hh"
#include "international.hh"
#include "main.hh"
#include "output-def.hh"
+#include "page-layout-problem.hh"
#include "paper-column.hh"
#include "paper-score.hh"
#include "simple-spacer.hh"
/*
We use the following optimal substructure. Let W (A) be our weight function.
- Let A_{k, n} = (a_{k, n,1}, ... a_{k, n, k}) be the optimal set of line breaks
+ Let A_{k, n} = (a_{k, n, 1}, ... a_{k, n, k}) be the optimal set of line breaks
for k systems and n potential breakpoints. a_{k, n, k} = n (it is the end of
the piece)
bool last = j == breaks_.size () - 1;
bool ragged = ragged_right || (last && ragged_last);
+ /* As a special case, if there is only one line in the score and ragged-right
+ hasn't been specifically forbidden and the line is stretched, use
+ ragged spacing. */
+ if (last && i == 0
+ && lines_.at (i, j).force_ >= 0
+ && !scm_is_bool (pscore_->layout ()->c_variable ("ragged-right"))
+ && !scm_is_bool (pscore_->layout ()->c_variable ("ragged-last")))
+ ragged = true;
+
return get_line_configuration (line, line_dims[RIGHT] - line_dims[LEFT], line_dims[LEFT], ragged);
}
vector<Column_x_positions>
Constrained_breaking::best_solution (vsize start, vsize end)
{
- vsize min_systems = min_system_count (start, end);
+ vsize min_systems = min_system_count (start, end);
vsize max_systems = max_system_count (start, end);
Real best_demerits = infinity_f;
vector<Column_x_positions> best_so_far;
int
Constrained_breaking::max_system_count (vsize start, vsize end)
{
- vsize brk = (end >= start_.size ()) ? breaks_.size () : starting_breakpoints_[end];
+ vsize brk = (end >= start_.size ()) ? breaks_.size () - 1 : starting_breakpoints_[end];
return brk - starting_breakpoints_[start];
}
Output_def *l = pscore_->layout ();
System *sys = pscore_->root_system ();
- Real space = robust_scm2double (l->c_variable ("ideal-system-space"), 0);
- SCM padding_scm = l->c_variable ("page-breaking-between-system-padding");
- if (!scm_is_number (padding_scm))
- padding_scm = l->c_variable ("between-system-padding");
- Real padding = robust_scm2double (padding_scm, 0.0);
+
+ // TODO: add support for minimum-distance and stretchability here and
+ // to the page-breaker.
+ SCM spacing_spec = l->c_variable ("between-system-spacing");
+ SCM page_breaking_spacing_spec = l->c_variable ("page-breaking-between-system-spacing");
+ Real space = 0;
+ Real padding = 0;
+ Page_layout_problem::read_spacing_spec (spacing_spec, &padding, ly_symbol2scm ("padding"));
+ Page_layout_problem::read_spacing_spec (page_breaking_spacing_spec, &padding, ly_symbol2scm ("padding"));
Interval first_line = line_dimensions_int (pscore_->layout (), 0);
Interval other_lines = line_dimensions_int (pscore_->layout (), 1);
ragged_right_);
for (vsize i = 0; i + 1 < breaks_.size (); i++)
{
- Real max_ext = 0;
for (vsize j = i + 1; j < breaks_.size (); j++)
{
int start = Paper_column::get_rank (all_[breaks_[i]]);
line.force_ = forces[i*breaks_.size () + j];
if (ragged && last && !isinf (line.force_))
- line.force_ = (line.force_ < 0) ? infinity_f : 0;
+ line.force_ = (line.force_ < 0 && j > i + 1) ? infinity_f : 0;
if (isinf (line.force_))
break;
Grob *c = all_[breaks_[j]];
+ line.last_column_ = c;
line.break_penalty_ = robust_scm2double (c->get_property ("line-break-penalty"), 0);
line.page_penalty_ = robust_scm2double (c->get_property ("page-break-penalty"), 0);
line.turn_penalty_ = robust_scm2double (c->get_property ("page-turn-penalty"), 0);
line.turn_permission_ = min_permission (line.page_permission_,
line.turn_permission_);
- max_ext = max (max_ext, extent.length ());
- line.extent_ = extent;
+ // TODO: see the hack regarding begin_of_line and
+ // rest_of_line extents in align-interface. Perhaps we
+ // should do the same thing here so that the effect extends
+ // between systems as well as within systems. It isn't as
+ // crucial here, however, because the effect is largest when
+ // dealing with large systems.
+ line.extent_ = (extent.is_empty ()
+ || isnan (extent[LEFT])
+ || isnan (extent[RIGHT]))
+ ? Interval (0, 0) : extent;
line.padding_ = padding;
line.space_ = space;
line.inverse_hooke_ = extent.length () + space;