]> git.donarmstrong.com Git - lilypond.git/blob - lily/staff-side.cc
release: 1.2.12
[lilypond.git] / lily / staff-side.cc
1 /*   
2   g-staff-side.cc --  implement Staff_side_element
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
10 #include "staff-side.hh"
11 #include "staff-symbol.hh"
12 #include "debug.hh"
13 #include "warn.hh"
14 #include "dimensions.hh"
15 #include "dimension-cache.hh"
16
17 Staff_side_element::Staff_side_element ()
18 {
19   dir_ = CENTER;
20   to_position_l_ = 0;
21   set_elt_property (transparent_scm_sym, SCM_BOOL_T);
22   axis_ = Y_AXIS;
23 }
24
25 void
26 Staff_side_element::do_pre_processing ()
27 {
28   if (!dir_)
29     dir_ = get_default_direction ();
30
31   if (axis_ == X_AXIS)
32     position_self ();
33 }
34
35 Direction
36 Staff_side_element::get_default_direction () const
37 {
38   return DOWN;
39 }
40
41
42 void
43 Staff_side_element::set_victim (Score_element *e)
44 {
45   add_dependency (e);
46   to_position_l_ = e;
47   to_position_l_->set_parent (this, axis_);
48 }
49
50 void
51 Staff_side_element::add_support (Score_element*e)
52 {
53   add_dependency (e);
54   support_l_arr_.push (e);
55 }
56
57
58 void
59 Staff_side_element::do_substitute_element_pointer (Score_element*o, Score_element*n)
60 {
61   Staff_symbol_referencer::do_substitute_element_pointer (o,n);
62   if (o == to_position_l_)
63     to_position_l_ = n;
64   else
65     support_l_arr_.unordered_substitute (o,n);
66 }
67
68 void
69 Staff_side_element::position_self ()
70 {
71   if (to_position_l_ &&
72       to_position_l_->get_elt_property (transparent_scm_sym) != SCM_BOOL_F)
73     return;
74
75   Axis other = Axis ((axis_ + 1) % NO_AXES);
76   if (parent_l (axis_)->empty_b (axis_)
77       &&parent_l (axis_)->empty_b (other)) // guh
78     {
79       warning (_("No support; erasing script"));
80       to_position_l_->set_empty (X_AXIS,Y_AXIS);
81       to_position_l_->set_elt_property (transparent_scm_sym, SCM_BOOL_T);
82       set_empty (X_AXIS, Y_AXIS);
83       return ;
84     }
85   
86   Interval dim;
87   Graphical_element *common = 0;
88   if (support_l_arr_.size ())
89     {
90       common = common_refpoint (typecast_array (support_l_arr_, (Graphical_element*)0),
91                                 axis_);
92
93       for (int i=0; i < support_l_arr_.size (); i++)
94         {
95           Score_element * e = support_l_arr_ [i];
96           Real coord = e->relative_coordinate (common, axis_);
97
98           dim.unite (coord + e->extent (axis_));
99         }
100     }
101   else
102      common = parent_l (axis_);
103
104   if (dim.empty_b ())
105     {
106       dim = Interval(0,0);
107     }
108
109   
110   Interval sym_dim
111     = to_position_l_
112     ? to_position_l_->extent (axis_)
113     : Interval(0,0);
114
115   Real off =  relative_coordinate (common, axis_);
116
117   SCM pad = remove_elt_property (padding_scm_sym);
118   if (pad != SCM_BOOL_F)
119     {
120       off += gh_scm2double (SCM_CDR(pad)) * dir_;
121     }
122   Real total_off = dim[dir_] + off;
123
124   /*
125     no_staff_support_scm_sym is ugh bugfix to get staccato dots right.
126    */
127   if (to_position_l_ && to_position_l_->get_elt_property (no_staff_support_scm_sym) == SCM_BOOL_F)
128      total_off += - sym_dim[-dir_];
129   
130   dim_cache_[axis_]->set_offset (total_off);
131   if (fabs (total_off) > 100 CM)
132     programming_error ("Huh ? Improbable staff side dim.");
133 }
134
135 void
136 Staff_side_element::do_post_processing ()
137 {
138   if (axis_ == Y_AXIS)
139     position_self ();
140 }
141
142
143 void
144 Staff_side_element::do_add_processing ()
145 {
146   if (get_elt_property (no_staff_support_scm_sym) == SCM_BOOL_F
147       && axis_ == Y_AXIS && staff_symbol_l ())
148     {
149       add_support (staff_symbol_l ());
150     }
151 }
152
153 Interval
154 Staff_side_element::do_height () const
155 {
156   Interval i;
157   if (to_position_l_)
158     return to_position_l_->extent (Y_AXIS);
159   return i;
160 }
161
162 void
163 Staff_side_element::do_print () const
164 {
165 #ifndef NPRINT
166   if (to_position_l_)
167     DEBUG_OUT << "positioning " << to_position_l_->name();
168
169   DEBUG_OUT << "axis == " << axis_name_str (axis_)
170        << ", dir == " << to_str ((int)dir_ );
171 #endif
172 }
173
174
175 Interval
176 Staff_side_item::do_width () const
177 {
178   Interval i;
179   if (to_position_l_)
180     return to_position_l_->extent (X_AXIS);
181   return i;
182 }
183
184 void
185 Staff_side_item::do_print () const
186 {
187   Staff_side_element::do_print ();
188 }
189
190 void
191 Staff_side_spanner::do_print () const
192 {
193   Staff_side_element::do_print ();
194 }