]> git.donarmstrong.com Git - lilypond.git/commitdiff
Add rotation support
authorErlend Aasland <erlenda@gmail.com>
Sun, 14 May 2006 14:06:37 +0000 (14:06 +0000)
committerErlend Aasland <erlenda@gmail.com>
Sun, 14 May 2006 14:06:37 +0000 (14:06 +0000)
ChangeLog
lily/grob.cc
lily/include/stencil.hh
lily/stencil-interpret.cc
lily/stencil-scheme.cc
lily/stencil.cc
scm/define-grob-properties.scm
scm/define-markup-commands.scm
scm/output-ps.scm
scm/output-svg.scm

index 4995fda109c4a62bc99e0ac5e4e2f52e62c3b822..e77cf7e79f32fe197da9e1793b921da17f19ff0e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2006-05-14  Erlend Aasland  <erlenda@gmail.com>
+
+       * lily/include/stencil.hh
+       * lily/stencil.cc (rotation): new function. Makes it possible
+       to rotate a stencil around a given offset.
+
+       * lily/grob.cc (get_print_stencil): add rotation support
+
+       * lily/stencil-interpret.cc (interpret_stencil_expression):
+       add rotation support
+
+       * lily/stencil-scheme.cc (ly:stencil-rotate): new function
+
+       * scm/define-grob-properties.scm: add 'rotation property
+
+       * scm/define-markup-commands.scm: add rotate markup command
+       
+       * scm/output-ps.scm: add rotation support in PostScript backend
+
+       * scm/output-svg.scm: add rotation support in SVG backend
+
 2006-05-13  Graham Percival  <gpermus@gmail.com>
 
        * Documentation/user/music-glossary.itely: French correction.
index fc49f16d4ddd7b5b6b67fc3da0629f5252d87d56..d66bc37208d9fd59f04372c55790262e78319230 100644 (file)
@@ -120,6 +120,15 @@ Grob::get_print_stencil () const
 
          retval = Stencil (m->extent_box (), expr);
        }
+      SCM rot = get_property ("rotation");
+      if (rot != SCM_EOL)
+       {
+         Real angle = scm_to_double (scm_car (rot));
+         Real x = scm_to_double (scm_cadr (rot));
+         Real y = scm_to_double (scm_caddr (rot));
+
+         retval.rotate (angle, Offset (x, y));
+       }
 
       /* color support... see interpret_stencil_expression () for more... */
       SCM color = get_property ("color");
@@ -522,6 +531,7 @@ ADD_INTERFACE (Grob, "grob-interface",
               "meta "
               "minimum-X-extent "
               "minimum-Y-extent "
+              "rotation "
               "springs-and-rods "
               "staff-symbol "
               "stencil "
index 0c9979d32701acfe1739db873307a3cffc36a26b..2211b8c661f327b281779e8757ff3e1278cb68ec 100644 (file)
@@ -73,6 +73,7 @@ public:
                    Real minimum);
   void add_stencil (Stencil const &m);
   void translate (Offset);
+  void rotate (Real, Offset);
   void align_to (Axis a, Real x);
   void translate_axis (Real, Axis);
 
index 52e9242d0b76ec157e10a6ea825c43ce12745c1d..e4387345361da7ba061cac04386d361eebeef56a 100644 (file)
@@ -54,6 +54,22 @@ interpret_stencil_expression (SCM expr,
          interpret_stencil_expression (scm_caddr (expr), func, func_arg, o);
          (*func) (func_arg, scm_list_1 (ly_symbol2scm ("resetcolor")));
 
+         return;
+       }
+      else if (head == ly_symbol2scm ("rotate-stencil"))
+       {
+         SCM args = scm_cadr (expr);
+         SCM angle = scm_car (args);
+         Offset tmp = o + robust_scm2offset (scm_cadr (args), Offset (0.0, 0.0));
+
+         SCM offset = ly_offset2scm (tmp);
+         SCM x = scm_car (offset);
+         SCM y = scm_cdr (offset);
+
+         (*func) (func_arg, scm_list_4 (ly_symbol2scm ("setrotation"), angle, x, y));
+         interpret_stencil_expression (scm_caddr (expr), func, func_arg, o);
+         (*func) (func_arg, scm_list_4 (ly_symbol2scm ("resetrotation"), angle, x, y));
+
          return;
        }
       else
