]> git.donarmstrong.com Git - lilypond.git/blob - lily/spanner.cc
release: 0.1.9
[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 Han-Wen Nienhuys <hanwen@stack.nl>
7 */
8
9 #include "debug.hh"
10 #include "spanner.hh"
11 #include "p-col.hh"
12 #include "p-score.hh"
13
14
15 IMPLEMENT_IS_TYPE_B1(Spanner,Score_elem);
16
17 void
18 Spanner::do_print()const
19 {
20 #ifndef NPRINT
21   DOUT << "Between col ";
22   if ( left_col_l_)
23         DOUT << left_col_l_->rank_i();
24   else 
25         DOUT << "nop";
26   DOUT << ", ";
27   if ( right_col_l_)
28         DOUT << right_col_l_->rank_i();
29   else 
30         DOUT << "nop";
31   if (broken_into_l_arr_.size())
32         DOUT << "with broken pieces\n";
33 #endif
34 }
35
36 void
37 Spanner::break_into_pieces (bool copy_deps_b)
38 {
39   if (  broken_into_l_arr_.size())
40         return; 
41          
42   PCol * left = left_col_l_;
43   PCol * right = right_col_l_;
44   if (left->daddy_l_) left = left->daddy_l_;
45   if (right->daddy_l_) right = right->daddy_l_;
46   
47   
48   Link_array<PCol> 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()->spanner ();
57         if (copy_deps_b)
58             span_p->copy_dependencies (*this);
59         left = break_cols[i-1];
60         right = break_cols[i];
61         if (!right->line_l_)
62             right = right->prebreak_p_;
63         if (!left->line_l_)
64             left = left->postbreak_p_;
65
66         assert (left&&right && left->line_l_ == right->line_l_);
67
68         span_p->left_col_l_  = left;
69         span_p->right_col_l_ = right;
70         
71         pscore_l_->typeset_broken_spanner (span_p);
72         broken_into_l_arr.push (span_p);
73     }
74    
75   broken_into_l_arr_ = broken_into_l_arr;
76 }
77
78 void
79 Spanner::set_my_columns()
80 {
81   if (!left_col_l_->line_l_)
82         left_col_l_ = left_col_l_->postbreak_p_;
83   if (!right_col_l_->line_l_)
84         right_col_l_ = right_col_l_->prebreak_p_;
85 }       
86
87 void
88 Spanner::do_break_processing()
89 {
90   set_my_columns();
91   
92   if (!line_l()) 
93     {
94         break_into_pieces (true);
95         for (int i=0; i < broken_into_l_arr_.size(); i++)
96             broken_into_l_arr_[i]->handle_broken_dependencies();
97     }
98   else 
99     {
100         handle_broken_dependencies();
101     }
102 }
103
104
105 Spanner::Spanner()
106 {
107   left_col_l_ = right_col_l_ = 0;
108 }
109
110
111 Interval
112 Spanner::do_width()const
113 {
114   Real r = right_col_l_->hpos_f_;
115   Real l = left_col_l_->hpos_f_;
116   assert (*left_col_l_ < *right_col_l_);
117   assert (r>=l);
118         
119   return Interval (0, r-l);
120 }
121
122 Line_of_score *
123 Spanner::line_l()const
124 {
125   if ( left_col_l_->line_l_ != right_col_l_->line_l_)
126         return 0;
127   return left_col_l_->line_l_;
128 }
129
130
131 Spanner*
132 Spanner::find_broken_piece (Line_of_score*l)const
133 {
134   for (int i=0; i < broken_into_l_arr_.size(); i++)
135         if (broken_into_l_arr_[i]->line_l() == l)
136             return broken_into_l_arr_[i];
137   return 0;                                
138           
139 }
140
141 bool
142 Spanner::broken_b()const
143 {
144   return broken_into_l_arr_.size();
145 }