X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fpaper-book.cc;h=6c5c02dabb61fcd52fa9f6980b84c970d1f284b7;hb=a2e0081b9f6263a3ddb8e7bf898f6592dad5f89e;hp=04759a3b1c3c8ae9ddd7666a4d5f4ddf80e63fd4;hpb=1c5b28defa29c019a3d2038bf4b19ed215ec2d87;p=lilypond.git diff --git a/lily/paper-book.cc b/lily/paper-book.cc index 04759a3b1c..6c5c02dabb 100644 --- a/lily/paper-book.cc +++ b/lily/paper-book.cc @@ -18,6 +18,12 @@ #include "warn.hh" +/* + Ugh. the Function of the Paper_book class is unclear. Trim this + file. + + */ + // JUNKME SCM stencil2line (Stencil stil, bool is_title = false) @@ -37,6 +43,8 @@ stencil2line (Stencil stil, bool is_title = false) Paper_book::Paper_book () { + pages_ = SCM_EOL; + lines_ = SCM_EOL; copyright_ = SCM_EOL; tagline_ = SCM_EOL; header_ = SCM_EOL; @@ -66,6 +74,8 @@ Paper_book::mark_smob (SCM smob) if (b->bookpaper_) scm_gc_mark (b->bookpaper_->self_scm ()); scm_gc_mark (b->header_); + scm_gc_mark (b->pages_); + scm_gc_mark (b->lines_); return b->tagline_; } @@ -82,6 +92,40 @@ Paper_book::print_smob (SCM smob, SCM port, scm_print_state*) 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 () +{ + SCM fields = SCM_EOL; + for (int i = dump_header_fieldnames_global.size (); i--; ) + fields + = scm_cons (ly_symbol2scm (dump_header_fieldnames_global[i].to_str0 ()), + fields); + return fields; +} /* TODO: there is too much code dup, and the interface is not @@ -91,182 +135,233 @@ void Paper_book::output (String outname) { if (!score_lines_.size ()) - // FIXME: no end-output? return; /* Generate all stencils to trigger font loads. */ - SCM pages = this->pages (); + pages (); + + Array output_formats = split_string (output_format_global, ','); + + for (int i = 0; i < output_formats.size (); i++) + { + String format = output_formats[i]; + Paper_outputter *out = get_paper_outputter (outname + "." + output_formats[i], format); + + + + + 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 (), + self_scm (), + scopes, + dump_fields (), + scm_makfrom0str (outname.to_str0 ()), + SCM_UNDEFINED + )) ; + + scm_gc_unprotect_object (out->self_scm ()); + } +} + + +void +Paper_book::classic_output (String outname) +{ + + /* Generate all stencils to trigger font loads. */ + lines (); - Paper_outputter *out = get_paper_outputter (outname); - int page_count = scm_ilength (pages); + // ugh code dup SCM scopes = SCM_EOL; if (ly_c_module_p (header_)) scopes = scm_cons (header_, scopes); - - out->output_header (bookpaper_, scopes, page_count, false); - for (SCM s = pages; s != SCM_EOL; s = ly_cdr (s)) + if (ly_c_module_p (score_lines_[0].header_)) + scopes = scm_cons (score_lines_[0].header_, scopes); + //end ugh + + + Array output_formats = split_string (output_format_global, ','); + + for (int i = 0; i < output_formats.size (); i++) { - Page *p = unsmob_page (ly_car (s)); - progress_indication ("[" + to_string (p->number_)); - out->output_page (p, ly_cdr (s) == SCM_EOL); - progress_indication ("]"); + String format = output_formats[i]; + String func_nm = format; + func_nm = "output-classic-framework-" + func_nm; + + SCM func = ly_scheme_function (func_nm.to_str0 ()); + + Paper_outputter *out = get_paper_outputter (outname + "." + format, format); + + 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 ()); } - - out->output_scheme (scm_list_1 (ly_symbol2scm ("end-output"))); + progress_indication ("\n"); } -Stencil -Paper_book::title (int i) + + +LY_DEFINE(ly_paper_book_pages, "ly:paper-book-pages", + 1,0,0, + (SCM pb), + "Return pages in book PB.") { - SCM user_title = bookpaper_->lookup_variable (ly_symbol2scm ("user-title")); - SCM book_title = bookpaper_->lookup_variable (ly_symbol2scm ("book-title")); - SCM score_title = bookpaper_->lookup_variable (ly_symbol2scm ("score-title")); - SCM field = (i == 0 ? ly_symbol2scm ("bookTitle") - : ly_symbol2scm ("scoreTitle")); + 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 . +*/ +Stencil +Paper_book::book_title () +{ + SCM title_func = bookpaper_->lookup_variable (ly_symbol2scm ("book-title")); Stencil title; - // 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_[i].header_)) - scopes = scm_cons (score_lines_[i].header_, scopes); - //end ugh - - SCM s = ly_modules_lookup (scopes, field, SCM_BOOL_F); - if (s != SCM_BOOL_F) - title = *unsmob_stencil (scm_call_2 (user_title, - bookpaper_->self_scm (), - s)); - else - title = *unsmob_stencil (scm_call_2 (i == 0 ? book_title : score_title, - bookpaper_->self_scm (), - scopes)); + + SCM tit = SCM_EOL; + if (ly_c_procedure_p (title_func)) + tit = scm_call_2 (title_func, + bookpaper_->self_scm (), + scopes); + + if (unsmob_stencil (tit)) + title = *unsmob_stencil (tit); + if (!title.is_empty ()) title.align_to (Y_AXIS, UP); return title; } -void -Paper_book::classic_output (String outname) + + +Stencil +Paper_book::score_title (int i) { - Paper_outputter *out = get_paper_outputter (outname); + SCM title_func = bookpaper_->lookup_variable (ly_symbol2scm ("score-title")); - Output_def * p = bookpaper_; - while (p && p->parent_) - p = p->parent_; + Stencil title; // 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_lines_[i].header_)) + scopes = scm_cons (score_lines_[i].header_, scopes); //end ugh - - out->output_header (p, scopes, 0, true); - - SCM top_lines = score_lines_.top ().lines_; - Paper_line *first = unsmob_paper_line (scm_vector_ref (top_lines, - scm_int2num (0))); - Offset o (0, -0.5 * first->dim ()[Y_AXIS]); - int line_count = SCM_VECTOR_LENGTH (top_lines); - for (int i = 0; i < line_count; i++) - { - /* In classic compatibility TeX tracks how large things are, and - advances the Y pos for us. If we advance it too, we get too - much space. - FIXME: vague... why is TeX is different from other ouput - backends, why not fix the TeX backend? -- jcn */ - if (output_format_global == "tex") - o = Offset (0, 0); + SCM tit = SCM_EOL; + if (ly_c_procedure_p (title_func)) + tit =scm_call_2 (title_func, + bookpaper_->self_scm (), + scopes); - out->output_line (scm_vector_ref (top_lines, scm_int2num (i)), - &o, i == line_count - 1); - } + if (unsmob_stencil (tit)) + title = *unsmob_stencil (tit); + + + if (!title.is_empty ()) + title.align_to (Y_AXIS, UP); - out->output_scheme (scm_list_1 (ly_symbol2scm ("end-output"))); - progress_indication ("\n"); + return title; } -/* calculate book height, #lines, stencils. */ -void -Paper_book::init () + + +SCM +Paper_book::lines () { - int score_count = score_lines_.size (); + if (ly_c_pair_p (lines_)) + return lines_; - /* Calculate the full book height. Hmm, can't we cache system - heights while making stencils? */ - height_ = 0; + Stencil title = book_title (); + if (!title.is_empty ()) + lines_ = scm_cons (stencil2line (title, true), lines_); + + int score_count = score_lines_.size (); for (int i = 0; i < score_count; i++) { - Stencil title = this->title (i); + Stencil title = score_title (i); if (!title.is_empty ()) - height_ += title.extent (Y_AXIS).length (); + lines_ = scm_cons (stencil2line (title, true), lines_); - int line_count = SCM_VECTOR_LENGTH (score_lines_[i].lines_); - for (int j = 0; j < line_count; j++) - { - SCM s = scm_vector_ref ((SCM) score_lines_[i].lines_, scm_int2num (j)); - height_ += unsmob_paper_line (s)->dim ()[Y_AXIS]; - } + SCM line_list = scm_vector_to_list (score_lines_[i].lines_); // guh. + lines_ = scm_append (scm_list_2 (scm_reverse (line_list), lines_)); } - - Output_def *paper = bookpaper_; - SCM scopes = SCM_EOL; - if (ly_c_module_p (header_)) - scopes = scm_cons (header_, scopes); + lines_ = scm_reverse (lines_); - SCM make_tagline = paper->c_variable ("make-tagline"); - tagline_ = scm_call_2 (make_tagline, paper->self_scm (), scopes); - Real tag_height = 0; - if (Stencil *s = unsmob_stencil (tagline_)) - tag_height = s->extent (Y_AXIS).length (); - height_ += tag_height; + 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_copyright = paper->c_variable ("make-copyright"); - copyright_ = scm_call_2 (make_copyright, paper->self_scm (), scopes); - Real copy_height = 0; - if (Stencil *s = unsmob_stencil (copyright_)) - copy_height = s->extent (Y_AXIS).length (); - height_ += copy_height; + +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 -Paper_book::lines () +make_copyright (Output_def *paper, SCM scopes) { - int score_count = score_lines_.size (); - SCM lines = SCM_EOL; - for (int i = 0; i < score_count; i++) - { - Stencil title = this->title (i); - if (!title.is_empty ()) - lines = ly_snoc (stencil2line (title, true), lines); - lines = scm_append (scm_list_2 (lines, scm_vector_to_list (score_lines_[i].lines_))); - } - - //debug helper; ughr - 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_copyright = paper->c_variable ("make-copyright"); + SCM copyright = scm_call_2 (make_copyright, paper->self_scm (), scopes); + return copyright; } SCM Paper_book::pages () { - init (); - Page::page_count_ = 0; + if (ly_c_pair_p (pages_)) + return pages_; Output_def *paper = bookpaper_; Page *page = new Page (paper, 1); @@ -283,19 +378,27 @@ Paper_book::pages () SCM all = lines (); SCM proc = paper->c_variable ("page-breaking"); - SCM breaks = scm_apply_0 (proc, scm_list_n (all, scm_make_real (height_), + 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)); - /* Copyright on first page. */ - if (unsmob_stencil (copyright_)) - page->copyright_ = copyright_; - SCM pages = SCM_EOL; + /* + 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) @@ -312,27 +415,58 @@ Paper_book::pages () all = ly_cdr (all); line++; } - pages = scm_cons (page->self_scm (), pages); + if (i == page_count-1) + page->is_last_ = true; + + pages_ = scm_cons (page->self_scm (), pages_); } - /* Tagline on last page. */ - if (unsmob_stencil (tagline_)) - page->tagline_ = tagline_; - - return scm_reverse (pages); + pages_ = scm_reverse (pages_); + return pages_; } + + static SCM -c_ragged_page_breaks (SCM lines, Real book_height, Real text_height, +c_ragged_page_breaks (SCM lines, + Paper_book *book, + Real text_height, Real first, Real last) { int page_number = 0; - int page_count = int (book_height / text_height + 0.5); + + 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; s != SCM_EOL; s = ly_cdr (s)) + 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) @@ -356,14 +490,16 @@ 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 (ly_c_number_p (book), book, SCM_ARG2, __FUNCTION__, "real"); - SCM_ASSERT_TYPE (ly_c_number_p (text), text, SCM_ARG2, __FUNCTION__, "real"); - SCM_ASSERT_TYPE (ly_c_number_p (first), first, SCM_ARG2, __FUNCTION__, "real"); - SCM_ASSERT_TYPE (ly_c_number_p (last), last, SCM_ARG2, __FUNCTION__, "real"); + 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, - ly_scm2double (book), ly_scm2double (text), + return c_ragged_page_breaks (lines, b, + ly_scm2double (text), ly_scm2double (first), ly_scm2double (last)); }