]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/staff-side.cc
release: 1.2.13
[lilypond.git] / lily / staff-side.cc
index eba7d09a13fb852a22c0981e7e0b137439bd4ca0..1ac107f6c88f3995cb625c862ff29a08b52ea140 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_element::Staff_side_element ()
+{
+  dir_ = CENTER;
+  to_position_l_ = 0;
+  set_elt_property (transparent_scm_sym, SCM_BOOL_T);
+  axis_ = Y_AXIS;
+}
 
 void
-Staff_side::set_staffsym (Staff_symbol* s_l)
+Staff_side_element::do_pre_processing ()
 {
-  staff_sym_l_ = s_l;
-  add_dependency (s_l);
+  if (!dir_)
+    dir_ = get_default_direction ();
+
+  if (axis_ == X_AXIS)
+    position_self ();
 }
 
-Staff_side::Staff_side()
+Direction
+Staff_side_element::get_default_direction () const
 {
-  pos_i_ =0;
-  sym_int_ = Interval (0,0);
-  staff_size_i_ = 0;
-  staff_sym_l_ = 0;
-  dir_ = CENTER;
-  inside_staff_b_ = false;
+  return DOWN;
 }
 
+
 void
-Staff_side::read_staff_sym()
+Staff_side_element::set_victim (Score_element *e)
 {
-  if (! staff_sym_l_)
-    return ;
-  staff_size_i_ = staff_sym_l_->steps_i();
+  add_dependency (e);
+  to_position_l_ = e;
+  to_position_l_->set_parent (this, axis_);
 }
 
-
-Interval
-Staff_side::support_height() const
+void
+Staff_side_element::add_support (Score_element*e)
 {
-  Interval r;
-  
-  for (int i=0; i < support_l_arr_.size(); i++)
-    r.unite (support_l_arr_[i]->height());
-  if (r.empty_b()) 
-    {
-      r = Interval (0,0);
-    }
-  return r;
+  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);
 }
 
-int
-Staff_side::get_position_i() const
+void
+Staff_side_element::position_self ()
 {
-  if (!dir_) 
+  if (to_position_l_ &&
+      to_position_l_->get_elt_property (transparent_scm_sym) != SCM_BOOL_F)
+    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_i(): " 
-              "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_sym, SCM_BOOL_T);
+      set_empty (X_AXIS, Y_AXIS);
+      return ;
     }
   
-
-  Real y=0;
-  Real inter_f = paper()-> internote_f ();
-  if (!inside_staff_b_) 
+  Interval dim;
+  Graphical_element *common = 0;
+  if (support_l_arr_.size ())
     {
-      y  = (staff_sym_l_) ? dir_ * (staff_sym_l_->steps_i() + 2) : -2;  
-      y *=inter_f;
-      
-      Interval v= support_height();
+      common = common_refpoint (typecast_array (support_l_arr_, (Graphical_element*)0),
+                               axis_);
 
-      if (dir_ > 0) 
-       {
-         y = y >? (v.max() + 2*inter_f);
-       }
-      else if (dir_ < 0) 
+      for (int i=0; i < support_l_arr_.size (); i++)
        {
-         y = y <? (v.min() - 2*inter_f);
+         Score_element * e = support_l_arr_ [i];
+         Real coord = e->relative_coordinate (common, axis_);
+
+         dim.unite (coord + e->extent (axis_));
        }
     }
-  else 
+  else
+     common = parent_l (axis_);
+
+  if (dim.empty_b ())
+    {
+      dim = Interval(0,0);
+    }
+
+  
+  Interval sym_dim
+    = to_position_l_
+    ? to_position_l_->extent (axis_)
+    : Interval(0,0);
+
+  Real off =  relative_coordinate (common, axis_);
+
+  SCM pad = remove_elt_property (padding_scm_sym);
+  if (pad != SCM_BOOL_F)
     {
-      Interval v= support_height();
-      y = v[dir_]  + 2*dir_*inter_f;   // ugh
+      off += gh_scm2double (SCM_CDR(pad)) * dir_;
     }
-  return int (rint (Real (y)/inter_f)); // should ret a float?
+  Real total_off = dim[dir_] + off;
+
+  /*
+    no_staff_support_scm_sym is ugh bugfix to get staccato dots right.
+   */
+  if (to_position_l_ && to_position_l_->get_elt_property (no_staff_support_scm_sym) == SCM_BOOL_F)
+     total_off += - sym_dim[-dir_];
+  
+  dim_cache_[axis_]->set_offset (total_off);
+  if (fabs (total_off) > 100 CM)
+    programming_error ("Huh ? Improbable staff side dim.");
 }
 
-Interval
-Staff_side::symbol_height() const
+void
+Staff_side_element::do_post_processing ()
 {
-  return Interval (0,0);
+  if (axis_ == Y_AXIS)
+    position_self ();
 }
 
+
 void
-Staff_side::do_post_processing()
+Staff_side_element::do_add_processing ()
+{
+  if (get_elt_property (no_staff_support_scm_sym) == SCM_BOOL_F
+      && axis_ == Y_AXIS && staff_symbol_l ())
+    {
+      add_support (staff_symbol_l ());
+    }
+}
+
+Interval
+Staff_side_element::do_height () const
 {
-  sym_int_ = symbol_height();
-  pos_i_ = get_position_i();
-  if (dir_)
-    pos_i_ += int (rint (- sym_int_[-dir_] / paper()->internote_f ()));
+  Interval i;
+  if (to_position_l_)
+    return to_position_l_->extent (Y_AXIS);
+  return i;
 }
 
 void
-Staff_side::do_substitute_dependency (Score_elem*o, Score_elem*n)
-{ 
-  support_l_arr_.unordered_substitute (o,n);
-  if (staff_sym_l_ == o)
-    staff_sym_l_ = n ? (Staff_symbol*) n->spanner():0;
+Staff_side_element::do_print () const
+{
+#ifndef NPRINT
+  if (to_position_l_)
+    DEBUG_OUT << "positioning " << to_position_l_->name();
+
+  DEBUG_OUT << "axis == " << axis_name_str (axis_)
+       << ", dir == " << to_str ((int)dir_ );
+#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_item::do_print () const
+{
+  Staff_side_element::do_print ();
+}
 
-IMPLEMENT_IS_TYPE_B1(Staff_side, Score_elem);
+void
+Staff_side_spanner::do_print () const
+{
+  Staff_side_element::do_print ();
+}