Add support for minimum-distance into the page-breaker.
--- /dev/null
+\version "2.13.22"
+
+\header {
+ texidoc = "minimum-distance is correctly accounted for in page breaking."
+}
+
+\book {
+ \paper {
+ between-scores-system-spacing #'minimum-distance = #'20
+ paper-height = 8\cm
+ }
+
+ \score { c'1 }
+ \score { c'1 }
+ \score { c'1 }
+ \score { c'1 }
+}
+
/* NOTE: currently, we aren't using the space_ field of a
Line_details for anything. That's because the approximations
used for scoring a page configuration don't actually space things
- properly (for speed reasong) using springs anchored at the staff
+ properly (for speed reasons) using springs anchored at the staff
refpoints. Rather, the "space" is placed between the extent
boxes. To get a good result, therefore, the "space" value for
page breaking needs to be much smaller than the "space" value for
- page layout. Currently, we just make it zero always.
+ page layout. Currently, we just make it zero always, which means
+ that we will always prefer a tighter vertical layout.
*/
between_system_space_ = 0;
between_system_padding_ = 0;
+ between_system_min_distance_ = 0;
+ between_scores_system_padding_ = 0;
+ between_scores_system_min_distance_ = 0;
before_title_padding_ = 0;
+ before_title_min_distance_ = 0;
Output_def *l = pscore_->layout ();
SCM spacing_spec = l->c_variable ("between-system-spacing");
+ SCM between_scores_spec = l->c_variable ("between-scores-system-spacing");
SCM title_spec = l->c_variable ("before-title-spacing");
SCM page_breaking_spacing_spec = l->c_variable ("page-breaking-between-system-spacing");
Page_layout_problem::read_spacing_spec (spacing_spec,
&between_system_padding_,
ly_symbol2scm ("padding"));
+ Page_layout_problem::read_spacing_spec (between_scores_spec,
+ &between_scores_system_padding_,
+ ly_symbol2scm ("padding"));
Page_layout_problem::read_spacing_spec (page_breaking_spacing_spec,
&between_system_padding_,
ly_symbol2scm ("padding"));
Page_layout_problem::read_spacing_spec (title_spec,
&before_title_padding_,
ly_symbol2scm ("padding"));
+ Page_layout_problem::read_spacing_spec (between_scores_spec,
+ &between_scores_system_min_distance_,
+ ly_symbol2scm ("minimum-distance"));
+ Page_layout_problem::read_spacing_spec (spacing_spec,
+ &between_system_min_distance_,
+ ly_symbol2scm ("minimum-distance"));
+ Page_layout_problem::read_spacing_spec (page_breaking_spacing_spec,
+ &between_system_min_distance_,
+ ly_symbol2scm ("minimum-distance"));
+ Page_layout_problem::read_spacing_spec (title_spec,
+ &before_title_min_distance_,
+ ly_symbol2scm ("minimum-distance"));
Interval first_line = line_dimensions_int (pscore_->layout (), 0);
Interval other_lines = line_dimensions_int (pscore_->layout (), 1);
System *sys = pscore_->root_system ();
Interval begin_of_line_extent = sys->begin_of_line_pure_height (start_rank, end_rank);
Interval rest_of_line_extent = sys->rest_of_line_pure_height (start_rank, end_rank);
+ bool last = (end == breaks_.size () - 1);
Grob *c = all_[breaks_[end]];
out->last_column_ = c;
|| isnan (rest_of_line_extent[RIGHT]))
? Interval (0, 0) : rest_of_line_extent;
out->shape_ = Line_shape (begin_of_line_extent, rest_of_line_extent);
- out->padding_ = between_system_padding_;
+ out->padding_ = last ? between_scores_system_padding_ : between_system_padding_;
out->title_padding_ = before_title_padding_;
+ out->min_distance_ = last ? between_scores_system_min_distance_ : between_system_min_distance_;
+ out->title_min_distance_ = before_title_min_distance_;
out->space_ = between_system_space_;
out->inverse_hooke_ = out->full_height () + between_system_space_;
}
title_padding_ = 0;
Page_layout_problem::read_spacing_spec (spec, &padding_, ly_symbol2scm ("padding"));
Page_layout_problem::read_spacing_spec (title_spec, &title_padding_, ly_symbol2scm ("padding"));
+ Page_layout_problem::read_spacing_spec (spec, &min_distance_, ly_symbol2scm ("minimum-distance"));
+ Page_layout_problem::read_spacing_spec (title_spec, &title_min_distance_, ly_symbol2scm ("minimum-distance"));
last_column_ = 0;
force_ = 0;
SCM first_scm = pb->get_property ("first-markup-line");
first_markup_line_ = to_boolean (first_scm);
tight_spacing_ = to_boolean (pb->get_property ("tight-spacing"));
+ first_refpoint_offset_ = 0;
}
Real
Real padding_; /* compulsory space after this system (if we're not
last on a page) */
Real title_padding_;
+ Real min_distance_;
+ Real title_min_distance_;
Real bottom_padding_;
Real space_; /* spring length */
Real inverse_hooke_;
bool last_markup_line_;
bool first_markup_line_;
bool tight_spacing_;
+ Real first_refpoint_offset_;
Line_details ()
{
padding_ = 0;
title_padding_ = 0;
bottom_padding_ = 0;
+ min_distance_ = 0;
+ title_min_distance_ = 0;
space_ = 0;
inverse_hooke_ = 1;
tight_spacing_ = false;
last_markup_line_ = false;
first_markup_line_ = false;
tallness_ = 0;
+ first_refpoint_offset_ = 0;
}
Line_details (Prob *pb, Output_def *paper);
vsize systems_;
bool ragged_right_;
bool ragged_last_;
+
+ Real between_system_min_distance_;
+ Real between_system_padding_;
Real between_system_space_;
+ Real between_scores_system_min_distance_;
+ Real between_scores_system_padding_;
+ Real before_title_min_distance_;
Real before_title_padding_;
- Real between_system_padding_;
/* the (i,j)th entry is the configuration for breaking between
columns i and j */
Line_details const &old = ret.back ();
Line_details compressed = orig[i];
/*
- "padding" is the padding below the current line. The padding below
- "old" (taking into account whether "old" is a title) is already
- accounted for in the extent of the compressed line. The padding
- below the compressed line, therefore, should depend on whether its
- bottom-most line is a title or not.
+ We must account for the padding between the lines that we are compressing.
+ The padding values come from "old," which is the upper system here. Note
+ the meaning of tight-spacing: if a system has tight-spacing, then the padding
+ _before_ it is ignored.
*/
Real padding = 0;
if (!orig[i].tight_spacing_)
padding = orig[i].title_ ? old.title_padding_ : old.padding_;
compressed.shape_ = old.shape_.piggyback (orig[i].shape_, padding);
+ compressed.first_refpoint_offset_ += compressed.shape_.rest_[UP] - old.shape_.rest_[UP];
compressed.space_ += old.space_;
compressed.inverse_hooke_ += old.inverse_hooke_;
Real prev_hanging = 0;
Real prev_hanging_begin = 0;
Real prev_hanging_rest = 0;
+ Real prev_refpoint_hanging = 0;
for (vsize i = 0; i < cached_line_details_.size (); i++)
{
Line_shape shape = cached_line_details_[i].shape_;
Real a = shape.begin_[UP];
Real b = shape.rest_[UP];
- Real midline_hanging = max (prev_hanging_begin + a, prev_hanging_rest + b);
- Real hanging_begin = midline_hanging - shape.begin_[DOWN];
- Real hanging_rest = midline_hanging - shape.rest_[DOWN];
+ bool title = cached_line_details_[i].title_;
+ Real refpoint_hanging = max (prev_hanging_begin + a, prev_hanging_rest + b);
+
+ if (i > 0)
+ {
+ Real padding = 0;
+ if (!cached_line_details_[i].tight_spacing_)
+ padding = title
+ ? cached_line_details_[i-1].title_padding_
+ : cached_line_details_[i-1].padding_;
+ Real min_dist = title
+ ? cached_line_details_[i-1].title_min_distance_
+ : cached_line_details_[i-1].min_distance_;
+ refpoint_hanging = max (refpoint_hanging + padding,
+ prev_refpoint_hanging + min_dist
+ + cached_line_details_[i].first_refpoint_offset_);
+ }
+
+ Real hanging_begin = refpoint_hanging - shape.begin_[DOWN];
+ Real hanging_rest = refpoint_hanging - shape.rest_[DOWN];
Real hanging = max (hanging_begin, hanging_rest);
cached_line_details_[i].tallness_ = hanging - prev_hanging;
prev_hanging = hanging;
prev_hanging_begin = hanging_begin;
prev_hanging_rest = hanging_rest;
+ prev_refpoint_hanging = refpoint_hanging;
}
}
for (vsize i = 0; i < cached_line_details_.size (); i++)
{
- Real padding = 0;
Real ext_len;
if (cur_rod_height > 0)
- {
- if (!cached_line_details_[i].tight_spacing_)
- padding = (cached_line_details_[i].title_
- ? cached_line_details_[i - 1].title_padding_
- : cached_line_details_[i - 1].padding_);
- ext_len = cached_line_details_[i].tallness_;
- }
+ ext_len = cached_line_details_[i].tallness_;
else
- {
- ext_len = cached_line_details_[i].full_height();
- }
- Real next_rod_height = cur_rod_height + ext_len + padding;
+ ext_len = cached_line_details_[i].full_height();
+
+ Real next_rod_height = cur_rod_height + ext_len;
Real next_spring_height = cur_spring_height + cached_line_details_[i].space_;
Real next_height = next_rod_height + (ragged () ? next_spring_height : 0)
+ min_whitespace_at_bottom_of_page (cached_line_details_[i]);
rod_height_ += line.full_height ();
first_line_ = line;
}
- if (!line.tight_spacing_)
- rod_height_ += line.title_ ? last_line_.title_padding_ : last_line_.padding_;
+
spring_len_ += line.space_;
inverse_spring_k_ += line.inverse_hooke_;
void
Page_spacing::prepend_system (const Line_details &line)
{
- if (rod_height_ && !first_line_.tight_spacing_)
- rod_height_ += first_line_.title_ ? line.title_padding_ : line.padding_;
- else
+ if (!rod_height_)
last_line_ = line;
rod_height_ -= first_line_.full_height ();