]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/page-layout-problem.cc
Web: add links to Essay.
[lilypond.git] / lily / page-layout-problem.cc
index b4bb60b03d8cee68ef5b9042d8c9315d26d71240..1aa83d3c0b222a9a05dcc8d0efdea51dccd9b802 100644 (file)
 #include "page-layout-problem.hh"
 
 #include "align-interface.hh"
+#include "axis-group-interface.hh"
 #include "hara-kiri-group-spanner.hh"
 #include "international.hh"
 #include "item.hh"
 #include "output-def.hh"
 #include "paper-book.hh"
+#include "paper-column.hh"
 #include "pointer-group-interface.hh"
 #include "prob.hh"
 #include "skyline-pair.hh"
@@ -26,6 +28,8 @@ Page_layout_problem::Page_layout_problem (Paper_book *pb, SCM page_scm, SCM syst
   Prob *page = unsmob_prob (page_scm);
   header_height_ = 0;
   footer_height_ = 0;
+  header_padding_ = 0;
+  footer_padding_ = 0;
   page_height_ = 100;
 
   if (page)
@@ -44,33 +48,38 @@ Page_layout_problem::Page_layout_problem (Paper_book *pb, SCM page_scm, SCM syst
   bottom_skyline_.set_minimum_height (-header_height_);
 
   SCM between_system_spacing = SCM_EOL;
+  SCM between_scores_system_spacing = SCM_EOL;
   SCM after_title_spacing = SCM_EOL;
   SCM before_title_spacing = SCM_EOL;
   SCM between_title_spacing = SCM_EOL;
 
-  // first_system_spacing controls the spring from the top of the printable
+  // top_system_spacing controls the spring from the top of the printable
   // area to the first staff. It allows the user to control the offset of
   // the first staff (as opposed to the top of the first system) from the
-  // top of the page. Similarly for last_system_spacing.
-  SCM first_system_spacing = SCM_EOL;
-  SCM last_system_spacing = SCM_EOL;
+  // top of the page. Similarly for bottom_system_spacing.
+  SCM top_system_spacing = SCM_EOL;
+  SCM bottom_system_spacing = SCM_EOL;
   if (pb && pb->paper_)
     {
       Output_def *paper = pb->paper_;
       between_system_spacing = paper->c_variable ("between-system-spacing");
+      between_scores_system_spacing = paper->c_variable ("between-scores-system-spacing");
       after_title_spacing = paper->c_variable ("after-title-spacing");
       before_title_spacing = paper->c_variable ("before-title-spacing");
       between_title_spacing = paper->c_variable ("between-title-spacing");
-      last_system_spacing = paper->c_variable ("last-system-spacing");
-      first_system_spacing = paper->c_variable ("first-system-spacing");
+      bottom_system_spacing = paper->c_variable ("bottom-system-spacing");
+      top_system_spacing = paper->c_variable ("top-system-spacing");
       if (scm_is_pair (systems) && unsmob_prob (scm_car (systems)))
-       first_system_spacing = paper->c_variable ("first-system-title-spacing");
+       top_system_spacing = paper->c_variable ("top-title-spacing");
 
       // Note: the page height here does _not_ reserve space for headers and
-      // footers. This is because we want to anchor the first-system-spacing
+      // footers. This is because we want to anchor the top-system-spacing
       // spring at the _top_ of the header.
       page_height_ -= robust_scm2double (paper->c_variable ("top-margin"), 0)
        + robust_scm2double (paper->c_variable ("bottom-margin"), 0);
+
+      read_spacing_spec (top_system_spacing, &header_padding_, ly_symbol2scm ("padding"));
+      read_spacing_spec (bottom_system_spacing, &footer_padding_, ly_symbol2scm ("padding"));
     }
   bool last_system_was_title = false;
 
@@ -88,8 +97,14 @@ Page_layout_problem::Page_layout_problem (Paper_book *pb, SCM page_scm, SCM syst
              continue;
            }
 
-         SCM spec = first ? first_system_spacing
-           : (last_system_was_title ? after_title_spacing : between_system_spacing);
+         SCM spec = between_system_spacing;
+         if (first)
+           spec = top_system_spacing;
+         else if (last_system_was_title)
+           spec = after_title_spacing;
+         else if (0 == Paper_column::get_rank (sys->get_bound (LEFT)))
+           spec = between_scores_system_spacing;
+
          Spring spring (first ? 0 : 1, 0.0);
          Real padding = 0.0;
          alter_spring_from_spacing_spec (spec, &spring);
@@ -100,7 +115,7 @@ Page_layout_problem::Page_layout_problem (Paper_book *pb, SCM page_scm, SCM syst
        }
       else if (Prob *p = unsmob_prob (scm_car (s)))
        {
-         SCM spec = first ? first_system_spacing
+         SCM spec = first ? top_system_spacing
            : (last_system_was_title ? between_title_spacing : before_title_spacing);
          Spring spring (first ? 0 : 1, 0.0);
          Real padding = 0.0;
@@ -116,16 +131,16 @@ Page_layout_problem::Page_layout_problem (Paper_book *pb, SCM page_scm, SCM syst
 
   Spring last_spring (0, 0);
   Real last_padding = 0;
-  alter_spring_from_spacing_spec (last_system_spacing, &last_spring);
-  read_spacing_spec (last_system_spacing, &last_padding, ly_symbol2scm ("padding"));
+  alter_spring_from_spacing_spec (bottom_system_spacing, &last_spring);
+  read_spacing_spec (bottom_system_spacing, &last_padding, ly_symbol2scm ("padding"));
   last_spring.ensure_min_distance (last_padding - bottom_skyline_.max_height () + footer_height_);
   springs_.push_back (last_spring);
 
   if (elements_.size ())
     {
-      Real bottom_padding;
+      Real bottom_padding = 0;
 
-      // TODO: junk bottom-space now that we have last-spring-spacing?
+      // TODO: junk bottom-space now that we have bottom-system-spacing?
       // bottom-space has the flexibility that one can do it per-system.
       // NOTE: bottom-space is misnamed since it is not stretchable space.
       if (Prob *p = elements_.back ().prob)
@@ -154,26 +169,12 @@ Page_layout_problem::set_footer_height (Real height)
   footer_height_ = height;
 }
 
-Grob*
-Page_layout_problem::find_vertical_alignment (System *sys)
-{
-  extract_grob_set (sys, "elements", elts);
-  for (vsize i = 0; i < elts.size (); ++i)
-    if (Align_interface::has_interface (elts[i]))
-      return elts[i];
-
-  return 0;
-}
-
 void
 Page_layout_problem::append_system (System *sys, Spring const& spring, Real padding)
 {
-  Grob *align = find_vertical_alignment (sys);
+  Grob *align = sys->get_vertical_alignment ();
   if (!align)
-    {
-      sys->programming_error ("no VerticalAlignment in system: can't do vertical spacing");
-      return;
-    }
+    return;
 
   align->set_property ("positioning-done", SCM_BOOL_T);
 
@@ -389,9 +390,17 @@ Page_layout_problem::find_system_offsets ()
                  if (staff_idx)
                    loose_line_min_distances.push_back (min_offsets[staff_idx-1] - min_offsets[staff_idx]);
                  else
-                   // FIXME: this should reflect the min distance from the last staff
-                   // to the first loose line of this staff.
-                   loose_line_min_distances.push_back (0);
+                   {
+                     Real min_dist = 0;
+                     if (last_spaceable_line)
+                       min_dist = Axis_group_interface::minimum_distance (last_spaceable_line,
+                                                                          staff,
+                                                                          Y_AXIS);
+                     else // distance to the top margin
+                       min_dist = header_padding_ + header_height_ + staff->extent (staff, Y_AXIS)[UP];
+
+                     loose_line_min_distances.push_back (min_dist);
+                   }
                }
            }
 
@@ -408,7 +417,9 @@ Page_layout_problem::find_system_offsets ()
 
   if (loose_lines.size ())
     {
-      loose_line_min_distances.push_back (0); // FIXME: should be the min distance to the footer.
+      Grob *last = loose_lines.back ();
+      Interval last_ext = last->extent (last, Y_AXIS);
+      loose_line_min_distances.push_back (-last_ext[DOWN] + footer_height_ + footer_padding_);
       loose_lines.push_back (0);
 
       distribute_loose_lines (loose_lines, loose_line_min_distances,
@@ -491,7 +502,7 @@ Page_layout_problem::build_system_skyline (vector<Grob*> const& staves,
   Real first_translation = minimum_translations[0];
   Real last_spaceable_dy = 0;
   Real first_spaceable_dy = 0;
-  bool found_spaceable_staff;
+  bool found_spaceable_staff = false;
 
   for (vsize i = 0; i < staves.size (); ++i)
     {