]> git.donarmstrong.com Git - lilypond.git/blob - lily/dimension-cache.cc
release: 1.3.8
[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 #include "graphical-element.hh"
12
13 Dimension_cache::Dimension_cache (Dimension_cache const &d)
14 {
15   init();
16   callback_l_ = d.callback_l_;
17   empty_b_ = d.empty_b_;
18   basic_offset_ = d.basic_offset_;
19   extra_offset_ = d.extra_offset_;
20   off_valid_b_ = d.off_valid_b_;
21   off_callback_l_ = d.off_callback_l_;
22 }
23
24 Dimension_cache::Dimension_cache ()
25 {
26   init();
27 }
28
29 void
30 Dimension_cache::init()
31 {
32   callback_l_ =0;
33
34   basic_offset_ =0.0;
35   extra_offset_ =0.0;
36   
37   elt_l_ = 0;
38   dim_.set_empty ();
39   parent_l_ =0;
40   valid_b_ = false;
41   empty_b_ = false;
42   off_valid_b_ = false;
43   off_callback_l_ =0;
44 }
45
46
47 void
48 Dimension_cache::invalidate ()
49 {
50   off_valid_b_ =false;
51   valid_b_ = false;
52 }
53
54
55 void
56 Dimension_cache::set_offset (Real x)
57 {
58   // ugh!
59   /*
60
61     UGH ! UGH !
62     
63    */
64   
65   basic_offset_ = x;
66 }
67
68 void
69 Dimension_cache::translate (Real x)
70 {
71   basic_offset_ += x;
72 }
73
74 Real
75 Dimension_cache::relative_coordinate (Dimension_cache *refp) const
76 {
77   if (refp == this)
78     return 0.0;
79
80   /*
81     We catch PARENT_L_ == nil case with this, but we crash if we did
82     not ask for the absolute coordinate (ie. REFP == nil.)
83     
84    */
85   if (refp == parent_l_)
86     return get_offset ();
87   else
88     return get_offset () + parent_l_->relative_coordinate (refp);
89 }
90
91 Axis
92 Dimension_cache::axis () const
93 {
94   if (elt_l_-> dim_cache_[X_AXIS] == this)
95     return X_AXIS;
96   else
97     return Y_AXIS;
98 }
99
100 Real
101 Dimension_cache::get_offset () const
102 {
103   if (!off_valid_b_ && off_callback_l_ )
104     {
105       Dimension_cache *d = (Dimension_cache*) this;
106       d->off_valid_b_ = true;
107       d->basic_offset_ = (*off_callback_l_) (d);
108     }
109
110   return basic_offset_ + extra_offset_;
111 }
112
113 Dimension_cache *
114 Dimension_cache::common_refpoint (Dimension_cache const* s) const
115 {
116   Link_array<Dimension_cache> my_groups;
117   for (Dimension_cache const *c = this; c ; c = c->parent_l_)
118     my_groups.push ((Dimension_cache*)c);
119   
120   Dimension_cache const *common=0;
121   
122   for (Dimension_cache const * d = s; !common && d; d = d->parent_l_)
123     common = (Dimension_cache const*)my_groups.find_l (d);
124
125   return (Dimension_cache*) common;
126 }
127
128
129
130 void
131 Dimension_cache::set_empty (bool b)
132 {
133   if (empty_b_ != b)
134     {
135       empty_b_ = b;
136       if (!empty_b_)
137         invalidate ();
138     }
139 }  
140
141 Interval
142 Dimension_cache::get_dim () const
143 {
144   Interval r;
145   if (empty_b_)
146     {
147       r.set_empty ();
148       return r;
149     }
150       
151   if (!valid_b_)
152     {
153       Dimension_cache *nc = ((Dimension_cache*)this);
154       nc->dim_= (*callback_l_ ) (nc);
155       nc->valid_b_ = true;
156     }
157
158   r=dim_;
159
160   return r;
161 }
162
163 void
164 Dimension_cache::set_callback (Dim_cache_callback c)
165 {
166   callback_l_ =c;
167 }
168
169 void
170 Dimension_cache::set_offset_callback (Offset_cache_callback c)
171 {
172   off_callback_l_ =c;
173 }