2 spanner.cc -- implement Spanner
4 source file of the GNU LilyPond music typesetter
6 (c) 1996, 1997--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
9 #include "dimension-cache.hh"
12 #include "paper-column.hh"
13 #include "paper-score.hh"
14 #include "molecule.hh"
15 #include "paper-outputter.hh"
16 #include "score-column.hh"
17 #include "line-of-score.hh"
18 #include "break-align-item.hh"
21 Spanner::break_into_pieces ()
23 if (line_l () || broken_b ())
26 Item * left = spanned_drul_[LEFT];
27 Item * right = spanned_drul_[RIGHT];
31 warning (_ ("Left spanpoint is right spanpoint"));
35 Link_array<Item> break_points = pscore_l_->broken_col_range (left,right);
37 break_points.insert (left,0);
38 break_points.push (right);
40 for (int i=1; i < break_points.size(); i++)
42 Drul_array<Item*> bounds;
43 bounds[LEFT] = break_points[i-1];
44 bounds[RIGHT] = break_points[i];
48 Item *&pc_l = bounds[d] ;
50 pc_l = pc_l->find_broken_piece(- d);
54 while ((flip(&d))!= LEFT);
56 Spanner *span_p = dynamic_cast<Spanner*>(clone ());
57 span_p->set_bounds(LEFT,bounds[LEFT]);
58 span_p->set_bounds(RIGHT,bounds[RIGHT]);
60 pscore_l_->typeset_element (span_p);
61 broken_into_l_arr_.push (span_p);
64 broken_into_l_arr_.sort (Spanner::compare);
68 Spanner::set_my_columns()
70 Direction i = (Direction) LEFT;
73 if (!spanned_drul_[i]->line_l())
74 set_bounds(i,spanned_drul_[i]->find_broken_piece((Direction) -i));
76 while (flip(&i) != LEFT);
80 Spanner::set_bounds(Direction d, Item*i)
89 Prevent the column -> line_of_score -> column -> line_of_score -> etc situation
91 if (d== LEFT && !dynamic_cast<Line_of_score*> (this))
93 set_parent (i, X_AXIS);
96 if (spanned_drul_[Direction(-d)] == spanned_drul_[d]
98 warning (_f ("Spanner `%s' has equal left and right spanpoints", classname (this)));
104 Spanner::do_break_processing()
106 break_into_pieces ();
111 spanned_drul_[LEFT]=0;
112 spanned_drul_[RIGHT]=0;
115 Spanner::Spanner (Spanner const &s)
118 spanned_drul_[LEFT] = spanned_drul_[RIGHT] =0;
123 Spanner::spanner_length() const
125 Real l = spanned_drul_[LEFT]->relative_coordinate (0, X_AXIS);
126 Real r = spanned_drul_[RIGHT]->relative_coordinate (0, X_AXIS);
129 warning (_ ("spanner with negative length"));
135 Spanner::line_l() const
137 if (!spanned_drul_[LEFT] || !spanned_drul_[RIGHT])
139 if (spanned_drul_[LEFT]->line_l () != spanned_drul_[RIGHT]->line_l ())
141 return spanned_drul_[LEFT]->line_l();
146 Spanner::find_broken_piece (Line_of_score*l) const
148 Spanner* me = (Spanner*) this;
149 me->break_into_pieces ();
151 int idx = binsearch_link_array (broken_into_l_arr_, (Spanner*)l, Spanner::compare);
156 return broken_into_l_arr_ [idx];
161 Spanner::compare (Spanner * const &p1, Spanner * const &p2)
163 return p1->line_l ()->rank_i_ - p2->line_l ()->rank_i_;
167 Spanner::broken_b() const
169 return broken_into_l_arr_.size();
173 Spanner::get_rods () const
180 Spanner::get_springs () const
187 Spanner::do_space_processing ()
189 Array<Rod> rs (get_rods ());
190 for (int i=0; i < rs.size (); i++)
192 rs[i].add_to_cols ();
195 Array<Spring> ss (get_springs ());
196 for (int i=0; i < ss.size (); i++)
198 ss[i].add_to_cols ();
203 If this is a broken spanner, return the amount the left end is to be
204 shifted horizontally so that the spanner starts after the initial
205 clef and key on the staves. This is necessary for ties, slurs,
206 crescendo and decrescendo signs, for example.
209 Spanner::get_broken_left_end_align () const
211 Score_column *sc = dynamic_cast<Score_column*> (spanned_drul_[LEFT]->column_l());
213 // Relevant only if left span point is first column in line
215 sc->break_status_dir () == RIGHT)
219 We used to do a full search for the Break_align_item.
220 But that doesn't make a difference, since the Score_column
221 is likely to contain only a Break_align_item.
223 return sc->extent (X_AXIS)[RIGHT];