X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fpaper-book.cc;h=4678ee3895b88d6f8b11bd1e200d213a5dafac8e;hb=90fcc649dc06ad006158945acc15a69e24e942cd;hp=069fca16fdffd7dda201455d363e075caeca071b;hpb=edbaa4793402ff05a4d3c2823b0cd36862e591c2;p=lilypond.git diff --git a/lily/paper-book.cc b/lily/paper-book.cc index 069fca16fd..4678ee3895 100644 --- a/lily/paper-book.cc +++ b/lily/paper-book.cc @@ -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--2011 Jan Nieuwenhuizen - (c) 2004--2007 Jan Nieuwenhuizen + 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 . */ #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,12 +120,13 @@ Paper_book::add_performance (SCM s) performances_ = scm_cons (s, performances_); } -void +int Paper_book::output_aux (SCM output_channel, 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"); @@ -121,44 +134,59 @@ 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_); } 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))) { bool is_last_part = (is_last && !scm_is_pair (scm_cdr (p))); - pbookpart->output_aux (output_channel, - is_last_part, - first_page_number, - first_performance_number); + page_nb += pbookpart->output_aux (output_channel, + is_last_part, + first_page_number, + first_performance_number); } } else { if (scores_ == SCM_EOL) - return; + 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. */ - *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, - &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_)) @@ -170,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 ())); } } @@ -202,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_); } @@ -297,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 (unsmob_music_output (sys))) + if (Paper_score *ps = dynamic_cast (unsmob_music_output (sys))) { - vector cols = ps->get_columns (); + vector cols = ps->get_columns (); if (cols.size ()) { - Paper_column *col = dynamic_cast (cols.back ()); + Paper_column *col = dynamic_cast (cols.back ()); col->set_property (symbol, permission); col->find_prebroken_piece (LEFT)->set_property (symbol, permission); } @@ -332,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); } } } @@ -340,16 +384,17 @@ set_system_penalty (SCM sys, SCM header) void set_labels (SCM sys, SCM labels) { - if (Paper_score *ps = dynamic_cast (unsmob_music_output (sys))) + if (Paper_score *ps = dynamic_cast (unsmob_music_output (sys))) { vector cols = ps->get_columns (); if (cols.size ()) { - Paper_column *col = dynamic_cast (cols[0]); + Paper_column *col = dynamic_cast (cols[0]); col->set_property ("labels", scm_append_x (scm_list_2 (col->get_property ("labels"), labels))); - Paper_column *col_right = dynamic_cast (col->find_prebroken_piece (RIGHT)); + Paper_column *col_right + = dynamic_cast (col->find_prebroken_piece (RIGHT)); col_right->set_property ("labels", scm_append_x (scm_list_2 (col_right->get_property ("labels"), labels))); @@ -373,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); @@ -388,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 (); } @@ -469,28 +516,31 @@ 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->set_property ("page-break-permission", ly_symbol2scm ("allow")); - ps->set_property ("page-turn-permission", ly_symbol2scm ("allow")); - + 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); - 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); @@ -499,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); @@ -517,18 +579,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 (unsmob_music_output (scm_car (s)))) + if (Paper_score *pscore + = dynamic_cast (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_)); } @@ -546,7 +612,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"))) @@ -577,14 +643,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)