diff options
author | Han-Wen Nienhuys <hanwen@xs4all.nl> | 2005-10-16 13:28:20 +0000 |
---|---|---|
committer | Han-Wen Nienhuys <hanwen@xs4all.nl> | 2005-10-16 13:28:20 +0000 |
commit | 85d8b50f9d36b3f2d38aa11de3755cf563ac49e3 (patch) | |
tree | 83e9fc49ad1ea822d0f148006dc3dd9765d10839 | |
parent | 0f7c7f4503011bc1e191933cb8a9f0ba1f95aceb (diff) |
* lily/grob-property.cc (get_interfaces): new function.
* lily/grob-scheme.cc (LY_DEFINE): new function ly:grob-interfaces
* lily/stem.cc (calc_stem_end_position): new function.
(calc_length): new function.
document details for stem.
remove Stem::get_direction()
* lily/grob-scheme.cc (LY_DEFINE): new function ly:grob-set-callback!
* lily/grob-property.cc (set_callback): new function.
* lily/script-engraver.cc (make_script_from_event): don't trigger callback.
* scm/define-grobs.scm: change print-function to stencil callback everywhere.
* lily/grob-property.cc (try_callback): remove marker if applicable.
* lily/stem.cc (height): idem.
* lily/stem-tremolo.cc: idem.
* lily/include/grob.hh: remove Grob_status.
* lily/beam.cc (calc_direction): use pseudo-property for beam
direction callback.
(calc_positions): use callback
* lily/stem.cc (calc_stem_end_position): use callback.
(calc_positioning_done): idem.
(calc_direction): idem.
(calc_stem_end_position): idem
(calc_stem_info): idem.
* lily/grob-property.cc (get_property_data): new function:
(try_callback): new function.
* scm/define-grob-properties.scm (all-user-grob-properties): doc
callbacks property.
34 files changed, 235 insertions, 215 deletions
@@ -1,5 +1,18 @@ 2005-10-16 Han-Wen Nienhuys <hanwen@xs4all.nl> + * lily/grob-property.cc (get_interfaces): new function. + + * lily/grob-scheme.cc (LY_DEFINE): new function ly:grob-interfaces + + * lily/stem.cc (calc_stem_end_position): new function. + (calc_length): new function. + document details for stem. + remove Stem::get_direction() + + * lily/grob-scheme.cc (LY_DEFINE): new function ly:grob-set-callback! + + * lily/grob-property.cc (set_callback): new function. + * lily/script-engraver.cc (make_script_from_event): don't trigger callback. * lily/item-scheme.cc: new file. diff --git a/input/regression/accidental-cautionary.ly b/input/regression/accidental-cautionary.ly index 596b7290c4..1edec4a0bc 100644 --- a/input/regression/accidental-cautionary.ly +++ b/input/regression/accidental-cautionary.ly @@ -1,4 +1,4 @@ -\version "2.6.0" +\version "2.7.13" \header { texidoc = "Cautionary accidentals are indicated using either diff --git a/input/regression/accidental-double.ly b/input/regression/accidental-double.ly index f0bd207e2a..11460dd577 100644 --- a/input/regression/accidental-double.ly +++ b/input/regression/accidental-double.ly @@ -1,4 +1,4 @@ -\version "2.6.0" +\version "2.7.13" \header { texidoc = "If two forced accidentals happen at the same time, only one sharp sign is printed." diff --git a/input/regression/accidental-ledger.ly b/input/regression/accidental-ledger.ly index 1071d39a45..fae9f6d1e7 100644 --- a/input/regression/accidental-ledger.ly +++ b/input/regression/accidental-ledger.ly @@ -1,4 +1,4 @@ -\version "2.6.0" +\version "2.7.13" \header { diff --git a/input/regression/accidental-octave.ly b/input/regression/accidental-octave.ly index 342465c633..c79a4dc194 100644 --- a/input/regression/accidental-octave.ly +++ b/input/regression/accidental-octave.ly @@ -1,5 +1,5 @@ -\version "2.6.0" +\version "2.7.13" \header { texidoc=" diff --git a/input/regression/accidental-piano.ly b/input/regression/accidental-piano.ly index 642266bc3c..0c229cc677 100644 --- a/input/regression/accidental-piano.ly +++ b/input/regression/accidental-piano.ly @@ -6,7 +6,7 @@ accidental." } -\version "2.6.0" +\version "2.7.13" \layout { diff --git a/input/regression/accidental-placement.ly b/input/regression/accidental-placement.ly index ca1e7b6b32..c0ef2b07f4 100644 --- a/input/regression/accidental-placement.ly +++ b/input/regression/accidental-placement.ly @@ -1,5 +1,5 @@ -\version "2.6.0" +\version "2.7.13" \header { diff --git a/input/regression/accidental-quarter.ly b/input/regression/accidental-quarter.ly index 32b3ef495a..0aca2134cd 100644 --- a/input/regression/accidental-quarter.ly +++ b/input/regression/accidental-quarter.ly @@ -3,7 +3,7 @@ texidoc = "Quarter tone notation is supported, including threequarters flat." } -\version "2.6.0" +\version "2.7.13" \layout { raggedright = ##t } \relative c'' { diff --git a/input/regression/accidental-single-double.ly b/input/regression/accidental-single-double.ly index a7e196925e..824e419fc6 100644 --- a/input/regression/accidental-single-double.ly +++ b/input/regression/accidental-single-double.ly @@ -1,5 +1,5 @@ -\version "2.6.0" +\version "2.7.13" \header{ texidoc=" A sharp sign after a double sharp sign, as well as a flat sign diff --git a/input/regression/accidental-suggestions.ly b/input/regression/accidental-suggestions.ly index d160ed01e9..7f1c534af3 100644 --- a/input/regression/accidental-suggestions.ly +++ b/input/regression/accidental-suggestions.ly @@ -7,7 +7,7 @@ denoting Musica Ficta." } -\version "2.7.2" +\version "2.7.13" \paper { raggedright = ##t } diff --git a/input/regression/accidental-tie.ly b/input/regression/accidental-tie.ly index 55146b18a9..3651468934 100644 --- a/input/regression/accidental-tie.ly +++ b/input/regression/accidental-tie.ly @@ -1,4 +1,4 @@ -\version "2.6.0" +\version "2.7.13" \header { texidoc = "The second and third notes should not get accidentals, diff --git a/input/regression/accidental-unbroken-tie-spacing.ly b/input/regression/accidental-unbroken-tie-spacing.ly index 4c718a4932..2ca2d36b33 100644 --- a/input/regression/accidental-unbroken-tie-spacing.ly +++ b/input/regression/accidental-unbroken-tie-spacing.ly @@ -4,7 +4,7 @@ texidoc = "Tied accidentaled notes (which cause reminder accidentals) do not wreak havoc in the spacing when unbroken." } -\version "2.6.0" +\version "2.7.13" \layout { raggedright = ##t } diff --git a/input/regression/accidental-voice.ly b/input/regression/accidental-voice.ly index 66ab2514e8..a0d5a2c5a1 100644 --- a/input/regression/accidental-voice.ly +++ b/input/regression/accidental-voice.ly @@ -1,4 +1,4 @@ -\version "2.6.0" +\version "2.7.13" \layout { raggedright = ##t } \header{ diff --git a/input/regression/accidental.ly b/input/regression/accidental.ly index 1e8de5dcb5..0c04e44d46 100644 --- a/input/regression/accidental.ly +++ b/input/regression/accidental.ly @@ -1,5 +1,5 @@ -\version "2.6.0" +\version "2.7.13" \header{ texidoc=" diff --git a/input/regression/alignment-order.ly b/input/regression/alignment-order.ly index e933deb5ba..718187b862 100644 --- a/input/regression/alignment-order.ly +++ b/input/regression/alignment-order.ly @@ -3,7 +3,7 @@ anywhere in the vertical alignment. " } -\version "2.6.0" +\version "2.7.13" \paper { raggedright = ##t diff --git a/input/regression/alignment-vertical-spacing.ly b/input/regression/alignment-vertical-spacing.ly index 2fd0c0bd4f..5b7a8339b2 100644 --- a/input/regression/alignment-vertical-spacing.ly +++ b/input/regression/alignment-vertical-spacing.ly @@ -16,7 +16,7 @@ setting properties on individual object. @code{\override} in a } -\version "2.7.10" +\version "2.7.13" #(set-global-staff-size 13) diff --git a/input/regression/ambitus.ly b/input/regression/ambitus.ly index c839d69568..ceab79155d 100644 --- a/input/regression/ambitus.ly +++ b/input/regression/ambitus.ly @@ -6,7 +6,7 @@ signature. @code{AmbitusNoteHead} grobs also have ledger lines. " } -\version "2.6.0" +\version "2.7.13" \layout { raggedright = ##t diff --git a/input/regression/apply-context.ly b/input/regression/apply-context.ly index 9eff3c001d..e8bf2e1f16 100644 --- a/input/regression/apply-context.ly +++ b/input/regression/apply-context.ly @@ -1,5 +1,5 @@ -\version "2.7.10" +\version "2.7.13" \header { diff --git a/input/regression/apply-output.ly b/input/regression/apply-output.ly index 85829a0e88..59025e1044 100644 --- a/input/regression/apply-output.ly +++ b/input/regression/apply-output.ly @@ -1,5 +1,5 @@ -\version "2.7.10" +\version "2.7.13" \header { texidoc = "The @code{\applyOutput} expression is the most flexible way to @@ -15,13 +15,13 @@ position. #(define (mc-squared gr org cur) (let* ( - (ifs (ly:grob-property gr 'interfaces)) + (ifs (ly:grob-interfaces gr)) (sp (ly:grob-property gr 'staff-position)) ) (if (and (memq 'note-head-interface ifs) (memq sp '(-2 -3 -5))) (begin - (ly:grob-set-property! gr 'print-function Text_interface::print) + (ly:grob-set-callback! gr 'stencil Text_interface::print) (ly:grob-set-property! gr 'font-family 'roman) (ly:grob-set-property! gr 'text diff --git a/lily/beam-concave.cc b/lily/beam-concave.cc index f0e0cbde50..f8b31f460a 100644 --- a/lily/beam-concave.cc +++ b/lily/beam-concave.cc @@ -7,6 +7,7 @@ #include "stem.hh" #include "beam.hh" #include "staff-symbol-referencer.hh" +#include "directional-element-interface.hh" bool is_concave_single_notes (Array<int> const &positions, Direction beam_dir) @@ -98,7 +99,7 @@ Beam::check_concave (SCM smob) stems.del (i); else { - if (Direction dir = Stem::get_direction (stems[i])) + if (Direction dir = get_grob_direction (stems[i])) beam_dir = dir; } } diff --git a/lily/beam.cc b/lily/beam.cc index f4d29ed728..2ee9e7086c 100644 --- a/lily/beam.cc +++ b/lily/beam.cc @@ -716,13 +716,12 @@ Beam::set_stem_shorten (Grob *me) SCM shorten_elt = robust_list_ref (beam_count -1, shorten_list); - Real shorten_f = scm_to_double (shorten_elt) * staff_space; + Real shorten = scm_to_double (shorten_elt) * staff_space; - /* your similar cute comment here */ - shorten_f *= forced_fraction; + shorten *= forced_fraction; - if (shorten_f) - me->set_property ("shorten", scm_from_double (shorten_f)); + if (shorten) + me->set_property ("shorten", scm_from_double (shorten)); } MAKE_SCHEME_CALLBACK (Beam, calc_positions, 1); @@ -942,7 +941,7 @@ Beam::shift_region_to_valid (SCM grob) if (Stem::is_invisible (s)) continue; - Direction d = Stem::get_direction (s); + Direction d = get_grob_direction (s); Real left_y = Stem::get_stem_info (s).shortest_y_ @@ -1197,7 +1196,7 @@ Beam::forced_stem_count (Grob *me) /* I can imagine counting those boundaries as a half forced stem, but let's count them full for now. */ if (abs (Stem::chord_start_y (s)) > 0.1 - && (Stem::get_direction (s) != Stem::get_default_dir (s))) + && (get_grob_direction (s) != Stem::get_default_dir (s))) f++; } return f; @@ -1292,7 +1291,7 @@ Beam::rest_collision_callback (SCM element_smob, SCM axis) Real dx = last_visible_stem (beam)->relative_coordinate (0, X_AXIS) - x0; Real slope = dy && dx ? dy / dx : 0; - Direction d = Stem::get_direction (stem); + Direction d = get_grob_direction (stem); Real stem_y = pos[LEFT] + (stem->relative_coordinate (0, X_AXIS) - x0) * slope; Real beam_translation = get_beam_translation (beam); @@ -1370,7 +1369,7 @@ Beam::get_direction_beam_count (Grob *me, Direction d) /* Should we take invisible stems into account? */ - if (Stem::get_direction (stems[i]) == d) + if (get_grob_direction (stems[i]) == d) bc = max (bc, (Stem::beam_multiplicity (stems[i]).length () + 1)); } diff --git a/lily/grob-property.cc b/lily/grob-property.cc index 0513299cd8..529315402a 100644 --- a/lily/grob-property.cc +++ b/lily/grob-property.cc @@ -26,6 +26,12 @@ Grob::get_property_alist_chain (SCM def) const SCM_UNDEFINED); } +SCM +Grob::get_interfaces () const +{ + return interfaces_; +} + /* This special add_thing routine is slightly more efficient than @@ -160,7 +166,7 @@ Grob::internal_get_property (SCM sym) const #ifndef NDEBUG #include "protected-scm.hh" Protected_scm grob_property_callback_stack = SCM_EOL; -bool debug_property_callbacks; +bool debug_property_callbacks = 1; #endif SCM diff --git a/lily/grob-scheme.cc b/lily/grob-scheme.cc index 5626914b91..e3f72d999b 100644 --- a/lily/grob-scheme.cc +++ b/lily/grob-scheme.cc @@ -23,9 +23,9 @@ LY_DEFINE (ly_grob_set_callback_x, "ly:grob-set-callback!", Grob *sc = unsmob_grob (grob); SCM_ASSERT_TYPE (sc, grob, SCM_ARG1, __FUNCTION__, "grob"); SCM_ASSERT_TYPE (scm_is_symbol (sym), sym, SCM_ARG2, __FUNCTION__, "symbol"); - SCM_ASSERT_TYPE (ly_is_procedure (val), val, SCM_ARG3, __FUNCTION__, "procedure"); + SCM_ASSERT_TYPE (ly_is_procedure (proc), proc, SCM_ARG3, __FUNCTION__, "procedure"); - sc->set_callback (sym, val); + sc->set_callback (sym, proc); return SCM_UNSPECIFIED; } @@ -58,6 +58,17 @@ LY_DEFINE (ly_grob_property, "ly:grob-property", return sc->internal_get_property (sym); } + +LY_DEFINE (ly_grob_interfaces, "ly:grob-interfaces", + 1, 0, 0, (SCM grob), + "Return the interfaces list of grob @var{grob}.") +{ + Grob *sc = unsmob_grob (grob); + SCM_ASSERT_TYPE (sc, grob, SCM_ARG1, __FUNCTION__, "grob"); + + return sc->get_interfaces (); +} + LY_DEFINE (ly_grob_object, "ly:grob-object", 2, 0, 0, (SCM grob, SCM sym), "Return the value of a pointer in grob @var{g} of property @var{sym}. " diff --git a/lily/include/grob.hh b/lily/include/grob.hh index 7a74d8baee..96cfba86c3 100644 --- a/lily/include/grob.hh +++ b/lily/include/grob.hh @@ -108,7 +108,8 @@ public: bool internal_has_interface (SCM intf); static bool has_interface (Grob *me); - + SCM get_interfaces () const; + virtual void handle_broken_dependencies (); virtual void handle_prebroken_dependencies (); diff --git a/lily/include/stem.hh b/lily/include/stem.hh index a42daf856d..5e6260c6b0 100644 --- a/lily/include/stem.hh +++ b/lily/include/stem.hh @@ -26,24 +26,23 @@ public: static void add_head (Grob *me, Grob *n); static Stem_info get_stem_info (Grob *); static Real chord_start_y (Grob *); - static Direction get_direction (Grob *); static void set_stemend (Grob *, Real); - static Direction get_default_dir (Grob *); static Slice beam_multiplicity (Grob *); + static Direction get_default_dir (Grob*); static Real thickness (Grob *); static int head_count (Grob *); static bool is_invisible (Grob *); static Interval head_positions (Grob *); - static Real get_default_stem_end_position (Grob *me); static Real stem_end_position (Grob *); static Stencil flag (Grob *); static Stencil get_translated_flag (Grob*); static bool has_interface (Grob *); static void set_spacing_hints (Grob *); - + DECLARE_SCHEME_CALLBACK (print, (SCM)); DECLARE_SCHEME_CALLBACK (offset_callback, (SCM element, SCM axis)); DECLARE_SCHEME_CALLBACK (calc_direction, (SCM)); + DECLARE_SCHEME_CALLBACK (calc_length, (SCM)); DECLARE_SCHEME_CALLBACK (calc_stem_end_position, (SCM)); DECLARE_SCHEME_CALLBACK (calc_stem_info, (SCM)); DECLARE_SCHEME_CALLBACK (calc_positioning_done, (SCM)); diff --git a/lily/note-column.cc b/lily/note-column.cc index f49b65b986..0b7481529a 100644 --- a/lily/note-column.cc +++ b/lily/note-column.cc @@ -20,6 +20,7 @@ using namespace std; #include "note-head.hh" #include "accidental-placement.hh" #include "pointer-group-interface.hh" +#include "directional-element-interface.hh" /* TODO: figure out if we can prune this class. This is just an @@ -73,7 +74,7 @@ Note_column::dir (Grob *me) { Grob *stem = unsmob_grob (me->get_object ("stem")); if (stem && Stem::has_interface (stem)) - return Stem::get_direction (stem); + return get_grob_direction (stem); else { extract_grob_set (me, "note-heads", heads); diff --git a/lily/note-spacing.cc b/lily/note-spacing.cc index 8f55664c33..81ed7de0bc 100644 --- a/lily/note-spacing.cc +++ b/lily/note-spacing.cc @@ -8,6 +8,7 @@ #include "note-spacing.hh" +#include "directional-element-interface.hh" #include "grob-array.hh" #include "paper-column.hh" #include "moment.hh" @@ -300,7 +301,7 @@ Note_spacing::stem_dir_correction (Grob *me, Item *rcolumn, stems_drul[d] = stem; beams_drul[d] = Stem::get_beam (stem); - Direction sd = Stem::get_direction (stem); + Direction sd = get_grob_direction (stem); if (stem_dirs[d] && stem_dirs[d] != sd) { correct_stem_dirs = false; diff --git a/lily/script-engraver.cc b/lily/script-engraver.cc index 26d72f361d..63284c67e2 100644 --- a/lily/script-engraver.cc +++ b/lily/script-engraver.cc @@ -212,7 +212,6 @@ Script_engraver::acknowledge_note_column (Grob_info info) As the note head to put it on is not known now, postpone this decision to Script_interface::calc_direction (). */ - */ for (int i = 0; i < scripts_.size (); i++) { Grob *e = scripts_[i].script_; diff --git a/lily/staff-spacing.cc b/lily/staff-spacing.cc index a862a16f11..495458eb77 100644 --- a/lily/staff-spacing.cc +++ b/lily/staff-spacing.cc @@ -20,6 +20,7 @@ using namespace std; #include "stem.hh" #include "accidental-placement.hh" #include "pointer-group-interface.hh" +#include "directional-element-interface.hh" /* Insert some more space for the next note, in case it has a stem in @@ -66,7 +67,7 @@ Staff_spacing::next_note_correction (Grob *me, if (!bar_size.is_empty ()) if (Grob *stem = Note_column::get_stem (g)) { - Direction d = Stem::get_direction (stem); + Direction d = get_grob_direction (stem); if (d == DOWN) { Real stem_start = Stem::head_positions (stem) [DOWN]; diff --git a/lily/stem-tremolo.cc b/lily/stem-tremolo.cc index e5571b1e42..94e0c36683 100644 --- a/lily/stem-tremolo.cc +++ b/lily/stem-tremolo.cc @@ -123,7 +123,7 @@ Stem_tremolo::print (SCM grob) } Spanner *beam = Stem::get_beam (stem); - Direction stemdir = Stem::get_direction (stem); + Direction stemdir = get_grob_direction (stem); if (stemdir == 0) stemdir = UP; diff --git a/lily/stem.cc b/lily/stem.cc index 3f1bf40f33..7b90d475e1 100644 --- a/lily/stem.cc +++ b/lily/stem.cc @@ -80,48 +80,20 @@ Stem::chord_start_y (Grob *me) { Interval hp = head_positions (me); if (!hp.is_empty ()) - return hp[get_direction (me)] * Staff_symbol_referencer::staff_space (me) + return hp[get_grob_direction (me)] * Staff_symbol_referencer::staff_space (me) * 0.5; return 0; } -Real -Stem::stem_end_position (Grob *me) -{ - SCM p = me->get_property ("stem-end-position"); - Real pos; - if (!scm_is_number (p)) - { - pos = get_default_stem_end_position (me); - me->set_property ("stem-end-position", scm_from_double (pos)); - } - else - pos = scm_to_double (p); - - return pos; -} - -Direction -Stem::get_direction (Grob *me) -{ - Direction d = get_grob_direction (me); - if (!d) - { - d = get_default_dir (me); - // urg, AAARGH! - set_grob_direction (me, d); - } - return d; -} void Stem::set_stemend (Grob *me, Real se) { // todo: margins - Direction d = get_direction (me); + Direction d = get_grob_direction (me); - if (d && d * head_positions (me)[get_direction (me)] >= se * d) + if (d && d * head_positions (me)[get_grob_direction (me)] >= se * d) me->warning (_ ("weird stem size, check for narrow beams")); me->set_property ("stem-end-position", scm_from_double (se)); @@ -150,7 +122,7 @@ Stem::head_count (Grob *me) Grob * Stem::first_head (Grob *me) { - Direction d = get_direction (me); + Direction d = get_grob_direction (me); if (d) return extremal_heads (me)[-d]; return 0; @@ -160,7 +132,7 @@ Stem::first_head (Grob *me) Grob * Stem::last_head (Grob *me) { - Direction d = get_direction (me); + Direction d = get_grob_direction (me); if (d) return extremal_heads (me)[d]; return 0; @@ -248,54 +220,92 @@ Stem::is_invisible (Grob *me) && scm_to_int (me->get_property ("duration-log")) >= 1); } -Direction -Stem::get_default_dir (Grob *me) +MAKE_SCHEME_CALLBACK (Stem, calc_stem_end_position, 1) +SCM +Stem::calc_stem_end_position (SCM smob) { - int staff_center = 0; + Grob *me = unsmob_grob (smob); + + if (!head_count (me)) + return scm_from_double (0.0); + + + Real ss = Staff_symbol_referencer::staff_space (me); + int durlog = duration_log (me); + Array<Real> a; + + /* WARNING: IN HALF SPACES */ + Real length = robust_scm2double (me->get_property ("length"), 7); + + Direction dir = get_grob_direction (me); Interval hp = head_positions (me); - if (hp.is_empty ()) - return CENTER; + Real st = dir ? hp[dir] + dir * length : 0; - int udistance = (int) (UP *hp[UP] - staff_center); - int ddistance = (int) (DOWN *hp[DOWN] - staff_center); + /* TODO: change name to extend-stems to staff/center/'() */ + bool no_extend_b = to_boolean (me->get_property ("no-stem-extend")); + if (!no_extend_b && dir * st < 0) + st = 0.0; + + /* Make a little room if we have a upflag and there is a dot. + previous approach was to lengthen the stem. This is not + good typesetting practice. */ + if (!get_beam (me) && dir == UP + && durlog > 2) + { + Grob *closest_to_flag = extremal_heads (me)[dir]; + Grob *dots = closest_to_flag + ? Rhythmic_head::get_dots (closest_to_flag) : 0; + + if (dots) + { + Real dp = Staff_symbol_referencer::get_position (dots); + Real flagy = flag (me).extent (Y_AXIS)[-dir] * 2 / ss; + + /* Very gory: add myself to the X-support of the parent, + which should be a dot-column. */ + if (dir * (st + flagy - dp) < 0.5) + { + Grob *par = dots->get_parent (X_AXIS); - if (sign (ddistance - udistance)) - return Direction (sign (ddistance - udistance)); + if (Dot_column::has_interface (par)) + { + Side_position_interface::add_support (par, me); - return to_dir (me->get_property ("neutral-direction")); + /* TODO: apply some better logic here. The flag is + curved inwards, so this will typically be too + much. */ + } + } + } + } + + return scm_from_double (st); } -Real -Stem::get_default_stem_end_position (Grob *me) +MAKE_SCHEME_CALLBACK (Stem, calc_length, 1) +SCM +Stem::calc_length (SCM smob) { - Real ss = Staff_symbol_referencer::staff_space (me); + Grob *me = unsmob_grob (smob); + + SCM details = me->get_property ("details"); int durlog = duration_log (me); - SCM s; - Array<Real> a; - /* WARNING: IN HALF SPACES */ + Real ss = Staff_symbol_referencer::staff_space (me); Real length = 7; - SCM scm_len = me->get_property ("length"); - if (scm_is_number (scm_len)) - length = scm_to_double (scm_len); - else - { - s = me->get_property ("lengths"); - if (scm_is_pair (s)) - length = 2 * scm_to_double (robust_list_ref (durlog - 2, s)); - } + SCM s = scm_cdr (scm_assq (ly_symbol2scm ("lengths"), details)); + if (scm_is_pair (s)) + length = 2 * scm_to_double (robust_list_ref (durlog - 2, s)); - /* URGURGURG - 'set-default-stemlen' sets direction too. */ - Direction dir = get_direction (me); + Direction dir = get_grob_direction (me); /* Stems in unnatural (forced) direction should be shortened, according to [Roush & Gourlay] */ Interval hp = head_positions (me); if (dir && dir * hp[dir] >= 0) { - SCM sshorten = me->get_property ("stem-shorten"); + SCM sshorten = scm_cdr (scm_assq (ly_symbol2scm ("stem-shorten"), details)); SCM scm_shorten = scm_is_pair (sshorten) ? robust_list_ref (max (duration_log (me) - 2, 0), sshorten) : SCM_EOL; Real shorten = 2* robust_scm2double (scm_shorten, 0); @@ -333,49 +343,9 @@ Stem::get_default_stem_end_position (Grob *me) } length = max (length, minlen + 1.0); } - - Real st = dir ? hp[dir] + dir * length : 0; - - /* TODO: change name to extend-stems to staff/center/'() */ - bool no_extend_b = to_boolean (me->get_property ("no-stem-extend")); - if (!no_extend_b && dir * st < 0) - st = 0.0; - - /* Make a little room if we have a upflag and there is a dot. - previous approach was to lengthen the stem. This is not - good typesetting practice. */ - if (!get_beam (me) && dir == UP - && durlog > 2) - { - Grob *closest_to_flag = extremal_heads (me)[dir]; - Grob *dots = closest_to_flag - ? Rhythmic_head::get_dots (closest_to_flag) : 0; - - if (dots) - { - Real dp = Staff_symbol_referencer::get_position (dots); - Real flagy = flag (me).extent (Y_AXIS)[-dir] * 2 / ss; - - /* Very gory: add myself to the X-support of the parent, - which should be a dot-column. */ - if (dir * (st + flagy - dp) < 0.5) - { - Grob *par = dots->get_parent (X_AXIS); - - if (Dot_column::has_interface (par)) - { - Side_position_interface::add_support (par, me); - - /* TODO: apply some better logic here. The flag is - curved inwards, so this will typically be too - much. */ - } - } - } - } - return st; + + return scm_from_double (length); } - /* The log of the duration (Number of hooks on the flag minus two) */ int Stem::duration_log (Grob *me) @@ -395,7 +365,7 @@ Stem::calc_positioning_done (SCM smob) extract_grob_set (me, "note-heads", ro_heads); Link_array<Grob> heads (ro_heads); heads.sort (compare_position); - Direction dir = get_direction (me); + Direction dir = get_grob_direction (me); if (dir < 0) heads.reverse (); @@ -425,7 +395,7 @@ Stem::calc_positioning_done (SCM smob) { Real ell = heads[i]->extent (heads[i], X_AXIS).length (); - Direction d = get_direction (me); + Direction d = get_grob_direction (me); /* Reversed head should be shifted ell-thickness, but this looks too crowded, so we only shift ell-0.5*thickness. @@ -484,29 +454,31 @@ Stem::calc_direction (SCM smob) } else dir = get_default_dir (me); - + return scm_from_int (dir); } -MAKE_SCHEME_CALLBACK (Stem, calc_stem_end_position, 1); -SCM -Stem::calc_stem_end_position (SCM smob) +Direction +Stem::get_default_dir (Grob *me) { - Grob *me = unsmob_grob (smob); - - /* - Do the calculations for visible stems, but also for invisible stems - with note heads (i.e. half notes.) - */ - Real pos = 0.0; - if (head_count (me)) + Direction dir = CENTER; + int staff_center = 0; + Interval hp = head_positions (me); + if (!hp.is_empty ()) { - pos = stem_end_position (me); // ugh. Trigger direction calc. + int udistance = (int) (UP *hp[UP] - staff_center); + int ddistance = (int) (DOWN *hp[DOWN] - staff_center); + + if (sign (ddistance - udistance)) + dir = Direction (sign (ddistance - udistance)); + else + dir = to_dir (me->get_property ("neutral-direction")); } - - return scm_from_double (pos); + return dir; } + + MAKE_SCHEME_CALLBACK (Stem, height, 2); SCM Stem::height (SCM smob, SCM ax) @@ -542,6 +514,12 @@ Stem::height (SCM smob, SCM ax) return ly_interval2scm (iv); } +Real +Stem::stem_end_position (Grob *me) +{ + return robust_scm2double (me->get_property ("stem-end-position"), 0); +} + Stencil Stem::flag (Grob *me) { @@ -587,7 +565,7 @@ Stem::flag (Grob *me) else staffline_offs = ""; - char dir = (get_direction (me) == UP) ? 'u' : 'd'; + char dir = (get_grob_direction (me) == UP) ? 'u' : 'd'; String font_char = flag_style + to_string (dir) + staffline_offs + to_string (log); Font_metric *fm = Font_interface::get_default_font (me); @@ -652,7 +630,7 @@ Stem::print (SCM smob) { Grob *me = unsmob_grob (smob); Stencil mol; - Direction d = get_direction (me); + Direction d = get_grob_direction (me); Real stemlet_length = robust_scm2double (me->get_property ("stemlet-length"), 0.0); @@ -675,7 +653,7 @@ Stem::print (SCM smob) if (is_invisible (me)) return SCM_EOL; - Real y2 = stem_end_position (me); + Real y2 = robust_scm2double (me->get_property ("stem-end-position"), 0.0); Real y1 = y2; Real half_space = Staff_symbol_referencer::staff_space (me) * 0.5; @@ -729,12 +707,12 @@ Stem::get_translated_flag (Grob *me) Stencil fl = flag (me); if (!fl.is_empty ()) { - Direction d = get_direction (me); + Direction d = get_grob_direction (me); Real blot = me->get_layout ()->get_dimension (ly_symbol2scm ("blotdiameter")); Real stem_width = thickness (me); Real half_space = Staff_symbol_referencer::staff_space (me) * 0.5; - Real y2 = stem_end_position (me); + Real y2 = robust_scm2double (me->get_property ("stem-end-position"), 0.0); fl.translate_axis (y2 * half_space - d * blot / 2, Y_AXIS); fl.translate_axis (stem_width / 2, X_AXIS); } @@ -762,7 +740,7 @@ Stem::offset_callback (SCM element_smob, SCM) else attach = Note_head::stem_attachment_coordinate (f, X_AXIS); - Direction d = get_direction (me); + Direction d = get_grob_direction (me); Real real_attach = head_wid.linear_combination (d * attach); r = real_attach; @@ -825,7 +803,8 @@ Stem::calc_stem_info (SCM smob) int beam_count = Beam::get_direction_beam_count (beam, my_dir); /* Simple standard stem length */ - SCM lengths = me->get_property ("beamed-lengths"); + SCM details = me->get_property ("details"); + SCM lengths = scm_cdr (scm_assq (ly_symbol2scm ("beamed-lengths"), details)); Real ideal_length = scm_to_double (robust_list_ref (beam_count - 1, lengths)) @@ -835,7 +814,7 @@ Stem::calc_stem_info (SCM smob) - 0.5 * beam_thickness; /* Condition: sane minimum free stem length (chord to beams) */ - lengths = me->get_property ("beamed-minimum-free-lengths"); + lengths = scm_cdr (scm_assq (ly_symbol2scm ("beamed-minimum-free-lengths"), details)); Real ideal_minimum_free = scm_to_double (robust_list_ref (beam_count - 1, lengths)) * staff_space; @@ -893,11 +872,10 @@ Stem::calc_stem_info (SCM smob) ideal_y -= robust_scm2double (beam->get_property ("shorten"), 0); + SCM bemfl = scm_cdr (scm_assq (ly_symbol2scm ("beamed-extreme-minimum-free-lengths"), details)); + Real minimum_free - = scm_to_double (robust_list_ref - (beam_count - 1, - me->get_property - ("beamed-extreme-minimum-free-lengths"))) + = scm_to_double (robust_list_ref (beam_count - 1, bemfl)) * staff_space; Real minimum_length = minimum_free @@ -935,22 +913,36 @@ ADD_INTERFACE (Stem, "stem-interface", "The stem represent the graphical stem. " "In addition, it internally connects note heads, beams and" "tremolos. " - "Rests and whole notes have invisible stems.", + "Rests and whole notes have invisible stems." + + "\n\nThe following properties may be set in the details list." + "@table @code\n" + "@item beamed-lengths \n" + "list of stem lengths given beam multiplicity. \n" + "@item beamed-minimum-free-lengths \n" + "list of normal minimum free stem lengths (chord to beams) given beam multiplicity.\n" + "@item beamed-extreme-minimum-free-lengths\n" + "list of extreme minimum free stem lengths (chord to beams) given beam multiplicity.\n" + "@item lengths\n" + "Default stem lengths. The list gives a length for each flag-count.\n" + "@item stem-shorten\n" + "How much a stem in a forced direction " + "should be shortened. The list gives an amount depending on the number " + "of flags/beams." + "@end table\n" + + , /* properties */ "avoid-note-head " "beam " - "beamed-extreme-minimum-free-lengths " - "beamed-lengths " - "beamed-minimum-free-lengths " "beaming " "direction " "duration-log " "flag-style " "french-beaming " "length " - "lengths " "neutral-direction " "no-stem-extend " "note-heads " @@ -958,7 +950,6 @@ ADD_INTERFACE (Stem, "stem-interface", "rests " "stem-end-position " "stem-info " - "stem-shorten " "stemlet-length " "stroke-style " "thickness " diff --git a/lily/tie-column-format.cc b/lily/tie-column-format.cc index 3fb78cd166..bde9073652 100644 --- a/lily/tie-column-format.cc +++ b/lily/tie-column-format.cc @@ -14,6 +14,7 @@ #include "spanner.hh" #include "item.hh" #include "staff-symbol-referencer.hh" +#include "directional-element-interface.hh" #include <set> @@ -96,7 +97,7 @@ set_chord_outline (Array<Skyline_entry> *skyline, Interval y; y.add_point (Stem::stem_end_position (stem) * staff_space * .5); - Direction stemdir = Stem::get_direction (stem); + Direction stemdir = get_grob_direction (stem); y.add_point (Stem::head_positions (stem)[-stemdir] * staff_space * .5); diff --git a/scm/define-grob-properties.scm b/scm/define-grob-properties.scm index b80e958b39..5a15927a73 100644 --- a/scm/define-grob-properties.scm +++ b/scm/define-grob-properties.scm @@ -69,10 +69,6 @@ Choices include @code{curved} and @code{straight}.") multiple lines of text.") (beam-thickness ,ly:dimension? "thickness, measured in staffspace.") (beam-width ,ly:dimension? "width of the tremolo sign.") - (beamed-lengths ,list? "list of stem lengths given beam multiplicity .") - (beamed-minimum-free-lengths ,list? "list of normal minimum free stem lengths (chord to beams) given beam multiplicity.") - (beamed-extreme-minimum-free-lengths ,list? "list of extreme minimum free stem lengths (chord to beams) given beam multiplicity.") - (beamed-stem-shorten ,list? "How much to shorten beamed stems, when their direction is forced. It is a list, since the value is different depending on the number flags/beams.") @@ -300,8 +296,7 @@ left to a group of accidentals.") (length ,ly:dimension? "User override for the stem length of unbeamed stems.") (length-fraction ,number? "Length of ledger line as fraction of note head size.") - (lengths ,list? "Default stem lengths. The list gives a length -for each flag-count.") + (line-break-system-details ,list? "Alist of properties to use when this column is the start of a system.") @@ -439,10 +434,6 @@ location in terms of note head bounding box.") (stem-end-position ,number? "Where does the stem end (the end is opposite to the support-head.") - (stem-shorten ,list? "How much a stem in a forced direction -should be shortened. The list gives an amount depending on the number -of flags/beams.") - ;;[TODO: doco] (stem-spacing-correction ,number? "Optical correction amount for stems that are placed in tight configurations. For opposite diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm index d16e1c4b9a..0c83785411 100644 --- a/scm/define-grobs.scm +++ b/scm/define-grobs.scm @@ -1367,39 +1367,44 @@ (stem-info . ,Stem::calc_stem_info) (positioning-done . ,Stem::calc_positioning_done) (stencil . ,Stem::print) + (length . ,Stem::calc_length) )) (thickness . 1.3) - ;; 3.5 (or 3 measured from note head) is standard length - ;; 32nd, 64th flagged stems should be longer - (lengths . (3.5 3.5 3.5 4.5 5.0)) + (details + . ( + ;; 3.5 (or 3 measured from note head) is standard length + ;; 32nd, 64th flagged stems should be longer + (lengths . (3.5 3.5 3.5 4.5 5.0)) - ;; Stems in unnatural (forced) direction should be shortened by - ;; one staff space, according to [Roush & Gourlay]. - ;; Flagged stems we shorten only half a staff space. - (stem-shorten . (1.0 0.5)) + ;; FIXME. 3.5 yields too long beams (according to Ross and + ;; looking at Baerenreiter examples) for a number of common + ;; boundary cases. Subtracting half a beam thickness fixes + ;; this, but the bug may well be somewhere else. - ;; default stem direction for note on middle line - (neutral-direction . -1) + ;; FIXME this should come from 'lengths + (beamed-lengths . (3.26 3.5 3.6)) - ;; FIXME. 3.5 yields too long beams (according to Ross and - ;; looking at Baerenreiter examples) for a number of common - ;; boundary cases. Subtracting half a beam thickness fixes - ;; this, but the bug may well be somewhere else. + ;; The 'normal' minima + (beamed-minimum-free-lengths . (1.83 1.5 1.25)) + ;(beamed-minimum-free-lengths . (2.0 1.83 1.25)) - ;; FIXME this should come from 'lengths + ;; The 'extreme case' minima + (beamed-extreme-minimum-free-lengths . (2.0 1.25)) - (beamed-lengths . (3.26 3.5 3.6)) + ;; Stems in unnatural (forced) direction should be shortened by + ;; one staff space, according to [Roush & Gourlay]. + ;; Flagged stems we shorten only half a staff space. + (stem-shorten . (1.0 0.5)) - ;; We use the normal minima as minimum for the ideal lengths, - ;; and the extreme minima as abolute minimum length. + )) + - ;; The 'normal' minima - (beamed-minimum-free-lengths . (1.83 1.5 1.25)) - ;(beamed-minimum-free-lengths . (2.0 1.83 1.25)) + ;; default stem direction for note on middle line + (neutral-direction . -1) - ;; The 'extreme case' minima - (beamed-extreme-minimum-free-lengths . (2.0 1.25)) + ;; We use the normal minima as minimum for the ideal lengths, + ;; and the extreme minima as abolute minimum length. (X-offset-callbacks . (,Stem::offset_callback)) (X-extent-callback . ,Stem::width_callback) |