]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/staff-side.cc
release: 1.3.3
[lilypond.git] / lily / staff-side.cc
index 404283066c1378ece2d9cd41b932bf05c7ad5222..5f923b89d8186819fe04fe13cc44728b31dbef57 100644 (file)
-/*
-  staff-side.cc -- implement Staff_side
-
+/*   
+  g-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>
+  
+ */
 
-  (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
-*/
-
-#include "interval.hh"
-#include "paper-def.hh"
-#include "dimen.hh"
 #include "staff-side.hh"
-#include "staff-sym.hh"
+#include "staff-symbol.hh"
 #include "debug.hh"
+#include "warn.hh"
+#include "dimensions.hh"
+#include "dimension-cache.hh"
 
-
-Staff_side::Staff_side()
+Staff_side_element::Staff_side_element ()
 {
-  y_=0;
-  sym_int_ = Interval (0,0);
-  dir_ = CENTER;
+  set_direction (CENTER);
+  to_position_l_ = 0;
+  set_elt_property ("transparent", SCM_BOOL_T);
+  axis_ = Y_AXIS;
 }
 
+void
+Staff_side_element::do_pre_processing ()
+{
+  if (!get_direction ())
+    set_direction (get_default_direction ());
 
-Interval
-Staff_side::support_height() const
+  if (axis_ == X_AXIS)
+    position_self ();
+}
+
+Direction
+Staff_side_element::get_default_direction () const
 {
-  Interval y_int;
-  for (int i=0; i < support_l_arr_.size(); i++) 
-    {
-      Axis_group_element *common = 
-       common_group (support_l_arr_[i], Y_AXIS);
-       
-      Real y = support_l_arr_[i]->relative_coordinate (common, Y_AXIS)  
-       -relative_coordinate (common,Y_AXIS);
+  return DOWN;
+}
 
-      y_int.unite (y + support_l_arr_[i]->height());
-    }
 
+void
+Staff_side_element::set_victim (Score_element *e)
+{
+  add_dependency (e);
+  to_position_l_ = e;
+  to_position_l_->set_parent (this, axis_);
+}
 
-  if (y_int.empty_b())
-    {
-      y_int = Interval (0,0);
-    }
-  return y_int;
+void
+Staff_side_element::add_support (Score_element*e)
+{
+  add_dependency (e);
+  support_l_arr_.push (e);
 }
 
+
 void
-Staff_side::add_support (Score_elem*i)
+Staff_side_element::do_substitute_element_pointer (Score_element*o, Score_element*n)
 {
-  support_l_arr_.push (i);
-  add_dependency (i);
+  Staff_symbol_referencer::do_substitute_element_pointer (o,n);
+  if (o == to_position_l_)
+    to_position_l_ = n;
+  else
+    support_l_arr_.unordered_substitute (o,n);
 }
 
-Real
-Staff_side::get_position_f () const
+void
+Staff_side_element::position_self ()
 {
-  if (!dir_)
+  if (to_position_l_ &&
+      to_position_l_->get_elt_property ("transparent") != SCM_UNDEFINED)
+    return;
+
+  Axis other = Axis ((axis_ + 1) % NO_AXES);
+  if (parent_l (axis_)->empty_b (axis_)
+      &&parent_l (axis_)->empty_b (other)) // guh
     {
-      warning (_("Staff_side::get_position_f(): "
-                "somebody forgot to set my vertical direction, returning -20"));
-      return -20;
+      warning (_("No support; erasing script"));
+      to_position_l_->set_empty (X_AXIS,Y_AXIS);
+      to_position_l_->set_elt_property ("transparent", SCM_BOOL_T);
+      set_empty (X_AXIS, Y_AXIS);
+      return ;
     }
+  
+  Interval dim;
+  Graphical_element *common = 0;
+  if (support_l_arr_.size ())
+    {
+      common = common_refpoint (typecast_array (support_l_arr_, (Graphical_element*)0),
+                               axis_);
 
+      for (int i=0; i < support_l_arr_.size (); i++)
+       {
+         Score_element * e = support_l_arr_ [i];
+         Real coord = e->relative_coordinate (common, axis_);
 
-  Real y = 0;
-  Real inter_f = paper()-> internote_f ();
+         dim.unite (coord + e->extent (axis_));
+       }
+    }
+  else
+     common = parent_l (axis_);
 
-  Interval v = support_height();
+  if (dim.empty_b ())
+    {
+      dim = Interval(0,0);
+    }
+
+  
+  Interval sym_dim
+    = to_position_l_
+    ? to_position_l_->extent (axis_)
+    : Interval(0,0);
 
-  // ugh, dim[y] = PT over here
-  y = v[dir_] + 1 * dir_ * inter_f;
+  Real off =  relative_coordinate (common, axis_);
 
-  int y_i = (int)rint (y / inter_f);
-  // ugh: 5 -> staff_lines
-  if (abs (y_i) < 5)
+  SCM pad = remove_elt_property ("padding");
+  if (pad != SCM_UNDEFINED)
     {
-      if (!(abs (y_i) % 2))
-       y += (Real)dir_ * inter_f;
+      off += gh_scm2double (pad) * get_direction ();
     }
-//  else
-//    y = v[dir_] + 1 * dir_ * inter_f;
+  Real total_off = dim[get_direction ()] + off;
+
+  /*
+    "no-staff-support" is ugh bugfix to get staccato dots right.
+   */
+  if (to_position_l_ && to_position_l_->get_elt_property ("no-staff-support") == SCM_UNDEFINED)
+     total_off += - sym_dim[-get_direction ()];
+  
+  dim_cache_[axis_]->set_offset (total_off);
+  if (fabs (total_off) > 100 CM)
+    programming_error ("Huh ? Improbable staff side dim.");
+}
 
-  return y;
+void
+Staff_side_element::do_post_processing ()
+{
+  if (axis_ == Y_AXIS)
+    position_self ();
+}
+
+
+void
+Staff_side_element::do_add_processing ()
+{
+  if (get_elt_property ("no-staff-support") == SCM_UNDEFINED
+      && axis_ == Y_AXIS && staff_symbol_l ())
+    {
+      add_support (staff_symbol_l ());
+    }
 }
 
 Interval
-Staff_side::symbol_height() const
+Staff_side_element::do_height () const
 {
-  return Interval (0,0);
+  Interval i;
+  if (to_position_l_)
+    return to_position_l_->extent (Y_AXIS);
+  return i;
 }
 
 void
-Staff_side::do_post_processing()
+Staff_side_element::do_print () const
 {
-  sym_int_ = symbol_height();
-  y_ = get_position_f();
-  if (dir_)
-    y_ += - sym_int_[-dir_];
+#ifndef NPRINT
+  if (to_position_l_)
+    DEBUG_OUT << "positioning " << to_position_l_->name();
+
+  DEBUG_OUT << "axis == " << axis_name_str (axis_)
+       << ", dir == " << to_str ((int)get_direction () );
+#endif
+}
+
+
+Interval
+Staff_side_item::do_width () const
+{
+  Interval i;
+  if (to_position_l_)
+    return to_position_l_->extent (X_AXIS);
+  return i;
 }
 
 void
-Staff_side::do_substitute_dependency (Score_elem*o, Score_elem*n)
+Staff_side_item::do_print () const
 {
-  support_l_arr_.unordered_substitute (o,n);
+  Staff_side_element::do_print ();
 }
 
+void
+Staff_side_spanner::do_print () const
+{
+  Staff_side_element::do_print ();
+}
 
-IMPLEMENT_IS_TYPE_B1(Staff_side, Score_elem);