]> git.donarmstrong.com Git - lilypond.git/blob - lily/spanner.cc
0039caefb50735d7f373d0f7d2efccb131ac77ff
[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     PCol * left = left_col_l_;
40     PCol * right = right_col_l_;
41     if(left->daddy_l_) left = left->daddy_l_;
42     if(right->daddy_l_) right = right->daddy_l_;
43     
44     
45     Link_array<PCol> break_cols = pscore_l_->broken_col_range(left,right);
46     Link_array<Spanner> broken_into_l_arr;
47
48     break_cols.insert(left,0);
49     break_cols.push(right);
50
51     for (int i=1; i < break_cols.size(); i++) {
52         Spanner* span_p = clone()->spanner();
53         if (copy_deps_b)
54             span_p->copy_dependencies( *this );
55         left = break_cols[i-1];
56         right = break_cols[i];
57         if (!right->line_l_)
58             right = right->prebreak_p_;
59         if (!left->line_l_)
60             left = left->postbreak_p_;
61
62         assert(left&&right && left->line_l_ == right->line_l_);
63
64         span_p->left_col_l_  = left;
65         span_p->right_col_l_ = right;
66         
67         pscore_l_->typeset_broken_spanner(span_p);
68         broken_into_l_arr.push( span_p );
69     }
70      
71     broken_into_l_arr_ = broken_into_l_arr;
72 }
73
74 void
75 Spanner::set_my_columns()
76 {
77   if (!left_col_l_->line_l_)
78         left_col_l_ = left_col_l_->postbreak_p_;
79     if (!right_col_l_->line_l_)
80         right_col_l_ = right_col_l_->prebreak_p_;
81 }       
82
83 void
84 Spanner::do_break_processing()
85 {
86     set_my_columns();
87     
88     if (!line_l()) {
89         break_into_pieces(true);
90         for (int i=0; i < broken_into_l_arr_.size(); i++)
91             broken_into_l_arr_[i]->handle_broken_dependencies();
92     } else { 
93         handle_broken_dependencies();
94     }
95 }
96
97
98 Spanner::Spanner()
99 {
100     left_col_l_ = right_col_l_ = 0;
101 }
102
103
104 Interval
105 Spanner::do_width()const
106 {
107     Real r = right_col_l_->hpos_f_;
108     Real l = left_col_l_->hpos_f_;
109     assert(*left_col_l_ < *right_col_l_);
110     assert(r>=l);
111         
112     return Interval(0, r-l);
113 }
114
115 Line_of_score *
116 Spanner::line_l()const
117 {
118     if ( left_col_l_->line_l_ != right_col_l_->line_l_)
119         return 0;
120     return left_col_l_->line_l_;
121 }
122
123
124 Spanner*
125 Spanner::find_broken_piece(Line_of_score*l)const
126 {
127     for (int i=0; i < broken_into_l_arr_.size(); i++)
128         if(broken_into_l_arr_[i]->line_l() == l)
129             return broken_into_l_arr_[i];
130     return 0;                              
131           
132 }
133
134 bool
135 Spanner::broken_b()const
136 {
137     return broken_into_l_arr_.size();
138 }