2 stem-info.cc -- implement Stem_info
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--1999 Jan Nieuwenhuizen <janneke@gnu.org>
14 #include "align-element.hh"
16 #include "paper-def.hh"
18 #include "stem-info.hh"
20 #include "staff-symbol.hh"
22 Stem_info::Stem_info ()
26 FIXME: y dims should not be in internote.
29 Stem_info::Stem_info (Stem
*s
, int mult
)
33 x_
= stem_l_
->hpos_f ();
35 SCM bd
= stem_l_
->remove_elt_property (beam_dir_scm_sym
);
37 beam_dir_
= gh_scm2int (SCM_CDR(bd
));
40 Paper_def
* paper_l
= stem_l_
->paper_l ();
41 Real internote_f
= stem_l_
->staff_line_leading_f ()/2;
42 Real interbeam_f
= paper_l
->interbeam_f (mult_i_
);
43 Real beam_f
= paper_l
->beam_thickness_f ();
47 DOUT
<< "******" << i
++ << "******\n"
48 << "begin_f: " << stem_l_
->stem_begin_f () * dir_
49 << "\nchord_f/i: " << stem_l_
->chord_start_f () * dir_
/ internote_f
<< '\n';
52 // strangely enough, dim(chord_start_f) == pt (and not internote!)
53 idealy_f_
= stem_l_
->chord_start_f () / internote_f
;
55 // calculate using dim(y) == pt
56 idealy_f_
*= internote_f
;
58 // for simplicity, we calculate as if dir == UP
59 idealy_f_
*= beam_dir_
;
61 bool grace_b
= stem_l_
->get_elt_property (grace_scm_sym
) != SCM_BOOL_F
;
63 int stem_max
= (int)rint(paper_l
->get_var ("stem_max"));
64 String type_str
= grace_b
? "grace_" : "";
65 Real min_stem_f
= paper_l
->get_var (type_str
+ "minimum_stem_length"
66 + to_str (mult_i_
<? stem_max
)) * internote_f
;
67 Real stem_f
= paper_l
->get_var (type_str
+ "stem_length"
68 + to_str (mult_i_
<? stem_max
))* internote_f
;
70 if (!beam_dir_
|| (beam_dir_
== dir_
))
71 /* normal beamed stem */
76 idealy_f_
+= (mult_i_
- 1) * interbeam_f
;
82 miny_f_
+= min_stem_f
;
85 lowest beam of (UP) beam must never be lower than second staffline
87 Hmm, reference (Wanske?)
89 Although this (additional) rule is probably correct,
90 I expect that highest beam (UP) should also never be lower
91 than middle staffline, just as normal stems.
96 //highest beam of (UP) beam must never be lower than middle staffline
97 miny_f_
= miny_f_
>? 0;
98 //lowest beam of (UP) beam must never be lower than second staffline
99 miny_f_
= miny_f_
>? (- 2 * internote_f
- beam_f
100 + (mult_i_
> 0) * beam_f
+ interbeam_f
* (mult_i_
- 1));
107 // idealy_f_ -= (mult_i_ - 1) * interbeam_f;
108 // idealy_f_ += (mult_i_ - stem_l_->flag_i_ >? 0) * interbeam_f;
113 maxy_f_
-= min_stem_f
;
116 // set dim(y) == internote
117 idealy_f_
/= internote_f
;
118 miny_f_
/= internote_f
;
119 maxy_f_
/= internote_f
;
121 DOUT
<< "dir_: " << dir_
<< '\n';
122 DOUT
<< "mult_i_: " << mult_i_
<< '\n';
123 DOUT
<< "idealy_f_: " << idealy_f_
<< '\n';
124 DOUT
<< "miny_f_: " << miny_f_
<< '\n';
125 DOUT
<< "maxy_f_: " << maxy_f_
<< '\n';
127 idealy_f_
= maxy_f_
<? idealy_f_
;
128 idealy_f_
= miny_f_
>? idealy_f_
;
131 Beam
* beam_l
= stem_l_
->beam_l_
;
133 Dimension_cache
*common
= stem_l_
->common_group (beam_l
, Y_AXIS
);
134 Align_element
* align
= dynamic_cast<Align_element
*> (common
->element_l ());
135 if (align
&& align
->axis() == Y_AXIS
)
137 if (align
->threshold_interval_
[MIN
] !=
138 align
->threshold_interval_
[MAX
])
139 warning (_ ("minVerticalAlign != maxVerticalAlign: interstaff beams/slurs may be broken"));
141 interstaff_f_
= align
->threshold_interval_
[MIN
] / internote_f
;
143 Dimension_cache
* beam_refpoint
= beam_l
->dim_cache_
[Y_AXIS
];
144 Dimension_cache
* stem_refpoint
= stem_l_
->dim_cache_
[Y_AXIS
];
146 while (beam_refpoint
->parent_l_
!= common
)
147 beam_refpoint
= beam_refpoint
->parent_l_
;
148 while (stem_refpoint
->parent_l_
!= common
)
149 stem_refpoint
= stem_refpoint
->parent_l_
;
153 align
->get_priority (dynamic_cast<Score_element
*> (beam_refpoint
->element_l ()));
155 align
->get_priority (dynamic_cast<Score_element
*> (stem_refpoint
->element_l ()));
158 our staff is lower -> interstaff_f_ *= -1
160 if (beam_prio
< stem_prio
)
163 idealy_f_
+= interstaff_f_
* beam_dir_
;
164 miny_f_
+= interstaff_f_
* beam_dir_
;
165 maxy_f_
+= interstaff_f_
* beam_dir_
;