From: Neil Puttock Date: Sat, 30 Oct 2010 15:08:01 +0000 (+0100) Subject: Fix #888: Add ly:stencil-scale. X-Git-Tag: release/2.13.38-1~2 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=8af3c27f5b63009a9a8507fcfcc220a93dcbf725;p=lilypond.git Fix #888: Add ly:stencil-scale. * input/regression/stencil-scale.ly new regtest for testing ly:stencil-scale * lily/stencil-interpret.cc (interpret_stencil_expression): interpret new stencil command `scale-stencil', unscaling offset of body to compensate for change in output scale * lily/stencil-scheme.cc (ly_stencil_scale): export new function `ly:stencil-scale' * lily/stencil.cc, include/stencil.hh (scale): new method for scaling stencils * scm/define-markup-commands.scm (scale): new markup command * scm/define-stencil-commands.scm (ly:all-stencil-commands): add stencil commands for setting and resetting scale (`setscale', `resetscale') (ly:all-output-backend-commands): add `scale-stencil' command * scm/output-ps.scm, output-svg.scm (setscale, resetscale): implement stencil outputters for scaling --- 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 @@ -86,6 +86,22 @@ interpret_stencil_expression (SCM expr, 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 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 @@ -188,6 +188,17 @@ Stencil::translate_axis (Real x, Axis a) 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) { 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 @@ -3367,6 +3367,36 @@ when @var{label} is not found." 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 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 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) "\n") +(define (resetscale) + "\n") + (define (round-filled-box breapth width depth height blot-diameter) (entity 'rect "" @@ -642,6 +645,10 @@ (ly:format "\n" (- ang) x (- y))) +(define (setscale x y) + (ly:format "\n" + x y)) + (define (text font string) (dispatch `(fontify ,font ,(entity 'tspan (string->entities string)))))