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