]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/score-element.cc
release: 1.2.4
[lilypond.git] / lily / score-element.cc
index cbaadfc4f4b880c7c3e43090003c3f42c7b6479d..2dab6212bcbf1d4d6445a71d04857c5846148211 100644 (file)
@@ -3,13 +3,13 @@
 
   source file of the GNU LilyPond music typesetter
 
-  (c)  1997--1998 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+  (c)  1997--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
 */
 
 
 #include <string.h>
 
-#include "p-score.hh"
+#include "paper-score.hh"
 #include "paper-def.hh"
 #include "lookup.hh"
 #include "molecule.hh"
 #include "spanner.hh"
 #include "line-of-score.hh"
 #include "item.hh"
-#include "p-col.hh"
+#include "paper-column.hh"
 #include "molecule.hh"
 #include "misc.hh"
 #include "paper-outputter.hh"
+#include "dimension-cache.hh"
 
-#define PARANOID
+
+Interval
+Score_element::dim_cache_callback (Dimension_cache*c)
+{
+  Score_element *  e =dynamic_cast<Score_element*>( c->element_l());
+  if(e->dim_cache_[X_AXIS] == c)
+    return e->do_width ();
+  else
+    return e->do_height ();
+}
 
 Score_element::Score_element()
 {
-  transparent_b_ = false;
-  size_i_ = 0;
+  output_p_ =0;
+  dim_cache_[X_AXIS]->set_callback (dim_cache_callback);
+  dim_cache_[Y_AXIS]->set_callback (dim_cache_callback); 
+  used_b_ = false;
   pscore_l_=0;
+  lookup_l_ =0;
   status_i_ = 0;
+  original_l_ = 0;
+  element_property_alist_ = scm_protect_object (gh_cons (gh_cons (void_scm_sym, SCM_BOOL_T) , SCM_EOL));
 }
 
 Score_element::Score_element (Score_element const&s)
