From 14ca3493aab1a1f4f837f1b483ad9ea1d1e444ad Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Sun, 9 May 2004 19:27:53 +0000 Subject: [PATCH] * lily/paper-outputter.cc (output_stencil): dump font definitions before each stencil. * lily/include/paper-book.hh (struct Score_lines): new struct. Collect info per Paper-score. * lily/include/page.hh (class Page): to_stencil() returns Stencil everywhere. * lily/stencil.cc (find_expression_fonts): new function * lily/paper-outputter.cc (output_stencil): use interpret_stencil_expr * lily/stencil.cc (LY_DEFINE): ly_stencil_fonts: new function. (interpret_stencil_expr): new function. Generic stencil interpretation. --- ChangeLog | 11 ++++ lily/book.cc | 29 ++++----- lily/include/page.hh | 2 +- lily/include/paper-book.hh | 19 ++++-- lily/include/paper-line.hh | 2 +- lily/include/paper-outputter.hh | 3 +- lily/include/stencil.hh | 5 +- lily/page.cc | 25 ++++---- lily/paper-book.cc | 104 ++++++++++++++++++-------------- lily/paper-line.cc | 6 +- lily/paper-outputter.cc | 29 ++++----- lily/score.cc | 10 ++- lily/stencil.cc | 34 ++++++----- 13 files changed, 162 insertions(+), 117 deletions(-) diff --git a/ChangeLog b/ChangeLog index c9d5bc1961..368d51d1ff 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,16 @@ 2004-05-09 Han-Wen Nienhuys + * lily/paper-outputter.cc (output_stencil): dump font definitions + before each stencil. + + * lily/include/paper-book.hh (struct Score_lines): new + struct. Collect info per Paper-score. + + * lily/include/page.hh (class Page): to_stencil() returns Stencil + everywhere. + + * lily/stencil.cc (find_expression_fonts): new function + * lily/paper-outputter.cc (output_stencil): use interpret_stencil_expr diff --git a/lily/book.cc b/lily/book.cc index 0861d4f6a8..cf64b17455 100644 --- a/lily/book.cc +++ b/lily/book.cc @@ -9,7 +9,7 @@ #include #include "ly-smobs.icc" - +#include "stencil.hh" #include "book.hh" #include "global-context.hh" #include "ly-module.hh" @@ -67,15 +67,12 @@ Book::process (String outname, Music_output_def *default_def, SCM header) SCM systems = scores_[i]->book_rendering (outname, default_def, &paper); if (systems != SCM_UNDEFINED) { - if (paper) - paper_book->papers_.push (paper); - - paper_book->scores_.push (systems); + Score_lines sc; + sc.paper_ = paper; + sc.lines_ = systems; + sc.header_ =header; - // fixme. - //paper_book->global_headers_.push (global_input_file->header_); - //paper_book->headers_.push (scores_[i]->header_); - paper_book->headers_.push (header); + paper_book->score_lines_.push (sc); } } paper_book->output (outname); @@ -95,10 +92,14 @@ Book::to_stencil (Music_output_def *default_def, SCM header) &paper); if (systems != SCM_UNDEFINED) { - if (paper) - paper_book->papers_.push (paper); - paper_book->scores_.push (systems); - paper_book->headers_.push (header); + Score_lines sc; + sc.paper_ = paper; + sc.lines_ = systems; + sc.header_ =header; + + paper_book->score_lines_.push (sc); + + // wtf: code dup. } } @@ -107,7 +108,7 @@ Book::to_stencil (Music_output_def *default_def, SCM header) if (pages != SCM_EOL) { progress_indication (_f ("paper output to `%s'...", "")); - return (unsmob_page (ly_car (pages)))->to_stencil (); + return (unsmob_page (ly_car (pages)))->to_stencil ().smobbed_copy (); } return SCM_EOL; } diff --git a/lily/include/page.hh b/lily/include/page.hh index c0f929432e..00838a8dfc 100644 --- a/lily/include/page.hh +++ b/lily/include/page.hh @@ -42,7 +42,7 @@ public: /* available area for text. */ Real text_height () const; Real left_margin () const; - SCM to_stencil () const; + Stencil to_stencil () const; }; DECLARE_UNSMOB (Page, page); diff --git a/lily/include/paper-book.hh b/lily/include/paper-book.hh index 1e2c516377..b5efa753e9 100644 --- a/lily/include/paper-book.hh +++ b/lily/include/paper-book.hh @@ -13,6 +13,18 @@ #include "protected-scm.hh" #include "smobs.hh" +struct Score_lines +{ + SCM lines_; + SCM header_; + SCM global_header_; + Paper_def *paper_; + + Score_lines () ; + void gc_mark (); + SCM scopes (); +}; + class Paper_book { DECLARE_SMOBS (Paper_book, ); @@ -22,11 +34,8 @@ class Paper_book SCM tagline_; public: - Array scores_; - Array headers_; - Array global_headers_; - Link_array papers_; - + Array score_lines_; + Paper_book (); SCM lines (); diff --git a/lily/include/paper-line.hh b/lily/include/paper-line.hh index 771c77efc6..8c9bee071d 100644 --- a/lily/include/paper-line.hh +++ b/lily/include/paper-line.hh @@ -26,7 +26,7 @@ public: Paper_line (Offset, SCM, int penalty = 0, bool = false); Offset dim () const; - SCM to_stencil () const; + Stencil to_stencil () const; SCM stencils () const; bool is_title () const; int penalty () const; diff --git a/lily/include/paper-outputter.hh b/lily/include/paper-outputter.hh index 4d36d67a1f..7cf2a75e5d 100644 --- a/lily/include/paper-outputter.hh +++ b/lily/include/paper-outputter.hh @@ -30,7 +30,8 @@ class Paper_outputter SCM output_module_; Protected_scm file_; String filename_; - + Paper_def * paper_ ; // THIS IS BROKEN. + void output_expr (SCM expr, Offset o); void output_metadata (Paper_def*, SCM); void output_music_output_def (Music_output_def* odef); diff --git a/lily/include/stencil.hh b/lily/include/stencil.hh index c403ff8201..f31cc7b897 100644 --- a/lily/include/stencil.hh +++ b/lily/include/stencil.hh @@ -91,13 +91,12 @@ public: DECLARE_UNSMOB(Stencil,stencil); SCM fontify_atom (Font_metric const*, SCM atom); -void interpret_stencil_expr (SCM expr, +void interpret_stencil_expression (SCM expr, void (*func) (void*, SCM), void *func_arg, Offset o); Stencil create_stencil (SCM print); - - +SCM find_expression_fonts (SCM expr); #endif diff --git a/lily/page.cc b/lily/page.cc index 86a3af963a..1052da0d69 100644 --- a/lily/page.cc +++ b/lily/page.cc @@ -83,10 +83,10 @@ Page::print_smob (SCM smob, SCM port, scm_print_state*) return 1; } -static void -stack_stencils (Stencil &a, Stencil *b, Offset *origin) +static Stencil +stack_stencils (Stencil a, Stencil b, Offset *origin) { - Real height = b->extent (Y_AXIS).length (); + Real height = b.extent (Y_AXIS).length (); if (height > 50 CM) { programming_error (to_string ("Improbable stencil height: %f", height)); @@ -94,16 +94,17 @@ stack_stencils (Stencil &a, Stencil *b, Offset *origin) } Offset o = *origin; o.mirror (Y_AXIS); - b->translate (o); - a.add_stencil (*b); + b.translate (o); + a.add_stencil (b); (*origin)[Y_AXIS] += height; + return a; } -SCM +Stencil Page::to_stencil () const { SCM proc = paper_->lookup_variable (ly_symbol2scm ("page-to-stencil")); - return scm_call_1 (proc, self_scm ()); + return *unsmob_stencil (scm_call_1 (proc, self_scm ())); } //urg @@ -138,14 +139,14 @@ LY_DEFINE (ly_page_header_lines_footer_stencil, "ly:page-header-lines-footer-ste if (Stencil *s = unsmob_stencil (p->header_)) { - stack_stencils (stencil, s, &o); + stencil = stack_stencils (stencil, *s, &o); o[Y_AXIS] += p->paper_->get_dimension (ly_symbol2scm ("head-sep")); } for (SCM s = p->lines_; s != SCM_EOL; s = ly_cdr (s)) { Paper_line *p = unsmob_paper_line (ly_car (s)); - stack_stencils (stencil, unsmob_stencil (p->to_stencil ()), &o); + stencil = stack_stencils (stencil, p->to_stencil (), &o); /* Do not put vfill between title and its music, */ if (ly_cdr (s) != SCM_EOL && (!p->is_title () || vfill < 0)) @@ -166,11 +167,11 @@ LY_DEFINE (ly_page_header_lines_footer_stencil, "ly:page-header-lines-footer-ste o[Y_AXIS] -= unsmob_stencil (p->footer_)->extent (Y_AXIS).length (); if (Stencil *s = unsmob_stencil (p->copyright_)) - stack_stencils (stencil, s, &o); + stencil = stack_stencils (stencil, *s, &o); if (Stencil *s = unsmob_stencil (p->tagline_)) - stack_stencils (stencil, s, &o); + stencil = stack_stencils (stencil, *s, &o); if (Stencil *s = unsmob_stencil (p->footer_)) - stack_stencils (stencil, s, &o); + stencil = stack_stencils (stencil, *s, &o); return stencil.smobbed_copy (); } diff --git a/lily/paper-book.cc b/lily/paper-book.cc index c986136fc1..048295b0a4 100644 --- a/lily/paper-book.cc +++ b/lily/paper-book.cc @@ -56,17 +56,10 @@ SCM Paper_book::mark_smob (SCM smob) { Paper_book *b = (Paper_book*) SCM_CELL_WORD_1 (smob); - for (int i = 0; i < b->headers_.size (); i++) - scm_gc_mark (b->headers_[i]); - for (int i = 0; i < b->global_headers_.size (); i++) - scm_gc_mark (b->global_headers_[i]); - for (int i = 0; i < b->papers_.size (); i++) - scm_gc_mark (b->papers_[i]->self_scm ()); - for (int i = 0; i < b->scores_.size (); i++) - scm_gc_mark (b->scores_[i]); + for (int i = 0; i < b->score_lines_.size (); i++) + b->score_lines_[i].gc_mark (); scm_gc_mark (b->copyright_); - return b->tagline_; } @@ -86,31 +79,18 @@ Paper_book::print_smob (SCM smob, SCM port, scm_print_state*) void Paper_book::output (String outname) { - if (!papers_.size ()) + if (!score_lines_.size ()) // FIXME: no end-output? return; /* Generate all stencils to trigger font loads. */ SCM pages = this->pages (); - Paper_def *paper = papers_[0]; + Paper_def *paper = score_lines_[0].paper_; Paper_outputter *out = paper->get_paper_outputter (outname); int page_count = scm_ilength (pages); out->output_header (paper, scopes (0), page_count, false); -#if 0 - /* Ugh; fixme. */ - int paper_count = papers_.size (); - for (int i = 1; i < paper_count; i ++) - { - SCM fonts = papers_[i]->font_descriptions (); - out->output_scheme (scm_list_3 (ly_symbol2scm ("define-fonts"), - papers_[i]->self_scm (), - //FIXME: - ly_quote_scm (ly_list_qsort_uniq_x (fonts)))); - } -#endif - for (SCM s = pages; s != SCM_EOL; s = ly_cdr (s)) { Page *p = unsmob_page (ly_car (s)); @@ -126,15 +106,10 @@ Paper_book::output (String outname) SCM Paper_book::scopes (int i) { - SCM scopes = SCM_EOL; - if (headers_[i]) - scopes = scm_cons (headers_[i], scopes); - if (global_headers_.size () - && global_headers_[i] && global_headers_[i] != headers_[i]) - scopes = scm_cons (global_headers_[i], scopes); - return scopes; + return score_lines_[i].scopes (); } + Stencil Paper_book::title (int i) { @@ -152,11 +127,11 @@ Paper_book::title (int i) SCM s = ly_modules_lookup (scopes, field); if (s != SCM_UNDEFINED && scm_variable_bound_p (s) == SCM_BOOL_T) title = *unsmob_stencil (scm_call_2 (user_title, - papers_[0]->self_scm (), + score_lines_[0].paper_->self_scm (), scm_variable_ref (s))); else title = *unsmob_stencil (scm_call_2 (i == 0 ? book_title : score_title, - papers_[0]->self_scm (), + score_lines_[0].paper_->self_scm (), scopes)); if (!title.is_empty ()) title.align_to (Y_AXIS, UP); @@ -167,14 +142,16 @@ Paper_book::title (int i) void Paper_book::classic_output (String outname) { - int count = scores_.size (); - Paper_outputter *out = papers_.top ()->get_paper_outputter (outname); - out->output_header (papers_.top (), scopes (count - 1), 0, true); + int count = score_lines_.size (); + Paper_def * p = score_lines_.top ().paper_; + Paper_outputter *out = p->get_paper_outputter (outname); + out->output_header (p, scopes (count - 1), 0, true); - Paper_line *first = unsmob_paper_line (scm_vector_ref (scores_.top (), + 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 ((SCM) scores_.top ()); + 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 @@ -186,7 +163,7 @@ Paper_book::classic_output (String outname) if (output_format_global == "tex") o = Offset (0, 0); - out->output_line (scm_vector_ref ((SCM) scores_.top (), scm_int2num (i)), + out->output_line (scm_vector_ref (top_lines, scm_int2num (i)), &o, i == line_count - 1); } @@ -198,7 +175,7 @@ Paper_book::classic_output (String outname) void Paper_book::init () { - int score_count = scores_.size (); + int score_count = score_lines_.size (); /* Calculate the full book height. Hmm, can't we cache system heights while making stencils? */ @@ -209,15 +186,15 @@ Paper_book::init () if (!title.is_empty ()) height_ += title.extent (Y_AXIS).length (); - int line_count = SCM_VECTOR_LENGTH ((SCM) scores_[i]); + int line_count = SCM_VECTOR_LENGTH (score_lines_[i].lines_); for (int j = 0; j < line_count; j++) { - SCM s = scm_vector_ref ((SCM) scores_[i], scm_int2num (j)); + SCM s = scm_vector_ref ((SCM) score_lines_[i].lines_, scm_int2num (j)); height_ += unsmob_paper_line (s)->dim ()[Y_AXIS]; } } - Paper_def *paper = papers_[0]; + Paper_def *paper = score_lines_[0].paper_; SCM scopes = this->scopes (0); SCM make_tagline = paper->c_variable ("make-tagline"); @@ -238,15 +215,16 @@ Paper_book::init () SCM Paper_book::lines () { - int score_count = scores_.size (); + 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 (scores_[i]))); + 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)) @@ -259,7 +237,7 @@ Paper_book::pages () { init (); Page::page_count_ = 0; - Paper_def *paper = papers_[0]; + Paper_def *paper = score_lines_[0].paper_; Page *page = new Page (paper, 1); Real text_height = page->text_height (); @@ -357,3 +335,37 @@ LY_DEFINE (ly_ragged_page_breaks, "ly:ragged-page-breaks", ly_scm2double (book), ly_scm2double (text), ly_scm2double (first), ly_scm2double (last)); } + +/****************************************************************/ + +Score_lines::Score_lines () +{ + lines_ = SCM_EOL; + global_header_ = SCM_EOL; + header_ = SCM_EOL; + paper_ = 0; +} + +void +Score_lines::gc_mark () +{ + scm_gc_mark (lines_); + scm_gc_mark (global_header_); + scm_gc_mark (header_); + if (paper_) + scm_gc_mark (paper_->self_scm ()); +} + + +SCM +Score_lines::scopes () +{ + SCM scopes = SCM_EOL; + if (header_) + scopes = scm_cons (header_, scopes); + if (SCM_MODULEP(global_header_) + && global_header_ != header_) + scopes = scm_cons (global_header_, scopes); + + return scopes; +} diff --git a/lily/paper-line.cc b/lily/paper-line.cc index 56c97c7ea1..d92a32370c 100644 --- a/lily/paper-line.cc +++ b/lily/paper-line.cc @@ -83,10 +83,10 @@ Paper_line::dim () const stencil_.extent (Y_AXIS).length ()); } -SCM +Stencil Paper_line::to_stencil () const { - return stencil_.smobbed_copy (); + return stencil_; } LY_DEFINE (ly_paper_line_height, "ly:paper-line-height", @@ -122,6 +122,6 @@ LY_DEFINE (ly_paper_line_stencil, "ly:paper-line-stencil", { Paper_line *pl = unsmob_paper_line (line); SCM_ASSERT_TYPE (pl, line, SCM_ARG1, __FUNCTION__, "paper-line"); - return pl->to_stencil (); + return pl->to_stencil ().smobbed_copy (); } diff --git a/lily/paper-outputter.cc b/lily/paper-outputter.cc index 7b93840f12..49351e11d3 100644 --- a/lily/paper-outputter.cc +++ b/lily/paper-outputter.cc @@ -35,6 +35,7 @@ extern SCM stencil2line (Stencil* stil, bool is_title = false); Paper_outputter::Paper_outputter (String filename) { filename_ = filename; + paper_ = 0; file_ = scm_open_file (scm_makfrom0str (filename.to_str0 ()), scm_makfrom0str ("w")); @@ -78,6 +79,7 @@ void Paper_outputter::output_header (Paper_def *paper, SCM scopes, int page_count, bool is_classic) { + paper_ = paper; // BROKEN BROKEN BROKEN. String creator = gnu_lilypond_version_string (); creator += " (http://lilypond.org)"; time_t t (time (0)); @@ -96,16 +98,6 @@ Paper_outputter::output_header (Paper_def *paper, SCM scopes, int page_count, output_music_output_def (paper); output_scheme (scm_list_1 (ly_symbol2scm ("header-end"))); - - /* TODO: maybe have Scheme extract the fonts directly from \paper ? - - Alternatively, we could simply load the fonts on demand in the - output, and do away with this define-fonts step. */ - SCM fonts = paper->font_descriptions (); - output_scheme (scm_list_3 (ly_symbol2scm ("define-fonts"), - paper->self_scm (), - //FIXME: - ly_quote_scm (ly_list_qsort_uniq_x (fonts)))); } void @@ -120,11 +112,13 @@ Paper_outputter::output_line (SCM line, Offset *origin, bool is_last) dim[Y_AXIS] = 50 CM; } + output_scheme (scm_list_3 (ly_symbol2scm ("start-system"), ly_quote_scm (ly_offset2scm (*origin)), ly_quote_scm (ly_offset2scm (dim)))); - output_stencil (*unsmob_stencil (p->to_stencil ())); + + output_stencil (p->to_stencil ()); (*origin)[Y_AXIS] += dim[Y_AXIS]; output_scheme (scm_list_2 (ly_symbol2scm ("stop-system"), @@ -134,13 +128,14 @@ Paper_outputter::output_line (SCM line, Offset *origin, bool is_last) void Paper_outputter::output_page (Page *p, bool is_last) { + Stencil page_stencil = p->to_stencil (); output_scheme (scm_list_1 (ly_symbol2scm ("start-page"))); - output_scheme (scm_list_3 (ly_symbol2scm ("start-system"), ly_quote_scm (ly_offset2scm (Offset (0, 0))), ly_quote_scm (ly_offset2scm (Offset (0, 0))))); - output_stencil (*unsmob_stencil (p->to_stencil ())); + + output_stencil (page_stencil); output_scheme (scm_list_2 (ly_symbol2scm ("stop-system"), SCM_BOOL_T)); output_scheme (scm_list_2 (ly_symbol2scm ("stop-page"), @@ -167,7 +162,13 @@ paper_outputter_dump (void * po, SCM x) void Paper_outputter::output_stencil (Stencil stil) { - interpret_stencil_expr (stil.expr (), paper_outputter_dump, + SCM fonts = find_expression_fonts (stil.expr ()); + + output_scheme (scm_list_3 (ly_symbol2scm ("define-fonts"), + paper_->self_scm (), + ly_quote_scm (ly_list_qsort_uniq_x (fonts)))); + + interpret_stencil_expression (stil.expr (), paper_outputter_dump, (void*) this, Offset (0,0)); } diff --git a/lily/score.cc b/lily/score.cc index 262baa7155..b287028e24 100644 --- a/lily/score.cc +++ b/lily/score.cc @@ -168,9 +168,13 @@ default_rendering (SCM music, SCM outdef, SCM header, SCM outname) { Paper_book *paper_book = new Paper_book (); Paper_score *ps = dynamic_cast (output); - paper_book->papers_.push (ps->paper_); - paper_book->scores_.push (systems); - paper_book->headers_.push (header); + + Score_lines sc; + sc.paper_ = ps->paper_; + sc.lines_ = systems; + sc.header_ = header; + + paper_book->score_lines_.push (sc); paper_book->classic_output (ly_scm2string (outname)); scm_gc_unprotect_object (paper_book->self_scm ()); diff --git a/lily/stencil.cc b/lily/stencil.cc index e109152582..bbca94953e 100644 --- a/lily/stencil.cc +++ b/lily/stencil.cc @@ -9,7 +9,7 @@ #include #include // isinf -#include "input.hh" +#include "input-smob.hh" #include "font-metric.hh" #include "dimensions.hh" #include "interval.hh" @@ -188,7 +188,7 @@ Stencil::add_at_edge (Axis a, Direction d, Stencil const &s, Real padding, /****************************************************************/ void -interpret_stencil_expr (SCM expr, +interpret_stencil_expression (SCM expr, void (*func) (void*, SCM), void *func_arg, Offset o) @@ -223,7 +223,7 @@ interpret_stencil_expr (SCM expr, } else if (head == ly_symbol2scm ("combine-stencil")) { - interpret_stencil_expr (ly_cadr (expr), func, func_arg, o); + interpret_stencil_expression (ly_cadr (expr), func, func_arg, o); expr = ly_caddr (expr); } else @@ -241,18 +241,18 @@ interpret_stencil_expr (SCM expr, struct Font_list { - SCM list_; + SCM fonts_; }; static void find_font_function (void * fs, SCM x) { - Font_struct * me = (Font_struct*)fs; + Font_list * me = (Font_list*)fs; if (ly_car (x) == ly_symbol2scm ("placebox")) { SCM args = ly_cdr (x); - SCM what = ly_caddr (x); + SCM what = ly_caddr (args); if (ly_c_pair_p (what)) { @@ -265,18 +265,24 @@ find_font_function (void * fs, SCM x) } } -LY_DEFINE(ly_stencil_fonts, "ly:stencil-fonts", - 1,0,0, (s), - "Analyse @var{s}, and return a list of fonts used in @var{s}." +SCM +find_expression_fonts (SCM expr) { - Stencil *stil =unsmob_stencil (s); - SCM_ASSERT_TYPE (stil, s, SCM_ARG1, __FUNCTION__, "Stencil"); Font_list fl; - fl.list_ = SCM_EOL; + fl.fonts_ = SCM_EOL; - interpret_stencil_expr (stil.expr (), &find_font_function, + interpret_stencil_expression (expr, &find_font_function, (void*) &fl, Offset (0,0)); - return fl.list_; + return fl.fonts_; +} + +LY_DEFINE(ly_stencil_fonts, "ly:stencil-fonts", + 1, 0, 0, (SCM s), + "Analyse @var{s}, and return a list of fonts used in @var{s}.") +{ + Stencil *stil =unsmob_stencil (s); + SCM_ASSERT_TYPE (stil, s, SCM_ARG1, __FUNCTION__, "Stencil"); + return find_expression_fonts (stil->expr ()); } -- 2.39.2