X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fpage-breaking.cc;h=e064a81f086b1506ff2cc3f6d6974dc8094171f2;hb=79d8f8b56bedb175206ded3a25ce14ea4e331454;hp=e03a5c97c154f6a2576378fe1cb4e3b74fae4fd3;hpb=2f38710a2b40a24977441aa7faa05b6ab132f3cf;p=lilypond.git diff --git a/lily/page-breaking.cc b/lily/page-breaking.cc index e03a5c97c1..e064a81f08 100644 --- a/lily/page-breaking.cc +++ b/lily/page-breaking.cc @@ -1,10 +1,20 @@ /* - page-breaking.cc -- implement a superclass and utility - functions shared by various page-breaking algorithms + This file is part of LilyPond, the GNU music typesetter. - source file of the GNU LilyPond music typesetter + Copyright (C) 2006--2009 Joe Neeman - (c) 2006--2009 Joe Neeman + LilyPond is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + LilyPond is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LilyPond. If not, see . */ /* @@ -89,8 +99,10 @@ compress_lines (const vector &orig) { Line_details const &old = ret.back (); Line_details compressed = orig[i]; + Real padding = orig[i].title_ ? old.title_padding_ : old.padding_; + compressed.extent_[DOWN] = old.extent_[DOWN]; - compressed.extent_[UP] = old.extent_[UP] + orig[i].extent_.length () + old.padding_; + compressed.extent_[UP] = old.extent_[UP] + orig[i].extent_.length () + padding; compressed.space_ += old.space_; compressed.inverse_hooke_ += old.inverse_hooke_; @@ -488,14 +500,7 @@ Page_breaking::create_system_list () { if (Paper_score *ps = dynamic_cast (unsmob_music_output (scm_car (s)))) { - SCM system_count = ps->layout ()->c_variable ("system-count"); - - if (scm_is_number (system_count)) - s = scm_append (scm_list_3 (scm_list_1 (scm_car (s)), - scm_vector_to_list (ps->get_paper_systems ()), - scm_cdr (s))); - else - system_specs_.push_back (System_spec (ps)); + system_specs_.push_back (System_spec (ps)); } else { @@ -520,8 +525,25 @@ Page_breaking::find_chunks_and_breaks (Break_predicate is_break) { if (system_specs_[i].pscore_) { - vector cols - = system_specs_[i].pscore_->root_system ()->used_columns (); + vector cols; + + SCM system_count = system_specs_[i].pscore_->layout ()->c_variable ("system-count"); + if (scm_is_number (system_count)) + { + // With system-count given, the line configuration for + // this score is fixed. We need to ensure that chunk + // boundaries only occur at line breaks. + Constrained_breaking breaking (system_specs_[i].pscore_); + vector details = breaking.line_details (0, VPOS, scm_to_int (system_count)); + + cols.push_back (system_specs_[i].pscore_->root_system ()->used_columns ()[0]); + for (vsize j = 0; j < details.size (); j++) + cols.push_back (details[j].last_column_); + } + else + cols = system_specs_[i].pscore_->root_system ()->used_columns (); + + int last_chunk_idx = 0; vector line_breaker_columns; line_breaker_columns.push_back (0); @@ -535,10 +557,22 @@ Page_breaking::find_chunks_and_breaks (Break_predicate is_break) cols[j], last); + // NOTE: even in the breaks_ list, forced_line_count_ + // refers to the number of lines between a + // Break_position and the start of that /chunk/. This + // is needed for system_count_bounds to work correctly, + // since it mixes Break_positions from breaks_ and + // chunks_. + if (scm_is_number (system_count)) + cur_pos.forced_line_count_ = j - last_chunk_idx; + if (break_point || (i == system_specs_.size () - 1 && last)) breaks_.push_back (cur_pos); if (chunk_end || last) - chunks_.push_back (cur_pos); + { + chunks_.push_back (cur_pos); + last_chunk_idx = j; + } if ((break_point || chunk_end) && !last) line_breaker_columns.push_back (j); @@ -614,7 +648,10 @@ Page_breaking::system_count_bounds (vector const &chunks, for (vsize i = 0; i + 1 < chunks.size (); i++) { vsize sys = next_system (chunks[i]); - if (system_specs_[sys].pscore_) + + if (chunks[i+1].forced_line_count_) + ret[i] = chunks[i+1].forced_line_count_; + else if (system_specs_[sys].pscore_) { vsize start; vsize end; @@ -697,7 +734,10 @@ Page_breaking::set_to_ideal_line_configuration (vsize start, vsize end) for (vsize i = 0; i+1 < current_chunks_.size (); i++) { vsize sys = next_system (current_chunks_[i]); - if (system_specs_[sys].pscore_) + + if (current_chunks_[i+1].forced_line_count_) + div.push_back (current_chunks_[i+1].forced_line_count_); + else if (system_specs_[sys].pscore_) { line_breaker_args (sys, current_chunks_[i], current_chunks_[i+1], &start, &end); div.push_back (line_breaking_[sys].best_solution (start, end).size ()); @@ -723,11 +763,6 @@ Page_breaking::cache_line_details (vsize configuration_index) if (cached_configuration_index_ != configuration_index) { cached_configuration_index_ = configuration_index; - Real padding = 0; - SCM spacing_spec = book_->paper_->c_variable ("between-system-spacing"); - SCM page_breaking_spacing_spec = book_->paper_->c_variable ("page-breaking-between-system-spacing"); - 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")); Line_division &div = current_configurations_[configuration_index]; uncompressed_line_details_.clear (); @@ -746,10 +781,7 @@ Page_breaking::cache_line_details (vsize configuration_index) else { assert (div[i] == 1); - uncompressed_line_details_.push_back (Line_details (system_specs_[sys].prob_)); - uncompressed_line_details_.back ().padding_ = - robust_scm2double (system_specs_[sys].prob_->get_property ("next-padding"), - padding); + uncompressed_line_details_.push_back (Line_details (system_specs_[sys].prob_, book_->paper_)); } } cached_line_details_ = compress_lines (uncompressed_line_details_); @@ -821,8 +853,12 @@ Page_breaking::min_page_count (vsize configuration, vsize first_page_num) for (vsize i = 0; i < cached_line_details_.size (); i++) { Real ext_len = cached_line_details_[i].extent_.length (); - Real next_rod_height = cur_rod_height + ext_len - + ((cur_rod_height > 0) ? cached_line_details_[i].padding_: 0); + Real padding = 0; + if (cur_rod_height > 0) + padding = cached_line_details_[i].title_ ? + cached_line_details_[i-1].title_padding_ : cached_line_details_[i-1].padding_; + + Real next_rod_height = cur_rod_height + ext_len + padding; 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]); @@ -1338,9 +1374,9 @@ Page_breaking::last_break_position () const Real Page_breaking::min_whitespace_at_top_of_page (Line_details const &line) const { - SCM first_system_spacing = book_->paper_->c_variable ("first-system-spacing"); + SCM first_system_spacing = book_->paper_->c_variable ("top-system-spacing"); if (line.title_) - first_system_spacing = book_->paper_->c_variable ("first-system-title-spacing"); + first_system_spacing = book_->paper_->c_variable ("top-title-spacing"); Real min_distance = -infinity_f; Real padding = 0; @@ -1359,7 +1395,7 @@ Page_breaking::min_whitespace_at_top_of_page (Line_details const &line) const Real Page_breaking::min_whitespace_at_bottom_of_page (Line_details const &line) const { - SCM last_system_spacing = book_->paper_->c_variable ("last-system-spacing"); + SCM last_system_spacing = book_->paper_->c_variable ("bottom-system-spacing"); Real min_distance = -infinity_f; Real padding = 0;