Drul_array<Grob*> e (extremal_heads (me));
- return Interval (Staff_symbol_referencer::position_f (e[DOWN]),
- Staff_symbol_referencer::position_f (e[UP]));
+ return Interval (Staff_symbol_referencer::get_position (e[DOWN]),
+ Staff_symbol_referencer::get_position (e[UP]));
}
/*
Note head that determines hshift for upstems
- */
+
+ WARNING: triggers direction
+*/
Grob*
Stem::support_head (Grob*me)
{
/*
The note head which forms one end of the stem.
- */
+
+ WARNING: triggers direction
+*/
Grob*
Stem::first_head (Grob*me)
{
Grob * n = unsmob_grob (ly_car (s));
- int p = int (Staff_symbol_referencer::position_f (n));
+ int p = int (Staff_symbol_referencer::get_position (n));
Direction d = LEFT;
do {
for (SCM s = me->get_grob_property ("note-heads"); gh_pair_p (s); s = ly_cdr (s))
{
Grob * n = unsmob_grob (ly_car (s));
- int p = int (Staff_symbol_referencer::position_f (n));
+ int p = int (Staff_symbol_referencer::get_position (n));
ps.push (p);
}
bool
Stem::invisible_b (Grob*me)
{
- return ! (head_count (me) && Note_head::balltype_i (support_head (me)) >= 1);
+ return ! (head_count (me)
+ && gh_scm2int (me->get_grob_property ("duration-log")) >= 1);
}
Direction
Real
Stem::get_default_stem_end_position (Grob*me)
{
+ /* Tab notation feature: make stem end extend out of staff. */
SCM up_to_staff = me->get_grob_property ("up-to-staff");
- if (to_boolean(up_to_staff))
+ if (to_boolean (up_to_staff))
{
int line_count = Staff_symbol_referencer::line_count (me);
-
Direction dir = get_direction (me);
-
- return dir* (line_count + 3.5);
+ return dir * (line_count + 3.5);
}
bool grace_b = to_boolean (me->get_grob_property ("grace"));
}
}
-
Real shorten_f = 0.0;
SCM sshorten = me->get_grob_property ("stem-shorten");
Interval hp = head_positions (me);
Real st = hp[dir] + dir * length_f;
+
+ /*
+ TODO: change name to extend-stems to staff/center/'()
+ */
bool no_extend_b = to_boolean (me->get_grob_property ("no-stem-extend"));
if (!grace_b && !no_extend_b && dir * st < 0) // junkme?
st = 0.0;
good typesetting practice.
*/
- if (!beam_l (me) && dir == UP
+ if (!get_beam (me) && dir == UP
&& duration_log (me) > 2)
{
Grob * closest_to_flag = extremal_heads (me)[dir];
Grob * dots = closest_to_flag
- ? Rhythmic_head::dots_l (closest_to_flag ) : 0;
+ ? Rhythmic_head::get_dots (closest_to_flag ) : 0;
if (dots)
{
- Real dp = Staff_symbol_referencer::position_f (dots);
+ Real dp = Staff_symbol_referencer::get_position (dots);
Real flagy = flag (me).extent (Y_AXIS)[-dir] * 2
/ Staff_symbol_referencer::staff_space (me);
Real thick = 0.0;
if (invisible)
thick = gh_scm2double (me->get_grob_property ("thickness"))
- * me->paper_l ()->get_var ("linethickness");
+ * me->get_paper ()->get_var ("linethickness");
Grob *hed = support_head (me);
}
bool parity= true; // todo: make me settable.
- int lastpos = int (Staff_symbol_referencer::position_f (heads[0]));
+ int lastpos = int (Staff_symbol_referencer::get_position (heads[0]));
for (int i=1; i < heads.size (); i ++)
{
- Real p = Staff_symbol_referencer::position_f (heads[i]);
+ Real p = Staff_symbol_referencer::get_position (heads[i]);
int dy =abs (lastpos- (int)p);
if (dy <= 1)
}
else
{
- me->remove_grob_property ("molecule-callback");
+ me->set_grob_property ("molecule-callback", SCM_EOL);
}
return SCM_UNSPECIFIED;
Interval iv;
if (mol != SCM_EOL)
iv = unsmob_molecule (mol)->extent (a);
+ if (Grob *b =get_beam (me))
+ {
+ Direction d = get_direction (me);
+ iv[d] += d * Beam::get_thickness (b) /2.0 ;
+ }
+
return ly_interval2scm (iv);
}
e.g. "stroke-style", maybe with values "" (i.e. no stroke),
"single" and "double". Needs more discussion.
*/
- String style, fstyle, staffline_offs;
- SCM fst = me->get_grob_property ("flag-style");
- if (gh_string_p (fst))
- {
- fstyle = ly_scm2string (fst);
- }
+ String style, staffline_offs;
- SCM st = me->get_grob_property ("style");
- if (gh_symbol_p (st))
+ SCM style_scm = me->get_grob_property ("style");
+ if (gh_symbol_p (style_scm))
{
- style = (ly_scm2string (scm_symbol_to_string (st)));
+ style = (ly_scm2string (scm_symbol_to_string (style_scm)));
}
else
{
}
bool adjust = to_boolean (me->get_grob_property ("adjust-if-on-staffline"));
- if (String::compare_i (style, "mensural") == 0)
+ if (String::compare (style, "mensural") == 0)
/* Mensural notation: For notes on staff lines, use different
flags than for notes between staff lines. The idea is that
flags are always vertically aligned with the staff lines,
--hwn.
*/
- Grob *first = first_head(me);
- int sz = Staff_symbol_referencer::line_count (me)-1;
- int p = (int)rint (Staff_symbol_referencer::position_f (first));
- staffline_offs = (((p ^ sz) & 0x1) == 0) ? "1" : "0";
+ int p = (int)rint (Staff_symbol_referencer::get_position (first_head (me)));
+ staffline_offs = Staff_symbol_referencer::on_staffline (me, p) ?
+ "1" : "0";
}
else
{
{
staffline_offs = "";
}
- char c = (get_direction (me) == UP) ? 'u' : 'd';
- String index_str
- = String ("flags-") + style + to_str (c) + staffline_offs + to_str (duration_log (me));
- Molecule m
- = Font_interface::get_default_font (me)->find_by_name (index_str);
- if (!fstyle.empty_b ())
- m.add_molecule (Font_interface::get_default_font (me)->find_by_name (String ("flags-") + to_str (c) + fstyle));
- return m;
+ char dir = (get_direction (me) == UP) ? 'u' : 'd';
+ String font_char =
+ style + to_string (dir) + staffline_offs + to_string (duration_log (me));
+ Font_metric *fm = Font_interface::get_default_font (me);
+ Molecule flag = fm->find_by_name ("flags-" + font_char);
+ if (flag.empty_b ())
+ {
+ me->warning (_f ("flag `%s' not found", font_char));
+ }
+
+ SCM stroke_scm = me->get_grob_property ("flag-style");
+ if (gh_string_p (stroke_scm))
+ {
+ String stroke = ly_scm2string (stroke_scm);
+ if (!stroke.empty_b ())
+ {
+ String font_char = to_string (dir) + stroke;
+ Molecule stroke = fm->find_by_name ("flags-" + font_char);
+ if (stroke.empty_b ())
+ {
+ me->warning (_f ("flag stroke `%s' not found", font_char));
+ }
+ else
+ {
+ flag.add_molecule (stroke);
+ }
+ }
+ }
+
+ return flag;
}
MAKE_SCHEME_CALLBACK (Stem,dim_callback,2);
Grob * lh = last_head (me);
if (!lh)
return SCM_EOL;
- y1 = Staff_symbol_referencer::position_f (lh);
+ y1 = Staff_symbol_referencer::get_position (lh);
}
else
{
Grob * lh = first_head (me);
if (!lh)
return SCM_EOL;
- y1 = Staff_symbol_referencer::position_f (lh);
+ y1 = Staff_symbol_referencer::get_position (lh);
}
Real y2 = stem_end_position (me);
{
Real stem_width = gh_scm2double (me->get_grob_property ("thickness"))
// URG
- * me->paper_l ()->get_var ("linethickness");
+ * me->get_paper ()->get_var ("linethickness");
Molecule ss =Lookup::filledbox (Box (Interval (-stem_width/2, stem_width/2),
Interval (stem_y[DOWN]*dy, stem_y[UP]*dy)));
mol.add_molecule (ss);
}
- if (!beam_l (me) && abs (duration_log (me)) > 2)
+ if (!get_beam (me) && abs (duration_log (me)) > 2)
{
Molecule fl = flag (me);
fl.translate_axis (stem_y[d]*dy, Y_AXIS);
{
Real rule_thick
= gh_scm2double (me->get_grob_property ("thickness"))
- * me->paper_l ()->get_var ("linethickness");
+ * me->get_paper ()->get_var ("linethickness");
r += - d * rule_thick * 0.5;
return gh_double2scm (r);
}
-
-
Grob*
-Stem::beam_l (Grob*me)
+Stem::get_beam (Grob*me)
{
SCM b= me->get_grob_property ("beam");
return unsmob_grob (b);
}
-// ugh still very long.
Stem_info
-Stem::calc_stem_info (Grob*me)
+Stem::get_stem_info (Grob *me)
{
- SCM up_to_staff = me->get_grob_property ("up-to-staff");
- if (gh_scm2bool(up_to_staff)) {
-
- // Up-to-staff : the stem end out of the staff.
-
- /*
- FIXME: duplicate code.
- */
- int line_count = Staff_symbol_referencer::line_count (me);
-
- Stem_info si ;
-
- Direction dir = get_direction (me);
-
- si.ideal_y_ = dir* (line_count + 1.5);
- si.dir_ = dir;
- si.shortest_y_ = si.ideal_y_;
-
- return si;
- }
-
+ /* Return cached info if available */
SCM scm_info = me->get_grob_property ("stem-info");
-
- if (gh_pair_p (scm_info ))
+ if (!gh_pair_p (scm_info))
{
- Stem_info si ;
-
- si.dir_ = Directional_element_interface::get(me);
- si.ideal_y_ = gh_scm2double (gh_car (scm_info));
- si.shortest_y_ = gh_scm2double (gh_cadr (scm_info));
+ calc_stem_info (me);
+ scm_info = me->get_grob_property ("stem-info");
+ }
+
+ Stem_info si;
+ si.dir_ = Directional_element_interface::get (me);
+ si.ideal_y_ = gh_scm2double (gh_car (scm_info));
+ si.shortest_y_ = gh_scm2double (gh_cadr (scm_info));
+ return si;
+}
- return si;
+void
+Stem::calc_stem_info (Grob *me)
+{
+ /* Tab notation feature: make stem end extend out of staff. */
+ SCM up_to_staff = me->get_grob_property ("up-to-staff");
+ if (to_boolean (up_to_staff))
+ {
+ int line_count = Staff_symbol_referencer::line_count (me);
+ Direction dir = get_direction (me);
+ Real ideal_y = dir * (line_count + 1.5);
+ Real shortest_y = ideal_y;
+
+ me->set_grob_property ("stem-info",
+ scm_list_n (gh_double2scm (ideal_y),
+ gh_double2scm (shortest_y),
+ SCM_UNDEFINED));
+ return;
}
- Direction mydir = Directional_element_interface::get (me);
+ Direction my_dir = Directional_element_interface::get (me);
Real staff_space = Staff_symbol_referencer::staff_space (me);
- Real half_space = staff_space / 2;
+ Grob *beam = get_beam (me);
+ Real beam_translation = Beam::get_beam_translation (beam);
+ Real beam_thickness = gh_scm2double (beam->get_grob_property ("thickness"));
+ int beam_count = Beam::get_direction_beam_count (beam, my_dir);
+
+
+ /* Simple standard stem length */
+ Real ideal_length =
+ gh_scm2double (robust_list_ref
+ (beam_count - 1,
+ me->get_grob_property ("beamed-lengths")))
+ * staff_space
+ /* stem only extends to center of beam */
+ - 0.5 * beam_thickness;
- Grob * beam = beam_l (me);
- int beam_count = beam_multiplicity(me).length()+1;
- Real beam_translation= Beam::get_beam_translation (beam);
- Real thick = gh_scm2double (beam->get_grob_property ("thickness"));
- Real note_start = chord_start_y (me);
-
- /* from here on, calculate as if dir == UP */
- note_start *= mydir;
- SCM grace_prop = me->get_grob_property ("grace");
+ /* Condition: sane minimum free stem length (chord to beams) */
+ Real ideal_minimum_free =
+ gh_scm2double (robust_list_ref
+ (beam_count - 1,
+ me->get_grob_property ("beamed-minimum-free-lengths")))
+ * staff_space;
- bool grace_b = to_boolean (grace_prop);
- SCM bml = robust_list_ref ( beam_count ,
- me->get_grob_property ("beamed-minimum-lengths"));
- Real minimum_length = gh_scm2double(bml)*staff_space;
- SCM bl = robust_list_ref ( beam_count ,
- me->get_grob_property ("beamed-lengths"));
- Real stem_length = gh_scm2double(bl) * staff_space;
+ /* UGH
+ It seems that also for ideal minimum length, we must use
+ the maximum beam count (for this direction):
+
+ \score{ \notes\relative c''{ [a8 a32] }}
+
+ must be horizontal. */
+ Real height_of_my_beams = beam_thickness
+ + (beam_count - 1) * beam_translation;
+ Real ideal_minimum_length = ideal_minimum_free
+ + height_of_my_beams
+ /* stem only extends to center of beam */
+ - 0.5 * beam_thickness;
- /*
- stem goes to center of beam, hence 0.5
- */
- Real beam_lengthen = beam_translation* (beam_count - 1)
- + ((beam_count > 0) ? thick : 0) - 0.5 * thick;
+ ideal_length = ideal_length >? ideal_minimum_length;
- Real shortest_y = note_start + minimum_length + beam_lengthen;
- Real ideal_y = stem_length + note_start + beam_lengthen;
+
+ /* Convert to Y position, calculate for dir == UP */
+ Real note_start =
+ /* staff positions */
+ head_positions (me)[my_dir] * 0.5
+ * my_dir;
+ Real ideal_y = note_start + ideal_length;
- /*
- lowest beam of (UP) beam must never be lower than second staffline
- Hmm, reference (Wanske?)
+ /* Conditions for Y position */
- Although this (additional) rule is probably correct,
- I expect that highest beam (UP) should also never be lower
- than middle staffline, just as normal stems.
+ /* Lowest beam of (UP) beam must never be lower than second staffline
+
+ Reference?
+
+ Although this (additional) rule is probably correct,
+ I expect that highest beam (UP) should also never be lower
+ than middle staffline, just as normal stems.
- Add: not for knees. Not sure if that's is a good thing.
- */
+ Reference?
+
+ Obviously not for grace beams.
+
+ Also, not for knees. Seems to be a good thing. */
+ SCM grace = me->get_grob_property ("grace");
+ bool grace_b = to_boolean (grace);
bool no_extend_b = to_boolean (me->get_grob_property ("no-stem-extend"));
bool knee_b = to_boolean (beam->get_grob_property ("knee"));
if (!grace_b && !no_extend_b && !knee_b)
{
- /* highest beam of (UP) beam must never be lower than middle
- staffline
- lowest beam of (UP) beam must never be lower than second staffline
- */
- ideal_y =
- ideal_y >? 0
- >? (- 2 * half_space - thick + beam_lengthen);
+ /* Highest beam of (UP) beam must never be lower than middle
+ staffline */
+ ideal_y = ideal_y >? 0;
+ /* Lowest beam of (UP) beam must never be lower than second staffline */
+ ideal_y = ideal_y >? (-staff_space
+ - beam_thickness + height_of_my_beams);
}
-
-
- // ideal_y = ideal_y >? shortest_y;
- SCM s = beam->get_grob_property ("shorten");
- if (gh_number_p (s))
- ideal_y -= gh_scm2double (s);
+
+ SCM shorten = beam->get_grob_property ("shorten");
+ if (gh_number_p (shorten))
+ ideal_y -= gh_scm2double (shorten);
+
+
+ Real minimum_free =
+ gh_scm2double (robust_list_ref
+ (beam_count - 1,
+ me->get_grob_property
+ ("beamed-extreme-minimum-free-lengths")))
+ * staff_space;
+
+ Real minimum_length = minimum_free
+ + height_of_my_beams
+ /* stem only extends to center of beam */
+ - 0.5 * beam_thickness;
+
+ Real minimum_y = note_start + minimum_length;
- ideal_y *= mydir;
- shortest_y *= mydir;
+
+ ideal_y *= my_dir;
+ Real shortest_y = minimum_y * my_dir;
me->set_grob_property ("stem-info",
scm_list_n (gh_double2scm (ideal_y),
gh_double2scm (shortest_y),
SCM_UNDEFINED));
-
- Stem_info si;
- si.dir_ = mydir;
- si.shortest_y_ = shortest_y;
- si.ideal_y_ = ideal_y;
-
- return si;
}
-
-// move to stem?
Slice
Stem::beam_multiplicity (Grob *stem)
{
ADD_INTERFACE (Stem,"stem-interface",
"A stem",
- "up-to-staff avoid-note-head adjust-if-on-staffline thickness stem-info beamed-lengths beamed-minimum-lengths lengths beam stem-shorten duration-log beaming neutral-direction stem-end-position support-head note-heads direction length style no-stem-extend flag-style dir-forced");
+ "up-to-staff avoid-note-head adjust-if-on-staffline thickness stem-info beamed-lengths beamed-minimum-free-lengths beamed-extreme-minimum-free-lengths lengths beam stem-shorten duration-log beaming neutral-direction stem-end-position support-head note-heads direction length style no-stem-extend flag-style");