index 2619ffd25e52627c141ac93a761b9368db41a0b2..66f182593186240567c0b34a38e71a71565fb075 100644 (file)
@@ -319,6 +319,25 @@ LY_DEFINE (ly_bracket, "ly:bracket",
                          0.95 * scm_to_double (t)).smobbed_copy ();
 }
 
+LY_DEFINE (ly_rotate_stencil, "ly:stencil-rotate",
+          4, 0, 0, (SCM stil, SCM angle, SCM x, SCM y),
+          "Return a @var{stil} rotated @var{angle} degrees around point (@var{x}, @var{y}).")
+{
+  Stencil *s = unsmob_stencil (stil);
+  SCM_ASSERT_TYPE (s, stil, SCM_ARG1, __FUNCTION__, "stencil");
+  SCM_ASSERT_TYPE (scm_is_number (angle), angle, SCM_ARG2, __FUNCTION__, "number");
+  SCM_ASSERT_TYPE (scm_is_number (x), x, SCM_ARG3, __FUNCTION__, "number");
+  SCM_ASSERT_TYPE (scm_is_number (y), y, SCM_ARG4, __FUNCTION__, "number");
+  Real a = scm_to_double (angle);
+  Real x_off = scm_to_double (x);
+  Real y_off = scm_to_double (y);
+
+  SCM new_s = s->smobbed_copy ();
+  Stencil *q = unsmob_stencil (new_s);
+  q->rotate (a, Offset (x_off, y_off));
+  return new_s;
+}
+
 LY_DEFINE (ly_filled_box, "ly:round-filled-box",
           3, 0, 0,
           (SCM xext, SCM yext, SCM blot),
index 2fad44274d43f0a99c685a143c5598be51dd2f34..dd3bb2626ea93f5559672a062c1a6769dc3726f0 100644 (file)
@@ -78,6 +78,44 @@ Stencil::origin () const
   return origin_;
 }
 
