]> git.donarmstrong.com Git - lilypond.git/blob - lily/dimension-cache.cc
patch::: 1.2.0.jcn1
[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> my_groups;
104   for (Dimension_cache const *c = this; c ; c = c->parent_l_)
105     my_groups.push ((Dimension_cache*)c);
106   
107   Dimension_cache const *common=0;
108   
109   for (Dimension_cache const * d = s; !common && d; d = d->parent_l_)
110     common = (Dimension_cache const*)my_groups.find_l (d);
111
112   return (Dimension_cache*)common;
113 }
114
115
116
117 void
118 Dimension_cache::set_empty (bool b)
119 {
120   if (empty_b_ != b)
121     {
122       empty_b_ = b;
123       if (!empty_b_)
124         invalidate ();
125     }
126 }  
127
128 void
129 Dimension_cache::set_dim (Interval v)
130 {
131   dim_ = v;
132   valid_b_ = true;
133 }
134   
135
136 Interval
137 Dimension_cache::get_dim () const
138 {
139   Interval r;
140   if (empty_b_)
141     {
142       r.set_empty ();
143       return r;
144     }
145       
146   if (!valid_b_)
147     {
148       Dimension_cache *nc = ((Dimension_cache*)this);
149       nc->dim_= (*callback_l_ ) (nc);
150       nc->valid_b_ = true;
151     }
152
153   r=dim_;
154   if (!r.empty_b()) // float exception on DEC Alpha
155     r += offset_;
156
157   return r;
158 }
159
160 void
161 Dimension_cache::set_callback (Dim_cache_callback c)
162 {
163   callback_l_ =c;
164 }
165
166 Real
167 Dimension_cache::offset () const
168 {
169   return offset_;
170 }