source file of the GNU LilyPond music typesetter
- (c) 1998--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+ (c) 1998--2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
*/
+#include <math.h>
+#include "warn.hh"
#include "dimension-cache.hh"
#include "parray.hh"
+#include "score-element.hh"
+
Dimension_cache::Dimension_cache (Dimension_cache const &d)
{
init();
- callback_l_ = d.callback_l_;
- empty_b_ = d.empty_b_;
- offset_ = d.offset_; //let's hope others will copy the refpoint appropriately.
+ extent_callback_l_ = d.extent_callback_l_;
+ basic_offset_ = d.basic_offset_;
+ extra_offset_ = d.extra_offset_;
+ off_valid_b_ = d.off_valid_b_;
+ off_callbacks_ = d.off_callbacks_;
+ parent_l_ = d.parent_l_;
}
Dimension_cache::Dimension_cache ()
void
Dimension_cache::init()
{
- callback_l_ =0;
- offset_ =0.0;
+ extent_callback_l_ =0;
+ basic_offset_ =0.0;
+ extra_offset_ =0.0;
+
elt_l_ = 0;
dim_.set_empty ();
parent_l_ =0;
valid_b_ = false;
- empty_b_ = false;
+ off_valid_b_ = false;
}
void
-Dimension_cache::invalidate ()
-{
- valid_b_ = false;
- invalidate_dependencies ();
-}
-
-void
-Dimension_cache::invalidate_dependencies ()
+Dimension_cache::translate (Real x)
{
- for (int i=0; i < dependencies_l_arr_.size (); i++)
- {
- Dimension_cache * g = dependencies_l_arr_[i];
- if (g->valid_b_)
- {
- g->invalidate ();
- }
- }
+ extra_offset_ += x;
}
-void
-Dimension_cache::set_offset (Real x)
+Real
+Dimension_cache::relative_coordinate (Dimension_cache *refp) const
{
- invalidate_dependencies ();
- offset_ = x;
-}
+ if (refp == this)
+ return 0.0;
-void
-Dimension_cache::translate (Real x)
-{
- invalidate_dependencies ();
- offset_ += x;
+ /*
+ We catch PARENT_L_ == nil case with this, but we crash if we did
+ not ask for the absolute coordinate (ie. REFP == nil.)
+
+ */
+ if (refp == parent_l_)
+ return get_offset ();
+ else
+ return get_offset () + parent_l_->relative_coordinate (refp);
}
-
-Real
-Dimension_cache::absolute_coordinate () const
+Axis
+Dimension_cache::axis () const
{
- Real r = offset_;
- for (Dimension_cache * c = parent_l_;
- c; c = c->parent_l_)
- r += c->offset_;
- return r;
+ if (elt_l_-> dim_cache_[X_AXIS] == this)
+ return X_AXIS;
+ else
+ return Y_AXIS;
}
-/*
- what *should* these functions *do* anyway.
- */
Real
-Dimension_cache::relative_coordinate (Dimension_cache *d) const
+Dimension_cache::get_offset () const
{
- Real r =0.0;
- if (d == this) // UGH
- return 0.0;
-
- for (Dimension_cache* c = parent_l_;
- c != d;
- c = c->parent_l_)
- r += c->offset_;
- return r;
+ Dimension_cache *me = (Dimension_cache*) this;
+ while (off_callbacks_.size ())
+ {
+ Offset_cache_callback c = me->off_callbacks_[0];
+ me->off_callbacks_.del (0);
+ Real r = (*c) (me);
+ if (isinf (r) || isnan (r))
+ {
+ r = 0.0;
+ programming_error ("Infinity or NaN encountered");
+ }
+ me->basic_offset_ +=r;
+ }
+ return basic_offset_ + extra_offset_;
}
Dimension_cache *
-Dimension_cache::common_group (Dimension_cache const* s) const
+Dimension_cache::common_refpoint (Dimension_cache const* s) const
{
- Link_array<Dimension_cache> my_groups;
- for (Dimension_cache const *c = this; c ; c = c->parent_l_)
- my_groups.push ((Dimension_cache*)c);
-
- Dimension_cache const *common=0;
-
- for (Dimension_cache const * d = s; !common && d; d = d->parent_l_)
- common = (Dimension_cache const*)my_groups.find_l (d);
-
- return (Dimension_cache*)common;
+ /*
+ I don't like the quadratic aspect of this code. Maybe this should
+ be rewritten some time, but the largest chain of parents might be
+ 10 high or so, so it shouldn't be a real issue. */
+ for (Dimension_cache const *c = this; c; c = c->parent_l_)
+ for (Dimension_cache const * d = s; d; d = d->parent_l_)
+ if (d == c)
+ return (Dimension_cache*)d;
+
+ return 0;
}
-
-
-void
-Dimension_cache::set_empty (bool b)
-{
- if (empty_b_ != b)
- {
- empty_b_ = b;
- if (!empty_b_)
- invalidate ();
- }
-}
-
-void
-Dimension_cache::set_dim (Interval v)
+Interval
+Dimension_cache::point_dimension_callback (Dimension_cache const* )
{
- dim_ = v;
- valid_b_ = true;
+ return Interval (0,0);
}
-
Interval
Dimension_cache::get_dim () const
{
Interval r;
- if (empty_b_)
+ Dimension_cache *nc = ((Dimension_cache*)this);
+ if (!extent_callback_l_)
{
- r.set_empty ();
- return r;
+ nc->dim_.set_empty ();
}
-
- if (!valid_b_)
+ else if (!valid_b_)
{
- Dimension_cache *nc = ((Dimension_cache*)this);
- nc->dim_= (*callback_l_ ) (nc);
+ nc->dim_= (*extent_callback_l_ ) (nc);
nc->valid_b_ = true;
}
r=dim_;
- if (!r.empty_b()) // float exception on DEC Alpha
- r += offset_;
-
return r;
}
void
-Dimension_cache::set_callback (Dim_cache_callback c)
+Dimension_cache::set_extent_callback (Dim_cache_callback c)
{
- callback_l_ =c;
+ extent_callback_l_ =c;
}
-Real
-Dimension_cache::offset () const
-{
- return offset_;
-}
+