X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;ds=sidebyside;f=lily%2Fpaper-book.cc;h=c2b4b34fdc661e25274e33a8fb84f8dae2fb1d54;hb=015bb3813eb4ac879df0561e5c6e28e9d1146792;hp=9683445fffd2fb028581b4cfdef21d59eea16b69;hpb=c2d7bd9507fb36d3f7da86653e3fb0b905ec2bc1;p=lilypond.git diff --git a/lily/paper-book.cc b/lily/paper-book.cc index 9683445fff..c2b4b34fdc 100644 --- a/lily/paper-book.cc +++ b/lily/paper-book.cc @@ -3,37 +3,26 @@ source file of the GNU LilyPond music typesetter - (c) 2004 Jan Nieuwenhuizen + (c) 2004--2005 Jan Nieuwenhuizen */ -#include "ly-module.hh" -#include "main.hh" -#include "page.hh" #include "paper-book.hh" + +#include "main.hh" #include "output-def.hh" -#include "paper-outputter.hh" -#include "paper-line.hh" #include "paper-score.hh" -#include "stencil.hh" +#include "paper-system.hh" #include "warn.hh" - -/* - Ugh. the Function of the Paper_book class is unclear. Trim this - file. - - */ - +#include "ly-smobs.icc" Paper_book::Paper_book () { - pages_ = SCM_EOL; - lines_ = SCM_EOL; - copyright_ = SCM_EOL; - tagline_ = SCM_EOL; + pages_ = SCM_BOOL_F; + systems_ = SCM_BOOL_F; header_ = SCM_EOL; - bookpaper_ = 0; + paper_ = 0; smobify_self (); } @@ -41,8 +30,6 @@ Paper_book::~Paper_book () { } -#include "ly-smobs.icc" - IMPLEMENT_DEFAULT_EQUAL_P (Paper_book); IMPLEMENT_SMOBS (Paper_book) IMPLEMENT_TYPE_P (Paper_book, "ly:paper-book?") @@ -51,55 +38,28 @@ SCM Paper_book::mark_smob (SCM smob) { Paper_book *b = (Paper_book*) SCM_CELL_WORD_1 (smob); - for (int i = 0; i < b->score_lines_.size (); i++) - b->score_lines_[i].gc_mark (); + for (int i = 0; i < b->score_systems_.size (); i++) + b->score_systems_[i].gc_mark (); - scm_gc_mark (b->copyright_); - if (b->bookpaper_) - scm_gc_mark (b->bookpaper_->self_scm ()); + if (b->paper_) + scm_gc_mark (b->paper_->self_scm ()); scm_gc_mark (b->header_); scm_gc_mark (b->pages_); - scm_gc_mark (b->lines_); - return b->tagline_; + return b->systems_; } int Paper_book::print_smob (SCM smob, SCM port, scm_print_state*) { - Paper_book *b = (Paper_book*) ly_cdr (smob); + Paper_book *b = (Paper_book*) SCM_CELL_WORD_1 (smob); scm_puts ("#<", port); scm_puts (classname (b), port); scm_puts (" ", port); - //scm_puts (b->, port); scm_puts (">", port); return 1; } -Array -split_string (String s, char c) -{ - Array rv; - while (s.length ()) - { - int i = s.index (c); - - if (i == 0) - { - s = s.nomid_string (0, 1); - continue; - } - - if (i < 0) - i = s.length () ; - - rv.push (s.cut_string (0, i)); - s = s.nomid_string (0, i); - } - - return rv; -} - SCM dump_fields () { @@ -111,132 +71,85 @@ dump_fields () return fields; } -/* - TODO: there is too much code dup, and the interface is not - clear. FIXME. - */ void Paper_book::output (String outname) { - if (!score_lines_.size ()) + if (!score_systems_.size ()) return; - + /* Generate all stencils to trigger font loads. */ pages (); + + SCM scopes = SCM_EOL; + if (ly_c_module_p (header_)) + scopes = scm_cons (header_, scopes); + + String mod_nm = "scm framework-" + output_backend_global; - Array output_formats = split_string (output_format_global, ','); - - for (int i = 0; i < output_formats.size (); i++) + SCM mod = scm_c_resolve_module (mod_nm.to_str0 ()); + if (make_pages) { - String format = output_formats[i]; - Paper_outputter *out = get_paper_outputter (outname + "." + output_formats[i], format); - - + SCM func = scm_c_module_lookup (mod, "output-framework"); - - SCM scopes = SCM_EOL; - if (ly_c_module_p (header_)) - scopes = scm_cons (header_, scopes); - - String func_nm = format; - func_nm = "output-framework-" + func_nm; - - SCM func = ly_scheme_function (func_nm.to_str0 ()); - scm_apply_0 (func, scm_list_n (out->self_scm (), + func = scm_variable_ref (func); + scm_apply_0 (func, scm_list_n (scm_makfrom0str (outname.to_str0 ()), self_scm (), scopes, dump_fields (), - scm_makfrom0str (outname.to_str0 ()), - SCM_UNDEFINED - )) ; - - scm_gc_unprotect_object (out->self_scm ()); + SCM_UNDEFINED)); } + + if (make_preview) + { + SCM func = scm_c_module_lookup (mod, "output-preview-framework"); + func = scm_variable_ref (func); + scm_apply_0 (func, scm_list_n (scm_makfrom0str (outname.to_str0 ()), + self_scm (), + scopes, + dump_fields (), + SCM_UNDEFINED)); + } + progress_indication ("\n"); } - void Paper_book::classic_output (String outname) { - /* Generate all stencils to trigger font loads. */ - lines (); - + systems (); // ugh code dup SCM scopes = SCM_EOL; if (ly_c_module_p (header_)) scopes = scm_cons (header_, scopes); - if (ly_c_module_p (score_lines_[0].header_)) - scopes = scm_cons (score_lines_[0].header_, scopes); + if (ly_c_module_p (score_systems_[0].header_)) + scopes = scm_cons (score_systems_[0].header_, scopes); //end ugh - - Array output_formats = split_string (output_format_global, ','); - - for (int i = 0; i < output_formats.size (); i++) - { - String format = output_formats[i]; - String func_nm = format; - func_nm = "output-classic-framework-" + func_nm; + String format = output_backend_global; + String mod_nm = "scm framework-" + format; - SCM func = ly_scheme_function (func_nm.to_str0 ()); + SCM mod = scm_c_resolve_module (mod_nm.to_str0 ()); + SCM func = scm_c_module_lookup (mod, "output-classic-framework"); + - Paper_outputter *out = get_paper_outputter (outname + "." + format, format); + func = scm_variable_ref (func); + scm_apply_0 (func, scm_list_n (scm_makfrom0str (outname.to_str0 ()), + self_scm (), + scopes, + dump_fields (), + SCM_UNDEFINED)); - scm_apply_0 (func, scm_list_n (out->self_scm (), - self_scm (), - scopes, - dump_fields (), - scm_makfrom0str (outname.to_str0 ()), - SCM_UNDEFINED - )) ; - - scm_gc_unprotect_object (out->self_scm ()); - } - progress_indication ("\n"); } - - -LY_DEFINE(ly_paper_book_pages, "ly:paper-book-pages", - 1,0,0, - (SCM pb), - "Return pages in book PB.") -{ - return unsmob_paper_book(pb)->pages (); -} - - -LY_DEFINE(ly_paper_book_lines, "ly:paper-book-lines", - 1,0,0, - (SCM pb), - "Return lines in book PB.") -{ - return unsmob_paper_book (pb)->lines (); -} - - -LY_DEFINE(ly_paper_book_book_paper, "ly:paper-book-book-paper", - 1,0,0, - (SCM pb), - "Return pages in book PB.") -{ - return unsmob_paper_book(pb)->bookpaper_->self_scm (); -} - -/* - -TODO: resurrect more complex user-tweaks for titling . - -*/ +/* TODO: resurrect more complex user-tweaks for titling? */ Stencil Paper_book::book_title () { - SCM title_func = bookpaper_->lookup_variable (ly_symbol2scm ("book-title")); + SCM title_func = paper_->lookup_variable (ly_symbol2scm ("book-title")); Stencil title; SCM scopes = SCM_EOL; @@ -247,7 +160,7 @@ Paper_book::book_title () SCM tit = SCM_EOL; if (ly_c_procedure_p (title_func)) tit = scm_call_2 (title_func, - bookpaper_->self_scm (), + paper_->self_scm (), scopes); if (unsmob_stencil (tit)) @@ -259,12 +172,10 @@ Paper_book::book_title () return title; } - - Stencil Paper_book::score_title (int i) { - SCM title_func = bookpaper_->lookup_variable (ly_symbol2scm ("score-title")); + SCM title_func = paper_->lookup_variable (ly_symbol2scm ("score-title")); Stencil title; @@ -273,244 +184,127 @@ Paper_book::score_title (int i) if (ly_c_module_p (header_)) scopes = scm_cons (header_, scopes); - if (ly_c_module_p (score_lines_[i].header_)) - scopes = scm_cons (score_lines_[i].header_, scopes); + if (ly_c_module_p (score_systems_[i].header_)) + scopes = scm_cons (score_systems_[i].header_, scopes); //end ugh SCM tit = SCM_EOL; if (ly_c_procedure_p (title_func)) - tit =scm_call_2 (title_func, - bookpaper_->self_scm (), + tit = scm_call_2 (title_func, + paper_->self_scm (), scopes); if (unsmob_stencil (tit)) title = *unsmob_stencil (tit); - if (!title.is_empty ()) title.align_to (Y_AXIS, UP); return title; } - - +void +set_system_penalty (Paper_system * ps, SCM header) +{ + if (ly_c_module_p (header)) + { + SCM force = ly_module_lookup (header, ly_symbol2scm ("breakbefore")); + if (SCM_VARIABLEP(force) + && scm_is_bool (SCM_VARIABLE_REF(force))) + { + ps->break_before_penalty_ = to_boolean (SCM_VARIABLE_REF(force)) + ? -10000 + : 10000; + } + } +} + SCM -Paper_book::lines () +Paper_book::systems () { - if (ly_c_pair_p (lines_)) - return lines_; + if (systems_ != SCM_BOOL_F) + return systems_; + + systems_ = SCM_EOL; + Stencil title = book_title (); - Stencil title = book_title (); if (!title.is_empty ()) { - Paper_line *pl = new Paper_line (title, -10001, true); + Paper_system *ps = new Paper_system (title, true); + set_system_penalty (ps, header_); - lines_ = scm_cons (pl->self_scm (), lines_); - scm_gc_unprotect_object (pl->self_scm ()); + systems_ = scm_cons (ps->self_scm (), systems_); + scm_gc_unprotect_object (ps->self_scm ()); } - int score_count = score_lines_.size (); + int score_count = score_systems_.size (); for (int i = 0; i < score_count; i++) { Stencil title = score_title (i); if (!title.is_empty ()) { - Paper_line *pl = new Paper_line (title, -10001, true); - lines_ = scm_cons (pl->self_scm (), lines_); - scm_gc_unprotect_object (pl->self_scm ()); + Paper_system *ps = new Paper_system (title, true); + systems_ = scm_cons (ps->self_scm (), systems_); + scm_gc_unprotect_object (ps->self_scm ()); + + set_system_penalty (ps, score_systems_[i].header_); + } - if (scm_vector_p (score_lines_[i].lines_) == SCM_BOOL_T) + if (scm_vector_p (score_systems_[i].systems_) == SCM_BOOL_T) { - SCM line_list = scm_vector_to_list (score_lines_[i].lines_); // guh. - lines_ = scm_append (scm_list_2 (scm_reverse (line_list), lines_)); + // guh. + SCM system_list = scm_vector_to_list (score_systems_[i].systems_); + + system_list = scm_reverse (system_list); + systems_ = scm_append (scm_list_2 (system_list, systems_)); } } - lines_ = scm_reverse (lines_); - + systems_ = scm_reverse (systems_); + int i = 0; - for (SCM s = lines_; s != SCM_EOL; s = ly_cdr (s)) - unsmob_paper_line (ly_car (s))->number_ = ++i; - return lines_; -} - - -SCM -make_tagline (Output_def*paper, SCM scopes) -{ - SCM make_tagline = paper->c_variable ("make-tagline"); - SCM tagline = scm_call_2 (make_tagline, paper->self_scm (), scopes); - return tagline; -} - -SCM -make_copyright (Output_def *paper, SCM scopes) -{ - SCM make_copyright = paper->c_variable ("make-copyright"); - SCM copyright = scm_call_2 (make_copyright, paper->self_scm (), scopes); - return copyright; + Paper_system *last = 0; + for (SCM s = systems_; s != SCM_EOL; s = scm_cdr (s)) + { + Paper_system *ps = unsmob_paper_system (scm_car (s)); + ps->number_ = ++i; + + if (last + && last->is_title () + && !ps->break_before_penalty_) + ps->break_before_penalty_ = 10000; + last = ps; + } + + return systems_; } SCM Paper_book::pages () { - if (ly_c_pair_p (pages_)) + if (SCM_BOOL_F != pages_) return pages_; - Output_def *paper = bookpaper_; - Page *page = new Page (paper, 1); - - Real text_height = page->text_height (); - - Real copy_height = 0; - if (Stencil *s = unsmob_stencil (copyright_)) - copy_height = s->extent (Y_AXIS).length (); - - Real tag_height = 0; - if (Stencil *s = unsmob_stencil (tagline_)) - tag_height = s->extent (Y_AXIS).length (); - - SCM all = lines (); - SCM proc = paper->c_variable ("page-breaking"); - SCM breaks = scm_apply_0 (proc, scm_list_n (all, - self_scm (), - scm_make_real (text_height), - scm_make_real (-copy_height), - scm_make_real (-tag_height), - SCM_UNDEFINED)); - - - /* - UGH - move this out of C++. - */ - SCM scopes = SCM_EOL; - if (ly_c_module_p (header_)) - scopes = scm_cons (header_, scopes); - - tagline_ = make_tagline (bookpaper_, scopes); - copyright_ = make_tagline (bookpaper_, scopes); - - int page_count = SCM_VECTOR_LENGTH ((SCM) breaks); - int line = 1; - - for (int i = 0; i < page_count; i++) - { - if (i) - page = new Page (paper, i + 1); - - int next = i + 1 < page_count - ? ly_scm2int (scm_vector_ref (breaks, scm_int2num (i))) : 0; - while ((!next && all != SCM_EOL) || line <= next) - { - SCM s = ly_car (all); - page->lines_ = ly_snoc (s, page->lines_); - page->height_ += unsmob_paper_line (s)->dim ()[Y_AXIS]; - page->line_count_++; - all = ly_cdr (all); - line++; - } - if (i == page_count-1) - page->is_last_ = true; - - pages_ = scm_cons (page->self_scm (), pages_); - } - - pages_ = scm_reverse (pages_); + pages_ = SCM_EOL; + SCM proc = paper_->c_variable ("page-breaking"); + pages_ = scm_apply_0 (proc, scm_list_2 (systems (), self_scm ())); return pages_; } - -static SCM -c_ragged_page_breaks (SCM lines, - Paper_book *book, - Real text_height, - Real first, Real last) -{ - int page_number = 0; - - Real book_height =0.; - for (SCM s = lines ; ly_c_pair_p (s); s = ly_cdr (s)) - { - book_height += unsmob_paper_line (ly_car (s))->dim ()[Y_AXIS]; - } - - /* - UGH. following stuff should go out of C++. - */ - SCM scopes = SCM_EOL; - if (ly_c_module_p (book->header_)) - scopes = scm_cons (book->header_, scopes); - - - SCM tag = make_tagline (book->bookpaper_, scopes); - if (unsmob_stencil (tag)) - { - book_height += unsmob_stencil (tag)->extent (Y_AXIS).length (); - } - - SCM cr = make_copyright (book->bookpaper_, scopes); - if (unsmob_stencil (cr)) - { - book_height += unsmob_stencil (cr)->extent (Y_AXIS).length (); - } - - int page_count = int (book_height / text_height + 0.5); // ceil? - SCM breaks = SCM_EOL; - Real page_height = text_height + first; - Real h = 0; - int number = 0; - for (SCM s = lines; ly_c_pair_p (s); s = ly_cdr (s)) - { - Paper_line *pl = unsmob_paper_line (ly_car (s)); - if (!pl->is_title () && h < page_height) - number++; - h += pl->dim ()[Y_AXIS]; - if (!pl->is_title () && h > page_height) - { - breaks = ly_snoc (scm_int2num (number), breaks); - page_number++; - page_height = text_height + (page_number == page_count) * last; - h = 0; - } - if (ly_cdr (s) == SCM_EOL) - breaks = ly_snoc (scm_int2num (pl->number_), breaks); - } - - return scm_vector (breaks); -} - -LY_DEFINE (ly_ragged_page_breaks, "ly:ragged-page-breaks", - 5, 0, 0, (SCM lines, SCM book, SCM text, SCM first, SCM last), - "Return a vector with line numbers of page breaks.") -{ - Paper_book* b = unsmob_paper_book (book); - - SCM_ASSERT_TYPE (scm_pair_p (lines), lines, SCM_ARG1, __FUNCTION__, "list"); - SCM_ASSERT_TYPE (b, book, SCM_ARG2, __FUNCTION__, "Paper_book"); - SCM_ASSERT_TYPE (ly_c_number_p (text), text, SCM_ARG3, __FUNCTION__, "number"); - SCM_ASSERT_TYPE (ly_c_number_p (first), first, SCM_ARG4, __FUNCTION__, "number"); - SCM_ASSERT_TYPE (ly_c_number_p (last), last, SCM_ARG5, __FUNCTION__, "number"); - - return c_ragged_page_breaks (lines, b, - ly_scm2double (text), - ly_scm2double (first), ly_scm2double (last)); -} - /****************************************************************/ -Score_lines::Score_lines () +Score_systems::Score_systems () { - lines_ = SCM_EOL; + systems_ = SCM_EOL; header_ = SCM_EOL; } void -Score_lines::gc_mark () +Score_systems::gc_mark () { - scm_gc_mark (lines_); + scm_gc_mark (systems_); scm_gc_mark (header_); }