]> git.donarmstrong.com Git - lilypond.git/blob - lily/rest-collision.cc
release: 0.1.8
[lilypond.git] / lily / rest-collision.cc
1 /*
2   rest-collision.cc -- implement Rest_collision
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
7 */
8
9 #include "debug.hh"
10 #include "rest-collision.hh"
11 #include "rest-column.hh"
12 #include "note-column.hh"
13 #include "stem.hh"
14 #include "note-head.hh"
15 #include "collision.hh"
16 #include "paper-def.hh"
17
18
19 IMPLEMENT_IS_TYPE_B1(Rest_collision,Item);
20
21 void
22 Rest_collision::add (Note_column *nc_l)
23 {
24     add_dependency (nc_l);
25     ncol_l_arr_.push (nc_l);
26 }
27
28 void
29 Rest_collision::add (Rest_column *rc_l)
30 {
31     add_dependency (rc_l);
32     rest_l_arr_.push (rc_l);
33 }
34
35 void
36 Rest_collision::do_post_processing()
37 {
38     /*
39       handle rest under beam (do_post: beams are calculated now)
40
41       [todo]
42       i-d like to have access to the beam itself, 
43       iso only the (half-initialised?) stem
44
45       what about combination of collisions and rest under beam
46      */
47
48     // no rests to collide
49     if (!rest_l_arr_.size())
50         return;
51     // can this happen?
52     Stem* stem_l = rest_l_arr_[0]->stem_l_;
53     if (!stem_l)
54         return;
55     // no beam
56     if (!(stem_l->beams_left_i_ || stem_l->beams_right_i_))
57         return;
58
59     int dir_i = rest_l_arr_[0]->dir_i_;
60     int midpos = 4;
61 #if 1
62     // ugh
63     int stem_length_i = 7 - 2;
64     // ugh, Stem::stem_start vs Stem::stem_end
65     int pos = (stem_l->stem_end_f() - midpos) - dir_i * stem_length_i;
66 #else // nogo: stem_start not set for rests?
67     int pos = (stem_l->stem_start_f() - midpos) + dir_i * 2;
68 #endif
69     rest_l_arr_[0]->translate_heads (pos);      
70 }
71
72 void
73 Rest_collision::do_pre_processing()
74 {
75     /* 
76       handle rest-rest and rest-note collisions
77
78       [todo]
79       decide not to print rest if too crowded?
80      */
81
82     // no rests to collide
83     if (!rest_l_arr_.size())
84         return;
85
86     // no partners to collide with
87     if (rest_l_arr_.size() + ncol_l_arr_.size () < 2)
88         return;
89
90     // meisjes met meisjes
91     if (!ncol_l_arr_.size()) {
92         int dy = rest_l_arr_.size() > 2 ? 6 : 4;
93         
94         rest_l_arr_[0]->translate_heads (rest_l_arr_[0]->dir_i_ *dy);   
95         // top is last element...
96         rest_l_arr_.top()->translate_heads (rest_l_arr_.top ()->dir_i_* dy);    
97     }
98     // meisjes met jongetjes
99     else {
100 #if 0 // breendet: rests go always under
101         // geen gemug, trug op je rug
102         int dir_i = -1;
103         rest_l_arr_[0]->translate_heads (dir_i * 3);    
104 #else
105         // int dir_i = - ncol_l_arr_[0]->dir_i_;
106         int dir_i = rest_l_arr_[0]->dir_i_;
107         // hope it's 4: if it works->doco
108         int midpos = 4;
109         
110         // minimum move
111         int minpos = 4;
112         
113         // quart rest height
114         // UGH Should get dims from table!
115         int size_i = 6;
116         
117         int sep_i = 3 + size_i / 2;
118         for (int i = 0; i < ncol_l_arr_.size(); i++) {
119             // how to know whether to sort?
120             ncol_l_arr_[i]->sort();
121             for ( int j = 0; j < ncol_l_arr_[i]->head_l_arr_.size(); j++)
122                 minpos = minpos >? dir_i * 
123                     (ncol_l_arr_[i]->head_l_arr_[j]->position_i_ -midpos) + sep_i;
124         }
125         rest_l_arr_[0]->translate_heads (dir_i * minpos);       
126 #endif
127     }
128 }
129
130 void
131 Rest_collision::do_print() const
132 {
133 #ifndef NPRINT
134     DOUT << "rests: " << rest_l_arr_.size() << ", ";
135     DOUT << "cols: " << ncol_l_arr_.size();
136 #endif
137 }
138
139 void
140 Rest_collision::do_substitute_dependency (Score_elem*o,Score_elem*n)
141 {
142     Item*o_l = o->item();
143     Item*n_l = n?n->item():0;
144     
145     rest_l_arr_.substitute ((Rest_column*)o_l,(Rest_column*)n_l);
146     ncol_l_arr_.substitute ((Note_column*)o_l,(Note_column*)n_l);
147 }
148
149 Rest_collision::Rest_collision()
150 {
151     transparent_b_ = true;
152     empty_b_ = true;
153 }