2 rest-collision.cc -- implement Rest_collision
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
10 #include "rest-collision.hh"
11 #include "note-column.hh"
13 #include "note-head.hh"
14 #include "collision.hh"
15 #include "paper-def.hh"
19 Rest_collision::add_column (Note_column
*nc_l
)
21 add_dependency (nc_l
);
23 rest_l_arr_
.push (nc_l
);
25 ncol_l_arr_
.push (nc_l
);
29 Rest_collision::do_pre_processing()
32 handle rest-rest and rest-note collisions
35 * decide not to print rest if too crowded?
37 * ignore rests under beams.
40 // no rests to collide
41 if (!rest_l_arr_
.size())
44 // no partners to collide with
45 if (rest_l_arr_
.size() + ncol_l_arr_
.size () < 2)
48 // meisjes met meisjes
49 if (!ncol_l_arr_
.size())
52 UGH. Should get dims from table. Should have minimum dist.
54 int dy
= rest_l_arr_
.size() > 2 ? 6 : 4;
56 rest_l_arr_
[0]->translate_rests (rest_l_arr_
[0]->dir () *dy
);
57 rest_l_arr_
.top()->translate_rests (rest_l_arr_
.top ()->dir ()* dy
);
59 // meisjes met jongetjes
62 if (rest_l_arr_
.size () > 1)
64 warning (_("Too many colliding rests."));
66 if (ncol_l_arr_
.size () > 1)
68 warning (_("Too many notes for rest collision."));
70 Note_column
* rcol
= rest_l_arr_
[0];
72 // try to be opposite of noteheads.
73 Direction dir
= - ncol_l_arr_
[0]->dir();
76 for (int i
=0; i
< rcol
->rest_l_arr_
.size(); i
++)
77 restdim
.unite (rcol
->rest_l_arr_
[i
]->extent (Y_AXIS
));
79 if (restdim
.empty_b ())
83 Real staff_space
= rcol
->rest_l_arr_
[0]->staff_line_leading_f ();
84 Real internote_f
= staff_space
/2;
85 Real minimum_dist
= paper_l ()->get_var ("restcollision_minimum_dist")
89 assumption: ref points are the same.
92 for (int i
= 0; i
< ncol_l_arr_
.size(); i
++)
94 notedim
.unite (ncol_l_arr_
[i
]->extent (Y_AXIS
));
97 Interval
inter (notedim
);
98 inter
.intersect (restdim
);
101 minimum_dist
+ dir
* (notedim
[dir
] - restdim
[-dir
]) >? 0;
104 int stafflines
= rcol
->rest_l_arr_
[0]->lines_i ();
107 // move discretely by half spaces.
108 int discrete_dist
= int (ceil (dist
/ (0.5 *staff_space
)));
110 // move by whole spaces inside the staff.
111 if (discrete_dist
< stafflines
+1)
112 discrete_dist
= int (ceil (discrete_dist
/ 2.0)* 2.0);
114 rcol
->translate_rests (dir
* discrete_dist
);
119 Rest_collision::do_print() const
122 DOUT
<< "rests: " << rest_l_arr_
.size() << ", ";
123 DOUT
<< "cols: " << ncol_l_arr_
.size();
128 Rest_collision::do_substitute_element_pointer (Score_element
*o
,Score_element
*n
)
130 if (Note_column
*onl
= dynamic_cast<Note_column
*> (o
))
132 Note_column
*n_l
= n
?dynamic_cast<Note_column
*> (n
):0;
133 rest_l_arr_
.substitute (onl
, n_l
);
134 ncol_l_arr_
.substitute (onl
, n_l
);
138 Rest_collision::Rest_collision()
140 set_elt_property (transparent_scm_sym
, SCM_BOOL_T
);