-Spacing_result
-space_systems_on_min_pages (vector<Line_details> const &lines,
- Real page_height,
- Real odd_pages_penalty)
-{
- vector<Line_details> compressed_lines = compress_lines (lines);
- vsize min_p_count = min_page_count (compressed_lines, page_height);
- Spacing_result ret;
-
- if (min_p_count == 1)
- {
- Spacing_result candidate1 = space_systems_on_1_page (compressed_lines, page_height);
- candidate1.force_.back () += odd_pages_penalty;
- candidate1.demerits_ += odd_pages_penalty;
- if (compressed_lines.size () == 1)
- ret = candidate1;
- else
- {
- Spacing_result candidate2 = space_systems_on_2_pages (compressed_lines, page_height);
- ret = (candidate1.demerits_ < candidate2.demerits_) ?
- candidate1 : candidate2;
- }
+ bool overfull = (space.rod_height_ > paper_height
+ || (ragged
+ && (space.rod_height_ + space.spring_len_ > paper_height)));
+ // This 'if' statement is a little hard to parse. It won't consider this configuration
+ // if it is overfull unless the current configuration is the first one with this start
+ // point. We also make an exception (and consider this configuration) if the previous
+ // configuration we tried had fewer lines than min-systems-per-page.
+ if (!breaker_->too_few_lines (line_count)
+ && page_start < line
+ && overfull)
+ break;
+
+ line_count += lines_[page_start].compressed_nontitle_lines_count_;
+ if (page > 0 || page_start == 0)
+ {
+ // If the last page is ragged, set its force to zero. This way, we will leave
+ // the last page half-empty rather than trying to balance things out
+ // (which only makes sense in non-ragged situations).
+ if (line == lines_.size () - 1 && ragged && last && space.force_ > 0)
+ space.force_ = 0;
+
+ Real demerits = space.force_ * space.force_;
+
+ // Clamp the demerits at BAD_SPACING_PENALTY, even if the page
+ // is overfull. This ensures that TERRIBLE_SPACING_PENALTY takes
+ // precedence over overfull pages.
+ demerits = min (demerits, BAD_SPACING_PENALTY);
+ demerits += (prev ? prev->demerits_ : 0);
+
+ Real penalty = breaker_->line_count_penalty (line_count);
+ if (page_start > 0)
+ penalty += lines_[page_start - 1].page_penalty_
+ + (page % 2 == 0) ? lines_[page_start - 1].turn_penalty_ : 0;
+
+ /* Deal with widow/orphan lines */
+ /* Last line of paragraph is first line on the new page */
+ if ((page_start > 0)
+ && (page_start < lines_.size ())
+ && (lines_[page_start].last_markup_line_))
+ penalty += breaker_->orphan_penalty ();
+ /* First line of paragraph is last line on the previous page */
+ if ((page_start > 0)
+ && (page_start < lines_.size ())
+ && (lines_[page_start - 1].first_markup_line_))
+ penalty += breaker_->orphan_penalty ();
+
+ demerits += penalty;
+ if (demerits < cur.demerits_ || page_start == line)
+ {
+ cur.demerits_ = demerits;
+ cur.force_ = space.force_;
+ cur.penalty_ = penalty + (prev ? prev->penalty_ : 0);
+ cur.system_count_status_ = breaker_->line_count_status (line_count)
+ | (prev ? prev->system_count_status_ : 0);
+ cur.prev_ = page_start - 1;
+ cur.page_ = prev ? prev->page_ + 1 : first_page_num_;
+ }
+ }
+
+ if (page_start > 0
+ && lines_[page_start - 1].page_permission_ == ly_symbol2scm ("force"))
+ break;