]> git.donarmstrong.com Git - lilypond.git/commitdiff
Issue 3362: Let Stencil::add_stencil and ly:stencil-add flatten combine-stencil expre...
authorDavid Kastrup <dak@gnu.org>
Wed, 8 May 2013 10:04:39 +0000 (12:04 +0200)
committerDavid Kastrup <dak@gnu.org>
Sun, 19 May 2013 08:57:41 +0000 (10:57 +0200)
Reduces memory usage, and the depth of recursion when interpreting stencils.

lily/stencil-scheme.cc
lily/stencil.cc

index 7791f02d5ac5b040759724434c877080c690500d..37203f4edaed9cb817809c19ffbe598b2f60efe0 100644 (file)
@@ -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 ();
 }
 
index eb3420d0723e00aff81f78c36e9647a29fc30b75..0a7f40205d610ef16d331675657132752ecf0403 100644 (file)
@@ -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_);
 }