]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/paper-book.cc
resolve merge
[lilypond.git] / lily / paper-book.cc
index fd519d5d751fee66e7af54d84a8f14b989c40e04..9907e56d95a16b94d1f90d0e4c040c96e9c86d2a 100644 (file)
@@ -1,9 +1,20 @@
 /*
-  paper-book.cc -- implement Paper_book
+  This file is part of LilyPond, the GNU music typesetter.
 
-  source file of the GNU LilyPond music typesetter
+  Copyright (C) 2004--2011 Jan Nieuwenhuizen <janneke@gnu.org>
 
-  (c) 2004--2009 Jan Nieuwenhuizen <janneke@gnu.org>
+  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/>.
 */
 
 #include "paper-book.hh"
@@ -63,7 +74,7 @@ Paper_book::mark_smob (SCM smob)
 }
 
 int
-Paper_book::print_smob (SCM smob, SCM port, scm_print_state*)
+Paper_book::print_smob (SCM smob, SCM port, scm_print_state *)
 {
   Paper_book *b = (Paper_book *) SCM_CELL_WORD_1 (smob);
   (void)b;
@@ -123,7 +134,7 @@ Paper_book::output_aux (SCM output_channel,
       scm_call_3 (proc,
                  performances (),
                  output_channel,
-                 scm_long2num (*first_performance_number));
+                 scm_from_long (*first_performance_number));
       *first_performance_number += scm_ilength (performances_);
     }
 
@@ -144,7 +155,7 @@ Paper_book::output_aux (SCM output_channel,
       if (scores_ == SCM_EOL)
        return 0;
       paper_->set_variable (ly_symbol2scm ("first-page-number"),
-                           scm_long2num (*first_page_number));
+                           scm_from_long (*first_page_number));
       paper_->set_variable (ly_symbol2scm ("is-last-bookpart"),
                            ly_bool2scm (is_last));
       /* Generate all stencils to trigger font loads.  */
