]> git.donarmstrong.com Git - lilypond.git/blob - lily/dimension-cache.cc
release: 1.3.34
[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--2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7  */
8
9 #include "dimension-cache.hh"
10 #include "parray.hh"
11 #include "score-element.hh"
12
13
14 Dimension_cache::Dimension_cache (Dimension_cache const &d)
15 {
16   init();
17   extent_callback_l_ = d.extent_callback_l_;
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   parent_l_ = d.parent_l_;  
23 }
24
25 Dimension_cache::Dimension_cache ()
26 {
27   init();
28 }
29
30 void
31 Dimension_cache::init()
32 {
33   extent_callback_l_ =0;
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   off_valid_b_ = false;
42 }
43
44
45 void
46 Dimension_cache::translate (Real x)
47 {
48   extra_offset_ += x;
49 }
50
51 Real
52 Dimension_cache::relative_coordinate (Dimension_cache *refp) const
53 {
54   if (refp == this)
55     return 0.0;
56
57   /*
58     We catch PARENT_L_ == nil case with this, but we crash if we did
59     not ask for the absolute coordinate (ie. REFP == nil.)
60     
61    */
62   if (refp == parent_l_)
63     return get_offset ();
64   else
65     return get_offset () + parent_l_->relative_coordinate (refp);
66 }
67
68 Axis
69 Dimension_cache::axis () const
70 {
71   if (elt_l_-> dim_cache_[X_AXIS] == this)
72     return X_AXIS;
73   else
74     return Y_AXIS;
75 }
76
77 Real
78 Dimension_cache::get_offset () const
79 {
80   Dimension_cache *me = (Dimension_cache*) this;
81   while (off_callbacks_.size ())
82     {
83       Offset_cache_callback c = me->off_callbacks_[0];
84       me->off_callbacks_.del (0);
85       me->basic_offset_ += (*c) (me);
86     }
87   return basic_offset_ + extra_offset_;
88 }
89
90 Dimension_cache *
91 Dimension_cache::common_refpoint (Dimension_cache const* s) const
92 {
93   /*
94     I don't like the quadratic aspect of this code. Maybe this should
95     be rewritten some time, but the largest chain of parents might be
96     10 high or so, so it shouldn't be a real issue. */
97   for (Dimension_cache const *c = this; c; c = c->parent_l_)
98     for (Dimension_cache const * d = s; d; d = d->parent_l_)
99       if (d == c)
100         return (Dimension_cache*)d;
101
102   return 0;
103 }
104
105 Interval
106 Dimension_cache::point_dimension_callback (Dimension_cache const* )
107 {
108   return Interval (0,0);
109 }
110
111 Interval
112 Dimension_cache::get_dim () const
113 {
114   Interval r;
115   Dimension_cache *nc = ((Dimension_cache*)this);
116   if (!extent_callback_l_)
117     {
118       nc->dim_.set_empty ();
119     }
120   else if (!valid_b_)
121     {
122       nc->dim_= (*extent_callback_l_ ) (nc);
123       nc->valid_b_ = true;
124     }
125
126   r=dim_;
127   return r;
128 }
129
130 void
131 Dimension_cache::set_callback (Dim_cache_callback c)
132 {
133   extent_callback_l_ =c;
134 }
135
136