]> git.donarmstrong.com Git - lilypond.git/blob - lily/spanner.cc
01a02cf8d44e7bd408037b11f35fa45ed931fe35
[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     mtor << "Between col ";
22     if ( left_col_l_ )
23         mtor << left_col_l_->rank_i();
24     else 
25         mtor << "nop";
26     mtor << ", ";
27     if ( right_col_l_ )
28         mtor << right_col_l_->rank_i();
29     else 
30         mtor << "nop";
31     if (broken_into_l_arr_.size())
32         mtor << "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         Spanner* span_p = clone()->spanner();
56         if (copy_deps_b)
57             span_p->copy_dependencies( *this );
58         left = break_cols[i-1];
59         right = break_cols[i];
60         if (!right->line_l_)
61             right = right->prebreak_p_;
62         if (!left->line_l_)
63             left = left->postbreak_p_;
64
65         assert(left&&right && left->line_l_ == right->line_l_);
66
67         span_p->left_col_l_  = left;
68         span_p->right_col_l_ = right;
69         
70         pscore_l_->typeset_broken_spanner(span_p);
71         broken_into_l_arr.push( span_p );
72     }
73      
74     broken_into_l_arr_ = broken_into_l_arr;
75 }
76
77 void
78 Spanner::set_my_columns()
79 {
80   if (!left_col_l_->line_l_)
81         left_col_l_ = left_col_l_->postbreak_p_;
82     if (!right_col_l_->line_l_)
83         right_col_l_ = right_col_l_->prebreak_p_;
84 }       
85
86 void
87 Spanner::do_break_processing()
88 {
89     set_my_columns();
90     
91     if (!line_l()) {
92         break_into_pieces(true);
93         for (int i=0; i < broken_into_l_arr_.size(); i++)
94             broken_into_l_arr_[i]->handle_broken_dependencies();
95     } else { 
96         handle_broken_dependencies();
97     }
98 }
99
100
101 Spanner::Spanner()
102 {
103     left_col_l_ = right_col_l_ = 0;
104 }
105
106
107 Interval
108 Spanner::do_width()const
109 {
110     Real r = right_col_l_->hpos_f_;
111     Real l = left_col_l_->hpos_f_;
112     assert(*left_col_l_ < *right_col_l_);
113     assert(r>=l);
114         
115     return Interval(0, r-l);
116 }
117
118 Line_of_score *
119 Spanner::line_l()const
120 {
121     if ( left_col_l_->line_l_ != right_col_l_->line_l_)
122         return 0;
123     return left_col_l_->line_l_;
124 }
125
126
127 Spanner*
128 Spanner::find_broken_piece(Line_of_score*l)const
129 {
130     for (int i=0; i < broken_into_l_arr_.size(); i++)
131         if(broken_into_l_arr_[i]->line_l() == l)
132             return broken_into_l_arr_[i];
133     return 0;                              
134           
135 }
136
137 bool
138 Spanner::broken_b()const
139 {
140     return broken_into_l_arr_.size();
141 }