]> git.donarmstrong.com Git - lilypond.git/blob - lily/graphical-element.cc
release: 0.1.61
[lilypond.git] / lily / graphical-element.cc
1 /*
2   graphical-element.cc -- implement Graphical_element
3
4   source file of the GNU LilyPond music typesetter
5
6   (c)  1997--1998 Han-Wen Nienhuys <hanwen@stack.nl>
7 */
8
9 #include "graphical-element.hh"
10 #include "axis-group-element.hh"
11 #include "debug.hh"
12
13 bool
14 Graphical_element::empty_b () const
15 {
16   return empty_b_; 
17 }
18
19 Graphical_element::Graphical_element ()
20 {
21   init ();
22 }
23
24 Graphical_element::Graphical_element (Graphical_element const &s)
25 {
26   init ();
27   empty_b_ = s.empty_b_;
28   axis_group_l_a_[0] = axis_group_l_a_[1] =0;
29   offset_ = Offset (0,0);
30
31
32 Graphical_element::~Graphical_element ()
33 {
34   
35 }
36
37 void
38 Graphical_element::init ()
39 {
40   empty_b_ = false;
41   axis_group_l_a_[X_AXIS] = axis_group_l_a_[Y_AXIS] =0;
42   offset_ = Offset (0,0);
43   cached_valid_b_a_ [X_AXIS] = cached_valid_b_a_[Y_AXIS] = false;
44 }
45
46 void
47 Graphical_element::invalidate_cache (Axis a)
48 {
49   Graphical_element * g = this;
50   while (g && g->cached_valid_b_a_[a])
51     {
52       g->cached_valid_b_a_ [a] = false;  
53       g = g->axis_group_l_a_[a];
54     }
55 }
56
57 Real
58 Graphical_element::absolute_coordinate (Axis a) const
59 {
60   Real r = offset_[a];
61   for (Axis_group_element * axis_group_l = axis_group_l_a_[a];
62        axis_group_l; axis_group_l = axis_group_l->axis_group_l_a_[a])
63         
64     r += axis_group_l->offset_[a];
65   return r;
66 }
67  
68
69 Offset
70 Graphical_element::absolute_offset() const
71 {
72   return Offset (absolute_coordinate (X_AXIS), absolute_coordinate (Y_AXIS));
73 }
74
75 void
76 Graphical_element::translate_axis (Real y, Axis a)
77 {
78   if (axis_group_l_a_[a])
79     axis_group_l_a_[a]->invalidate_cache (a);
80   offset_[a] += y;
81 }
82
83 Real
84 Graphical_element::relative_coordinate (Axis_group_element*e, Axis a) const
85 {
86   Real r =0.0;
87   for (Axis_group_element * axis_group_l = axis_group_l_a_[a];
88        axis_group_l != e;
89        axis_group_l = axis_group_l->axis_group_l_a_[a])
90     r +=  axis_group_l->offset_[a];
91
92   return r;
93 }
94
95 Axis_group_element* 
96 Graphical_element::common_group (Graphical_element const* s, Axis a) const
97 {
98   Link_array<Axis_group_element> my_groups;
99   for (Axis_group_element * axis_group_l = axis_group_l_a_[a];
100        axis_group_l;
101        axis_group_l = axis_group_l->axis_group_l_a_[a])
102     my_groups.push (axis_group_l);
103
104   Axis_group_element* common_l=0;
105   for (Axis_group_element * axis_group_l = s->axis_group_l_a_[a];
106        !common_l && axis_group_l;
107        axis_group_l = axis_group_l->axis_group_l_a_[a])
108     common_l = my_groups.find_l (axis_group_l);
109
110   return common_l;
111 }
112
113
114
115 void
116 Graphical_element::translate (Offset offset)
117 {
118   translate_axis (offset[Y_AXIS], Y_AXIS);
119   translate_axis (offset[X_AXIS], X_AXIS);
120 }
121
122 Interval
123 Graphical_element::width() const
124 {
125   return extent (X_AXIS);
126 }
127
128 void
129 Graphical_element::set_empty (bool b)
130 {
131   if (empty_b_ != b)
132     {
133       empty_b_ = b;
134       if (!empty_b_)
135         {
136           invalidate_cache (X_AXIS);
137           invalidate_cache (Y_AXIS);
138         }
139     }
140   
141 }
142
143 Interval
144 Graphical_element::extent (Axis a) const
145 {
146   if (empty_b_)
147     return Interval ();
148   
149   if (!cached_valid_b_a_[a])
150     {
151       Graphical_element *self = (Graphical_element*)this;
152       self->cached_dimension_a_[a] = (a == X_AXIS)? do_width(): do_height ();
153       self->cached_valid_b_a_[a] = true;
154     }
155   
156   Interval r(cached_dimension_a_[a]);
157   if (!r.empty_b()) // float exception on DEC Alpha
158     r+=offset_[a];
159
160   return r;
161 }
162
163 Interval
164 Graphical_element::height() const
165 {
166   return extent (Y_AXIS);
167 }
168
169 void
170 Graphical_element::unlink ()
171 {
172     for (int j=0; j < 2; j++)
173     if (axis_group_l_a_[j])
174       axis_group_l_a_[j]->remove_element (this);
175 }
176
177 void
178 Graphical_element::junk_links ()
179 {
180     axis_group_l_a_[X_AXIS] = axis_group_l_a_[Y_AXIS] =0;
181 }
182
183 void
184 Graphical_element::print () const
185 {
186 #ifndef NPRINT
187   if (offset_.x() || offset_.y ())
188     DOUT << "offset: " << offset_.str() ;
189   DOUT << "\n";
190 #endif
191 }
192
193 IMPLEMENT_IS_TYPE_B(Graphical_element);
194