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