]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/line-spanner.cc
Merge branch 'jneeman' of git+ssh://jneem@git.sv.gnu.org/srv/git/lilypond into jneeman
[lilypond.git] / lily / line-spanner.cc
index 07bd16fcc768120be1330159731a38844503e7b2..2f99a0dce2fcfad53815a1eacbc4a113c0c91d57 100644 (file)
@@ -3,12 +3,11 @@
 
   source file of the GNU LilyPond music typesetter
 
-  (c) 2000--2005 Jan Nieuwenhuizen <janneke@gnu.org>
+  (c) 2000--2006 Jan Nieuwenhuizen <janneke@gnu.org>
 */
 
 #include "line-spanner.hh"
 
-#include <math.h>
 
 #include "spanner.hh"
 #include "output-def.hh"
@@ -26,33 +25,46 @@ zigzag_stencil (Grob *me,
                Offset to)
 {
   Offset dz = to -from;
-  Real dx = dz[X_AXIS];
-  Real dy = dz[Y_AXIS];
 
   Real thick = Staff_symbol_referencer::line_thickness (me);
   thick *= robust_scm2double (me->get_property ("thickness"), 1.0); // todo: staff sym referencer? 
 
   Real staff_space = Staff_symbol_referencer::staff_space (me);
 
-  double w = robust_scm2double (me->get_property ("zigzag-width"), 1) * staff_space;
-  double l = robust_scm2double (me->get_property ("zigzag-length"), 1) * w;
-  double h = l > w / 2 ? sqrt (l * l - w * w / 4) : 0;
-
-  SCM list = scm_list_n (ly_symbol2scm ("zigzag-line"),
-                        ly_bool2scm (true),
-                        scm_make_real (w),
-                        scm_make_real (h),
-                        scm_make_real (thick),
-                        scm_make_real (dx),
-                        scm_make_real (dy),
-                        SCM_UNDEFINED);
+  Real w = robust_scm2double (me->get_property ("zigzag-width"), 1) * staff_space;
+  int count = (int) ceil (dz.length () / w);
+  w = dz.length () / count;
+
+  Real l = robust_scm2double (me->get_property ("zigzag-length"), 1) * w;
+  Real h = l > w / 2 ? sqrt (l * l - w * w / 4) : 0;
+
+  Offset rotation_factor = complex_exp (Offset (0, dz.arg ()));
+
+  Offset points[3];
+  points[0] = Offset (0, -h / 2);
+  points[1] = Offset (w / 2, h / 2);
+  points[2] = Offset (w, -h / 2);
+  for (int i = 0; i < 3; i++)
+    points[i] = complex_multiply (points[i], rotation_factor);
+
+  Stencil squiggle (Line_interface::make_line (thick, points[0], points[1]));
+  squiggle.add_stencil (Line_interface::make_line (thick, points[1], points[2]));
+
+  Stencil total;
+  for (int i = 0; i < count; i++)
+    {
+      Stencil moved_squiggle (squiggle);
+      moved_squiggle.translate (from + Offset (i * w, 0) * rotation_factor);
+      total.add_stencil (moved_squiggle);
+    }
+
   Box b;
   b.add_point (Offset (0, 0));
   b.add_point (dz);
   b[X_AXIS].widen (thick / 2);
   b[Y_AXIS].widen (thick / 2);
 
-  return Stencil (b, list);
+  return Stencil (b, total.expr ());
 }
 
 MAKE_SCHEME_CALLBACK (Line_spanner, after_line_breaking, 1);
@@ -83,7 +95,7 @@ Line_spanner::after_line_breaking (SCM g)
       /*
        Can't do suicide, since this mucks up finding the trend.
       */
-      me->set_property ("print-function", SCM_EOL);
+      me->set_property ("transparent", SCM_BOOL_T);
     }
   return SCM_EOL;
 }
