]> git.donarmstrong.com Git - lilypond.git/blob - lily/dimension-cache.cc
release: 1.3.39
[lilypond.git] / lily / dimension-cache.cc
1 /*   
2   dimension-cache.cc --  implement Dimension_cache
3   
4   source file of the GNU LilyPond music typesetter
5   
6   (c) 1998--2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7  */
8 #include <math.h>
9 #include "warn.hh"
10
11 #include "dimension-cache.hh"
12 #include "parray.hh"
13 #include "score-element.hh"
14
15
16 Dimension_cache::Dimension_cache (Dimension_cache const &d)
17 {
18   init();
19   extent_callback_l_ = d.extent_callback_l_;
20   basic_offset_ = d.basic_offset_;
21   extra_offset_ = d.extra_offset_;
22   off_valid_b_ = d.off_valid_b_;
23   off_callbacks_ = d.off_callbacks_;
24   parent_l_ = d.parent_l_;  
25 }
26
27 Dimension_cache::Dimension_cache ()
28 {
29   init();
30 }
31
32 void
33 Dimension_cache::init()
34 {
35   extent_callback_l_ =0;
36   basic_offset_ =0.0;
37   extra_offset_ =0.0;
38   
39   elt_l_ = 0;
40   dim_.set_empty ();
41   parent_l_ =0;
42   valid_b_ = false;
43   off_valid_b_ = false;
44 }
45
46
47 void
48 Dimension_cache::translate (Real x)
49 {
50   extra_offset_ += x;
51 }
52
53 Real
54 Dimension_cache::relative_coordinate (Dimension_cache *refp) const
55 {
56   if (refp == this)
57     return 0.0;
58
59   /*
60     We catch PARENT_L_ == nil case with this, but we crash if we did
61     not ask for the absolute coordinate (ie. REFP == nil.)
62     
63    */
64   if (refp == parent_l_)
65     return get_offset ();
66   else
67     return get_offset () + parent_l_->relative_coordinate (refp);
68 }
69
70 Axis
71 Dimension_cache::axis () const
72 {
73   if (elt_l_-> dim_cache_[X_AXIS] == this)
74     return X_AXIS;
75   else
76     return Y_AXIS;
77 }
78
79 Real
80 Dimension_cache::get_offset () const
81 {
82   Dimension_cache *me = (Dimension_cache*) this;
83   while (off_callbacks_.size ())
84     {
85       Offset_cache_callback c = me->off_callbacks_[0];
86       me->off_callbacks_.del (0);
87       Real r =  (*c) (me);
88       if (isinf (r) || isnan (r))
89         {
90           r = 0.0;
91           programming_error ("Infinity or NaN encountered");
92         }
93       me->basic_offset_ +=r;
94     }
95   return basic_offset_ + extra_offset_;
96 }
97
98 Dimension_cache *
99 Dimension_cache::common_refpoint (Dimension_cache const* s) const
100 {
101   /*
102     I don't like the quadratic aspect of this code. Maybe this should
103     be rewritten some time, but the largest chain of parents might be
104     10 high or so, so it shouldn't be a real issue. */
105   for (Dimension_cache const *c = this; c; c = c->parent_l_)
106     for (Dimension_cache const * d = s; d; d = d->parent_l_)
107       if (d == c)
108         return (Dimension_cache*)d;
109
110   return 0;
111 }
112
113 Interval
114 Dimension_cache::point_dimension_callback (Dimension_cache const* )
115 {
116   return Interval (0,0);
117 }
118
119 Interval
120 Dimension_cache::get_dim () const
121 {
122   Interval r;
123   Dimension_cache *nc = ((Dimension_cache*)this);
124   if (!extent_callback_l_)
125     {
126       nc->dim_.set_empty ();
127     }
128   else if (!valid_b_)
129     {
130       nc->dim_= (*extent_callback_l_ ) (nc);
131       nc->valid_b_ = true;
132     }
133
134   r=dim_;
135   return r;
136 }
137
138 void
139 Dimension_cache::set_callback (Dim_cache_callback c)
140 {
141   extent_callback_l_ =c;
142 }
143
144