]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/paper-book.cc
Web-es: add missing '@end ifset'
[lilypond.git] / lily / paper-book.cc
index 1962f3b2ec61d71254ac3b03dc61143692c413c9..79896e6da1d52e7c1a7cffd0a9399d4e65f7c69b 100644 (file)
@@ -1,14 +1,26 @@
 /*
-  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--2009 Jan Nieuwenhuizen <janneke@gnu.org>
 
-  (c) 2004--2007 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"
 
 #include "grob.hh"
+#include "international.hh"
 #include "main.hh"
 #include "output-def.hh"
 #include "paper-column.hh"
@@ -62,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;
@@ -108,13 +120,13 @@ Paper_book::add_performance (SCM s)
   performances_ = scm_cons (s, performances_);
 }
 
-void
+int
 Paper_book::output_aux (SCM output_channel,
-                       bool is_first,
                        bool is_last,
                        int *first_page_number,
                        int *first_performance_number)
 {
+  int page_nb = 0;
   if (scm_is_pair (performances_))
     {
       SCM proc = ly_lily_module_constant ("write-performances-midis");
@@ -128,44 +140,53 @@ Paper_book::output_aux (SCM output_channel,
 
   if (scm_is_pair (bookparts_))
     {
-      bool is_first_part = is_first;
-      for (SCM p = scm_reverse (bookparts_); scm_is_pair (p); p = scm_cdr (p))
+      for (SCM p = bookparts_; scm_is_pair (p); p = scm_cdr (p))
        if (Paper_book *pbookpart = unsmob_paper_book (scm_car (p)))
          {
            bool is_last_part = (is_last && !scm_is_pair (scm_cdr (p)));
-           pbookpart->output_aux (output_channel,
-                                  is_first_part,
-                                  is_last_part,
-                                  first_page_number,
-                                  first_performance_number);
-           is_first_part = false;
+           page_nb += pbookpart->output_aux (output_channel,
+                                             is_last_part,
+                                             first_page_number,
+                                             first_performance_number);
          }
     }
   else
     {
       if (scores_ == SCM_EOL)
-       return;
-      paper_->set_variable (ly_symbol2scm ("part-first-page-number"),
+       return 0;
+      paper_->set_variable (ly_symbol2scm ("first-page-number"),
                            scm_long2num (*first_page_number));
-      paper_->set_variable (ly_symbol2scm ("part-is-first"),
-                           ly_bool2scm (is_first));
-      paper_->set_variable (ly_symbol2scm ("part-is-last"),
+      paper_->set_variable (ly_symbol2scm ("is-last-bookpart"),
                            ly_bool2scm (is_last));
       /* Generate all stencils to trigger font loads.  */
-      *first_page_number += scm_ilength (pages ());
+      page_nb = scm_ilength (pages ());
+      *first_page_number += page_nb;
     }
+  return page_nb;
 }
 
 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;
-  output_aux (output_channel,
-             true,
-             true,
-             &first_page_number,
-             &first_performance_number);
+
+  /* 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_))
@@ -177,25 +198,40 @@ Paper_book::output (SCM output_channel)
 
   if (get_program_option ("print-pages"))
     {
-      SCM func = scm_c_module_lookup (mod, "output-framework");
-
-      func = scm_variable_ref (func);
-      scm_apply_0 (func, scm_list_n (output_channel,
-                                    self_scm (),
-                                    scopes,
-                                    dump_fields (),
-                                    SCM_UNDEFINED));
+      SCM framework = ly_module_lookup (mod,
+                                       ly_symbol2scm ("output-framework"));
+
+      if (framework != SCM_BOOL_F)
+       {
+         SCM func = scm_variable_ref (framework);
+         scm_apply_0 (func, scm_list_n (output_channel,
+                                        self_scm (),
+                                        scopes,
+                                        dump_fields (),
+                                        SCM_UNDEFINED));
+       }
+      else
+       warning (_f ("program option -dprint-pages not supported by backend `%s'",
+                    get_output_backend_name ()));
     }
 
   if (get_program_option ("preview"))
     {
-      SCM func = scm_c_module_lookup (mod, "output-preview-framework");
-      func = scm_variable_ref (func);
-      scm_apply_0 (func, scm_list_n (output_channel,
-                                    self_scm (),
-                                    scopes,
-                                    dump_fields (),
-                                    SCM_UNDEFINED));
+      SCM framework
+       = ly_module_lookup (mod, ly_symbol2scm ("output-preview-framework"));
+
+      if (framework != SCM_BOOL_F)
+       {
+         SCM func = scm_variable_ref (framework);
+         scm_apply_0 (func, scm_list_n (output_channel,
+                                        self_scm (),
+                                        scopes,
+                                        dump_fields (),
+                                        SCM_UNDEFINED));
+       }
+      else
+       warning (_f ("program option -dpreview not supported by backend `%s'",
+                    get_output_backend_name ()));
     }
 }
 
@@ -304,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);
        }
@@ -339,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);
        }
     }
 }
@@ -347,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)));
@@ -380,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);
 
@@ -395,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 ();
     }
@@ -481,23 +521,21 @@ Paper_book::get_system_specs ()
              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"));
+
              paper_system_set_stencil (ps, *unsmob_stencil (t));
-             ps->set_property ("is-title", SCM_BOOL_T); 
-             if (scm_is_pair (scm_cdr (list)))
-               {
-                 /* 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));
-               }
+             ps->set_property ("is-title", SCM_BOOL_T);
+             if (list != texts)
+               /* For each markup other than the first, place it as closely as
+                  possible to the previous markup and don't allow 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);
@@ -524,18 +562,22 @@ Paper_book::systems ()
   systems_ = SCM_EOL;
   if (scm_is_pair (bookparts_))
     {
-      for (SCM p = scm_reverse (bookparts_); scm_is_pair (p); p = scm_cdr (p))
+      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_));
            }
@@ -553,7 +595,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")))
@@ -584,14 +626,17 @@ Paper_book::pages ()
   pages_ = SCM_EOL;
   if (scm_is_pair (bookparts_))
     {
-      for (SCM p = scm_reverse (bookparts_); scm_is_pair (p); p = scm_cdr (p))
+      for (SCM p = bookparts_; scm_is_pair (p); p = scm_cdr (p))
        if (Paper_book *pbookpart = unsmob_paper_book (scm_car (p)))
          pages_ = scm_append_x (scm_list_2 (pages_, pbookpart->pages ()));
     }
-  else
+  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)