]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/include/page-spacing.hh
Run grand replace for 2015.
[lilypond.git] / lily / include / page-spacing.hh
index e1fa582d922fa8013e7d9535945db9f33e0feba7..4775baf67439da958720aec320e885aa1733f4a4 100644 (file)
@@ -1,40 +1,58 @@
 /*
-  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--2015 Joe Neeman <joeneeman@gmail.com>
 
-  (c) 2006--2007 Joe Neeman <joeneeman@gmail.com>
+  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 <http://www.gnu.org/licenses/>.
 */
 
 #ifndef PAGE_SPACING_HH
 #define PAGE_SPACING_HH
 
 #include "constrained-breaking.hh"
-
-struct Spacing_result {
-  vector<vsize> systems_per_page_;
-  vector<Real> force_;
-  Real penalty_;
-  Real demerits_;
-
-  Spacing_result ()
-  {
-    penalty_ = 0;
-    demerits_ = infinity_f;
-  }
-};
+#include "page-spacing-result.hh"
+
+/* 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;
 
 /* 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<Line_details> const &lines, Real page_height, bool ragged, bool ragged_last);
-  Spacing_result solve (vsize page_count);
+  Page_spacer (vector<Line_details> 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 +63,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<Line_details> 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<Page_spacing_node> state_;
+  vector<Page_spacing_node> simple_state_;
   vsize max_page_count_;
 
   bool ragged_;
@@ -65,29 +94,33 @@ private:
   bool calc_subproblem (vsize page, vsize lines);
 };
 
-vsize
-min_page_count (vector<Line_details> const &lines,
-               Real page_height, bool ragged, bool ragged_last);
-
-Spacing_result
-space_systems_on_n_pages (vector<Line_details> const&,
-                         vsize n,
-                         Real page_height,
-                         bool ragged,
-                         bool ragged_last);
-
-Spacing_result
-space_systems_on_n_or_one_more_pages (vector<Line_details> const&,
-                                     vsize n,
-                                     Real page_height,
-                                     Real odd_pages_penalty,
-                                     bool ragged,
-                                     bool ragged_last);
-Spacing_result
-space_systems_on_best_pages (vector<Line_details> 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 */