]> git.donarmstrong.com Git - lilypond.git/commitdiff
Avoid orphan/widow markup lines.
authorBoris Shingarov <shingarov@gmail.com>
Thu, 21 Jan 2010 23:26:46 +0000 (15:26 -0800)
committerJoe Neeman <joeneeman@gmail.com>
Thu, 21 Jan 2010 23:26:46 +0000 (15:26 -0800)
lily/constrained-breaking.cc
lily/include/constrained-breaking.hh
lily/include/page-breaking.hh
lily/page-breaking.cc
lily/page-spacing.cc
lily/paper-book.cc

index 2fead2460d504499cd5bfa89763a2d01ad313b07..518015f72040a8bf331b4489e60e637ef5ac5f5a 100644 (file)
@@ -525,4 +525,8 @@ Line_details::Line_details (Prob *pb, Output_def *paper)
   title_ = to_boolean (pb->get_property ("is-title"));
   compressed_lines_count_ = 1;
   compressed_nontitle_lines_count_ = title_ ? 0 : 1;
+  SCM last_scm  = pb->get_property ("last-markup-line");
+  last_markup_line_  = to_boolean (last_scm);
+  SCM first_scm = pb->get_property ("first-markup-line");
+  first_markup_line_ = to_boolean (first_scm);
 }
index bb8a1d0c38b084239efd81199d9858fc2b341731..f36ab74df55e88477afc5294c862b426d567316e 100644 (file)
@@ -52,6 +52,8 @@ struct Line_details {
      class. */
   int compressed_lines_count_;
   int compressed_nontitle_lines_count_;
+  bool last_markup_line_;
+  bool first_markup_line_;
 
   Line_details ()
   {
@@ -71,6 +73,8 @@ struct Line_details {
     title_ = false;
     compressed_lines_count_ = 1;
     compressed_nontitle_lines_count_ = 1;
+    last_markup_line_ = false;
+    first_markup_line_ = false;
   }
 
   Line_details (Prob *pb, Output_def *paper);
index 002d7def29ee7e9be8409d77dbb91d9236c83b8b..96857798ef9bbfb6925b76257cd8b5754a6c7b4b 100644 (file)
@@ -127,6 +127,7 @@ public:
   bool too_few_lines (int line_count) const;
   Real min_whitespace_at_top_of_page (Line_details const&) const;
   Real min_whitespace_at_bottom_of_page (Line_details const&) const;
+  int orphan_penalty () const;
 
 protected:
   Paper_book *book_;
@@ -180,6 +181,7 @@ private:
   int max_systems_per_page_;
   int min_systems_per_page_;
   vsize system_count_;
+  int orphan_penalty_;
 
   vector<Line_division> current_configurations_;
   vector<Break_position> current_chunks_;
index a961dce545967c7494df3713e864cbf059d97fb0..494a32bed026169c9579940a39c34600645ccedb 100644 (file)
@@ -174,6 +174,7 @@ Page_breaking::Page_breaking (Paper_book *pb, Break_predicate is_break)
   systems_per_page_ = max (0, robust_scm2int (pb->paper_->c_variable ("systems-per-page"), 0));
   max_systems_per_page_ = max (0, robust_scm2int (pb->paper_->c_variable ("max-systems-per-page"), 0));
   min_systems_per_page_ = max (0, robust_scm2int (pb->paper_->c_variable ("min-systems-per-page"), 0));
+  orphan_penalty_ = robust_scm2int (pb->paper_->c_variable ("orphan-penalty"), 100000);
 
   if (systems_per_page_ && (max_systems_per_page_ || min_systems_per_page_))
     {
@@ -1407,3 +1408,9 @@ Page_breaking::min_whitespace_at_bottom_of_page (Line_details const &line) const
   // FIXME: take into account the height of the footer
   return max (0.0, max (padding, min_distance + line.extent_[DOWN]));
 }
+
+int
+Page_breaking::orphan_penalty () const
+{
+  return orphan_penalty_;
+}
index 8919257caa54c493f7d600af56831987a6b9524c..8dbf1834cf3e332de74b78642c5c6307dd81cbc2 100644 (file)
@@ -245,6 +245,18 @@ Page_spacer::calc_subproblem (vsize page, vsize line)
            penalty += lines_[page_start-1].page_penalty_
              + (page % 2 == 0) ? lines_[page_start-1].turn_penalty_ : 0;
 
+         /* Deal with widow/orphan lines */
+         /* Last line of paragraph is first line on the new page */
+         if ((page_start > 0) &&
+             (page_start < lines_.size ()) &&
+             (lines_[page_start].last_markup_line_))
+                 penalty += breaker_->orphan_penalty ();
+         /* First line of paragraph is last line on the previous page */
+         if ((page_start > 0) &&
+             (page_start < lines_.size ()) &&
+             (lines_[page_start-1].first_markup_line_))
+                 penalty += breaker_->orphan_penalty ();
+
          demerits += penalty;
          if (demerits < cur.demerits_ || page_start == line)
            {
index 79896e6da1d52e7c1a7cffd0a9399d4e65f7c69b..81b3a4782cb5365c369bab14af6dd618aa335565 100644 (file)
@@ -516,15 +516,20 @@ Paper_book::get_system_specs ()
                                  paper_->self_scm (),
                                  page_properties,
                                  scm_car (s));
-         for (SCM list = texts ; scm_is_pair (list) ; list = scm_cdr (list))
+         Prob *ps;
+         SCM list;
+         for (list = texts ; scm_is_pair (list) ; list = scm_cdr (list))
            {
              SCM t = scm_car (list);
              // TODO: init props
-             Prob *ps = make_paper_system (SCM_EOL);
+             ps = make_paper_system (SCM_EOL);
              ps->set_property ("page-break-permission",
                                ly_symbol2scm ("allow"));
              ps->set_property ("page-turn-permission",
                                ly_symbol2scm ("allow"));
+             ps->set_property ("last-markup-line",  SCM_BOOL_F);
+             ps->set_property ("first-markup-line",
+                         list == texts? SCM_BOOL_T : SCM_BOOL_F);
 
              paper_system_set_stencil (ps, *unsmob_stencil (t));
              ps->set_property ("is-title", SCM_BOOL_T);
@@ -544,6 +549,18 @@ Paper_book::get_system_specs ()
              // FIXME: figure out penalty.
              //set_system_penalty (ps, scores_[i].header_);
            }
+         // We may want to place a check here, for whether the line is too short
+         if (list == texts)
+           {
+             // if there is only one line in the paragraph,
+             // do not try to avoid orphans
+             ps->set_property ("last-markup-line", SCM_BOOL_F);
+             ps->set_property ("first-markup-line", SCM_BOOL_F);
+           }
+         else
+           {
+             ps->set_property ("last-markup-line", SCM_BOOL_T);
+           }
        }
       else
        assert (0);