]> git.donarmstrong.com Git - lilypond.git/blob - lily/dimension-cache.cc
release: 1.2.4
[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 Real
73 Dimension_cache::relative_coordinate (Dimension_cache *refp) const
74 {
75   if (refp == this)
76     return 0.0;
77
78   /*
79     We catch PARENT_L_ == nil case with this, but we crash if we did
80     not ask for the absolute coordinate (ie. REFP == nil.)
81     
82    */
83   if (refp == parent_l_)
84     return offset_;
85   else
86     return offset_ + parent_l_->relative_coordinate (refp);
87 }
88
89 Dimension_cache *
90 Dimension_cache::common_refpoint (Dimension_cache const* s) const
91 {
92   Link_array<Dimension_cache> my_groups;
93   for (Dimension_cache const *c = this; c ; c = c->parent_l_)
94     my_groups.push ((Dimension_cache*)c);
95   
96   Dimension_cache const *common=0;
97   
98   for (Dimension_cache const * d = s; !common && d; d = d->parent_l_)
99     common = (Dimension_cache const*)my_groups.find_l (d);
100
101   return (Dimension_cache*) common;
102 }
103
104
105
106 void
107 Dimension_cache::set_empty (bool b)
108 {
109   if (empty_b_ != b)
110     {
111       empty_b_ = b;
112       if (!empty_b_)
113         invalidate ();
114     }
115 }  
116
117 Interval
118 Dimension_cache::get_dim () const
119 {
120   Interval r;
121   if (empty_b_)
122     {
123       r.set_empty ();
124       return r;
125     }
126       
127   if (!valid_b_)
128     {
129       Dimension_cache *nc = ((Dimension_cache*)this);
130       nc->dim_= (*callback_l_ ) (nc);
131       nc->valid_b_ = true;
132     }
133
134   r=dim_;
135
136   return r;
137 }
138
139 void
140 Dimension_cache::set_callback (Dim_cache_callback c)
141 {
142   callback_l_ =c;
143 }
144