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