]> git.donarmstrong.com Git - lilypond.git/commitdiff
* lily/paper-outputter.cc (output_stencil): dump font definitions
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Sun, 9 May 2004 19:27:53 +0000 (19:27 +0000)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Sun, 9 May 2004 19:27:53 +0000 (19:27 +0000)
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.

13 files changed:
ChangeLog
lily/book.cc
lily/include/page.hh
lily/include/paper-book.hh
lily/include/paper-line.hh
lily/include/paper-outputter.hh
lily/include/stencil.hh
lily/page.cc
lily/paper-book.cc
lily/paper-line.cc
lily/paper-outputter.cc
lily/score.cc
lily/stencil.cc

index c9d5bc19613cdf355ca5e733bf106fbf6db1fe69..368d51d1ff489f9c6ceae733b605d71e05901329 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
 2004-05-09  Han-Wen Nienhuys   <hanwen@xs4all.nl>
 
+       * 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
 
index 0861d4f6a8daf01d5b1af3518d5abb4a604ec607..cf64b174555b0f0387267e45918a5e0a30650efb 100644 (file)
@@ -9,7 +9,7 @@
 #include <stdio.h>
 
 #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'...", "<markup>"));
-      return (unsmob_page (ly_car (pages)))->to_stencil ();
+      return (unsmob_page (ly_car (pages)))->to_stencil ().smobbed_copy ();
     }
   return SCM_EOL;
 }
index c0f929432e32ffbc36ef515cd05abce7468970bd..00838a8dfc5d828ca346ea6690456531bda32eb6 100644 (file)
@@ -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);
index 1e2c516377e3b428ff0984229a8fb4da052dc163..b5efa753e948ef9eab62675d3532b9cabfa5dabf 100644 (file)
 #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<SCM> scores_;
-  Array<SCM> headers_;
-  Array<SCM> global_headers_;
-  Link_array<Paper_def> papers_;
-  
+  Array<Score_lines> score_lines_;
+
   Paper_book ();
 
   SCM lines ();
index 771c77efc6874e906085582f2434cc7441ab3083..8c9bee071df02e46b6a92c28059918461cd64e86 100644 (file)
@@ -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;
index 4d36d67a1f06270eacd403717ee30198442e5f1c..7cf2a75e5ddbb8e7f8842556a4234ffd0cf76718 100644 (file)
@@ -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);
index c403ff8201697483b13b7ce60e15d63dcf861ebb..f31cc7b897d20bb34958c2ea4a9a3e9940c4bf20 100644 (file)
@@ -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
index 86a3af963a6dc724711c16ddfd7c66f40685bec5..1052da0d693bab5ea1c479af4efa4079190505b5 100644 (file)
@@ -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 ();
 }
index c986136fc103f86fc9e52c4c8f0fabb9b209932c..048295b0a4c3689ef2c7ff3b684dc77b641e166e 100644 (file)
@@ -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;
+}
index 56c97c7ea1168f3368e7cf6df7e928599675acda..d92a32370cf3ff823abac6422fcec65b35c2e107 100644 (file)
@@ -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 ();
 }
 
index 7b93840f124eae255380ad9047a923089111b3e9..49351e11d3e7de677383eeeebcf321013dbc2f44 100644 (file)
@@ -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));
 }
 
index 262baa7155766268a38fd6571d1fae5da3b89af9..b287028e24f04e02962c6f494c28dbc45f2f8bc4 100644 (file)
@@ -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<Paper_score*> (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 ());
index e1091525824c2f4552b6450382d01c33900b6af9..bbca94953efb13023a8626d20e8b352102c7585f 100644 (file)
@@ -9,7 +9,7 @@
 #include <math.h>
 #include <libc-extension.hh>   // 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 ());
 }