]> git.donarmstrong.com Git - lilypond.git/blob - lily/dimension-cache.cc
release: 1.3.13
[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 "score-element.hh"
12
13
14 Dimension_cache::Dimension_cache (Dimension_cache const &d)
15 {
16   init();
17   callback_l_ = d.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   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   Link_array<Dimension_cache> my_groups;
94   for (Dimension_cache const *c = this; c ; c = c->parent_l_)
95     my_groups.push ((Dimension_cache*)c);
96   
97   Dimension_cache const *common=0;
98   
99   for (Dimension_cache const * d = s; !common && d; d = d->parent_l_)
100     common = (Dimension_cache const*)my_groups.find_l (d);
101
102   return (Dimension_cache*) common;
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 (!callback_l_)
117     {
118       nc->dim_.set_empty ();
119     }
120   else if (!valid_b_)
121     {
122       nc->dim_= (*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   callback_l_ =c;
134 }
135
136