]> git.donarmstrong.com Git - lilypond.git/blob - lily/dimension-cache.cc
release: 1.1.35
[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--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7  */
8
9 #include "dimension-cache.hh"
10 #include "parray.hh"
11
12 Dimension_cache::Dimension_cache (Dimension_cache const &d)
13 {
14   init();
15   callback_l_ = d.callback_l_;
16   empty_b_ = d.empty_b_;
17   offset_ = d.offset_; //let's hope others will copy  the refpoint appropriately. 
18 }
19
20 Dimension_cache::Dimension_cache ()
21 {
22   init();
23 }
24
25 void
26 Dimension_cache::init()
27 {
28   callback_l_ =0;
29   offset_ =0.0;
30   elt_l_ = 0;
31   dim_.set_empty ();
32   parent_l_ =0;
33   valid_b_ = false;
34   empty_b_ = false;
35 }
36
37
38 void
39 Dimension_cache::invalidate ()
40 {
41   valid_b_ = false;
42   invalidate_dependencies ();
43 }
44
45 void
46 Dimension_cache::invalidate_dependencies ()
47 {
48   for (int i=0; i < dependencies_l_arr_.size (); i++)
49     {
50       Dimension_cache * g = dependencies_l_arr_[i];
51       if (g->valid_b_)
52         {
53           g->invalidate ();
54         }
55     }
56 }
57
58 void
59 Dimension_cache::set_offset (Real x)
60 {
61   invalidate_dependencies ();
62   offset_ = x;
63 }
64
65 void
66 Dimension_cache::translate (Real x)
67 {
68   invalidate_dependencies ();
69   offset_ += x;
70 }
71
72
73 Real
74 Dimension_cache::absolute_coordinate () const
75 {
76   Real r = offset_;
77   for (Dimension_cache * c = parent_l_;
78        c; c = c->parent_l_)
79     r += c->offset_;
80   return r;
81 }
82
83 /*
84   what *should* these functions *do* anyway.
85  */
86 Real
87 Dimension_cache::relative_coordinate (Dimension_cache *d) const
88 {
89   Real r =0.0;
90   if (d == this)                // UGH
91     return 0.0;
92
93   for (Dimension_cache* c = parent_l_;
94        c != d;
95        c = c->parent_l_)
96     r +=  c->offset_;
97   return r;
98 }
99
100 Dimension_cache *
101 Dimension_cache::common_group (Dimension_cache const* s) const
102 {
103   Link_array<Dimension_cache const> my_groups;
104   for (Dimension_cache const *c = this;
105        c ; c = c->parent_l_)
106     my_groups.push (c);
107   
108   
109   Dimension_cache const *common=0;
110   
111   for (Dimension_cache const * d = s;
112        !common && d;
113        d = d->parent_l_)
114     common = my_groups.find_l (d);
115
116   return (Dimension_cache*)common;
117 }
118
119
120
121 void
122 Dimension_cache::set_empty (bool b)
123 {
124   if (empty_b_ != b)
125     {
126       empty_b_ = b;
127       if (!empty_b_)
128         invalidate ();
129     }
130 }  
131
132 void
133 Dimension_cache::set_dim (Interval v)
134 {
135   dim_ = v;
136   valid_b_ = true;
137 }
138   
139
140 Interval
141 Dimension_cache::get_dim () const
142 {
143   Interval r;
144   if (empty_b_)
145     {
146       r.set_empty ();
147       return r;
148     }
149       
150   if (!valid_b_)
151     {
152       Dimension_cache *nc = ((Dimension_cache*)this);
153       nc->dim_= (*callback_l_ ) (nc);
154       nc->valid_b_ = true;
155     }
156
157   r=dim_;
158   if (!r.empty_b()) // float exception on DEC Alpha
159     r += offset_;
160
161   return r;
162 }
163
164 void
165 Dimension_cache::set_callback (Dim_cache_callback c)
166 {
167   callback_l_ =c;
168 }