2 spanner.cc -- implement Spanner
4 source file of the GNU LilyPond music typesetter
6 (c) 1996, 1997--2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
10 #include "dimension-cache.hh"
13 #include "paper-column.hh"
14 #include "paper-score.hh"
15 #include "molecule.hh"
16 #include "paper-outputter.hh"
17 #include "paper-column.hh"
18 #include "line-of-score.hh"
19 #include "break-align-item.hh"
22 Spanner::do_break_processing()
26 if (line_l () || broken_b ())
29 Item * left = spanned_drul_[LEFT];
30 Item * right = spanned_drul_[RIGHT];
34 warning (_ ("Left spanpoint is right spanpoint"));
38 Link_array<Item> break_points = pscore_l_->broken_col_range (left,right);
40 break_points.insert (left,0);
41 break_points.push (right);
43 for (int i=1; i < break_points.size(); i++)
45 Drul_array<Item*> bounds;
46 bounds[LEFT] = break_points[i-1];
47 bounds[RIGHT] = break_points[i];
51 Item *&pc_l = bounds[d] ;
53 pc_l = pc_l->find_broken_piece(- d);
57 while ((flip(&d))!= LEFT);
59 Spanner *span_p = dynamic_cast<Spanner*>(clone ());
60 span_p->set_bounds(LEFT,bounds[LEFT]);
61 span_p->set_bounds(RIGHT,bounds[RIGHT]);
63 pscore_l_->typeset_element (span_p);
64 broken_into_l_arr_.push (span_p);
67 broken_into_l_arr_.sort (Spanner::compare);
71 Spanner::set_my_columns()
73 Direction i = (Direction) LEFT;
76 if (!spanned_drul_[i]->line_l())
77 set_bounds(i,spanned_drul_[i]->find_broken_piece((Direction) -i));
79 while (flip(&i) != LEFT);
83 Spanner::set_bounds(Direction d, Item*i)
92 Prevent the column -> line_of_score -> column -> line_of_score -> etc situation
94 if (d== LEFT && !dynamic_cast<Line_of_score*> (this))
96 set_parent (i, X_AXIS);
99 if (spanned_drul_[Direction(-d)] == spanned_drul_[d]
101 warning (_f ("Spanner `%s' has equal left and right spanpoints", classname (this)));
107 spanned_drul_[LEFT]=0;
108 spanned_drul_[RIGHT]=0;
111 Spanner::Spanner (Spanner const &s)
114 spanned_drul_[LEFT] = spanned_drul_[RIGHT] =0;
119 Spanner::spanner_length() const
121 Real l = spanned_drul_[LEFT]->relative_coordinate (0, X_AXIS);
122 Real r = spanned_drul_[RIGHT]->relative_coordinate (0, X_AXIS);
125 programming_error ("spanner with negative length");
131 Spanner::line_l() const
133 if (!spanned_drul_[LEFT] || !spanned_drul_[RIGHT])
135 if (spanned_drul_[LEFT]->line_l () != spanned_drul_[RIGHT]->line_l ())
137 return spanned_drul_[LEFT]->line_l();
142 Spanner::find_broken_piece (Line_of_score*l) const
144 int idx = binsearch_link_array (broken_into_l_arr_, (Spanner*)l, Spanner::compare);
149 return broken_into_l_arr_ [idx];
154 Spanner::compare (Spanner * const &p1, Spanner * const &p2)
156 return p1->line_l ()->rank_i_ - p2->line_l ()->rank_i_;
160 Spanner::broken_b() const
162 return broken_into_l_arr_.size();
166 Spanner::get_rods () const
173 Spanner::get_springs () const
180 Spanner::do_space_processing ()
182 Array<Rod> rs (get_rods ());
183 for (int i=0; i < rs.size (); i++)
185 rs[i].add_to_cols ();
188 Array<Spring> ss (get_springs ());
189 for (int i=0; i < ss.size (); i++)
191 if (isinf (ss[i].distance_f_))
192 programming_error ("weird spring");
194 ss[i].add_to_cols ();
199 If this is a broken spanner, return the amount the left end is to be
200 shifted horizontally so that the spanner starts after the initial
201 clef and key on the staves. This is necessary for ties, slurs,
202 crescendo and decrescendo signs, for example.
205 Spanner::get_broken_left_end_align () const
207 Paper_column *sc = dynamic_cast<Paper_column*> (spanned_drul_[LEFT]->column_l());
209 // Relevant only if left span point is first column in line
211 sc->break_status_dir () == RIGHT)
215 We used to do a full search for the Break_align_item.
216 But that doesn't make a difference, since the Paper_column
217 is likely to contain only a Break_align_item.
219 return sc->extent (X_AXIS)[RIGHT];