X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fpaper-book.cc;h=95be368234106029c178a74ed3ae152e9a6e6823;hb=5225c5f57f7120683be517c7eea8e391c976004a;hp=48b0fe34f77ebc62d156c00d9da67e1a18db09b2;hpb=9be810ebcf226f2e5d7445f4e647f13aa0ac29e3;p=lilypond.git diff --git a/lily/paper-book.cc b/lily/paper-book.cc index 48b0fe34f7..95be368234 100644 --- a/lily/paper-book.cc +++ b/lily/paper-book.cc @@ -3,17 +3,21 @@ source file of the GNU LilyPond music typesetter - (c) 2004--2006 Jan Nieuwenhuizen + (c) 2004--2007 Jan Nieuwenhuizen */ #include "paper-book.hh" +#include "grob.hh" #include "main.hh" #include "output-def.hh" +#include "paper-column.hh" #include "paper-score.hh" #include "paper-system.hh" #include "text-interface.hh" #include "warn.hh" +#include "program-option.hh" +#include "page-marker.hh" #include "ly-smobs.icc" @@ -65,7 +69,7 @@ SCM dump_fields () { SCM fields = SCM_EOL; - for (int i = dump_header_fieldnames_global.size (); i--;) + for (vsize i = dump_header_fieldnames_global.size (); i--;) fields = scm_cons (ly_symbol2scm (dump_header_fieldnames_global[i].c_str ()), fields); @@ -89,9 +93,9 @@ Paper_book::output (SCM output_channel) { if (scm_is_pair (performances_)) { - SCM proc = ly_lily_module_constant ("paper-book-write-midis"); - - scm_call_2 (proc, self_scm (), output_channel); + SCM proc = ly_lily_module_constant ("write-performances-midis"); + + scm_call_2 (proc, performances (), output_channel); } if (scores_ == SCM_EOL) @@ -104,10 +108,11 @@ Paper_book::output (SCM output_channel) if (ly_is_module (header_)) scopes = scm_cons (header_, scopes); - String mod_nm = "scm framework-" + output_backend_global; + string mod_nm = "scm framework-" + get_output_backend_name (); SCM mod = scm_c_resolve_module (mod_nm.c_str ()); - if (make_print) + + if (get_program_option ("print-pages")) { SCM func = scm_c_module_lookup (mod, "output-framework"); @@ -119,7 +124,7 @@ Paper_book::output (SCM output_channel) SCM_UNDEFINED)); } - if (make_preview) + if (get_program_option ("preview")) { SCM func = scm_c_module_lookup (mod, "output-preview-framework"); func = scm_variable_ref (func); @@ -134,6 +139,13 @@ Paper_book::output (SCM output_channel) void Paper_book::classic_output (SCM output) { + if (scm_is_pair (performances_)) + { + SCM proc = ly_lily_module_constant ("write-performances-midis"); + + scm_call_2 (proc, performances (), output); + } + /* Generate all stencils to trigger font loads. */ systems (); @@ -144,8 +156,8 @@ Paper_book::classic_output (SCM output) if (ly_is_module (header_0_)) scopes = scm_cons (header_0_, scopes); - String format = output_backend_global; - String mod_nm = "scm framework-" + format; + string format = get_output_backend_name (); + string mod_nm = "scm framework-" + format; SCM mod = scm_c_resolve_module (mod_nm.c_str ()); SCM func = scm_c_module_lookup (mod, "output-classic-framework"); @@ -216,7 +228,28 @@ Paper_book::score_title (SCM header) } void -set_system_penalty (Prob *ps, SCM header) +set_page_permission (SCM sys, SCM symbol, SCM permission) +{ + if (Paper_score *ps = dynamic_cast (unsmob_music_output (sys))) + { + vector cols = ps->get_columns (); + if (cols.size ()) + { + Paper_column *col = dynamic_cast (cols.back ()); + col->set_property (symbol, permission); + col->find_prebroken_piece (LEFT)->set_property (symbol, permission); + } + } + else if (Prob *pb = unsmob_prob (sys)) + pb->set_property (symbol, permission); +} + +/* read the breakbefore property of a score block and set up the preceding + system-spec to honour it. That is, SYS should be the system spec that + immediately precedes the score (from which HEADER is taken) + in the get_system_specs () list */ +void +set_system_penalty (SCM sys, SCM header) { if (ly_is_module (header)) { @@ -224,16 +257,21 @@ set_system_penalty (Prob *ps, SCM header) if (SCM_VARIABLEP (force) && scm_is_bool (SCM_VARIABLE_REF (force))) { - ps->set_property ("penalty", - scm_from_int(to_boolean (SCM_VARIABLE_REF (force)) - ? -10000 - : 10000)); + if (to_boolean (SCM_VARIABLE_REF (force))) + { + set_page_permission (sys, ly_symbol2scm ("page-break-permission"), + ly_symbol2scm ("force")); + set_page_permission (sys, ly_symbol2scm ("line-break-permission"), + ly_symbol2scm ("force")); + } + else + set_page_permission (sys, ly_symbol2scm ("page-break-permission"), SCM_EOL); } } } -void -Paper_book::add_score_title (SCM header) +SCM +Paper_book::get_score_title (SCM header) { Stencil title = score_title (header); if (title.is_empty ()) @@ -247,30 +285,27 @@ Paper_book::add_score_title (SCM header) SCM props = paper_->lookup_variable (ly_symbol2scm ("score-title-properties")); Prob *ps = make_paper_system (props); paper_system_set_stencil (ps, title); - - systems_ = scm_cons (ps->self_scm (), systems_); - ps->unprotect (); - set_system_penalty (ps, header); + + return ps->self_scm (); } + + return SCM_BOOL_F; } + SCM -Paper_book::systems () +Paper_book::get_system_specs () { - if (systems_ != SCM_BOOL_F) - return systems_; - - systems_ = SCM_EOL; + SCM system_specs = SCM_EOL; + Stencil title = book_title (); - if (!title.is_empty ()) { SCM props = paper_->lookup_variable (ly_symbol2scm ("book-title-properties")); Prob *ps = make_paper_system (props); paper_system_set_stencil (ps, title); - set_system_penalty (ps, header_); - systems_ = scm_cons (ps->self_scm (), systems_); + system_specs = scm_cons (ps->self_scm (), system_specs); ps->unprotect (); } @@ -279,7 +314,7 @@ Paper_book::systems () paper_->self_scm ()); SCM header = SCM_EOL; - for (SCM s = scm_reverse (scores_); s != SCM_EOL; s = scm_cdr (s)) + for (SCM s = scm_reverse (scores_); scm_is_pair (s); s = scm_cdr (s)) { if (ly_is_module (scm_car (s))) { @@ -287,17 +322,31 @@ Paper_book::systems () if (header_0_ == SCM_EOL) header_0_ = header; } + else if (Page_marker *page_marker = unsmob_page_marker (scm_car (s))) + { + /* a page marker: set previous element page break or turn permission */ + if (scm_is_pair (system_specs)) + set_page_permission (scm_car (system_specs), + page_marker->permission_symbol (), + page_marker->permission_value ()); + } else if (Music_output *mop = unsmob_music_output (scm_car (s))) { if (Paper_score *pscore = dynamic_cast (mop)) { - add_score_title (header); + SCM title = get_score_title (header); - header = SCM_EOL; + if (scm_is_pair (system_specs)) + set_system_penalty (scm_car (system_specs), header); + + if (unsmob_prob (title)) + { + system_specs = scm_cons (title, system_specs); + unsmob_prob (title)->unprotect (); + } - 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_)); + header = SCM_EOL; + system_specs = scm_cons (pscore->self_scm (), system_specs); } else { @@ -306,18 +355,6 @@ Paper_book::systems () */ } } - else if (scm_is_vector (scm_car (s))) - { - /* - UGH. code dup. - */ - add_score_title (header); - header = SCM_EOL; - - SCM system_list = scm_vector_to_list (scm_car (s)); - system_list = scm_reverse (system_list); - systems_ = scm_append (scm_list_2 (system_list, systems_)); - } else if (Text_interface::is_markup (scm_car (s))) { SCM t = Text_interface::interpret_markup (paper_->self_scm (), @@ -326,9 +363,12 @@ Paper_book::systems () // 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")); + paper_system_set_stencil (ps, *unsmob_stencil (t)); ps->set_property ("is-title", SCM_BOOL_T); - systems_ = scm_cons (ps->self_scm (), systems_); + system_specs = scm_cons (ps->self_scm (), system_specs); ps->unprotect (); // FIXME: figure out penalty. @@ -338,11 +378,38 @@ Paper_book::systems () assert (0); } + system_specs = scm_reverse_x (system_specs, SCM_EOL); + return system_specs; +} + +SCM +Paper_book::systems () +{ + if (systems_ != SCM_BOOL_F) + return systems_; + + systems_ = SCM_EOL; + 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)))) + { + 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_)); + } + else + { + systems_ = scm_cons (scm_car (s), systems_); + } + } + systems_ = scm_reverse (systems_); + /* backwards compatibility for the old page breaker */ int i = 0; Prob *last = 0; - for (SCM s = systems_; s != SCM_EOL; s = scm_cdr (s)) + for (SCM s = systems_; scm_is_pair (s); s = scm_cdr (s)) { Prob *ps = unsmob_prob (scm_car (s)); ps->set_property ("number", scm_from_int (++i)); @@ -352,6 +419,16 @@ Paper_book::systems () && !scm_is_number (ps->get_property ("penalty"))) ps->set_property ("penalty", scm_from_int (10000)); last = ps; + + if (scm_is_pair (scm_cdr (s))) + { + SCM perm = ps->get_property ("page-break-permission"); + Prob *next = unsmob_prob (scm_cadr (s)); + if (perm == SCM_EOL) + next->set_property ("penalty", scm_from_int (10001)); + else if (perm == ly_symbol2scm ("force")) + next->set_property ("penalty", scm_from_int (-10001)); + } } return systems_; @@ -364,8 +441,22 @@ Paper_book::pages () return pages_; pages_ = SCM_EOL; - SCM proc = paper_->c_variable ("page-breaking"); - pages_ = scm_apply_0 (proc, scm_list_2 (systems (), self_scm ())); + SCM proc = paper_->c_variable ("page-breaking-wrapper"); + pages_ = scm_apply_0 (proc, scm_list_1 (self_scm ())); + + /* set systems_ from the pages */ + if (systems_ == SCM_BOOL_F) + { + systems_ = SCM_EOL; + for (SCM p = pages_; scm_is_pair (p); p = scm_cdr (p)) + { + Prob *page = unsmob_prob (scm_car (p)); + SCM systems = page->get_property ("lines"); + + systems_ = scm_append (scm_list_2 (systems_, systems)); + } + } + return pages_; }