+ /* TODO: maybe property stroke-style should take different values,
+ e.g. "" (i.e. no stroke), "single" and "double" (currently, it's
+ '() or "grace"). */
+ String flag_style;
+
+ SCM flag_style_scm = me->get_grob_property ("flag-style");
+ if (gh_symbol_p (flag_style_scm))
+ {
+ flag_style = ly_symbol2string (flag_style_scm);
+ }
+
+ if (flag_style == "no-flag")
+ {
+ return Molecule ();
+ }
+
+ bool adjust = to_boolean (me->get_grob_property ("adjust-if-on-staffline"));
+
+ String staffline_offs;
+ if (String::compare (flag_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,
+ regardless if the note head is on a staff line or between two
+ staff lines. In other words, the inner end of a flag always
+ touches a staff line.
+ */
+ {
+ if (adjust)
+ {
+ /* Urrgh! We have to detect wether this stem ends on a staff
+ line or between two staff lines. But we can not call
+ stem_end_position(me) or get_default_stem_end_position(me),
+ since this encounters the flag and hence results in an
+ infinite recursion. However, in pure mensural notation,
+ there are no multiple note heads attached to a single stem,
+ neither is there usually need for using the stem_shorten
+ property (except for 32th and 64th notes, but that is not a
+ problem since the stem length in this case is augmented by
+ an integral multiple of staff_space). Hence, it should be
+ sufficient to just take the first note head, assume it's
+ the only one, look if it's on a staff line, and select the
+ flag's shape accordingly. In the worst case, the shape
+ looks slightly misplaced, but that will usually be the
+ programmer's fault (e.g. when trying to attach multiple
+ note heads to a single stem in mensural notation). */
+
+ /*
+ perhaps the detection whether this correction is needed should
+ happen in a different place to avoid the recursion.
+
+ --hwn.
+ */
+ 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 = "2";
+ }
+ }
+ else
+ {
+ staffline_offs = "";
+ }
+
+ char dir = (get_direction (me) == UP) ? 'u' : 'd';
+ String font_char =
+ flag_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_style_scm = me->get_grob_property ("stroke-style");
+ if (gh_string_p (stroke_style_scm))
+ {
+ String stroke_style = ly_scm2string (stroke_style_scm);
+ if (!stroke_style.empty_b ())
+ {
+ String font_char = to_string (dir) + stroke_style;
+ 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);
+SCM
+Stem::dim_callback (SCM e, SCM ax)
+{
+ Axis a = (Axis) gh_scm2int (ax);
+ assert (a == X_AXIS);
+ Grob *se = unsmob_grob (e);