X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fbook.cc;h=96243e1b954647127c7dc50d4bd51ed1293618cb;hb=c6554467b0a9beddf0d7ef12746ae31a25fe36e7;hp=7400270e7b6ef154a6052f3c0d0005d69b7cd67d;hpb=da66c77772050eccbb972538c2cf9f6ec76018b4;p=lilypond.git diff --git a/lily/book.cc b/lily/book.cc index 7400270e7b..96243e1b95 100644 --- a/lily/book.cc +++ b/lily/book.cc @@ -3,52 +3,86 @@ source file of the GNU LilyPond music typesetter - (c) 1997--2004 Han-Wen Nienhuys + (c) 1997--2007 Han-Wen Nienhuys */ -#include +#include "book.hh" -#include "ly-smobs.icc" +#include +using namespace std; -#include "book.hh" -#include "global-context.hh" -#include "ly-module.hh" #include "main.hh" -#include "music-iterator.hh" -#include "music-output-def.hh" -#include "music-output.hh" #include "music.hh" -#include "page.hh" +#include "output-def.hh" #include "paper-book.hh" -#include "paper-def.hh" #include "score.hh" +#include "text-interface.hh" #include "warn.hh" +#include "performance.hh" +#include "paper-score.hh" +#include "page-marker.hh" + +#include "ly-smobs.icc" Book::Book () - : Input () { + paper_ = 0; header_ = SCM_EOL; + scores_ = SCM_EOL; + bookparts_ = SCM_EOL; + input_location_ = SCM_EOL; smobify_self (); + + input_location_ = make_input (Input ()); } -#if 0 -Book::Book (Book const &src) - : Input (src) +Book::Book (Book const &s) { + paper_ = 0; header_ = SCM_EOL; + scores_ = SCM_EOL; + bookparts_ = SCM_EOL; + input_location_ = SCM_EOL; smobify_self (); - int score_count = src.scores_.size (); - for (int i = 0; i < score_count; i++) - scores_.push (src.scores_[i]->clone ()); + if (s.paper_) + { + paper_ = s.paper_->clone (); + paper_->unprotect (); + } + + input_location_ = make_input (*s.origin ()); -#if 0 - header_ = ly_make_anonymous_module (); - if (is_module (src.header_)) - ly_import_module (header_, src.header_); -#endif + header_ = ly_make_anonymous_module (false); + if (ly_is_module (s.header_)) + ly_module_copy (header_, s.header_); + + SCM *t = &scores_; + for (SCM p = s.scores_; scm_is_pair (p); p = scm_cdr (p)) + { + Score *newscore = unsmob_score (scm_car (p))->clone (); + + *t = scm_cons (newscore->self_scm (), SCM_EOL); + t = SCM_CDRLOC (*t); + newscore->unprotect (); + } + + t = &bookparts_; + for (SCM p = s.bookparts_; scm_is_pair (p); p = scm_cdr (p)) + { + Book *newpart = unsmob_book (scm_car (p))->clone (); + + *t = scm_cons (newpart->self_scm (), SCM_EOL); + t = SCM_CDRLOC (*t); + newpart->unprotect (); + } +} + +Input * +Book::origin () const +{ + return unsmob_input (input_location_); } -#endif Book::~Book () { @@ -60,10 +94,14 @@ IMPLEMENT_DEFAULT_EQUAL_P (Book); SCM Book::mark_smob (SCM s) { - Book *book = (Book*) SCM_CELL_WORD_1 (s); - int score_count = book->scores_.size (); - for (int i = 0; i < score_count; i++) - scm_gc_mark (book->scores_[i]->self_scm ()); + Book *book = (Book *) SCM_CELL_WORD_1 (s); + + if (book->paper_) + scm_gc_mark (book->paper_->self_scm ()); + scm_gc_mark (book->scores_); + scm_gc_mark (book->bookparts_); + scm_gc_mark (book->input_location_); + return book->header_; } @@ -75,52 +113,171 @@ Book::print_smob (SCM, SCM p, scm_print_state*) } void -Book::process (String outname, Music_output_def *default_def, SCM header) +Book::add_score (SCM s) { - Paper_book *paper_book = new Paper_book (); - int score_count = scores_.size (); - for (int i = 0; i < score_count; i++) + scores_ = scm_cons (s, scores_); +} + +void +Book::set_parent (Book *parent) +{ + if (!paper_) + { + paper_ = new Output_def (); + paper_->unprotect (); + } + paper_->parent_ = parent->paper_; + /* If this part is the first child of parent, copy its header */ + if (ly_is_module (parent->header_) && (scm_is_null (parent->bookparts_))) + { + SCM tmp_header = ly_make_anonymous_module (false); + ly_module_copy (tmp_header, parent->header_); + if (ly_is_module (header_)) + ly_module_copy (tmp_header, header_); + header_ = tmp_header; + } +} + +/* Before an explicit \bookpart is encountered, scores are added to the book. + * But once a bookpart is added, the previous scores shall be collected into + * a new bookpart. + */ +void +Book::add_scores_to_bookpart () +{ + if (scm_is_pair (scores_)) + { + /* If scores have been added to this book, add them to a child + * book part */ + Book *part = new Book; + part->set_parent (this); + part->scores_ = scores_; + bookparts_ = scm_cons (part->self_scm (), bookparts_); + part->unprotect (); + scores_ = SCM_EOL; + } +} + +void +Book::add_bookpart (SCM b) +{ + add_scores_to_bookpart (); + Book *part = unsmob_book (b); + part->set_parent (this); + bookparts_ = scm_cons (b, bookparts_); +} + +bool +Book::error_found () +{ + for (SCM s = scores_; scm_is_pair (s); s = scm_cdr (s)) + if (Score *score = unsmob_score (scm_car (s))) + if (score->error_found_) + return true; + + for (SCM part = bookparts_; scm_is_pair (part); part = scm_cdr (part)) + if (Book *bookpart = unsmob_book (scm_car (part))) + if (bookpart->error_found ()) + return true; + + return false; +} + +Paper_book * +Book::process (Output_def *default_paper, + Output_def *default_layout) +{ + return process (default_paper, default_layout, 0); +} + +void +Book::process_bookparts (Paper_book *output_paper_book, Output_def *paper, Output_def *layout) +{ + add_scores_to_bookpart (); + for (SCM p = scm_reverse (bookparts_); scm_is_pair (p); p = scm_cdr (p)) { - Paper_def *paper = 0; - SCM systems = scores_[i]->book_rendering (outname, default_def, &paper); - if (systems != SCM_UNDEFINED) + if (Book *book = unsmob_book (scm_car (p))) + { + Paper_book *paper_book_part = book->process (paper, layout, output_paper_book); + if (paper_book_part) + output_paper_book->add_bookpart (paper_book_part->self_scm ()); + } + } +} + +void +Book::process_score (SCM s, Paper_book *output_paper_book, Output_def *layout) +{ + if (Score *score = unsmob_score (scm_car (s))) + { + SCM outputs = score + ->book_rendering (output_paper_book->paper_, layout); + + while (scm_is_pair (outputs)) { - if (paper) - paper_book->papers_.push (paper); - paper_book->scores_.push (systems); - - // fixme. - //paper_book->global_headers_.push (global_input_file->header_); - //paper_book->headers_.push (scores_[i]->header_); - paper_book->headers_.push (header); + Music_output *output = unsmob_music_output (scm_car (outputs)); + + if (Performance *perf = dynamic_cast (output)) + output_paper_book->add_performance (perf->self_scm ()); + else if (Paper_score *pscore = dynamic_cast (output)) + { + if (ly_is_module (score->get_header ())) + output_paper_book->add_score (score->get_header ()); + output_paper_book->add_score (pscore->self_scm ()); + } + + outputs = scm_cdr (outputs); } } - paper_book->output (outname); - scm_gc_unprotect_object (paper_book->self_scm ()); + else if (Text_interface::is_markup_list (scm_car (s)) + || unsmob_page_marker (scm_car (s))) + output_paper_book->add_score (scm_car (s)); + else + assert (0); + } -/* FIXME: WIP, this is a hack. Return first page as stencil. */ -SCM -Book::to_stencil (Music_output_def *default_def, SCM header) +/* Concatenate all score or book part outputs into a Paper_book + */ +Paper_book * +Book::process (Output_def *default_paper, + Output_def *default_layout, + Paper_book *parent_part) { + Output_def *paper = paper_ ? paper_ : default_paper; + + /* If top book, recursively check score errors */ + if (!parent_part && error_found ()) + return 0; + + if (!paper) + return 0; + Paper_book *paper_book = new Paper_book (); - int score_count = scores_.size (); - for (int i = 0; i < score_count; i++) + Real scale = scm_to_double (paper->c_variable ("output-scale")); + Output_def *scaled_bookdef = scale_output_def (paper, scale); + paper_book->paper_ = scaled_bookdef; + if (parent_part) { - Paper_def *paper = 0; - SCM systems = scores_[i]->book_rendering ("", default_def, &paper); - if (systems != SCM_UNDEFINED) - { - if (paper) - paper_book->papers_.push (paper); - paper_book->scores_.push (systems); - paper_book->headers_.push (header); - } + paper_book->parent_ = parent_part; + paper_book->paper_->parent_ = parent_part->paper_; + } + paper_book->header_ = header_; + + if (scm_is_pair (bookparts_)) + { + /* Process children book parts */ + process_bookparts (paper_book, paper, default_layout); + } + else + { + /* Process scores */ + /* Render in order of parsing. */ + for (SCM s = scm_reverse (scores_); scm_is_pair (s); s = scm_cdr (s)) + { + process_score (s, paper_book, default_layout); + } } - SCM pages = paper_book->pages (); - scm_gc_unprotect_object (paper_book->self_scm ()); - if (pages != SCM_EOL) - return unsmob_page (ly_car (pages))->to_stencil (); - return SCM_EOL; + return paper_book; }