diff --git a/lily/include/stencil-interpret.hh b/lily/include/stencil-interpret.hh index 5c955aff57..2d9586c333 100644 --- a/lily/include/stencil-interpret.hh +++ b/lily/include/stencil-interpret.hh @@ -22,13 +22,6 @@ #include "lily-guile.hh" -class Stencil_sink { -public: - virtual SCM output(SCM expr) = 0; -}; - -void interpret_stencil_expression (SCM expr, - Stencil_sink *sink, - Offset o); +SCM interpret_stencil_expression (SCM expr, SCM module); #endif diff --git a/lily/paper-book.cc b/lily/paper-book.cc index 10e043be87..c085eebff5 100644 --- a/lily/paper-book.cc +++ b/lily/paper-book.cc @@ -19,6 +19,7 @@ #include "paper-book.hh" +#include "cpu-timer.hh" #include "grob.hh" #include "international.hh" #include "main.hh" @@ -176,6 +177,10 @@ Paper_book::output (SCM output_channel) &first_performance_number)) return; + Cpu_timer timer; + + message (_ ("Outputting book...")); + SCM scopes = SCM_EOL; if (ly_is_module (header_)) scopes = scm_cons (header_, scopes); @@ -240,6 +245,8 @@ Paper_book::output (SCM output_channel) warning (_f ("program option -dcrop not supported by backend `%s'", get_output_backend_name ())); } + + debug_output (_f ("elapsed time: %.2f seconds", timer.read ())); } void diff --git a/lily/paper-outputter.cc b/lily/paper-outputter.cc index 3aead8f2f2..f0fd93cc35 100644 --- a/lily/paper-outputter.cc +++ b/lily/paper-outputter.cc @@ -26,6 +26,7 @@ #include "input.hh" #include "lily-imports.hh" #include "lily-version.hh" +#include "ly-scm-list.hh" #include "main.hh" #include "output-def.hh" #include "paper-book.hh" @@ -100,20 +101,18 @@ Paper_outputter::output_scheme (SCM scm) return str; } -struct Scm_to_file : Stencil_sink -{ - Paper_outputter *po_; - - virtual SCM output (SCM scm) override { return po_->output_scheme (scm); } -}; - void Paper_outputter::output_stencil (Stencil stil) { - Scm_to_file stf; - stf.po_ = this; - - interpret_stencil_expression (stil.expr (), &stf, Offset (0, 0)); + SCM output = interpret_stencil_expression (stil.expr (), output_module_); + /* + Evaluate the output expressions and return the result as a list. + */ + output = scm_cons (ly_symbol2scm ("list"), output); + output = scm_eval (output, output_module_); + for (SCM &s : as_ly_scm_list (output)) + if (scm_is_string (s)) + dump_string (s); } void diff --git a/lily/stencil-interpret.cc b/lily/stencil-interpret.cc index 827c32e844..02b84520f7 100644 --- a/lily/stencil-interpret.cc +++ b/lily/stencil-interpret.cc @@ -20,23 +20,23 @@ #include "stencil-interpret.hh" #include "stencil.hh" -void -interpret_stencil_expression (SCM expr, Stencil_sink *sink, Offset o) +static SCM +interpret_stencil_expression_aux (SCM expr, SCM module, Offset o, SCM list) { while (1) { if (!scm_is_pair (expr)) - return; + return list; SCM head = scm_car (expr); if (scm_is_eq (head, ly_symbol2scm ("delay-stencil-evaluation"))) { - interpret_stencil_expression (scm_force (scm_cadr (expr)), sink, o); - return; + return interpret_stencil_expression_aux ( + scm_force (scm_cadr (expr)), module, o, list); } if (scm_is_eq (head, ly_symbol2scm ("footnote"))) - return; + return list; if (scm_is_eq (head, ly_symbol2scm ("translate-stencil"))) { o += from_scm (scm_cadr (expr)); @@ -46,24 +46,26 @@ interpret_stencil_expression (SCM expr, Stencil_sink *sink, Offset o) { for (SCM x = scm_cdr (expr); scm_is_pair (x); x = scm_cdr (x)) - interpret_stencil_expression (scm_car (x), sink, o); - return; + list = interpret_stencil_expression_aux (scm_car (x), module, o, list); + return list; } else if (scm_is_eq (head, ly_symbol2scm ("grob-cause"))) { SCM grob = scm_cadr (expr); - SCM link - = sink->output (scm_list_3 (head, ly_quote_scm (to_scm (o)), grob)); - interpret_stencil_expression (scm_caddr (expr), sink, o); - if (scm_is_true (link)) - sink->output (scm_list_1 (ly_symbol2scm ("no-origin"))); - return; + SCM link = scm_list_3 (head, ly_quote_scm (to_scm (o)), grob); + list = scm_cons (link, list); + list = interpret_stencil_expression_aux (scm_caddr (expr), module, o, + list); + list = scm_cons (scm_list_3 (ly_symbol2scm ("if"), link, + ly_symbol2scm ("no-origin")), list); + return list; } - else if (scm_is_eq (head, ly_symbol2scm ("color"))) + else if (scm_is_eq (head, ly_symbol2scm ("color"))) { SCM color = scm_cadr (expr); + SCM setcolor = ly_symbol2scm ("setcolor"); if (scm_is_string (color)) - sink->output (scm_list_2 (ly_symbol2scm ("setcolor"), color)); + list = scm_cons (scm_list_2 (setcolor, color), list); else { SCM r = scm_car (color); @@ -72,26 +74,28 @@ interpret_stencil_expression (SCM expr, Stencil_sink *sink, Offset o) if (scm_to_int (scm_length (color)) == 4) { SCM a = scm_cadddr (color); - sink->output (scm_list_5 (ly_symbol2scm ("setcolor"), r, g, b, a)); + list = scm_cons (scm_list_5 (setcolor, r, g, b, a), list); } else - sink->output (scm_list_4 (ly_symbol2scm ("setcolor"), r, g, b)); + list = scm_cons (scm_list_4 (setcolor, r, g, b), list); } - interpret_stencil_expression (scm_caddr (expr), sink, o); - sink->output (scm_list_1 (ly_symbol2scm ("resetcolor"))); + list = interpret_stencil_expression_aux (scm_caddr (expr), module, o, + list); + list = scm_cons (scm_list_1 (ly_symbol2scm ("resetcolor")), list); - return; + return list; } else if (scm_is_eq (head, ly_symbol2scm ("output-attributes"))) { SCM attributes = scm_cadr (expr); - sink->output (scm_list_2 (ly_symbol2scm ("start-group-node"), - ly_quote_scm (attributes))); - interpret_stencil_expression (scm_caddr (expr), sink, o); - sink->output (scm_list_1 (ly_symbol2scm ("end-group-node"))); + list = scm_cons (scm_list_2 (ly_symbol2scm ("start-group-node"), + ly_quote_scm (attributes)), list); + list = interpret_stencil_expression_aux (scm_caddr (expr), module, o, + list); + list = scm_cons (scm_list_1 (ly_symbol2scm ("end-group-node")), list); - return; + return list; } else if (scm_is_eq (head, ly_symbol2scm ("rotate-stencil"))) { @@ -103,13 +107,14 @@ interpret_stencil_expression (SCM expr, Stencil_sink *sink, Offset o) SCM x = scm_car (offset); SCM y = scm_cdr (offset); - sink->output ( - scm_list_4 (ly_symbol2scm ("setrotation"), angle, x, y)); - interpret_stencil_expression (scm_caddr (expr), sink, o); - sink->output ( - scm_list_4 (ly_symbol2scm ("resetrotation"), angle, x, y)); + list = scm_cons ( + scm_list_4 (ly_symbol2scm ("setrotation"), angle, x, y), list); + list = interpret_stencil_expression_aux (scm_caddr (expr), module, o, + list); + list = scm_cons ( + scm_list_4 (ly_symbol2scm ("resetrotation"), angle, x, y), list); - return; + return list; } else if (scm_is_eq (head, ly_symbol2scm ("scale-stencil"))) { @@ -119,12 +124,13 @@ interpret_stencil_expression (SCM expr, Stencil_sink *sink, Offset o) Offset unscaled = o.scale (Offset (1 / scm_to_double (x_scale), 1 / scm_to_double (y_scale))); - sink->output ( - scm_list_3 (ly_symbol2scm ("setscale"), x_scale, y_scale)); - interpret_stencil_expression (scm_caddr (expr), sink, unscaled); - sink->output (scm_list_1 (ly_symbol2scm ("resetscale"))); + list = scm_cons ( + scm_list_3 (ly_symbol2scm ("setscale"), x_scale, y_scale), list); + list = interpret_stencil_expression_aux (scm_caddr (expr), module, + unscaled, list); + list = scm_cons (scm_list_1 (ly_symbol2scm ("resetscale")), list); - return; + return list; } else if (scm_is_eq (head, ly_symbol2scm ("with-outline"))) { @@ -132,10 +138,18 @@ interpret_stencil_expression (SCM expr, Stencil_sink *sink, Offset o) } else { - sink->output (scm_list_4 (ly_symbol2scm ("placebox"), - to_scm (o[X_AXIS]), to_scm (o[Y_AXIS]), - expr)); - return; + list = scm_cons (scm_list_4 (ly_symbol2scm ("placebox"), + to_scm (o[X_AXIS]), to_scm (o[Y_AXIS]), + expr), list); + return list; } } } + +SCM interpret_stencil_expression (SCM expr, SCM module) +{ + SCM list = interpret_stencil_expression_aux (expr, module, Offset (0, 0), + SCM_EOL); + list = scm_reverse (list); + return list; +}