-  :  Directed_graph_node (s), Graphical_element (s)
-{
-  /* called from derived ctor, so most info points to the same deps
-     as (Directed_graph_node&)s. Nobody points to us, so don't copy
-     dependents.      
-   */
-  copy_edges_out (s);
-  transparent_b_ = s.transparent_b_;
+  : Graphical_element (s)
+{
+  used_b_ = true;
+  original_l_ =(Score_element*) &s;
+  element_property_alist_ = scm_protect_object (scm_list_copy (s.element_property_alist_));
+  dependency_arr_ = s.dependency_arr_;
+  output_p_ =0;
   status_i_ = s.status_i_;
+  lookup_l_ = s.lookup_l_;
   pscore_l_ = s.pscore_l_;
-  size_i_ = s.size_i_;
 }
 
-
-  
-
 Score_element::~Score_element()
 {
+  delete output_p_; 
   assert (status_i_ >=0);
+  status_i_  = -1;
 }
 
 Score_element*
 Score_element::dependency (int i) const
 {
-  return (Score_element*) get_out_edge_arr ()[i];
+  return dependency_arr_ [i];
 }
 
 int
 Score_element::dependency_size () const
 {
-  return get_out_edge_arr ().size ();
+  return dependency_arr_.size ();
 }
 
-Score_element*
-Score_element::dependent (int i) const
+SCM
+Score_element::get_elt_property (SCM sym) const
 {
-  return (Score_element*) get_in_edge_arr()[i];
+  SCM s =  scm_assq(sym, element_property_alist_);
+
+  // is this a good idea?
+  if (s == SCM_BOOL_F && pscore_l_ && pscore_l_->paper_l_)
+    s = pscore_l_->paper_l_->get_scm_var (sym);
+
+  return s;
 }
 
-int
-Score_element::dependent_size() const
+SCM
+Score_element::remove_elt_property (SCM key)
 {
-  return get_in_edge_arr().size ();
+  SCM s = get_elt_property (key); 
+  SCM_CDR(element_property_alist_) =  scm_assq_remove_x (SCM_CDR (element_property_alist_), key);
+  return s;
 }
 
-
+void
+Score_element::set_elt_property (SCM s, SCM v)
+{
+  SCM_CDR(element_property_alist_) =
+    scm_assoc_set_x (SCM_CDR (element_property_alist_), s, v);
+}
 
 Interval
 Score_element::do_width() const 
 {
   Interval r;
 
-  Molecule*m = brew_molecule_p();
+  Molecule*m = output_p_ ?  output_p_ : do_brew_molecule_p();
   r = m->extent().x ();
-  delete m;
+
+  if (!output_p_)
+    delete m;
   
   return r;
 }
@@ -97,24 +125,24 @@ Interval
 Score_element::do_height() const 
 {
   Interval r;
-  Molecule*m = brew_molecule_p();
+  Molecule*m = output_p_ ?  output_p_ : do_brew_molecule_p();
   r = m->extent().y ();
-  delete m;
+  if (!output_p_)
+    delete m;
+
   return r;
 }
 
-
-/*
-  STANDARD METHS
- */
 void
 Score_element::print() const
 {
 #ifndef NPRINT
-  DOUT << name() << "{\n";
-  DOUT << "dets: " << dependent_size() << "dependencies: " << 
-    dependency_size();
+  DOUT << classname(this) << "{\n";
+  if (check_debug && !monitor->silent_b ("Score_element"))
+    ly_display_scm (element_property_alist_);
+  DOUT << "dependencies: " << dependency_size();
+  if (original_l_)
+    DOUT << "Copy ";
   Graphical_element::do_print ();
   do_print();
   
@@ -122,43 +150,52 @@ Score_element::print() const
 #endif
 }
 
-
 Paper_def*
-Score_element::paper()  const
+Score_element::paper_l ()  const
 {
-  assert (pscore_l_);
-  return pscore_l_->paper_l_;
+ return pscore_l_->paper_l_;
 }
 
-
 Lookup const *
 Score_element::lookup_l () const
 {
-  return pscore_l_->paper_l_->lookup_l (size_i_);
+  if (!lookup_l_)
+    {
+      Score_element * urg = (Score_element*)this;
+      SCM sz = urg->remove_elt_property (fontsize_scm_sym);
+      int i = (sz != SCM_BOOL_F)
+       ? gh_scm2int (SCM_CDR (sz))
+       : 0;
+
+      urg->lookup_l_ =  (Lookup*)pscore_l_->paper_l_->lookup_l (i);
+    }
+  return lookup_l_;
 }
 
 void
 Score_element::add_processing()
 {
+  assert (status_i_ >=0);
   if (status_i_)
     return;
   status_i_ ++;
   do_add_processing();
 }
 
-
 void
 Score_element::calculate_dependencies (int final, int busy,
                                    Score_element_method_pointer funcptr)
 {
+  assert (status_i_ >=0);
+
   if (status_i_ >= final)
     return;
 
   assert (status_i_!= busy);
   status_i_= busy;
 
-  for (int i=0; i < dependency_size(); i++)
-    dependency (i)->calculate_dependencies (final, busy, funcptr);
+  for (int i=0; i < dependency_arr_.size(); i++)
+    dependency_arr_[i]->calculate_dependencies (final, busy, funcptr);
 
   Link_array<Score_element> extra (get_extra_dependencies());
   for (int i=0; i < extra.size(); i++)
@@ -171,13 +208,21 @@ Score_element::calculate_dependencies (int final, int busy,
 }
 
 void
-Score_element::do_brew_molecule () 
+Score_element::output_processing () 
 {
-  if (transparent_b_)
+  if (get_elt_property (transparent_scm_sym) != SCM_BOOL_F)
     return;
-  Molecule *output= brew_molecule_p ();
-  pscore_l_->outputter_l_->output_molecule (output, absolute_offset (), name());
-  delete output;
+
+  // we're being silly here. 
+  if (output_p_)
+    delete output_p_;
+  
+  output_p_ = do_brew_molecule_p ();
+  Offset o (relative_coordinate (0, X_AXIS), relative_coordinate (0, Y_AXIS));
+  
+  pscore_l_->outputter_l_->output_molecule (output_p_,
+                                           o,
+                                           classname(this));
 }
 
 /*
@@ -185,7 +230,6 @@ Score_element::do_brew_molecule ()
   VIRTUAL STUBS
 
  */
-
 void
 Score_element::do_break_processing()
 {
@@ -219,30 +263,15 @@ Score_element::do_add_processing()
 }
 
 void
-Score_element::do_substitute_dependency (Score_element*,Score_element*)
-{
-}
-void
-Score_element::do_substitute_dependent (Score_element*,Score_element*)
+Score_element::do_substitute_element_pointer (Score_element*,Score_element*)
 {
 }
 
-void
-Score_element::do_unlink()
-{
-}
-
-void
-Score_element::do_junk_links()
-{
-}
-
-IMPLEMENT_IS_TYPE_B1(Score_element, Graphical_element);
 
 Molecule*
-Score_element::brew_molecule_p() const
+Score_element::do_brew_molecule_p() const
 {
-  Atom a (lookup_l ()->fill (Box (Interval (0,0), Interval (0,0))));
+  Molecule a (lookup_l ()->fill (Box (Interval (0,0), Interval (0,0))));
   return new Molecule (a);
 }
 
@@ -262,20 +291,30 @@ Score_element::line_l() const
 void
 Score_element::remove_dependency (Score_element*e)
 {
-  remove_edge_out (e);
+  int i;
+  while ((i = dependency_arr_.find_i (e)) >=0 )
+    dependency_arr_.unordered_del (i);
+
   substitute_dependency (e, 0);
 }
 
 void
 Score_element::add_dependency (Score_element*e)
 {
-  Directed_graph_node::add_edge (e);
+  if (e)
+    {
+      dependency_arr_.push (e);
+      e->used_b_ = true;
+    }
+  else
+    programming_error ("Null dependency added");
 }
+
 void
 Score_element::substitute_dependency (Score_element* old, Score_element* new_l)
 {
-  do_substitute_dependency (old,new_l);
-  old->do_substitute_dependent (this, 0);
+  do_substitute_element_pointer (old,new_l);
+  old->do_substitute_element_pointer (this, 0);
 }
 
 void
@@ -291,17 +330,17 @@ Score_element::handle_broken_dependencies()
       Score_element * elt = dependency (i);
       if (elt->line_l() != line)
        {
-         if (dynamic_cast <Spanner *> (elt)) 
+         if (Spanner *sp = dynamic_cast<Spanner *> (elt)) 
            {
-             Spanner * sp = dynamic_cast <Spanner *> (elt);
              Spanner * broken = sp->find_broken_piece (line);
              substitute_dependency (sp, broken);
 
-             add_dependency (broken);
+             if (broken)
+               add_dependency (broken);
            }
-         else if (dynamic_cast <Item *> (elt))
+         else if (Item *original = dynamic_cast <Item *> (elt))
            {
-             Item * my_item = dynamic_cast <Item *> (elt)->find_prebroken_piece (line);
+             Item * my_item = original->find_prebroken_piece (line);
                
              substitute_dependency (elt, my_item);
              if (my_item)
@@ -333,16 +372,20 @@ Score_element::handle_broken_dependencies()
 void
 Score_element::handle_prebroken_dependencies()
 {
+  /*  dynamic_cast<Item*> (this) && 
+  if (!break_status_dir ())
+    return;
+  */
   Link_array<Score_element> old_arr, new_arr;
   
   for (int i=0; i < dependency_size(); i++) 
     {
       Score_element * elt = dependency (i);
       Item *it_l = dynamic_cast <Item *> (elt);
-      if (it_l && it_l->breakable_b_)
+      if (it_l && it_l->broken_original_b ())
        if (Item *me = dynamic_cast<Item*> (this) )
          {
-           Score_element *new_l = it_l->find_prebroken_piece (me->break_status_dir_);
+           Score_element *new_l = it_l->find_prebroken_piece (me->break_status_dir ());
            if (new_l != elt) 
              {
                new_arr.push (new_l);
@@ -351,10 +394,11 @@ Score_element::handle_prebroken_dependencies()
          }
        else 
          {
-           new_arr.push (it_l->broken_to_drul_[LEFT]);
-           old_arr.push (0);
-           old_arr.push (0);           
-           new_arr.push (it_l->broken_to_drul_[RIGHT]);                
+           Direction d = LEFT;
+           do {
+             old_arr.push (0);
+             new_arr.push (it_l->find_prebroken_piece (d));
+           } while (flip(&d)!= LEFT);
          }
     }
   
@@ -363,32 +407,18 @@ Score_element::handle_prebroken_dependencies()
       substitute_dependency (old_arr[i], new_arr[i]);
 }
 
-
 void
-Score_element::junk_links ()
+Score_element::handle_prebroken_dependents()
 {
-  Directed_graph_node::junk_links();
-  Graphical_element::junk_links ();
-  do_junk_links();
 }
 
 void
-Score_element::unlink()
+Score_element::handle_broken_dependents()
 {
-  do_unlink();
-  while (dependency_size()) 
-    {
-      do_substitute_dependency (dependency (0),0);
-      remove_edge_out_idx (0);
-    }
-  while  (dependent_size()) 
-    {
-      dependent (0)->remove_dependency (this);
-    }
-  Graphical_element::unlink ();
 }
 
 
+
 Link_array<Score_element>
 Score_element::get_extra_dependencies() const
 {
@@ -399,6 +429,10 @@ Score_element::get_extra_dependencies() const
 bool
 Score_element::linked_b() const
 {
-  return get_extra_dependencies().size() || 
-    dependency_size();
+  return used_b_;
+}
+
+void
+Score_element::do_print () const
+{
 }