]> git.donarmstrong.com Git - lilypond.git/blob - lily/rest-collision.cc
release: 0.1.11
[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_;
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 = (int)(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     {
93         int dy = rest_l_arr_.size() > 2 ? 6 : 4;
94         
95         rest_l_arr_[0]->translate_heads (rest_l_arr_[0]->dir_ *dy);     
96         // top is last element...
97         rest_l_arr_.top()->translate_heads (rest_l_arr_.top ()->dir_* dy);      
98     }
99   // meisjes met jongetjes
100   else 
101     {
102 #if 0 // breendet: rests go always under
103         // geen gemug, trug op je rug
104         int dir_i = -1;
105         rest_l_arr_[0]->translate_heads (dir_i * 3);    
106 #else
107         // int dir_i = - ncol_l_arr_[0]->dir_;
108         int dir_i = rest_l_arr_[0]->dir_;
109         // hope it's 4: if it works->doco
110         int midpos = 4;
111         
112       // minimum move
113         int minpos = 4;
114         
115         // quart rest height
116         // UGH Should get dims from table!
117         int size_i = 6;
118         
119         int sep_i = 3 + size_i / 2;
120         for (int i = 0; i < ncol_l_arr_.size(); i++) 
121           {
122             // how to know whether to sort?
123             ncol_l_arr_[i]->sort();
124             for (int j = 0; j < ncol_l_arr_[i]->head_l_arr_.size(); j++)
125                 minpos = minpos >? dir_i * 
126                     (ncol_l_arr_[i]->head_l_arr_[j]->position_i_ -midpos) + sep_i;
127           }
128         rest_l_arr_[0]->translate_heads (dir_i * minpos);       
129 #endif
130     }
131 }
132
133 void
134 Rest_collision::do_print() const
135 {
136 #ifndef NPRINT
137   DOUT << "rests: " << rest_l_arr_.size() << ", ";
138   DOUT << "cols: " << ncol_l_arr_.size();
139 #endif
140 }
141
142 void
143 Rest_collision::do_substitute_dependency (Score_elem*o,Score_elem*n)
144 {
145   Item*o_l = o->item();
146   Item*n_l = n?n->item():0;
147   
148   rest_l_arr_.substitute ((Rest_column*)o_l,(Rest_column*)n_l);
149   ncol_l_arr_.substitute ((Note_column*)o_l,(Note_column*)n_l);
150 }
151
152 Rest_collision::Rest_collision()
153 {
154   transparent_b_ = true;
155   empty_b_ = true;
156 }