[Top][All Lists]
[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);
+}