+ while (1)
+ {
+ if (!scm_is_pair (expr))
+ return;
+
+ SCM head = scm_car (expr);
+
+ if (head == ly_symbol2scm ("translate-stencil"))
+ {
+ o += ly_scm2offset (scm_cadr (expr));
+ expr = scm_caddr (expr);
+ }
+ else if (head == ly_symbol2scm ("combine-stencil"))
+ {
+ for (SCM x = scm_cdr (expr); scm_is_pair (x); x = scm_cdr (x))
+ interpret_stencil_expression (scm_car (x), func, func_arg, o);
+ return;
+ }
+ else if (head == ly_symbol2scm ("grob-cause"))
+ {
+ SCM grob = scm_cadr (expr);
+
+ (*func) (func_arg, scm_list_3 (head,
+ ly_quote_scm (ly_offset2scm (o)), grob));
+ interpret_stencil_expression (scm_caddr (expr), func, func_arg, o);
+ (*func) (func_arg, scm_list_1 (ly_symbol2scm ("no-origin")));
+ return;
+ }
+ else if (head == ly_symbol2scm ("color"))
+ {
+ SCM color = scm_cadr (expr);
+ SCM r = scm_car (color);
+ SCM g = scm_cadr (color);
+ SCM b = scm_caddr (color);
+
+ (*func) (func_arg, scm_list_4 (ly_symbol2scm ("setcolor"), r, g, b));
+ interpret_stencil_expression (scm_caddr (expr), func, func_arg, o);
+ (*func) (func_arg, scm_list_1 (ly_symbol2scm ("resetcolor")));
+
+ return;
+ }
+ else
+ {
+ (*func) (func_arg,
+ scm_list_4 (ly_symbol2scm ("placebox"),
+ scm_make_real (o[X_AXIS]),
+ scm_make_real (o[Y_AXIS]),
+ expr));
+ return;
+ }
+ }