summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--input/regression/stencil-scale.ly23
-rw-r--r--lily/include/stencil.hh1
-rw-r--r--lily/stencil-interpret.cc16
-rw-r--r--lily/stencil-scheme.cc17
-rw-r--r--lily/stencil.cc11
-rw-r--r--scm/define-markup-commands.scm30
-rw-r--r--scm/define-stencil-commands.scm5
-rw-r--r--scm/output-ps.scm7
-rw-r--r--scm/output-svg.scm7
9 files changed, 115 insertions, 2 deletions
diff --git a/input/regression/stencil-scale.ly b/input/regression/stencil-scale.ly
new file mode 100644
index 0000000000..03cfd2e19c
--- /dev/null
+++ b/input/regression/stencil-scale.ly
@@ -0,0 +1,23 @@
+\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
+}
diff --git a/lily/include/stencil.hh b/lily/include/stencil.hh
index fe13d583e4..ed0a5c96c9 100644
--- a/lily/include/stencil.hh
+++ b/lily/include/stencil.hh
@@ -79,6 +79,7 @@ public:
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;
diff --git a/lily/stencil-interpret.cc b/lily/stencil-interpret.cc
index 509c89aba4..6985f2bbf0 100644
--- a/lily/stencil-interpret.cc
+++ b/lily/stencil-interpret.cc
@@ -88,6 +88,22 @@ interpret_stencil_expression (SCM expr,
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
{
(*func) (func_arg,
diff --git a/lily/stencil-scheme.cc b/lily/stencil-scheme.cc
index f6ac03b3c2..5c859251ef 100644
--- a/lily/stencil-scheme.cc
+++ b/lily/stencil-scheme.cc
@@ -390,3 +390,20 @@ LY_DEFINE (ly_all_stencil_expressions, "ly:all-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 = 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;
+}
diff --git a/lily/stencil.cc b/lily/stencil.cc
index 74af9a0ab4..02f7f89b12 100644
--- a/lily/stencil.cc
+++ b/lily/stencil.cc
@@ -189,6 +189,17 @@ Stencil::translate_axis (Real x, Axis a)
}
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)
{
expr_ = scm_list_3 (ly_symbol2scm ("combine-stencil"), s.expr_, expr_);
diff --git a/scm/define-markup-commands.scm b/scm/define-markup-commands.scm
index d6c992e537..9f86121e16 100644
--- a/scm/define-markup-commands.scm
+++ b/scm/define-markup-commands.scm
@@ -3368,6 +3368,36 @@ when @var{label} is not found."
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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
diff --git a/scm/define-stencil-commands.scm b/scm/define-stencil-commands.scm
index 07f3463828..bbb2ac2a9f 100644
--- a/scm/define-stencil-commands.scm
+++ b/scm/define-stencil-commands.scm
@@ -46,15 +46,15 @@ defined in the output modules (output-*.scm)"
repeat-slash
resetcolor
resetrotation
+ resetscale
round-filled-box
setcolor
setrotation
+ setscale
text
unknown
url-link
utf-8-string
- white-dot
- white-text
zigzag-line
))
@@ -68,6 +68,7 @@ are used internally in lily/stencil-interpret.cc."
combine-stencil
delay-stencil-evaluation
rotate-stencil
+ scale-stencil
translate-stencil
))
diff --git a/scm/output-ps.scm b/scm/output-ps.scm
index 723a616369..ac7cc53d44 100644
--- a/scm/output-ps.scm
+++ b/scm/output-ps.scm
@@ -303,3 +303,10 @@
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")
diff --git a/scm/output-svg.scm b/scm/output-svg.scm
index 2388195528..9b1b250f77 100644
--- a/scm/output-svg.scm
+++ b/scm/output-svg.scm
@@ -615,6 +615,9 @@
(define (resetrotation ang x y)
"</g>\n")
+(define (resetscale)
+ "</g>\n")
+
(define (round-filled-box breapth width depth height blot-diameter)
(entity
'rect ""
@@ -642,6 +645,10 @@
(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)))))