source file of the GNU LilyPond music typesetter
- (c) 1996--2002 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+ (c) 1996--2003 Han-Wen Nienhuys <hanwen@cs.uu.nl>
Jan Nieuwenhuizen <janneke@gnu.org>
TODO: This is way too hairy
SCM s;
Array<Real> a;
- Real length_f = 3.5;
+ Real length = 3.5;
SCM scm_len = me->get_grob_property ("length");
if (gh_number_p (scm_len))
{
- length_f = gh_scm2double (scm_len);
+ length = gh_scm2double (scm_len);
}
else
{
s = me->get_grob_property ("lengths");
if (gh_pair_p (s))
{
- length_f = 2* gh_scm2double (robust_list_ref (duration_log(me) -2, s));
+ length = 2* gh_scm2double (robust_list_ref (duration_log(me) -2, s));
}
}
- Real shorten_f = 0.0;
+ Real shorten = 0.0;
SCM sshorten = me->get_grob_property ("stem-shorten");
- if (gh_pair_p (sshorten))
+ SCM scm_shorten = gh_pair_p (sshorten) ?
+ robust_list_ref ((duration_log (me) - 2) >? 0, sshorten): SCM_EOL;
+ if (gh_number_p (scm_shorten))
{
- shorten_f = 2* gh_scm2double (robust_list_ref ((duration_log (me) - 2) >? 0, sshorten));
+ shorten = 2* gh_scm2double (scm_shorten);
}
- /* On boundary: shorten only half */
- if (abs (chord_start_y (me)) == 0.5)
- shorten_f *= 0.5;
+
/* URGURGURG
'set-default-stemlen' sets direction too
dir = get_default_dir (me);
Directional_element_interface::set (me, dir);
}
+
+ /* On boundary: shorten only half */
+ if (abs (head_positions (me)[get_direction (me)]) <= 1)
+ shorten *= 0.5;
/* stems in unnatural (forced) direction should be shortened,
according to [Roush & Gourlay] */
- if (chord_start_y (me)
- && (get_direction (me) != get_default_dir (me)))
- length_f -= shorten_f;
+ if (!chord_start_y (me)
+ || (get_direction (me) != get_default_dir (me)))
+ length -= shorten;
Interval hp = head_positions (me);
- Real st = hp[dir] + dir * length_f;
-
+ Real st = hp[dir] + dir * length;
/*
TODO: change name to extend-stems to staff/center/'()
heads.reverse ();
- bool invisible = invisible_b (me);
- Real thick = 0.0;
- if (invisible)
- thick = gh_scm2double (me->get_grob_property ("thickness"))
- * me->get_paper ()->get_var ("linethickness");
+ Real thick = gh_scm2double (me->get_grob_property ("thickness"))
+ * me->get_paper ()->get_var ("linethickness");
-
Grob *hed = support_head (me);
Real w = Note_head::head_extent (hed,X_AXIS)[dir];
for (int i=0; i < heads.size (); i++)
X_AXIS);
}
- bool parity= true; // todo: make me settable.
+ bool parity= true;
int lastpos = int (Staff_symbol_referencer::get_position (heads[0]));
for (int i=1; i < heads.size (); i ++)
{
Real l = Note_head::head_extent (heads[i], X_AXIS).length ();
Direction d = get_direction (me);
- heads[i]->translate_axis (l * d, X_AXIS);
+ /* reversed head should be shifted l-thickness, but this looks
+ too crowded, so we only shift l-0.5*thickness.
+ Notice that this leads to assymetry: Normal heads overlap
+ the stem 100% whereas reversed heads only overlaps the stem
+ 50% */
+ #define magic 0.5
+ heads[i]->translate_axis ((l-thick*magic) * d, X_AXIS);
if (invisible_b(me))
- heads[i]->translate_axis (-thick *2* d , X_AXIS);
+ heads[i]->translate_axis (-thick*(2-magic) * d , X_AXIS);
/* TODO:
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);
}
Molecule
Stem::flag (Grob*me)
{
- /* TODO: rename flag-style into something more appropriate,
- 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))
+ /* 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))
{
- fstyle = ly_scm2string (fst);
+ flag_style = ly_symbol2string (flag_style_scm);
}
- SCM st = me->get_grob_property ("style");
- if (gh_symbol_p (st))
- {
- style = (ly_scm2string (scm_symbol_to_string (st)));
- }
- else
+ if (flag_style == "no-flag")
{
- style = "";
+ return Molecule ();
}
+
bool adjust = to_boolean (me->get_grob_property ("adjust-if-on-staffline"));
- if (String::compare (style, "mensural") == 0)
+ 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,
--hwn.
*/
- Grob *first = first_head(me);
- int sz = Staff_symbol_referencer::line_count (me)-1;
- int p = (int)rint (Staff_symbol_referencer::get_position (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_string
- = String ("flags-") + style + to_string (c) + staffline_offs + to_string (duration_log (me));
- Molecule m
- = Font_interface::get_default_font (me)->find_by_name (index_string);
- if (!fstyle.empty_b ())
- m.add_molecule (Font_interface::get_default_font (me)->find_by_name (String ("flags-") + to_string (c) + fstyle));
- return m;
+
+ 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);
/*
TODO: make the stem start a direction ?
*/
-
-
-
if (to_boolean (me->get_grob_property ("avoid-note-head")))
{
Grob * lh = last_head (me);
/* Simple standard stem length */
+ SCM lengths = me->get_grob_property ("beamed-lengths");
Real ideal_length =
- gh_scm2double (robust_list_ref
- (beam_count - 1,
- me->get_grob_property ("beamed-lengths")))
+ gh_scm2double (robust_list_ref (beam_count - 1,lengths))
+
* staff_space
/* stem only extends to center of beam */
- 0.5 * beam_thickness;
-
/* Condition: sane minimum free stem length (chord to beams) */
+ lengths = me->get_grob_property ("beamed-minimum-free-lengths");
Real ideal_minimum_free =
- gh_scm2double (robust_list_ref
- (beam_count - 1,
- me->get_grob_property ("beamed-minimum-free-lengths")))
+ gh_scm2double (robust_list_ref (beam_count - 1, lengths))
* staff_space;
- int my_beam_count = Stem::beam_multiplicity (me).length () + 1;
-#if 0
- Real height_of_my_beams = beam_thickness
- + (my_beam_count - 1) * beam_translation;
-#else
+
/* UGH
It seems that also for ideal minimum length, we must use
the maximum beam count (for this direction):
must be horizontal. */
Real height_of_my_beams = beam_thickness
+ (beam_count - 1) * beam_translation;
-#endif
Real ideal_minimum_length = ideal_minimum_free
+ height_of_my_beams
if (gh_number_p (shorten))
ideal_y -= gh_scm2double (shorten);
-
Real minimum_free =
gh_scm2double (robust_list_ref
(beam_count - 1,
ADD_INTERFACE (Stem,"stem-interface",
"A stem",
- "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");
+ "french-beaming 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 flag-style no-stem-extend stroke-style");