--- /dev/null
+\version "2.13.38"
+
+\header {
+ texidoc = "Stencils can be scaled using @code{ly:stencil-scale}.
+Negative values will flip or mirror the stencil without changing its origin; this
+may result in collisions unless the scaled stencil is realigned (e.g., the time
+signature in this test)."
+}
+
+\relative c' {
+ \override Staff.Clef #'stencil =
+ #(lambda (grob)
+ (ly:stencil-scale (ly:clef::print grob) 1 -1))
+ \override Staff.TimeSignature #'stencil =
+ #(lambda (grob)
+ (ly:stencil-aligned-to
+ (ly:stencil-scale (ly:time-signature::print grob) -2 1)
+ X LEFT))
+ \override MultiMeasureRestText #'stencil =
+ #(lambda (grob)
+ (ly:stencil-scale (ly:text-interface::print grob) 2 1.6))
+ R1\fermataMarkup
+}
void rotate_degrees_absolute (Real, Offset);
void align_to (Axis a, Real x);
void translate_axis (Real, Axis);
+ void scale (Real, Real);
Interval extent (Axis) const;
Box extent_box () const;
interpret_stencil_expression (scm_caddr (expr), func, func_arg, o);
(*func) (func_arg, scm_list_4 (ly_symbol2scm ("resetrotation"), angle, x, y));
+ return;
+ }
+ else if (head == ly_symbol2scm ("scale-stencil"))
+ {
+ SCM args = scm_cadr (expr);
+ SCM x_scale = scm_car (args);
+ SCM y_scale = scm_cadr (args);
+ Offset unscaled = o.scale (Offset (1 / scm_to_double (x_scale),
+ 1 / scm_to_double (y_scale)));
+
+ (*func) (func_arg, scm_list_3 (ly_symbol2scm ("setscale"), x_scale,
+ y_scale));
+ interpret_stencil_expression (scm_caddr (expr), func, func_arg,
+ unscaled);
+ (*func) (func_arg, scm_list_1 (ly_symbol2scm ("resetscale")));
+
return;
}
else
{
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 = unsmob_stencil (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 = unsmob_stencil (new_s);
+
+ q->scale (scm_to_double (x), scm_to_double (y));
+ return new_s;
+}
translate (o);
}
+void
+Stencil::scale (Real x, Real y)
+{
+ expr_ = scm_list_3 (ly_symbol2scm ("scale-stencil"),
+ scm_list_2 (scm_from_double (x),
+ scm_from_double (y)),
+ expr_);
+ dim_[X_AXIS] *= x;
+ dim_[Y_AXIS] *= y;
+}
+
void
Stencil::add_stencil (Stencil const &s)
{
x-ext
y-ext)))
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; scaling
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(define-markup-command (scale layout props factor-pair arg)
+ (number-pair? markup?)
+ #:category graphic
+ "
+@cindex scaling markup
+@cindex mirroring markup
+
+Scale @var{arg}. @var{factor-pair} is a pair of numbers
+representing the scaling-factor in the X and Y axes.
+Negative values may be used to produce mirror images.
+
+@lilypond[verbatim,quote]
+\\markup {
+ \\line {
+ \\scale #'(2 . 1)
+ stretched
+ \\scale #'(1 . -1)
+ mirrored
+ }
+}
+@end lilypond"
+ (let ((stil (interpret-markup layout props arg))
+ (sx (car factor-pair))
+ (sy (cdr factor-pair)))
+ (ly:stencil-scale stil sx sy)))
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Markup list commands
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
repeat-slash
resetcolor
resetrotation
+ resetscale
round-filled-box
setcolor
setrotation
+ setscale
text
unknown
url-link
utf-8-string
- white-dot
- white-text
zigzag-line
))
combine-stencil
delay-stencil-evaluation
rotate-stencil
+ scale-stencil
translate-stencil
))
thickness
(convert-path-exps exps)
(if fill? "fill" ""))))
+
+(define (setscale x y)
+ (ly:format "gsave ~4l scale\n"
+ (list x y)))
+
+(define (resetscale)
+ "grestore\n")
(define (resetrotation ang x y)
"</g>\n")
+(define (resetscale)
+ "</g>\n")
+
(define (round-filled-box breapth width depth height blot-diameter)
(entity
'rect ""
(ly:format "<g transform=\"rotate(~4f, ~4f, ~4f)\">\n"
(- ang) x (- y)))
+(define (setscale x y)
+ (ly:format "<g transform=\"scale(~4f, ~4f)\">\n"
+ x y))
+
(define (text font string)
(dispatch `(fontify ,font ,(entity 'tspan (string->entities string)))))