lilypond-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: dumb stacking page breaker


From: Nicolas Sceaux
Subject: Re: dumb stacking page breaker
Date: Sun, 15 Jul 2007 00:37:43 +0200
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.1 (darwin)

Joe Neeman <address@hidden> writes:
> [...]
> To fit with this, I'd suggest that you move 
> Stacking_page_breaking::compute_page_breaks to something like 
> Page_breaking::pack_systems_on_least_pages and change its interface to match 
> the other system-spacing stuff (ie. take a configuration_index instead of the 
> lines directly and return Spacing_result instead of just the systems per 
> page). Then you can return the uncompressed/compressed line stuff to private 
> within Page_breaking.

Joe,

Here is a new patch accounting for your remarks.

Should Page_breaking::pack_systems_on_least_pages also compute the
Page_spacing_result force_, demerits_, etc, slots, even though they are
not used in the subclass? (to better conform to the protocol designed
for the other spacing methods).

nicolas

diff --git a/lily/include/page-breaking.hh b/lily/include/page-breaking.hh
index 082384d..52a9581 100644
--- a/lily/include/page-breaking.hh
+++ b/lily/include/page-breaking.hh
@@ -131,6 +131,8 @@ protected:
                                                       vsize first_page_num);
   Page_spacing_result space_systems_on_best_pages (vsize configuration_index,
                                              vsize first_page_num);
+  Page_spacing_result pack_systems_on_least_pages (vsize configuration_index,
+                                                  vsize first_page_num);
   vsize min_page_count (vsize configuration_index, vsize first_page_num);
   bool all_lines_stretched (vsize configuration_index);
   Real blank_page_penalty () const;
diff --git a/lily/include/page-spacing.hh b/lily/include/page-spacing.hh
index ba05a4d..9bb3780 100644
--- a/lily/include/page-spacing.hh
+++ b/lily/include/page-spacing.hh
@@ -71,7 +71,7 @@ struct Page_spacing
   }
 
   void calc_force ();
-
+  void resize (Real new_height);
   void append_system (const Line_details &line);
   void prepend_system (const Line_details &line);
   void clear ();
diff --git a/lily/include/stacking-page-breaking.hh 
b/lily/include/stacking-page-breaking.hh
new file mode 100644
index 0000000..32f3aeb
--- /dev/null
+++ b/lily/include/stacking-page-breaking.hh
@@ -0,0 +1,26 @@
+/*
+  stacking-page-breaking.hh -- declare a page-breaker that stacks as
+  many systems on a page before moving to the next one. Specialized
+  for books with many pages, or a lot of text.
+
+  source file of the GNU LilyPond music typesetter
+
+  (c) 2007 Nicolas Sceaux <address@hidden>
+*/
+
+#ifndef STACKING_PAGE_BREAKING_HH
+#define STACKING_PAGE_BREAKING_HH
+
+#include "page-breaking.hh"
+#include "page-spacing.hh"
+
+class Stacking_page_breaking: public Page_breaking
+{
+public:
+  virtual SCM solve ();
+
+  Stacking_page_breaking (Paper_book *pb);
+  virtual ~Stacking_page_breaking ();
+};
+
+#endif /* STACKING_PAGE_BREAKING_HH */
diff --git a/lily/page-breaking-scheme.cc b/lily/page-breaking-scheme.cc
index 2241b50..0a86744 100644
--- a/lily/page-breaking-scheme.cc
+++ b/lily/page-breaking-scheme.cc
@@ -10,6 +10,7 @@
 #include "paper-book.hh"
 #include "page-turn-page-breaking.hh"
 #include "optimal-page-breaking.hh"
