summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Neeman <joeneeman@gmail.com>2010-06-14 19:30:55 +0300
committerJoe Neeman <joeneeman@gmail.com>2010-07-13 15:52:38 -0700
commit4a6773dd60ef6ef481e37b00049c9eedcb5b8193 (patch)
treef34116971db2b62a253ddf87e763a2e18999ff50
parent1886ed3be6b7b47ce2ede9e1cbbbea9d43bbc518 (diff)
Fix 1112.
Add support for minimum-distance into the page-breaker.
-rw-r--r--input/regression/page-breaking-min-distance.ly18
-rw-r--r--lily/constrained-breaking.cc33
-rw-r--r--lily/include/constrained-breaking.hh13
-rw-r--r--lily/page-breaking.cc51
-rw-r--r--lily/page-spacing.cc7
5 files changed, 93 insertions, 29 deletions
diff --git a/input/regression/page-breaking-min-distance.ly b/input/regression/page-breaking-min-distance.ly
new file mode 100644
index 0000000000..ad8dbdb20a
--- /dev/null
+++ b/input/regression/page-breaking-min-distance.ly
@@ -0,0 +1,18 @@
+\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 }
+}
+
diff --git a/lily/constrained-breaking.cc b/lily/constrained-breaking.cc
index 8e08d1fc87..0779c133a1 100644
--- a/lily/constrained-breaking.cc
+++ b/lily/constrained-breaking.cc
@@ -383,30 +383,51 @@ Constrained_breaking::initialize ()
/* 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);
@@ -460,6 +481,7 @@ Constrained_breaking::fill_line_details (Line_details *const out, vsize start, v
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;
@@ -486,8 +508,10 @@ Constrained_breaking::fill_line_details (Line_details *const out, vsize start, v
|| 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_;
}
@@ -509,6 +533,8 @@ Line_details::Line_details (Prob *pb, Output_def *paper)
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;
@@ -532,6 +558,7 @@ Line_details::Line_details (Prob *pb, Output_def *paper)
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
diff --git a/lily/include/constrained-breaking.hh b/lily/include/constrained-breaking.hh
index fbe12eb05b..c461859f7c 100644
--- a/lily/include/constrained-breaking.hh
+++ b/lily/include/constrained-breaking.hh
@@ -49,6 +49,8 @@ struct Line_details {
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_;
@@ -72,6 +74,7 @@ struct Line_details {
bool last_markup_line_;
bool first_markup_line_;
bool tight_spacing_;
+ Real first_refpoint_offset_;
Line_details ()
{
@@ -80,6 +83,8 @@ struct 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;
@@ -95,6 +100,7 @@ struct Line_details {
last_markup_line_ = false;
first_markup_line_ = false;
tallness_ = 0;
+ first_refpoint_offset_ = 0;
}
Line_details (Prob *pb, Output_def *paper);
@@ -150,9 +156,14 @@ private:
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 */
diff --git a/lily/page-breaking.cc b/lily/page-breaking.cc
index 83ffd90fd5..aeeb7bb1b7 100644
--- a/lily/page-breaking.cc
+++ b/lily/page-breaking.cc
@@ -100,17 +100,17 @@ compress_lines (const vector<Line_details> &orig)
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_;
@@ -858,19 +858,38 @@ Page_breaking::compute_line_heights ()
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;
}
}
@@ -892,21 +911,13 @@ Page_breaking::min_page_count (vsize configuration, vsize first_page_num)
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]);
diff --git a/lily/page-spacing.cc b/lily/page-spacing.cc
index 4120afb514..33cf18a3fe 100644
--- a/lily/page-spacing.cc
+++ b/lily/page-spacing.cc
@@ -56,8 +56,7 @@ Page_spacing::append_system (const Line_details &line)
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_;
@@ -69,9 +68,7 @@ Page_spacing::append_system (const Line_details &line)
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 ();