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 "paper-column.hh"
17 #include "line-of-score.hh"
18 #include "break-align-item.hh"
21 Spanner::do_break_processing()
25 if (line_l () || broken_b ())
28 Item * left = spanned_drul_[LEFT];
29 Item * right = spanned_drul_[RIGHT];
33 warning (_ ("Left spanpoint is right spanpoint"));
37 Link_array<Item> break_points = pscore_l_->broken_col_range (left,right);
39 break_points.insert (left,0);
40 break_points.push (right);
42 for (int i=1; i < break_points.size(); i++)
44 Drul_array<Item*> bounds;
45 bounds[LEFT] = break_points[i-1];
46 bounds[RIGHT] = break_points[i];
50 Item *&pc_l = bounds[d] ;
52 pc_l = pc_l->find_broken_piece(- d);
56 while ((flip(&d))!= LEFT);
58 Spanner *span_p = dynamic_cast<Spanner*>(clone ());
59 span_p->set_bounds(LEFT,bounds[LEFT]);
60 span_p->set_bounds(RIGHT,bounds[RIGHT]);
62 pscore_l_->typeset_element (span_p);
63 broken_into_l_arr_.push (span_p);
66 broken_into_l_arr_.sort (Spanner::compare);
70 Spanner::set_my_columns()
72 Direction i = (Direction) LEFT;
75 if (!spanned_drul_[i]->line_l())
76 set_bounds(i,spanned_drul_[i]->find_broken_piece((Direction) -i));
78 while (flip(&i) != LEFT);
82 Spanner::set_bounds(Direction d, Item*i)
91 Prevent the column -> line_of_score -> column -> line_of_score -> etc situation
93 if (d== LEFT && !dynamic_cast<Line_of_score*> (this))
95 set_parent (i, X_AXIS);
98 if (spanned_drul_[Direction(-d)] == spanned_drul_[d]
100 warning (_f ("Spanner `%s' has equal left and right spanpoints", classname (this)));
106 spanned_drul_[LEFT]=0;
107 spanned_drul_[RIGHT]=0;
110 Spanner::Spanner (Spanner const &s)
113 spanned_drul_[LEFT] = spanned_drul_[RIGHT] =0;
118 Spanner::spanner_length() const
120 Real l = spanned_drul_[LEFT]->relative_coordinate (0, X_AXIS);
121 Real r = spanned_drul_[RIGHT]->relative_coordinate (0, X_AXIS);
124 programming_error ("spanner with negative length");
130 Spanner::line_l() const
132 if (!spanned_drul_[LEFT] || !spanned_drul_[RIGHT])
134 if (spanned_drul_[LEFT]->line_l () != spanned_drul_[RIGHT]->line_l ())
136 return spanned_drul_[LEFT]->line_l();
141 Spanner::find_broken_piece (Line_of_score*l) const
143 int idx = binsearch_link_array (broken_into_l_arr_, (Spanner*)l, Spanner::compare);
148 return broken_into_l_arr_ [idx];
153 Spanner::compare (Spanner * const &p1, Spanner * const &p2)
155 return p1->line_l ()->rank_i_ - p2->line_l ()->rank_i_;
159 Spanner::broken_b() const
161 return broken_into_l_arr_.size();
165 Spanner::get_rods () const
172 Spanner::get_springs () const
179 Spanner::do_space_processing ()
181 Array<Rod> rs (get_rods ());
182 for (int i=0; i < rs.size (); i++)
184 rs[i].add_to_cols ();
187 Array<Spring> ss (get_springs ());
188 for (int i=0; i < ss.size (); i++)
190 ss[i].add_to_cols ();
195 If this is a broken spanner, return the amount the left end is to be
196 shifted horizontally so that the spanner starts after the initial
197 clef and key on the staves. This is necessary for ties, slurs,
198 crescendo and decrescendo signs, for example.
201 Spanner::get_broken_left_end_align () const
203 Paper_column *sc = dynamic_cast<Paper_column*> (spanned_drul_[LEFT]->column_l());
205 // Relevant only if left span point is first column in line
207 sc->break_status_dir () == RIGHT)
211 We used to do a full search for the Break_align_item.
212 But that doesn't make a difference, since the Paper_column
213 is likely to contain only a Break_align_item.
215 return sc->extent (X_AXIS)[RIGHT];