+#include "stacking-page-breaking.hh"
 
 LY_DEFINE (ly_page_turn_breaking, "ly:page-turn-breaking",
           1, 0, 0, (SCM pb),
@@ -30,3 +31,13 @@ LY_DEFINE (ly_optimal_breaking, "ly:opti
   Optimal_page_breaking b (unsmob_paper_book (pb));
   return b.solve ();
 }
+
+LY_DEFINE (ly_stacking_breaking, "ly:stacking-breaking",
+          1, 0, 0, (SCM pb),
+          "Break (pages and lines) the @code{Paper_book} object @var{pb}"
+          "without looking for optimal spacing: stack as many lines on"
+          "a page before moving to the next one.")
+{
+  Stacking_page_breaking b (unsmob_paper_book (pb));
+  return b.solve ();
+}
diff --git a/lily/page-breaking.cc b/lily/page-breaking.cc
index 9ad8336..bd474cb 100644
--- a/lily/page-breaking.cc
+++ b/lily/page-breaking.cc
@@ -526,6 +526,7 @@ Page_breaking::cache_line_details (vsize
 {
   if (cached_configuration_index_ != configuration_index)
     {
+      cached_configuration_index_ = configuration_index;
       SCM padding_scm = book_->paper_->c_variable 
("page-breaking-between-system-padding");
       if (!scm_is_number (padding_scm))
        padding_scm = book_->paper_->c_variable ("between-system-padding");
@@ -758,6 +759,49 @@ Page_breaking::space_systems_on_best_pag
   return finalize_spacing_result (configuration, best);
 }
 
+Page_spacing_result
+Page_breaking::pack_systems_on_least_pages (vsize configuration, vsize 
first_page_num)
+{
+  Page_spacing_result res;
+  vsize page = 0;
+  vsize page_first_line = 0;
+  Page_spacing space (page_height (first_page_num, false));
+
+  cache_line_details (configuration);
+  for (vsize line = 0; line < cached_line_details_.size (); line++)
+    {
+      space.append_system (cached_line_details_[line]);
+      if ((line > page_first_line)
+          && (isinf (space.force_)
+              || (cached_line_details_[line].page_permission_ == ly_symbol2scm 
("force"))))
+        {
+          res.systems_per_page_.push_back (line - page_first_line);
+         page++;
+          space.resize (page_height (first_page_num + page, false));
+          space.clear ();
+          page_first_line = line;
+       }
+
+      if (line == cached_line_details_.size () - 1)
+        {
+          /* This is the last line */
+          /* When the last page height was computed, we did not know yet that 
it
+           * was the last one. If the systems put on it don't fit anymore, the 
last
+           * system is moved to a new page */
+          space.resize (page_height (first_page_num + page, true));
+          if ((line > page_first_line) && (isinf (space.force_)))
+            {
+              res.systems_per_page_.push_back (line - page_first_line);
+              res.systems_per_page_.push_back (1);
+            }
+          else
+            res.systems_per_page_.push_back (line + 1 - page_first_line);
+        }
+    }
+  res.systems_per_page_ = uncompress_solution (res.systems_per_page_, 
cached_line_details_);
+  return res;
+}
+
 /* Calculate demerits and fix res.systems_per_page_ so that
    it refers to the original line numbers, not the ones given by 
compress_lines (). */
 Page_spacing_result
diff --git a/lily/page-spacing.cc b/lily/page-spacing.cc
index fa1c273..82a037b 100644
--- a/lily/page-spacing.cc
+++ b/lily/page-spacing.cc
@@ -24,6 +24,13 @@ Page_spacing::calc_force ()
 }
 
 void
+Page_spacing::resize (Real new_height)
+{
+  page_height_ = new_height;
+  calc_force ();
+}
+
+void
 Page_spacing::append_system (const Line_details &line)
 {
   rod_height_ += last_line_.padding_;
diff --git a/lily/stacking-page-breaking.cc b/lily/stacking-page-breaking.cc
new file mode 100644
index 0000000..7fb4d70
--- /dev/null
+++ b/lily/stacking-page-breaking.cc
@@ -0,0 +1,47 @@
+/*
+  stacking-page-breaking.cc -- implement a page-breaker that stacks as
+  many systems on a page before moving to the next one. Specialized
+  for books with many pages, or a lot of text.
+
+  source file of the GNU LilyPond music typesetter
+
+  (c) 2007 Nicolas Sceaux <address@hidden>
+*/
+
+#include "international.hh"
+#include "stacking-page-breaking.hh"
+#include "output-def.hh"
+#include "page-spacing.hh"
+#include "paper-book.hh"
+
+static bool
+is_break (Grob *g)
+{
+  (void) g; /* shutup warning */
+  return false;
+}
+
+Stacking_page_breaking::Stacking_page_breaking (Paper_book *pb)
+  : Page_breaking (pb, is_break)
+{
+}
+
+Stacking_page_breaking::~Stacking_page_breaking ()
+{
+}
+
+SCM
+Stacking_page_breaking::solve ()
+{
+  vsize end = last_break_position ();
+
+  message ("Computing line breaks...");
+  set_to_ideal_line_configuration (0, end);
+  break_into_pieces (0, end, current_configuration (0));
+
+  message (_ ("Computing page breaks..."));
+  vsize first_page_num = robust_scm2int (book_->paper_->c_variable 
("first-page-number"), 1);
+  Page_spacing_result res = pack_systems_on_least_pages (0, first_page_num);
+  SCM lines = systems ();
+  return make_pages (res.systems_per_page_, lines);
+}

reply via email to

[Prev in Thread] Current Thread [Next in Thread]