+ SCM new_s = s->smobbed_copy ();
+ Stencil *q = Stencil::unsmob (new_s);
+ q->rotate_degrees_absolute (a, Offset (x_off, y_off));
+ return new_s;
+}
+
+LY_DEFINE (ly_round_filled_box, "ly:round-filled-box",
+ 3, 0, 0,
+ (SCM xext, SCM yext, SCM blot),
+ "Make a @code{Stencil} object that prints a black box of"
+ " dimensions @var{xext}, @var{yext} and roundness @var{blot}.")
+{
+ LY_ASSERT_TYPE (is_number_pair, xext, 1);
+ LY_ASSERT_TYPE (is_number_pair, yext, 2);
+ LY_ASSERT_TYPE (scm_is_number, blot, 3);
+
+ return Lookup::round_filled_box (Box (ly_scm2interval (xext), ly_scm2interval (yext)),
+ scm_to_double (blot)).smobbed_copy ();
+}
+
+LY_DEFINE (ly_round_filled_polygon, "ly:round-filled-polygon",
+ 2, 0, 0,
+ (SCM points, SCM blot),
+ "Make a @code{Stencil} object that prints a black polygon with"
+ " corners at the points defined by @var{points} (list of coordinate"
+ " pairs) and roundness @var{blot}.")
+{
+ SCM_ASSERT_TYPE (scm_ilength (points) > 0, points, SCM_ARG1, __FUNCTION__, "list of coordinate pairs");
+ LY_ASSERT_TYPE (scm_is_number, blot, 2);
+ vector<Offset> pts;
+ for (SCM p = points; scm_is_pair (p); p = scm_cdr (p))
+ {
+ SCM scm_pt = scm_car (p);
+ if (scm_is_pair (scm_pt))
+ {
+ pts.push_back (ly_scm2offset (scm_pt));
+ }
+ else
+ {
+ // TODO: Print out warning
+ }
+ }
+ return Lookup::round_filled_polygon (pts, 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.")
+{
+ LY_ASSERT_TYPE (ly_is_symbol, symbol, 1);
+ 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 ();
+}
+
+LY_DEFINE (ly_stencil_scale, "ly:stencil-scale",
+ 3, 0, 0, (SCM stil, SCM x, SCM y),
+ "Scale @var{stil} using the horizontal and vertical scaling"
+ " factors @var{x} and @var{y}.")
+{
+ Stencil *s = Stencil::unsmob (stil);
+ LY_ASSERT_SMOB (Stencil, stil, 1);
+ LY_ASSERT_TYPE (scm_is_number, x, 2);
+ LY_ASSERT_TYPE (scm_is_number, y, 3);
+
+ SCM new_s = s->smobbed_copy ();
+ Stencil *q = Stencil::unsmob (new_s);
+
+ q->scale (scm_to_double (x), scm_to_double (y));
+ return new_s;