@@ -157,14 +168,26 @@ Paper_book::output_aux (SCM output_channel,
 void
 Paper_book::output (SCM output_channel)
 {
-  int first_page_number = robust_scm2int (paper_->c_variable ("first-page-number"), 1);
+  int first_page_number
+    = robust_scm2int (paper_->c_variable ("first-page-number"), 1);
   int first_performance_number = 0;
+
+  /* FIXME: We need a line-width for ps output (framework-ps.scm:92).
+     If we don't have any, we take the paper-width unless we know
+     better which line-width to choose (e.g. if there are \bookparts
+     with different line-widths) and why we need it at all.
+  */
+
+  if (paper_->c_variable ("line-width") == SCM_UNDEFINED)
+    paper_->set_variable (ly_symbol2scm ("line-width"),
+                         paper_->c_variable ("paper-width"));
   if (!output_aux (output_channel,
                   true,
                   &first_page_number,
                   &first_performance_number))
     return;
-      
+
   SCM scopes = SCM_EOL;
   if (ly_is_module (header_))
     scopes = scm_cons (header_, scopes);
@@ -175,7 +198,8 @@ Paper_book::output (SCM output_channel)
 
   if (get_program_option ("print-pages"))
     {
-      SCM framework = ly_module_lookup (mod, ly_symbol2scm ("output-framework"));
+      SCM framework = ly_module_lookup (mod,
+                                       ly_symbol2scm ("output-framework"));
 
       if (framework != SCM_BOOL_F)
        {
@@ -193,7 +217,8 @@ Paper_book::output (SCM output_channel)
 
   if (get_program_option ("preview"))
     {
-      SCM framework = ly_module_lookup (mod, ly_symbol2scm ("output-preview-framework"));
+      SCM framework
+       = ly_module_lookup (mod, ly_symbol2scm ("output-preview-framework"));
 
       if (framework != SCM_BOOL_F)
        {
@@ -220,7 +245,7 @@ Paper_book::classic_output_aux (SCM output,
       scm_call_3 (proc,
                  performances (),
                  output,
-                 scm_long2num (*first_performance_number));
+                 scm_from_long (*first_performance_number));
       *first_performance_number += scm_ilength (performances_);
     }
   
@@ -315,12 +340,12 @@ Paper_book::score_title (SCM header)
 void
 set_page_permission (SCM sys, SCM symbol, SCM permission)
 {
-  if (Paper_score *ps = dynamic_cast<Paper_score*> (unsmob_music_output (sys)))
+  if (Paper_score *ps = dynamic_cast<Paper_score *> (unsmob_music_output (sys)))
     {
-      vector<Grob*> cols = ps->get_columns ();
+      vector<Grob *> cols = ps->get_columns ();
       if (cols.size ())
        {
-         Paper_column *col = dynamic_cast<Paper_column*> (cols.back ());
+         Paper_column *col = dynamic_cast<Paper_column *> (cols.back ());
          col->set_property (symbol, permission);
          col->find_prebroken_piece (LEFT)->set_property (symbol, permission);
        }
@@ -350,7 +375,8 @@ set_system_penalty (SCM sys, SCM header)
                                   ly_symbol2scm ("force"));
            }
          else
-           set_page_permission (sys, ly_symbol2scm ("page-break-permission"), SCM_EOL);
+           set_page_permission (sys, ly_symbol2scm ("page-break-permission"),
+                                SCM_EOL);
        }
     }
 }
@@ -358,16 +384,17 @@ set_system_penalty (SCM sys, SCM header)
 void
 set_labels (SCM sys, SCM labels)
 {
-  if (Paper_score *ps = dynamic_cast<Paper_score*> (unsmob_music_output (sys)))
+  if (Paper_score *ps = dynamic_cast<Paper_score *> (unsmob_music_output (sys)))
     {
       vector<Grob*> cols = ps->get_columns ();
       if (cols.size ())
        {
-         Paper_column *col = dynamic_cast<Paper_column*> (cols[0]);
+         Paper_column *col = dynamic_cast<Paper_column *> (cols[0]);
          col->set_property ("labels", 
                             scm_append_x (scm_list_2 (col->get_property ("labels"),
                                                       labels)));
-         Paper_column *col_right = dynamic_cast<Paper_column*> (col->find_prebroken_piece (RIGHT));
+         Paper_column *col_right
+           = dynamic_cast<Paper_column *> (col->find_prebroken_piece (RIGHT));
          col_right->set_property ("labels", 
                                   scm_append_x (scm_list_2 (col_right->get_property ("labels"),
                                                             labels)));
@@ -391,7 +418,8 @@ Paper_book::get_score_title (SCM header)
        TODO: this should come from the \layout {} block, which should
        override settings from \paper {}
       */
-      SCM props = paper_->lookup_variable (ly_symbol2scm ("score-title-properties"));
+      SCM props
+       = paper_->lookup_variable (ly_symbol2scm ("score-title-properties"));
       Prob *ps = make_paper_system (props);
       paper_system_set_stencil (ps, title);
 
@@ -406,14 +434,15 @@ SCM
 Paper_book::get_system_specs ()
 {
   SCM system_specs = SCM_EOL;
-  
+
   Stencil title = book_title ();
   if (!title.is_empty ())
     {
-      SCM props = paper_->lookup_variable (ly_symbol2scm ("book-title-properties"));
+      SCM props
+       = paper_->lookup_variable (ly_symbol2scm ("book-title-properties"));
       Prob *ps = make_paper_system (props);
       paper_system_set_stencil (ps, title);
-      
+
       system_specs = scm_cons (ps->self_scm (), system_specs);
       ps->unprotect ();
     }
@@ -487,28 +516,37 @@ 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 *first = 0;
+         Prob *last = 0;
+         for (SCM 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->set_property ("page-break-permission", ly_symbol2scm ("allow"));
-             ps->set_property ("page-turn-permission", ly_symbol2scm ("allow"));
-             
+             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", SCM_BOOL_F);
+
              paper_system_set_stencil (ps, *unsmob_stencil (t));
-             ps->set_property ("is-title", SCM_BOOL_T); 
-             if (scm_is_pair (scm_cdr (list)))
+             
+             SCM footnotes = get_footnotes (unsmob_stencil (t)->expr ());
+             ps->set_property ("footnotes", footnotes);
+             ps->set_property ("is-title", SCM_BOOL_T);
+             if (list == texts)
+               first = ps;
+             else
                {
-                 /* If an other markup is following, set this markup 
-                  * next padding and next space to 0, so that baseline-skip 
-                  * only should be taken into account for lines vertical
-                  * spacing. */
-                 ps->set_property ("next-padding", scm_double2num (0.0));
-                 ps->set_property ("next-space", scm_double2num (0.0));
+                 // last line so far, in a multi-line paragraph
+                 last = ps;
+                 //Place closely to previous line, no stretching.
+                 ps->set_property ("tight-spacing", SCM_BOOL_T);
                }
              system_specs = scm_cons (ps->self_scm (), system_specs);
              ps->unprotect ();
-             
+
              if (scm_is_pair (labels))
                {
                  set_labels (scm_car (system_specs), labels);
@@ -517,6 +555,14 @@ Paper_book::get_system_specs ()
              // FIXME: figure out penalty.
              //set_system_penalty (ps, scores_[i].header_);
            }
+         /* Set properties to avoid widowed/orphaned lines.
+            Single-line markup_lists are excluded, but in future
+            we may want to add the case of a very short, single line. */
+         if (first && last)
+           {
+             last->set_property ("last-markup-line", SCM_BOOL_T);
+             first->set_property ("first-markup-line", SCM_BOOL_T);
+           }
        }
       else
        assert (0);
@@ -537,16 +583,20 @@ Paper_book::systems ()
     {
       for (SCM p = bookparts_; scm_is_pair (p); p = scm_cdr (p))
        if (Paper_book *pbookpart = unsmob_paper_book (scm_car (p)))
-         systems_ = scm_append_x (scm_list_2 (systems_, pbookpart->systems ()));
+         systems_ = scm_append_x (scm_list_2 (systems_,
+                                              pbookpart->systems ()));
     }
   else
     {
       SCM specs = get_system_specs ();
       for (SCM s = specs; scm_is_pair (s); s = scm_cdr (s))
        {
-         if (Paper_score *pscore = dynamic_cast<Paper_score*> (unsmob_music_output (scm_car (s))))
+         if (Paper_score *pscore
+             = dynamic_cast<Paper_score *> (unsmob_music_output (scm_car (s))))
            {
-             SCM system_list = scm_vector_to_list (pscore->get_paper_systems ());
+             SCM system_list
+               = scm_vector_to_list (pscore->get_paper_systems ());
+
              system_list = scm_reverse (system_list);
              systems_ = scm_append (scm_list_2 (system_list, systems_));
            }
@@ -564,7 +614,7 @@ Paper_book::systems ()
        {
          Prob *ps = unsmob_prob (scm_car (s));
          ps->set_property ("number", scm_from_int (++i));
-         
+
          if (last
              && to_boolean (last->get_property ("is-title"))
              && !scm_is_number (ps->get_property ("penalty")))
@@ -601,8 +651,11 @@ Paper_book::pages ()
     }
   else if (scm_is_pair (scores_))
     {
-      SCM proc = paper_->c_variable ("page-breaking-wrapper");
-      pages_ = scm_apply_0 (proc, scm_list_1 (self_scm ()));
+      SCM page_breaking = paper_->c_variable ("page-breaking");
+      pages_ = scm_apply_0 (page_breaking, scm_list_1 (self_scm ()));
+      SCM post_process = paper_->c_variable ("page-post-process");
+      if (ly_is_procedure (post_process))
+       scm_apply_2 (post_process, paper_->self_scm (), pages_, SCM_EOL);
 
       /* set systems_ from the pages */
       if (systems_ == SCM_BOOL_F)