]> git.donarmstrong.com Git - lilypond.git/commitdiff
lilypond-1.3.11
authorfred <fred>
Tue, 26 Mar 2002 22:44:14 +0000 (22:44 +0000)
committerfred <fred>
Tue, 26 Mar 2002 22:44:14 +0000 (22:44 +0000)
lily/side-position-interface.cc [new file with mode: 0644]
lily/staff-symbol-referencer.cc
lily/text-engraver.cc

diff --git a/lily/side-position-interface.cc b/lily/side-position-interface.cc
new file mode 100644 (file)
index 0000000..b458095
--- /dev/null
@@ -0,0 +1,243 @@
+/*   
+  staff-side.cc --  implement Staff_side_element
+  
+  source file of the GNU LilyPond music typesetter
+  
+  (c) 1998--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+  
+ */
+
+#include "side-position-interface.hh"
+#include "staff-symbol.hh"
+#include "debug.hh"
+#include "warn.hh"
+#include "dimensions.hh"
+#include "dimension-cache.hh"
+#include "staff-symbol-referencer.hh"
+
+Side_position_interface::Side_position_interface (Score_element const *e)
+{
+  elt_l_ = (Score_element*)e;
+}
+
+
+void
+Side_position_interface::add_support (Score_element*e)
+{
+  SCM sup = elt_l_->get_elt_property ("side-support");
+  elt_l_->set_elt_property ("side-support",
+                           gh_cons (e->self_scm_,sup));
+}
+
+
+
+Direction
+Side_position_interface::get_direction () const
+{
+  SCM d = elt_l_->get_elt_property ("direction");
+  if (isdir_b (d))
+    return to_dir (d) ? to_dir (d) : DOWN;
+
+  Direction relative_dir = UP;
+  SCM reldir = elt_l_->get_elt_property ("side-relative-direction");   // should use a lambda.
+  if (isdir_b (reldir))
+    {
+      relative_dir = to_dir (reldir);
+    }
+  
+  SCM other_elt = elt_l_->get_elt_property ("direction-source");
+  Score_element * e = unsmob_element(other_elt);
+  if (e)
+    {
+      return (Direction)(relative_dir * Side_position_interface (e).get_direction ());
+    }
+  
+  return DOWN;
+}
+  
+/**
+   Callback that does the aligning.
+ */
+Real
+Side_position_interface::side_position (Dimension_cache const * c)
+{
+  Score_element * me = dynamic_cast<Score_element*> (c->element_l ());
+
+  Interval dim;
+  Axis  axis = c->axis ();
+  Score_element *common = me->parent_l (axis);
+  SCM support = me->get_elt_property ("side-support");
+  for (SCM s = support; s != SCM_EOL; s = gh_cdr (s))
+    {
+      Score_element * e  = unsmob_element ( gh_car (s));
+      if (e)
+       common = common->common_refpoint (e, axis);
+    }
+  
+  for (SCM s = support; s != SCM_EOL; s = gh_cdr (s))
+    {
+
+      Score_element * e  = unsmob_element ( gh_car (s));
+      if (e)
+       {
+         Real coord = e->relative_coordinate (common, axis);
+
+         dim.unite (coord + e->extent (axis));
+       }
+    }
+
+  if (dim.empty_b ())
+    {
+      dim = Interval(0,0);
+    }
+
+  Real off =  me->parent_l (axis)->relative_coordinate (common, axis);
+
+
+  Direction dir = Side_position_interface (me).get_direction ();
+    
+  SCM pad = me->remove_elt_property ("padding");
+  if (pad != SCM_UNDEFINED)
+    {
+      off += gh_scm2double (pad) * dir;
+    }
+  Real total_off = dim[dir] + off;
+
+  if (fabs (total_off) > 100 CM)
+    programming_error ("Huh ? Improbable staff side dim.");
+
+  return total_off;
+}
+
+Real
+Side_position_interface::self_alignment (Dimension_cache const *c)
+{
+  String s ("self-alignment-");
+  Axis ax = c->axis ();
+  s +=  (ax == X_AXIS) ? "X" : "Y";
+  Score_element *elm = dynamic_cast<Score_element*> (c->element_l ());
+  SCM align (elm->get_elt_property (s));
+  if (isdir_b (align))
+    {
+      Direction d = to_dir (align);
+      Interval ext(elm->extent (ax));
+      if (d)
+       {
+         return - ext[d];
+       }
+      return - ext.center ();
+    }
+  else
+    return 0.0;
+}
+
+
+Real
+directed_round (Real f, Direction d)
+{
+  if (d < 0)
+    return floor (f);
+  else
+    return ceil (f);
+}
+
+Real
+Side_position_interface::quantised_position (Dimension_cache const *c)
+{
+  Score_element * me = dynamic_cast<Score_element*> (c->element_l ());
+  Side_position_interface s(me);
+  Direction d = s.get_direction ();
+  Staff_symbol_referencer_interface si (me);
+
+  if (si.has_interface_b ())
+    {
+      Real p = si.position_f ();
+      Real rp = directed_round (p, d);
+
+      int ip = int  (rp);
+      if ((ip % 2) == 0)
+       {
+         ip += d;
+         rp += d;
+       }
+
+      return (rp - p) * si.staff_line_leading_f () / 2.0;
+    }
+  return 0.0;
+}
+
+Real
+Side_position_interface::aligned_side (Dimension_cache const *c)
+{
+  Score_element * me = dynamic_cast<Score_element*> (c->element_l ());
+  Side_position_interface s(me);
+  Direction d = s.get_direction ();
+  Axis ax = c->axis ();
+  Real o = side_position (c);
+
+  Interval iv =  me->extent (ax);
+
+  if (!iv.empty_b ())
+    {
+      o += - iv[-d];
+
+      SCM pad = me->get_elt_property ("padding");
+      if (gh_number_p (pad))
+       o += d *gh_scm2double (pad) ; 
+    }
+  return o;
+}
+
+
+
+
+void
+Side_position_interface::set_axis (Axis a)
+{
+  // prop transparent ? 
+  if (elt_l_->get_elt_property ("side-support") == SCM_UNDEFINED)
+    elt_l_->set_elt_property ("side-support" ,SCM_EOL);
+
+  elt_l_->dim_cache_[a]->off_callbacks_.push (aligned_side);
+}
+
+
+void
+Side_position_interface::set_quantised (Axis a)
+{
+  Dimension_cache * c = elt_l_->dim_cache_[a];
+  
+  c->off_callbacks_.push (quantised_position);
+}
+
+Axis
+Side_position_interface::get_axis () const
+{
+  Dimension_cache * c =  elt_l_->dim_cache_[X_AXIS];
+  for (int i=0 ; i < c->off_callbacks_.size();i ++)
+    if (c->off_callbacks_[i] == side_position
+       ||c->off_callbacks_[i] == aligned_side)
+      return X_AXIS;
+
+  
+  return Y_AXIS;
+}
+
+void
+Side_position_interface::set_direction (Direction d) 
+{
+  elt_l_->set_elt_property ("direction", gh_int2scm (d));
+}
+
+bool
+Side_position_interface::has_interface_b () const
+{
+  return elt_l_->get_elt_property ("side-support") != SCM_UNDEFINED;
+}
+
+bool
+Side_position_interface::supported_b () const
+{
+  SCM s =elt_l_->get_elt_property  ("side-support"); 
+  return s != SCM_UNDEFINED && s != SCM_EOL;
+}
index f2532f0d43e0cbda93eef0d2356e565a8f7d4ef0..8bd451109a9f864ffd326ccebe1311899f6ce7fa 100644 (file)
 #include "paper-def.hh"
 #include "dimension-cache.hh"
 