+/*
+ * Rotate this stencil around the point [x, y]
+ */
+void
+Stencil::rotate (Real a, Offset off)
+{
+  const Real x_cen = extent (X_AXIS).center ();
+  const Real y_cen = extent (Y_AXIS).center ();
+
+  /*
+   * Calculate the center of rotation
+   */
+  const Real x = x_cen + off[X_AXIS] * x_cen;
+  const Real y = y_cen + off[Y_AXIS] * y_cen;
+
+  /*
+   * Build scheme expression (processed in stencil-interpret.cc)
+   */
+  expr_ = scm_list_n (ly_symbol2scm ("rotate-stencil"),
+                     scm_list_2 (scm_from_double (a),
+                     scm_cons (scm_from_double (x), scm_from_double (y))),
+                     expr_, SCM_UNDEFINED);
+
+  /*
+   * Calculate the new bounding box
+   */
+  vector<Offset> pts;
+  pts.push_back (Offset (-x_cen, -y_cen));
+  pts.push_back (Offset (x_cen, -y_cen));
+  pts.push_back (Offset (x_cen, y_cen));
+  pts.push_back (Offset (-x_cen, y_cen));
+
+  const Offset rot = complex_exp (Offset (0, a * M_PI / 180.0));
+  dim_.set_empty ();
+  for (vsize i = 0; i < pts.size (); i++)
+    dim_.add_point (pts[i] * rot + Offset (x_cen, y_cen));
+}
+
 void
 Stencil::translate (Offset o)
 {
index ba1def6f73346027cf503b5f8b5c47522c59d234..d59d4661c92466beb9bafb8c3507435954c828a9 100644 (file)
@@ -352,6 +352,8 @@ quicker the slur attains it @code{height-limit}.")
      (remove-first ,boolean? "Remove the first staff of a orchestral score?")
      (right-padding ,ly:dimension? "Space to insert between note and
 accidentals.")
+     (rotation ,list? "Number of degrees to rotate this object, and what point
+to rotate around. #'(45 0 0) means rotate 45 degrees around the center of this object.")
      (same-direction-correction ,number? "Optical correction amount
 for stems that are placed in tight configurations. This amount is used
 for stems with the same direction to compensate for note-head to stem distance.")
index 8512d6d2574a7f05b73ffe98f19e5436ee2bdc4d..5eea9071697b96ef37e15e6c13f773eccc13a665 100644 (file)
@@ -118,6 +118,12 @@ circle of diameter 0 (ie sharp corners)."
   (ly:round-filled-box
    xext yext blot))
 
+(define-markup-command (rotate layout props ang arg) (number? markup?)
+  "Rotate object with @var{ang} degrees around its center."
+  (let* ((stil (interpret-markup layout props arg)))
+    (ly:stencil-rotate stil ang 0 0)))
+
+
 (define-markup-command (whiteout layout props arg) (markup?)
   "Provide a white underground for @var{arg}"
   (let* ((stil (interpret-markup layout props
index 2303bf2d02d6d4fb0b78232050f0886605bbc8e5..d7c55df028d4e1bae257ba6ba121f784d214b5ee 100644 (file)
 
   ;; JUNK this -- see lily.scm: ly:all-output-backend-commands
   #:export (unknown
-           blank
+           bezier-sandwich
+           char
            circle
-           dot
+           comment
+           dashed-line
            dashed-slur
-           char
-           setcolor
-           resetcolor
+           dot
+           draw-line
+           embedded-ps
            named-glyph
-           dashed-line
-           zigzag-line
-           comment
-           repeat-slash
+           no-origin
            placebox
-           bezier-sandwich
-           embedded-ps
+           polygon
+           repeat-slash
+           resetcolor
+           resetrotatino
            round-filled-box
+           setcolor
+               setrotation
            text
-           polygon
-           draw-line
-           no-origin))
+           zigzag-line))
 
 
 (use-modules (guile)
 ;; restore color from stack
 (define (resetcolor) "setrgbcolor\n")
 
+;; reset rotation
+(define (resetrotation ang x y)
+  (format "~a translate ~a rotate ~a translate\n"
+    (numbers->string4 (list x y))
+    (number->string (* -1 ang))
+    (numbers->string4 (list (* -1 x) (* -1 y)))))
+
 (define (round-filled-box left right bottom top blotdiam)
   (let* ((halfblot (/ blotdiam 2))
         (x (- halfblot left))
   (format #f "currentrgbcolor ~a setrgbcolor\n"
          (numbers->string4 (list r g b))))
 
+;; rotation around given point
+(define (setrotation ang x y)
+  (format "~a translate ~a rotate ~a translate\n"
+    (numbers->string4 (list x y))
+    (number->string ang)
+    (numbers->string4 (list (* -1 x) (* -1 y)))))
+
 (define (text font s)
   ;; (ly:warning (_ "TEXT backend-command encountered in Pango backend"))
   ;; (ly:warning (_ "Arguments: ~a ~a"" font str))
index fbf458a7a44767745599ac5f02c3b00e6cc42ce8..786a37ca177deb434518e3b5e2d650053dba97bd 100644 (file)
                (map offset->point (ly:list->offsets '() coords))))
    ))
 
+;; rotate around given point
+(define (setrotation ang x y)
+  (format "<g transform=\"rotate(~a,~a,~a)\">"
+    (number->string (* -1 ang))
+    (number->string x)
+    (number->string (* -1 y))))
+
+(define (resetrotation ang x y)
+  "</g>")
+
 (define (round-filled-box breapth width depth height blot-diameter)
   (entity 'rect ""
          ;; The stroke will stick out.  To use stroke,