X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Finclude%2Fpage-spacing.hh;h=206bcbf426bb4193ab7c0bdf03c3665c01711229;hb=e90f0536f9be39ada0bef0aeb0d275dec3b2fb5b;hp=b91540a03f7937622ea5eadafbd443f403939744;hpb=837a30f66f73ed048a82bef3a3ff1551d06a96da;p=lilypond.git diff --git a/lily/include/page-spacing.hh b/lily/include/page-spacing.hh index b91540a03f..206bcbf426 100644 --- a/lily/include/page-spacing.hh +++ b/lily/include/page-spacing.hh @@ -1,40 +1,59 @@ /* - page-spacing.hh -- routines for spacing systems - vertically across pages + This file is part of LilyPond, the GNU music typesetter. - source file of the GNU LilyPond music typesetter + Copyright (C) 2006--2011 Joe Neeman - (c) 2006 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 . */ #ifndef PAGE_SPACING_HH #define PAGE_SPACING_HH #include "constrained-breaking.hh" +#include "page-spacing-result.hh" -struct Spacing_result { - vector systems_per_page_; - vector force_; - Real penalty_; - Real demerits_; +/* This is a penalty that we add whenever a page breaking solution + is not bad enough to completely discard, but bad enough that + it is worse than any "proper" solution. For example, if we didn't + manage to fit systems on the desired number of pages or if there was + too big for a page. + + This constant is large enough that it dominates any reasonable penalty, + but small enough that nothing will overflow to infinity (so that we + can still distinguish bad spacings by the number of BAD_SPACING_PENALTYs + that they incur. + + BAD_SPACING_PENALTY is for occasions where the spacing is bad. + TERRIBLE_SPACING_PENALTY is for when we are disregarding a user override + (for example, we are failing to satisfy min-systems-per-page). These user + overrides are more important than getting good spacing, so they get a + larger penalty. +*/ +const Real BAD_SPACING_PENALTY = 1e6; +const Real TERRIBLE_SPACING_PENALTY = 1e8; - Spacing_result () - { - penalty_ = 0; - demerits_ = infinity_f; - } -}; /* for page_count > 2, we use a dynamic algorithm similar to constrained-breaking -- we have a class that stores the intermediate calculations so they can be reused for querying different page counts. */ - class Page_spacer { public: - Page_spacer (vector const &lines, Real page_height, bool ragged, bool ragged_last); - Spacing_result solve (vsize page_count); + Page_spacer (vector const &lines, vsize first_page_num, Page_breaking const*); + Page_spacing_result solve (vsize page_count); + Page_spacing_result solve (); private: struct Page_spacing_node @@ -45,17 +64,28 @@ private: force_ = infinity_f; penalty_ = infinity_f; prev_ = VPOS; + system_count_status_ = SYSTEM_COUNT_OK; + page_ = 0; } Real demerits_; Real force_; Real penalty_; vsize prev_; + vsize page_; + int system_count_status_; }; - Real page_height_; + Page_breaking const *breaker_; + vsize first_page_num_; vector lines_; + + // If a page-count is requested, we use state_, which + // is indexed by page*system, for our dynamic programming + // intermediate storage. Otherwise, we use simple_state_, + // which is indexed only by system. Matrix state_; + vector simple_state_; vsize max_page_count_; bool ragged_; @@ -65,17 +95,33 @@ private: bool calc_subproblem (vsize page, vsize lines); }; -Spacing_result -space_systems_on_min_pages (vector const&, - Real page_height, - Real odd_pages_penalty, - bool ragged, - bool ragged_last); -Spacing_result -space_systems_on_best_pages (vector const&, - Real page_height, - Real odd_pages_penalty, - bool ragged, - bool ragged_last); +struct Page_spacing +{ + Real force_; + Real page_height_; + Real rod_height_; + Real spring_len_; + Real inverse_spring_k_; + bool has_footnotes_; + + Line_details last_line_; + Line_details first_line_; + Page_breaking const *breaker_; + + Page_spacing (Real page_height, Page_breaking const *breaker) + { + page_height_ = page_height; + breaker_ = breaker; + has_footnotes_ = false; + clear (); + } + + void calc_force (); + void resize (Real new_height); + Real account_for_footnotes (Line_details const &line); + void append_system (const Line_details &line); + void prepend_system (const Line_details &line); + void clear (); +}; #endif /* PAGE_SPACING_HH */