-Staff_symbol_referencer::Staff_symbol_referencer ()
+Staff_symbol_referencer_interface::Staff_symbol_referencer_interface (Score_element const *sc)
 {
-  set_elt_property ("staff-position", gh_double2scm (0.0));
-  dim_cache_[Y_AXIS]->off_callbacks_.push (callback);
+  elt_l_ = (Score_element*)sc;
+}
+
+void
+Staff_symbol_referencer_interface::set_interface ()
+{
+  elt_l_->set_elt_property ("staff-position", gh_double2scm (0.0));
+  elt_l_->dim_cache_[Y_AXIS]->off_callbacks_.push (callback);
+}
+
+
+bool
+Staff_symbol_referencer_interface::has_interface_b ()
+{
+  return unsmob_element (elt_l_->get_elt_property ("staff-symbol"))
+    || gh_number_p (elt_l_->get_elt_property ("staff-position"));
 }
 
 
 int
-Staff_symbol_referencer::lines_i () const
+Staff_symbol_referencer_interface::lines_i () const
 {
   Staff_symbol *st = staff_symbol_l ();
   return st  ?  st->no_lines_i_ : 5;
 }
 
 Staff_symbol*
-Staff_symbol_referencer::staff_symbol_l () const
+Staff_symbol_referencer_interface::staff_symbol_l () const
 {
-  SCM st = get_elt_property ("staff-symbol");
+  SCM st = elt_l_->get_elt_property ("staff-symbol");
   return dynamic_cast<Staff_symbol* > (unsmob_element(st));
 }
 
 Real
