From: David Kastrup Date: Wed, 8 May 2013 10:04:39 +0000 (+0200) Subject: Issue 3362: Let Stencil::add_stencil and ly:stencil-add flatten combine-stencil expre... X-Git-Tag: release/2.17.19-1~8^2~10 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=64859b072648e37507ca91316e6182652351e502;p=lilypond.git Issue 3362: Let Stencil::add_stencil and ly:stencil-add flatten combine-stencil expressions Reduces memory usage, and the depth of recursion when interpreting stencils. --- diff --git a/lily/stencil-scheme.cc b/lily/stencil-scheme.cc index 7791f02d5a..37203f4eda 100644 --- a/lily/stencil-scheme.cc +++ b/lily/stencil-scheme.cc @@ -139,7 +139,8 @@ LY_DEFINE (ly_stencil_add, "ly:stencil-add", SCM_VALIDATE_REST_ARGUMENT (args); SCM expr = SCM_EOL; - SCM *tail = &expr; + SCM cs = ly_symbol2scm ("combine-stencil"); + Box extent; extent.set_empty (); @@ -150,12 +151,18 @@ LY_DEFINE (ly_stencil_add, "ly:stencil-add", SCM_ASSERT_TYPE (s, scm_car (args), SCM_ARGn, __FUNCTION__, "Stencil"); extent.unite (s->extent_box ()); - *tail = scm_cons (s->expr (), SCM_EOL); - tail = SCM_CDRLOC (*tail); + if (scm_is_pair (s->expr ()) && scm_is_eq (cs, s->expr ())) + { + expr = scm_reverse_x (scm_list_copy (scm_cdr (s->expr ())), + expr); + } + else + expr = scm_cons (s->expr (), expr); + args = scm_cdr (args); } - expr = scm_cons (ly_symbol2scm ("combine-stencil"), expr); + expr = scm_cons (cs, scm_reverse_x (expr, SCM_EOL)); return Stencil (extent, expr).smobbed_copy (); } diff --git a/lily/stencil.cc b/lily/stencil.cc index eb3420d072..0a7f40205d 100644 --- a/lily/stencil.cc +++ b/lily/stencil.cc @@ -205,7 +205,24 @@ Stencil::scale (Real x, Real y) void Stencil::add_stencil (Stencil const &s) { - expr_ = scm_list_3 (ly_symbol2scm ("combine-stencil"), s.expr_, expr_); + SCM cs = ly_symbol2scm ("combine-stencil"); + if (scm_is_pair (expr_) + && scm_is_eq (cs, scm_car (expr_))) + { + if (scm_is_pair (s.expr_) + && scm_is_eq (cs, scm_car (s.expr_))) + expr_ = scm_append (scm_list_2 (s.expr_, scm_cdr (expr_))); + else + expr_ = scm_cons2 (cs, s.expr_, scm_cdr (expr_)); + } + else + { + if (scm_is_pair (s.expr_) + && scm_is_eq (cs, scm_car (s.expr_))) + expr_ = scm_append (scm_list_2 (s.expr_, scm_list_1 (expr_))); + else + expr_ = scm_list_3 (cs, s.expr_, expr_); + } dim_.unite (s.dim_); }