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