+ Stencil target = *unsmob_stencil (stil);
+
+ target.align_to ((Axis)scm_to_int (axis),
+ scm_to_double (dir));
+ return target.smobbed_copy ();
+}
+
+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 ());
+}
+
+LY_DEFINE (ly_stencil_in_color, "ly:stencil-in-color",
+ 4, 0, 0, (SCM stc, SCM r, SCM g, SCM b),
+ "Put @var{stc} in a different color.")
+{
+ Stencil *stil = unsmob_stencil (stc);
+ SCM_ASSERT_TYPE (stil, stc, SCM_ARG1, __FUNCTION__, "Stencil");
+ return Stencil (stil->extent_box (),
+ scm_list_3 (ly_symbol2scm ("color"),
+ scm_list_3 (r, g, b),
+ stil->expr ())).smobbed_copy ();
+}
+
+struct Stencil_interpret_arguments
+{
+ SCM func;
+ SCM arg1;
+};
+
+void stencil_interpret_in_scm (void *p, SCM expr)
+{
+ Stencil_interpret_arguments *ap = (Stencil_interpret_arguments *) p;
+ scm_call_2 (ap->func, ap->arg1, expr);
+}
+
+LY_DEFINE (ly_interpret_stencil_expression, "ly:interpret-stencil-expression",
+ 4, 0, 0, (SCM expr, SCM func, SCM arg1, SCM offset),
+ "Parse EXPR, feed bits to FUNC with first arg ARG1")
+{
+ SCM_ASSERT_TYPE (ly_is_procedure (func), func, SCM_ARG1, __FUNCTION__,
+ "procedure");
+
+ Stencil_interpret_arguments a;
+ a.func = func;
+ a.arg1 = arg1;
+ Offset o = ly_scm2offset (offset);
+
+ interpret_stencil_expression (expr, stencil_interpret_in_scm, (void *) & a, o);
+
+ return SCM_UNSPECIFIED;
+}
+
+LY_DEFINE (ly_bracket, "ly:bracket",
+ 4, 0, 0,
+ (SCM a, SCM iv, SCM t, SCM p),
+ "Make a bracket in direction @var{a}. The extent of the bracket is "
+ "given by @var{iv}. The wings protude by an amount of @var{p}, which "
+ "may be negative. The thickness is given by @var{t}.")
+{
+ SCM_ASSERT_TYPE (is_axis (a), a, SCM_ARG1, __FUNCTION__, "axis");
+ SCM_ASSERT_TYPE (is_number_pair (iv), iv, SCM_ARG2, __FUNCTION__, "number pair");
+ SCM_ASSERT_TYPE (scm_is_number (t), a, SCM_ARG3, __FUNCTION__, "number");
+ SCM_ASSERT_TYPE (scm_is_number (p), a, SCM_ARG4, __FUNCTION__, "number");
+
+ return Lookup::bracket ((Axis)scm_to_int (a), ly_scm2interval (iv),
+ scm_to_double (t),
+ scm_to_double (p),
+ 0.95 * scm_to_double (t)).smobbed_copy ();
+}
+
+LY_DEFINE (ly_filled_box, "ly:round-filled-box",
+ 3, 0, 0,
+ (SCM xext, SCM yext, SCM blot),
+ "Make a @code{Stencil} "
+ "that prints a black box of dimensions @var{xext}, "
+ "@var{yext} and roundness @var{blot}.")
+{
+ SCM_ASSERT_TYPE (is_number_pair (xext), xext, SCM_ARG1, __FUNCTION__, "number pair");
+ SCM_ASSERT_TYPE (is_number_pair (yext), yext, SCM_ARG2, __FUNCTION__, "number pair");
+ SCM_ASSERT_TYPE (scm_is_number (blot), blot, SCM_ARG3, __FUNCTION__, "number");
+
+ return Lookup::round_filled_box (Box (ly_scm2interval (xext), ly_scm2interval (yext)),
+ scm_to_double (blot)).smobbed_copy ();
+}
+
+LY_DEFINE (ly_register_stencil_expression, "ly:register-stencil-expression",
+ 1, 0, 0,
+ (SCM symbol),
+ "Add @var{symbol} as head of a stencil expression")
+{
+ SCM_ASSERT_TYPE (scm_is_symbol (symbol), symbol,
+ SCM_ARG1, __FUNCTION__, "Symbol");
+ register_stencil_head (symbol);
+ return SCM_UNSPECIFIED;
+}
+
+LY_DEFINE (ly_all_stencil_expressions, "ly:all-stencil-expressions",
+ 0, 0, 0,
+ (),
+ "Return all symbols recognized as stencil expressions.")
+{
+ return all_stencil_heads ();