-Staff_symbol_referencer::staff_line_leading_f () const
+Staff_symbol_referencer_interface::staff_line_leading_f () const
 {
   Staff_symbol * st = staff_symbol_l ();
   if (st)
     return st->staff_line_leading_f_;
-  else if (pscore_l_ && paper_l ())
-    paper_l ()->get_var ("interline");
+  else if (elt_l_->pscore_l_ && elt_l_->paper_l ())
+    elt_l_->paper_l ()->get_var ("interline");
  
   return 0.0;
 }
 
 
 Real
-Staff_symbol_referencer::position_f () const
+Staff_symbol_referencer_interface::position_f () const
 {
   Real p =0.0;
-  SCM pos = get_elt_property ("staff-position");
+  SCM pos = elt_l_->get_elt_property ("staff-position");
   if (gh_number_p (pos))
     p = gh_scm2double (pos);
 
   Staff_symbol * st = staff_symbol_l ();
   if (st)
     {
-      Score_element * c = common_refpoint (st, Y_AXIS);
-      Real y = relative_coordinate (c, Y_AXIS)
+      Score_element * c = elt_l_->common_refpoint (st, Y_AXIS);
+      Real y = elt_l_->relative_coordinate (c, Y_AXIS)
        - st->relative_coordinate (c, Y_AXIS);
 
-      p += 2.0 * y / staff_line_leading_f ();
+      p += 2.0 * y / st->staff_line_leading_f ();
     }
   return  p;
 }
@@ -73,15 +87,17 @@ Staff_symbol_referencer::position_f () const
   should use offset callback!
  */
 Real
-Staff_symbol_referencer::callback (Dimension_cache const * c)
+Staff_symbol_referencer_interface::callback (Dimension_cache const * c)
 {
   Score_element * sc = dynamic_cast<Score_element*> (c->element_l ());
-  Staff_symbol_referencer * ref = dynamic_cast<Staff_symbol_referencer*> (sc);
+
+  
   SCM pos = sc->get_elt_property ("staff-position");
   Real off =0.0;
   if (gh_number_p (pos))
     {
-      off = gh_scm2double (pos) * ref->staff_line_leading_f () /2.0;
+      Real space = staff_symbol_referencer_interface (sc).staff_line_leading_f ();
+      off = gh_scm2double (pos) * space/2.0;
     }
   sc->set_elt_property ("staff-position", gh_double2scm (0.0));
 
@@ -90,20 +106,31 @@ Staff_symbol_referencer::callback (Dimension_cache const * c)
 
 
 void
-Staff_symbol_referencer::set_position (Real p)
+Staff_symbol_referencer_interface::set_position (Real p)
 {
-  Real halfspace = staff_line_leading_f ()* 0.5;
-  
-  translate_axis (- halfspace * position_f (), Y_AXIS);
-  Staff_symbol *st = staff_symbol_l ();
-  if (st)
-    translate_axis (halfspace * p, Y_AXIS);
+  Staff_symbol * st = staff_symbol_l ();
+  if (st && elt_l_->common_refpoint(st, Y_AXIS))
+    {
+      Real oldpos = position_f ();
+      elt_l_->set_elt_property ("staff-position", gh_double2scm (p - oldpos));
+    }
   else
     {
-      //      SCM pos = get_elt_property ("staff-position");
-      set_elt_property ("staff-position",
-                       gh_double2scm (p));
-                       //                      gh_double2scm (p + gh_scm2double (pos)));
+      elt_l_->set_elt_property ("staff-position",
+                               gh_double2scm (p));
+
     }
+
+  Array<Offset_cache_callback> &callbacks (elt_l_->dim_cache_[Y_AXIS]->off_callbacks_);
+  for (int i=0; i < callbacks.size ();i++)
+    if (callbacks[i] == callback)
+      return ;
+
+  callbacks.push (callback);
 }
 
+Staff_symbol_referencer_interface
+staff_symbol_referencer_interface (Score_element const*e)
+{
+  return e;                    // gee, I'm so smart!
+}
index 40646392ed5a4923bacddde0d0207c7fb22052fb..56f7b3eae1bcd2267509af96d42efd29cf4ad8a1 100644 (file)
@@ -9,7 +9,7 @@
 #include "dimension-cache.hh"
 
 #include "engraver.hh"
-#include "staff-side.hh"
+#include "side-position-interface.hh"
 #include "text-item.hh"
 #include "musical-request.hh"
 #include "note-head.hh"