@@ -97,7 +109,7 @@ Line_spanner::line_stencil (Grob *me,
   SCM type = me->get_property ("style");
 
   Stencil line;
-  
+
   if (scm_is_symbol (type)
       && (type == ly_symbol2scm ("line")
          || type == ly_symbol2scm ("dashed-line")
@@ -117,7 +129,7 @@ Line_spanner::line_stencil (Grob *me,
                                              ly_symbol2scm ("fetaMusic")),
                                    SCM_UNDEFINED);
 
-      Font_metric *fm = select_font (me->get_layout (),
+      Font_metric *fm = select_font (me->layout (),
                                     scm_cons (style_alist,
                                               alist_chain));
       Stencil m = fm->find_by_name ("scripts.trill_element");
@@ -143,8 +155,8 @@ Line_spanner::line_stencil (Grob *me,
 
   if (to_boolean (me->get_property ("arrow")))
     line.add_stencil (Line_interface::arrows (me, from, to, false, true));
-  
-  return Stencil ();
+
+  return line;
 }
 
 /*
@@ -188,11 +200,14 @@ Line_spanner::print (SCM smob)
 
   Real gap = robust_scm2double (me->get_property ("gap"), 0.0);
 
-  Offset ofxy (gap, 0); /*offset from start point to start of line*/
+  Offset ofxy (gap, 0); /* offset from start point to start of line */
   Offset dxy;
   Offset my_off;
   Offset his_off;
 
+  Real extra_dy = robust_scm2double (me->get_property ("extra-dy"),
+                                    0.0);
+  
   if (bound[RIGHT]->break_status_dir ())
     {
       if (bound[LEFT]->break_status_dir ())
@@ -210,9 +225,7 @@ Line_spanner::print (SCM smob)
        anymore. We have to find the piano-staff object.
       */
 
-      int k = broken_spanner_index (me);
-      Spanner *parent_sp = dynamic_cast<Spanner *> (me->original_);
-      Spanner *next_sp = parent_sp->broken_intos_ [k + 1];
+      Spanner *next_sp = me->broken_neighbor (RIGHT);
       Item *next_bound = next_sp->get_bound (RIGHT);
 
       if (next_bound->break_status_dir ())
@@ -237,11 +250,11 @@ Line_spanner::print (SCM smob)
       Real yoff = this_common_y->relative_coordinate (all_common_y, Y_AXIS);
 
       Offset p1 (bound[LEFT]->extent (commonx, X_AXIS)[RIGHT],
-                this_ext.center () + yoff);
+                this_ext.center () + yoff - extra_dy / 2);
       Offset p2 (bound[RIGHT]->extent (commonx, X_AXIS)[LEFT],
-                next_ext.center () + yoff);
+                next_ext.center () + yoff + extra_dy / 2);
 
-      Offset dz (p2 -p1);
+      Offset dz (p2 - p1);
       Real len = dz.length ();
 
       Offset dir = dz * (1 / len);
@@ -271,29 +284,38 @@ Line_spanner::print (SCM smob)
        {
          Axis ax = (Axis)a;
          dxy[ax]
-           = + bound[RIGHT]->extent (common[X_AXIS], ax).center ()
-           - bound[LEFT]->extent (common[X_AXIS], ax).center ();
+           = + robust_relative_extent (bound[RIGHT], common[X_AXIS], ax).center ()
+           - robust_relative_extent (bound[LEFT], common[X_AXIS], ax).center ();
 
          my_off[ax] = me->relative_coordinate (common[a], ax);
          his_off[ax] = bound[LEFT]->relative_coordinate (common[a], ax);
        }
 
-      ofxy = dxy * (off / dxy.length ());
+      ofxy = dxy * (off / dxy.length ()) ;
       dxy -= 2*ofxy;
 
+      dxy[Y_AXIS] += extra_dy;
+      
       Stencil line = line_stencil (me, Offset (0, 0), dxy);
 
       line.translate_axis (bound[LEFT]->extent (bound[LEFT], X_AXIS).length () / 2, X_AXIS);
-      line.translate (ofxy - my_off + his_off);
+      line.translate (ofxy - my_off + his_off + Offset (0, -extra_dy/2));
       return line.smobbed_copy ();
     }
 }
 
-ADD_INTERFACE (Line_spanner, "line-spanner-interface",
+ADD_INTERFACE (Line_spanner,
               "Generic line drawn between two objects, e.g. for use with glissandi.\n"
               "The property @code{style} can be @code{line}, "
               "@code{dashed-line}, @code{trill}, \n"
               "@code{dotted-line} or @code{zigzag}.\n"
               "\n",
-              "gap zigzag-width zigzag-length thickness arrow");
+
+              "extra-dy "
+              "arrow "
+              "gap "
+              "thickness "
+              "zigzag-length "
+              "zigzag-width "
+              );