]> git.donarmstrong.com Git - lilypond.git/blob - lily/staff-column.cc
release: 0.0.39-1
[lilypond.git] / lily / staff-column.cc
1 /*
2   staff-column.cc -- implement Staff_column
3
4   source file of the LilyPond music typesetter
5
6   (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
7 */
8 #include "proto.hh"
9 #include "plist.hh"
10 #include "staff.hh"
11 #include "voice.hh"
12 #include "time-description.hh"
13 #include "score-column.hh"
14 #include "staff-column.hh"
15 #include "commandrequest.hh"
16 #include "musicalrequest.hh"
17 #include "interval.hh"
18 #include "pscore.hh"
19 #include "item.hh"
20 #include "pcol.hh"
21 #include "voice-element.hh"
22
23 void
24 Staff_column::OK() const
25 {
26 #ifndef NDEBUG
27     assert (command_column_l_->when() == musical_column_l_->when());
28 #endif
29 }
30
31 Moment
32 Staff_column::when() const
33 {
34     return (command_column_l_)?
35         command_column_l_->when():
36         musical_column_l_->when();
37 }
38
39 void
40 Staff_column::add(Voice_element*ve)
41 {
42     for (iter_top(ve->reqs,j); j.ok(); j++) {
43         if (j->command()) {
44             Command_req * c_l = j->command();
45             if (c_l->timing()) {
46                 timing_req_l_arr_.push(j->command()->timing());
47             }
48             if (c_l->groupchange())
49                 creationreq_l_arr_.push(c_l);
50             else if (!c_l->barcheck() &&  !c_l->partial() &&
51                 !c_l->measuregrouping())
52                 setup_one_request(j);   // no need to bother children
53         } else {
54             if (j->rhythmic()) {
55                 musical_column_l_->add_duration(j->rhythmic()->duration());
56             }
57             if (!j->musical()->skip())
58                 setup_one_request(j);
59         }
60     }
61 }
62
63 Staff_column::Staff_column()
64 {
65     musical_column_l_ = 0;
66     command_column_l_ = 0;
67     staff_l_ = 0;
68 }
69
70
71
72
73 Staff_column::~Staff_column()
74 {
75 }
76
77 void
78 Staff_column::set_cols(Score_column*c1, Score_column*c2)
79 {
80     command_column_l_ = c1;
81     musical_column_l_ = c2;
82 }
83
84 void
85 Staff_column::setup_one_request(Request * j)
86 {
87     if (j->command()) // ugh
88         commandreq_l_arr_.push(j);
89     else if (j->musical())
90         musicalreq_l_arr_.push(j);
91 }
92
93 void
94 Staff_column::typeset_musical_item(Item*i)
95 {
96     assert(i);
97     Score_column * scorecolumn_l = musical_column_l_;
98     musical_column_l_->pcol_l_->pscore_l_->typeset_item(i, scorecolumn_l->pcol_l_,
99                                                         staff_l_->pstaff_l_);
100 }
101
102 /**
103   align items in #item_l_arr#,
104
105   @return the width of the items after aligning.
106  */
107 Interval
108 align_items(Array<Item*> item_l_arr)
109 {
110     Interval wid(0,0);
111     for  (int i =0; i < item_l_arr.size(); i++) {
112         Interval item_width= item_l_arr[i]->width();
113         Real dx =wid.right - item_width.left;
114         item_width += dx;
115         item_l_arr[i]->translate(Offset(dx ,0));
116         wid.unite(item_width);
117     }
118     return wid;
119 }
120
121 void 
122 translate_items(Real x,  Array<Item*> item_l_arr)
123 {
124     for  (int i =0; i < item_l_arr.size(); i++) 
125         item_l_arr[i]->translate(Offset(x, 0));
126 }
127 /*
128   UGR
129   This still sux
130   */
131 void
132 Staff_column::typeset_breakable_items(Array<Item *> &pre_p_arr,
133                                       Array<Item *> &nobreak_p_arr,
134                                       Array<Item *> &post_p_arr)
135 {
136     PCol * c= command_column_l_->pcol_l_;
137     PScore *ps_l=command_column_l_->pcol_l_->pscore_l_;
138     
139     if (!c->breakable_b()) {      
140         for  (int i =0; i < pre_p_arr.size(); i++)
141             delete pre_p_arr[i];
142         pre_p_arr.set_size(0);
143         for  (int i =0; i < post_p_arr.size(); i++)
144             delete post_p_arr[i];
145         post_p_arr.set_size(0);
146     }
147
148       
149     for  (int i =0; i < pre_p_arr.size(); i++) {
150         ps_l->typeset_item(pre_p_arr[i], c, staff_l_->pstaff_l_,0);
151     }
152     for  (int i =0; i < nobreak_p_arr.size(); i++) {
153         ps_l->typeset_item(nobreak_p_arr[i], c, staff_l_->pstaff_l_,1);
154     }
155     for  (int i =0; i < post_p_arr.size(); i++) {
156         ps_l->typeset_item(post_p_arr[i], c, staff_l_->pstaff_l_,2);
157     }
158
159     Interval pre_wid= align_items(pre_p_arr);
160     translate_items( -pre_wid.right, pre_p_arr);
161     align_items(nobreak_p_arr);
162     Interval post_wid =align_items(post_p_arr);
163     translate_items (-post_wid.left , post_p_arr);
164
165     pre_p_arr.set_size(0);
166     post_p_arr.set_size(0);
167     nobreak_p_arr.set_size(0);
168 }