]> git.donarmstrong.com Git - lilypond.git/blob - lily/spanner.cc
release: 1.0.1
[lilypond.git] / lily / spanner.cc
1 /*
2   spanner.cc -- implement Spanner
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1996, 1997--1998 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
8
9 #include "debug.hh"
10 #include "spanner.hh"
11 #include "p-col.hh"
12 #include "p-score.hh"
13 #include "tex-outputter.hh"
14 #include "molecule.hh"
15
16 IMPLEMENT_IS_TYPE_B1(Spanner,Score_element);
17
18 void
19 Spanner::do_print() const
20 {
21 #ifndef NPRINT
22   DOUT << "Between " << spanned_drul_[LEFT]->name ()
23        << " and " << spanned_drul_[RIGHT]->name() << '\n';
24   if (broken_into_l_arr_.size())
25     {
26       DOUT << "with broken pieces:\n";
27       for (int i=0; i < broken_into_l_arr_.size (); i++)
28         broken_into_l_arr_[i]->print ();
29     }  
30 #endif
31 }
32
33 void
34 Spanner::break_into_pieces ()
35 {
36   if (broken_into_l_arr_.size())
37     return; 
38          
39   Item * left = spanned_drul_[LEFT];
40   Item * right = spanned_drul_[RIGHT];
41   
42   if  (left == right)
43     {
44       warning (_ ("left spanpoint is right spanpoint\n"));
45       return;
46     }
47   
48   Link_array<Item> break_cols = pscore_l_->broken_col_range (left,right);
49   Link_array<Spanner> broken_into_l_arr;
50
51   break_cols.insert (left,0);
52   break_cols.push (right);
53
54   for (int i=1; i < break_cols.size(); i++) 
55     {
56       Spanner* span_p = clone()->access_Spanner ();
57       left = break_cols[i-1];
58       right = break_cols[i];
59       if (!right->line_l())
60         right = right->find_prebroken_piece(LEFT);
61       if (!left->line_l())
62         left = left->find_prebroken_piece(RIGHT);
63
64       assert (left&&right && left->line_l() == right->line_l());
65
66       span_p->set_bounds(LEFT,left);
67       span_p->set_bounds(RIGHT,right);
68         
69       pscore_l_->typeset_broken_spanner (span_p);
70       broken_into_l_arr.push (span_p);
71     }
72    
73   broken_into_l_arr_ = broken_into_l_arr;
74 }
75
76 void
77 Spanner::set_my_columns()
78 {
79   Direction i = (Direction)1;
80   do 
81     {
82       if (!spanned_drul_[i]->line_l())
83         set_bounds(i,spanned_drul_[i]->find_prebroken_piece((Direction)-i));
84     } 
85   while (flip(&i) != 1);
86 }       
87
88
89 void
90 Spanner::set_bounds(Direction d, Item*i)
91 {
92   if (spanned_drul_[d])
93     spanned_drul_[d]->attached_span_l_arr_.substitute(this,0);
94   
95   spanned_drul_[d] =i;
96   if (i)
97     i->attached_span_l_arr_.push(this);
98
99   if  (spanned_drul_[Direction(-d)] == spanned_drul_[d]
100        && i)
101     warning (_f ("Spanner `%s\' with equal left and right spanpoints", name ()));
102 }
103
104 void
105 Spanner::do_break_processing()
106 {
107   if (!line_l())
108     {
109       break_into_pieces ();
110       for (int i=0; i < broken_into_l_arr_.size(); i++)
111         broken_into_l_arr_[i]->handle_broken_dependencies();
112     }
113   else 
114     {
115       handle_broken_dependencies();
116     }
117 }
118
119 Spanner* 
120 Spanner::access_Spanner ()
121 {
122   return this;
123 }
124
125 Spanner::Spanner ()
126 {
127   spanned_drul_[LEFT]=0;
128   spanned_drul_[RIGHT]=0;
129 }
130
131 void
132 Spanner::do_brew_molecule () 
133 {
134   if (transparent_b_)
135     return ;
136   Molecule *output= brew_molecule_p ();
137   Offset left_off (spanned_drul_[LEFT]->absolute_coordinate(X_AXIS), 0);
138   Offset o = absolute_offset() + left_off;
139   pscore_l_->outputter_l_->output_molecule (output, o, name ());
140   delete output;
141 }
142
143 Interval
144 Spanner::do_width() const
145 {
146   Real l = spanned_drul_[LEFT]->absolute_coordinate (X_AXIS);
147   Real r = spanned_drul_[RIGHT]->absolute_coordinate (X_AXIS);
148   assert (r>=l);
149         
150   return Interval (0, r-l);
151 }
152
153 Line_of_score *
154 Spanner::line_l() const
155 {
156   if (!spanned_drul_[LEFT] || !spanned_drul_[RIGHT])
157     return 0;
158   if (spanned_drul_[LEFT]->line_l() != spanned_drul_[RIGHT]->line_l())
159     return 0;
160   return spanned_drul_[LEFT]->line_l();
161 }
162
163
164 Spanner*
165 Spanner::find_broken_piece (Line_of_score*l) const
166 {
167   for (int i=0; i < broken_into_l_arr_.size(); i++)
168     if (broken_into_l_arr_[i]->line_l() == l)
169       return broken_into_l_arr_[i];
170   return 0;                                
171           
172 }
173
174 bool
175 Spanner::broken_b() const
176 {
177   return broken_into_l_arr_.size();
178 }
179
180 void
181 Spanner::do_unlink() 
182 {
183   set_bounds (LEFT, 0);
184   set_bounds (RIGHT, 0);
185 }
186
187 void
188 Spanner::do_junk_links()
189 {
190   spanned_drul_[LEFT] = spanned_drul_[RIGHT] =0;
191 }
192
193 Array<Rod>
194 Spanner::get_rods () const
195 {
196   Array<Rod> r;
197   return r;
198 }
199
200 void
201 Spanner::do_space_processing ()
202 {
203   Array<Rod> rs (get_rods ());
204   for (int i=0; i < rs.size (); i++)
205     {
206       rs[i].add_to_cols ();
207     }
208 }