]> git.donarmstrong.com Git - lilypond.git/commitdiff
Fix #888: Add ly:stencil-scale.
authorNeil Puttock <n.puttock@gmail.com>
Sat, 30 Oct 2010 15:08:01 +0000 (16:08 +0100)
committerNeil Puttock <n.puttock@gmail.com>
Sat, 30 Oct 2010 15:29:23 +0000 (16:29 +0100)
* 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

input/regression/stencil-scale.ly [new file with mode: 0644]
lily/include/stencil.hh
lily/stencil-interpret.cc
lily/stencil-scheme.cc
lily/stencil.cc
scm/define-markup-commands.scm
scm/define-stencil-commands.scm
scm/output-ps.scm
scm/output-svg.scm

diff --git a/input/regression/stencil-scale.ly b/input/regression/stencil-scale.ly
new file mode 100644 (file)
index 0000000..03cfd2e
--- /dev/null
@@ -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
+}
index fe13d583e4ad772d6ce3ebca71a40c04e3b76811..ed0a5c96c9bf64104603c76f1caaf16182026230 100644 (file)
@@ -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;
index 509c89aba42e13ff82f6e675df48897ac499bfa3..6985f2bbf0b6ede100868594648fbea1a1d767e9 100644 (file)
@@ -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
index f6ac03b3c26cd43b5612b504ab0eba7bb55be608..5c859251ef19e9a432064527b66538c106ea13c7 100644 (file)
@@ -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;
+}
index 74af9a0ab4ccdb28705c53a740923fd9b0fd5601..02f7f89b121c1ed4fab4bd4ccdd95fbd8c50cacf 100644 (file)
@@ -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)
 {
index d6c992e537e91894ee4f05946d11d52fe0634191..9f86121e16b46ce8004d9ccf4fd926cdf65037da 100644 (file)
@@ -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
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
index 07f3463828fc9552bc3b184c57d074ef6c42214e..bbb2ac2a9f6e48977a6ffe178219b27869fee0b8 100644 (file)
@@ -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
     ))
 
index 723a616369bd5f7a4b37243c30dc4506a9f05e2e..ac7cc53d44b0a6bc0d12428ba0958987290b8991 100644 (file)
      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")
index 238819552866dd420a54b5c0d1876444e87b2d8b..9b1b250f77857a631b525bd90fa282b796b6e178 100644 (file)
 (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)))))