From e6caaa132f59006e5c47d0007b24bfedd07ad145 Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Sat, 16 Jul 2005 12:23:33 +0000 Subject: [PATCH] * lily/system.cc (do_derived_mark): don't mark from object_alist_ anymore, but do it centrally. Speedup: approximately 3-5 %. * ly/engraver-init.ly (AncientRemoveEmptyStaffContext): remove hammer hack. * lily/grob-scheme.cc (LY_DEFINE): new function ly:grob-object * scm/output-lib.scm: remove hammer-print-function. * lily/include/pointer-group-interface.hh (extract_grob_set): new macro. Declare a Link_array and fill it from a grob. (extract_item_set): idem for item. * lily/break-substitution.cc: add header. (fast_substitute_grob_array): rewrite for Grob_arrays. (substitute_grob_array): idem. * lily/group-interface.cc (add_thing): remove file. * flower/include/parray.hh (class Link_array): slice() is const. * lily/include/grob-array.hh: new file. * lily/grob-array.cc (spanner): new file. * lily/beam-quanting.cc (fill): read details property from beam. * lily/beam.cc: support details property. * lily/include/beam.hh: new struct, softcode beam quanting parameters * lily/include/grob.hh (class Grob): add interfaces_ member. * lily/bezier.cc (init_polynomial_cache): new function: cache binom(3,j) t^j (1-t)^{3-j} (curve_point): opps, actually use the cache for t^j , (1-t)^j! * lily/grob-property.cc (internal_get_object): new routine. (internal_set_object): idem. Store grob refrences in separate alist. This saves processing time, since properties aren't break-substituted, and the per grob namespace is smaller, both for grobs and non-grob properties. * scm/define-grob-properties.scm (all-internal-grob-properties): remove center-element. * lily/grob.cc: remove tweak-count, tweak-rank. --- ChangeLog | 49 +++++- flower/include/parray.hh | 2 +- input/typography-demo.ly | 2 +- lily/GNUmakefile | 2 +- lily/accidental-engraver.cc | 4 +- lily/accidental-placement.cc | 18 +- lily/accidental.cc | 2 +- lily/align-interface.cc | 12 +- lily/ambitus-engraver.cc | 6 +- lily/ambitus.cc | 4 +- lily/arpeggio-engraver.cc | 5 +- lily/arpeggio.cc | 22 ++- lily/axis-group-engraver.cc | 2 +- lily/axis-group-interface-scheme.cc | 16 +- lily/axis-group-interface.cc | 37 ++--- lily/bar-number-engraver.cc | 5 +- lily/beam-concave.cc | 4 +- lily/beam-quanting.cc | 106 +++++++----- lily/beam.cc | 75 ++++----- lily/bezier.cc | 43 ++++- lily/break-algorithm.cc | 1 - lily/break-align-engraver.cc | 3 +- lily/break-align-interface.cc | 34 ++-- lily/break-substitution.cc | 197 +++++++++++----------- lily/chord-tremolo-engraver.cc | 2 +- lily/cluster-engraver.cc | 2 +- lily/cluster.cc | 22 +-- lily/coherent-ligature-engraver.cc | 10 +- lily/dot-column-engraver.cc | 4 +- lily/dot-column.cc | 8 +- lily/drum-note-engraver.cc | 2 +- lily/dynamic-engraver.cc | 7 +- lily/easy-notation.cc | 2 +- lily/extender-engraver.cc | 12 +- lily/grid-line-interface.cc | 11 +- lily/grob-array.cc | 129 +++++++++++++++ lily/grob-interface.cc | 3 +- lily/grob-property.cc | 95 ++++++++++- lily/grob-scheme.cc | 15 ++ lily/grob.cc | 137 +++++----------- lily/group-interface.cc | 57 ------- lily/hairpin.cc | 8 +- lily/hara-kiri-group-spanner.cc | 8 +- lily/horizontal-bracket-engraver.cc | 2 +- lily/horizontal-bracket.cc | 6 +- lily/hyphen-engraver.cc | 12 +- lily/include/axis-group-interface.hh | 7 +- lily/include/beam.hh | 40 ++++- lily/include/grob-array.hh | 44 +++++ lily/include/grob.hh | 38 +++-- lily/include/group-interface.hh | 9 - lily/include/lily-guile-macros.hh | 2 + lily/include/lily-proto.hh | 1 + lily/include/music.hh | 2 + lily/include/separating-group-spanner.hh | 5 +- lily/include/spanner.hh | 4 +- lily/include/system.hh | 9 +- lily/include/translator-group.hh | 3 + lily/instrument-name-engraver.cc | 5 +- lily/item.cc | 4 +- lily/ledger-line-engraver.cc | 2 +- lily/ledger-line-spanner.cc | 21 +-- lily/lyric-extender.cc | 7 +- lily/mark-engraver.cc | 2 +- lily/metronome-engraver.cc | 2 +- lily/music.cc | 13 ++ lily/new-fingering-engraver.cc | 4 +- lily/note-collision.cc | 22 ++- lily/note-column.cc | 35 ++-- lily/note-head-line-engraver.cc | 2 +- lily/note-head.cc | 2 +- lily/note-spacing.cc | 50 +++--- lily/ottava-bracket.cc | 14 +- lily/paper-column.cc | 38 +++-- lily/phrasing-slur-engraver.cc | 2 +- lily/piano-pedal-bracket.cc | 2 +- lily/piano-pedal-engraver.cc | 2 +- lily/pitched-trill-engraver.cc | 4 +- lily/rest-collision.cc | 16 +- lily/rest.cc | 2 +- lily/rhythmic-column-engraver.cc | 4 +- lily/rhythmic-head.cc | 6 +- lily/score-engraver.cc | 2 +- lily/script-column.cc | 2 +- lily/script-engraver.cc | 2 +- lily/separating-group-spanner.cc | 32 ++-- lily/separating-line-group-engraver.cc | 17 +- lily/separation-item.cc | 34 ++-- lily/side-position-interface.cc | 14 +- lily/simple-spacer.cc | 4 +- lily/slur-configuration.cc | 2 +- lily/slur-engraver.cc | 2 +- lily/slur-scoring.cc | 21 ++- lily/slur.cc | 13 +- lily/spaceable-grob.cc | 19 ++- lily/spacing-engraver.cc | 2 +- lily/spacing-loose-columns.cc | 10 +- lily/spacing-spanner.cc | 126 +++++++------- lily/span-arpeggio-engraver.cc | 21 ++- lily/span-bar.cc | 23 +-- lily/spanner.cc | 10 +- lily/staff-spacing.cc | 22 +-- lily/staff-symbol-engraver.cc | 2 +- lily/staff-symbol-referencer.cc | 2 +- lily/stanza-number-align-engraver.cc | 2 +- lily/stem-engraver.cc | 4 +- lily/stem-tremolo.cc | 4 +- lily/stem.cc | 46 +++--- lily/system-start-delimiter-engraver.cc | 2 +- lily/system-start-delimiter.cc | 18 +- lily/system.cc | 199 ++++++++++++++--------- lily/tie-column.cc | 7 +- lily/translator-group.cc | 6 +- lily/tuplet-bracket.cc | 27 ++- lily/vertical-align-engraver.cc | 33 ++-- lily/volta-bracket.cc | 7 +- ly/engraver-init.ly | 3 - scm/define-grob-properties.scm | 5 - scm/lily-library.scm | 3 + scm/output-lib.scm | 40 +---- 120 files changed, 1389 insertions(+), 1029 deletions(-) create mode 100644 lily/grob-array.cc delete mode 100644 lily/group-interface.cc create mode 100644 lily/include/grob-array.hh diff --git a/ChangeLog b/ChangeLog index f98e1df068..e18074172c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,15 +1,36 @@ -2005-07-15 Graham Percival +2005-07-16 Han-Wen Nienhuys - * Documentation/user/lilypond-book.itely: fixes example. + * lily/system.cc (do_derived_mark): don't mark from object_alist_ + anymore, but do it centrally. Speedup: approximately 3-5 %. -2005-07-15 Nicolas Sceaux + * ly/engraver-init.ly (AncientRemoveEmptyStaffContext): remove + hammer hack. - * Documentation/user/global.itely (Creating titles): - * Documentation/user/examples.itely (All headers): change the - place of \header in \score blocks (after music block) to make - examples compile (cf. changes on parser.yy on 2005-07-10) + * lily/grob-scheme.cc (LY_DEFINE): new function ly:grob-object + + * scm/output-lib.scm: remove hammer-print-function. + + * lily/include/pointer-group-interface.hh (extract_grob_set): new + macro. Declare a Link_array and fill it from a grob. + (extract_item_set): idem for item. + + * lily/break-substitution.cc: add header. + (fast_substitute_grob_array): rewrite for Grob_arrays. + (substitute_grob_array): idem. + + * lily/group-interface.cc (add_thing): remove file. + + * flower/include/parray.hh (class Link_array): slice() is const. + + * lily/include/grob-array.hh: new file. + + * lily/grob-array.cc (spanner): new file. -2005-07-15 Han-Wen Nienhuys + * lily/beam-quanting.cc (fill): read details property from beam. + + * lily/beam.cc: support details property. + + * total speedups below: approx 10%. * lily/include/beam.hh: new struct, softcode beam quanting parameters @@ -26,13 +47,23 @@ alist. This saves processing time, since properties aren't break-substituted, and the per grob namespace is smaller, both for grobs and non-grob properties. - * scm/define-grob-properties.scm (all-internal-grob-properties): remove center-element. * lily/grob.cc: remove tweak-count, tweak-rank. +2005-07-15 Graham Percival + + * Documentation/user/lilypond-book.itely: fixes example. + +2005-07-15 Nicolas Sceaux + + * Documentation/user/global.itely (Creating titles): + * Documentation/user/examples.itely (All headers): change the + place of \header in \score blocks (after music block) to make + examples compile (cf. changes on parser.yy on 2005-07-10) + 2005-07-13 Graham Percival * python/convertrules.py: add exc -> ecc rule. diff --git a/flower/include/parray.hh b/flower/include/parray.hh index 6395cd493e..bc51bda5a0 100644 --- a/flower/include/parray.hh +++ b/flower/include/parray.hh @@ -159,7 +159,7 @@ public: return (T *) Array::get (i); } Link_array - slice (int l, int u) + slice (int l, int u) const { return Array::slice (l, u); } diff --git a/input/typography-demo.ly b/input/typography-demo.ly index 83d4c11acf..d0ad8ebc61 100644 --- a/input/typography-demo.ly +++ b/input/typography-demo.ly @@ -127,7 +127,7 @@ pianoLH = \relative c'' \repeat volta 2\new Voice { \context Staff #(set-accidental-style 'modern) \melody >> \lyricsto "singer" \new Lyrics \firstVerse - \lyricsto "singer" \new Lyrics \secondVerse +% \lyricsto "singer" \new Lyrics \secondVerse \new PianoStaff << \set PianoStaff.instrument = \markup { \bold diff --git a/lily/GNUmakefile b/lily/GNUmakefile index 6bf022fc80..9d34a9b3f0 100644 --- a/lily/GNUmakefile +++ b/lily/GNUmakefile @@ -6,7 +6,7 @@ SUBDIRS = include MODULE_LIBS= $(depth)/flower $(depth)/kpath-guile MODULE_INCLUDES= $(depth)/flower/include -MODULE_CXXFLAGS= +MODULE_CXXFLAGS= -Wno-pmf-conversions HELP2MAN_EXECS = lilypond STEPMAKE_TEMPLATES=c c++ executable po help2man diff --git a/lily/accidental-engraver.cc b/lily/accidental-engraver.cc index 9dc3010382..971f976239 100644 --- a/lily/accidental-engraver.cc +++ b/lily/accidental-engraver.cc @@ -375,7 +375,7 @@ Accidental_engraver::process_acknowledged_grobs () if (cautionary) a->set_property ("cautionary", SCM_BOOL_T); - support->set_property ("accidental-grob", a->self_scm ()); + support->set_object ("accidental-grob", a->self_scm ()); a->set_property ("accidentals", accs); accidentals_[i].accidental_ = a; @@ -410,7 +410,7 @@ Accidental_engraver::stop_translation_timestep () { if (Grob *g = accidentals_[i].accidental_) { - g->set_property ("tie", ties_[j]->self_scm ()); + g->set_object ("tie", ties_[j]->self_scm ()); accidentals_[i].tied_ = true; } ties_.del (j); diff --git a/lily/accidental-placement.cc b/lily/accidental-placement.cc index dc39d5a1aa..43055409cb 100644 --- a/lily/accidental-placement.cc +++ b/lily/accidental-placement.cc @@ -15,7 +15,7 @@ #include "pitch.hh" #include "warn.hh" #include "note-column.hh" -#include "group-interface.hh" +#include "pointer-group-interface.hh" #include "note-collision.hh" #include "accidental-interface.hh" @@ -53,7 +53,7 @@ Accidental_placement::add_accidental (Grob *me, Grob *a) int n = p->get_notename (); - SCM accs = me->get_property ("accidental-grobs"); + SCM accs = me->get_object ("accidental-grobs"); SCM key = scm_int2num (n); SCM entry = scm_assq (key, accs); if (entry == SCM_BOOL_F) @@ -67,7 +67,7 @@ Accidental_placement::add_accidental (Grob *me, Grob *a) accs = scm_assq_set_x (accs, key, entry); - me->set_property ("accidental-grobs", accs); + me->set_object ("accidental-grobs", accs); } /* @@ -78,13 +78,13 @@ Accidental_placement::split_accidentals (Grob *accs, Link_array *break_reminder, Link_array *real_acc) { - for (SCM acs = accs->get_property ("accidental-grobs"); scm_is_pair (acs); + for (SCM acs = accs->get_object ("accidental-grobs"); scm_is_pair (acs); acs = scm_cdr (acs)) for (SCM s = scm_cdar (acs); scm_is_pair (s); s = scm_cdr (s)) { Grob *a = unsmob_grob (scm_car (s)); - if (unsmob_grob (a->get_property ("tie"))) + if (unsmob_grob (a->get_object ("tie"))) break_reminder->push (a); else real_acc->push (a); @@ -237,7 +237,7 @@ Accidental_placement::position_accidentals (Grob *me) if (!me->is_live ()) return SCM_UNSPECIFIED; - SCM accs = me->get_property ("accidental-grobs"); + SCM accs = me->get_object ("accidental-grobs"); if (!scm_is_pair (accs)) return SCM_UNSPECIFIED; @@ -295,8 +295,7 @@ Accidental_placement::position_accidentals (Grob *me) Grob *c = note_cols[i]->get_parent (X_AXIS); if (Note_collision_interface::has_interface (c)) { - Link_array gs - = extract_grob_array (c, ly_symbol2scm ("elements")); + extract_grob_set (c, "elements", gs); note_cols.concat (gs); } @@ -304,8 +303,9 @@ Accidental_placement::position_accidentals (Grob *me) for (int i = note_cols.size (); i--;) { - heads.concat (extract_grob_array (note_cols[i], ly_symbol2scm ("note-heads"))); + heads.concat (extract_grob_array (note_cols[i], "note-heads")); } + heads.default_sort (); heads.uniq (); common[Y_AXIS] = common_refpoint_of_array (heads, common[Y_AXIS], Y_AXIS); diff --git a/lily/accidental.cc b/lily/accidental.cc index 9f08691f10..61536c4ed4 100644 --- a/lily/accidental.cc +++ b/lily/accidental.cc @@ -37,7 +37,7 @@ SCM Accidental_interface::after_line_breaking (SCM smob) { Grob *me = unsmob_grob (smob); - Grob *tie = unsmob_grob (me->get_property ("tie")); + Grob *tie = unsmob_grob (me->get_object ("tie")); if (tie && !tie->original_) me->suicide (); diff --git a/lily/align-interface.cc b/lily/align-interface.cc index 59575bba43..8d09d98dca 100644 --- a/lily/align-interface.cc +++ b/lily/align-interface.cc @@ -11,6 +11,7 @@ #include "spanner.hh" #include "item.hh" #include "axis-group-interface.hh" +#include "pointer-group-interface.hh" #include "hara-kiri-group-spanner.hh" MAKE_SCHEME_CALLBACK (Align_interface, alignment_callback, 2); @@ -57,9 +58,10 @@ Align_interface::align_to_fixed_distance (Grob *me, Axis a) Real dy = robust_scm2double (me->get_property ("forced-distance"), 0.0); - Link_array elems - = extract_grob_array (me, ly_symbol2scm ("elements")); + extract_grob_set (me, "elements", elem_source); + Link_array elems (elem_source); // writable.. + Real where_f = 0; Interval v; @@ -141,8 +143,8 @@ Align_interface::align_elements_to_extents (Grob *me, Axis a) Array dims; Link_array elems; - Link_array all_grobs - = extract_grob_array (me, ly_symbol2scm ("elements")); + + extract_grob_set (me, "elements", all_grobs); for (int i = 0; i < all_grobs.size (); i++) { Interval y = all_grobs[i]->extent (me, a); @@ -269,7 +271,7 @@ ADD_INTERFACE (Align_interface, "align-interface", "Order grobs from top to bottom, left to right, right to left or bottom" "to top.", "forced-distance stacking-dir align-dir threshold positioning-done " - "center-element elements axes"); + "elements axes"); struct Foobar { diff --git a/lily/ambitus-engraver.cc b/lily/ambitus-engraver.cc index a84f9d65ec..a07b04fa05 100644 --- a/lily/ambitus-engraver.cc +++ b/lily/ambitus-engraver.cc @@ -55,7 +55,7 @@ Ambitus_engraver::create_ambitus () heads_[d] = make_item ("AmbitusNoteHead", SCM_EOL); accidentals_[d] = make_item ("AmbitusAccidental", SCM_EOL); accidentals_[d]->set_parent (heads_[d], Y_AXIS); - heads_[d]->set_property ("accidental-grob", + heads_[d]->set_object ("accidental-grob", accidentals_[d]->self_scm ()); Axis_group_interface::add_element (group_, heads_[d]); Axis_group_interface::add_element (group_, accidentals_[d]); @@ -157,7 +157,7 @@ Ambitus_engraver::finalize () if (sig_alter == p.get_alteration ()) { accidentals_[d]->suicide (); - heads_[d]->set_property ("accidental-grob", SCM_EOL); + heads_[d]->set_object ("accidental-grob", SCM_EOL); } else { @@ -168,7 +168,7 @@ Ambitus_engraver::finalize () } while (flip (&d) != DOWN); - ambitus_->set_property ("note-heads", scm_list_2 (heads_[DOWN]->self_scm (), + ambitus_->set_object ("note-heads", scm_list_2 (heads_[DOWN]->self_scm (), heads_[UP]->self_scm ())); } else diff --git a/lily/ambitus.cc b/lily/ambitus.cc index a702fffb50..472df25037 100644 --- a/lily/ambitus.cc +++ b/lily/ambitus.cc @@ -15,7 +15,7 @@ #include "font-interface.hh" #include "output-def.hh" #include "lookup.hh" -#include "group-interface.hh" +#include "pointer-group-interface.hh" MAKE_SCHEME_CALLBACK (Ambitus, print, 1); SCM @@ -25,7 +25,7 @@ Ambitus::print (SCM smob) Stencil stencil; // join heads - Link_array heads (extract_grob_array (me, ly_symbol2scm ("note-heads"))); + extract_grob_set (me, "note-heads", heads); if (to_boolean (me->get_property ("join-heads")) && heads.size () > 1) { diff --git a/lily/arpeggio-engraver.cc b/lily/arpeggio-engraver.cc index 494326f47f..fc324c1582 100644 --- a/lily/arpeggio-engraver.cc +++ b/lily/arpeggio-engraver.cc @@ -7,7 +7,8 @@ */ #include "engraver.hh" -#include "group-interface.hh" + +#include "pointer-group-interface.hh" #include "arpeggio.hh" #include "stem.hh" #include "rhythmic-head.hh" @@ -70,7 +71,7 @@ Arpeggio_engraver::acknowledge_grob (Grob_info info) } else if (Note_column::has_interface (info.grob ())) { - info.grob ()->set_property ("arpeggio", arpeggio_->self_scm ()); + info.grob ()->set_object ("arpeggio", arpeggio_->self_scm ()); } } } diff --git a/lily/arpeggio.cc b/lily/arpeggio.cc index 7fede4a5ab..a578ac5d50 100644 --- a/lily/arpeggio.cc +++ b/lily/arpeggio.cc @@ -15,6 +15,7 @@ #include "warn.hh" #include "font-interface.hh" #include "lookup.hh" +#include "pointer-group-interface.hh" MAKE_SCHEME_CALLBACK (Arpeggio, print, 1); SCM @@ -23,9 +24,11 @@ Arpeggio::print (SCM smob) Grob *me = unsmob_grob (smob); Grob *common = me; - for (SCM s = me->get_property ("stems"); scm_is_pair (s); s = scm_cdr (s)) + + extract_grob_set (me, "stems", stems); + for (int i = 0; i < stems.size(); i++) { - Grob *stem = unsmob_grob (scm_car (s)); + Grob *stem = stems[i]; common = common->common_refpoint (Staff_symbol_referencer::get_staff_symbol (stem), Y_AXIS); } @@ -41,9 +44,9 @@ Arpeggio::print (SCM smob) Interval heads; Real my_y = me->relative_coordinate (common, Y_AXIS); - for (SCM s = me->get_property ("stems"); scm_is_pair (s); s = scm_cdr (s)) + for (int i = 0; i < stems.size(); i++) { - Grob *stem = unsmob_grob (scm_car (s)); + Grob *stem = stems[i]; Grob *ss = Staff_symbol_referencer::get_staff_symbol (stem); Interval iv = Stem::head_positions (stem); iv *= Staff_symbol::staff_space (ss) / 2.0; @@ -102,9 +105,12 @@ Arpeggio::brew_chord_bracket (SCM smob) Grob *me = unsmob_grob (smob); Grob *common = me; - for (SCM s = me->get_property ("stems"); scm_is_pair (s); s = scm_cdr (s)) + + + extract_grob_set (me, "stems", stems); + for (int i = 0; i < stems.size(); i++) { - Grob *stem = unsmob_grob (scm_car (s)); + Grob *stem = stems[i]; common = common->common_refpoint (Staff_symbol_referencer::get_staff_symbol (stem), Y_AXIS); } @@ -112,9 +118,9 @@ Arpeggio::brew_chord_bracket (SCM smob) Interval heads; Real my_y = me->relative_coordinate (common, Y_AXIS); - for (SCM s = me->get_property ("stems"); scm_is_pair (s); s = scm_cdr (s)) + for (int i = 0; i < stems.size(); i++) { - Grob *stem = unsmob_grob (scm_car (s)); + Grob *stem = stems[i]; Grob *ss = Staff_symbol_referencer::get_staff_symbol (stem); Interval iv = Stem::head_positions (stem); iv *= Staff_symbol::staff_space (ss) / 2.0; diff --git a/lily/axis-group-engraver.cc b/lily/axis-group-engraver.cc index 21e3abc7f7..965d16db4c 100644 --- a/lily/axis-group-engraver.cc +++ b/lily/axis-group-engraver.cc @@ -87,7 +87,7 @@ Axis_group_engraver::process_acknowledged_grobs () for (int i = 0; i < elts_.size (); i++) { - if (!unsmob_grob (elts_[i]->get_property ("axis-group-parent-Y"))) + if (!unsmob_grob (elts_[i]->get_object ("axis-group-parent-Y"))) { if (staffline_->get_parent (Y_AXIS) && staffline_->get_parent (Y_AXIS) == elts_[i]) diff --git a/lily/axis-group-interface-scheme.cc b/lily/axis-group-interface-scheme.cc index c53b5aebb4..a5e00341b9 100644 --- a/lily/axis-group-interface-scheme.cc +++ b/lily/axis-group-interface-scheme.cc @@ -9,18 +9,28 @@ #include "axis-group-interface.hh" #include "lily-guile.hh" +#include "grob.hh" +#include "grob-array.hh" LY_DEFINE(ly_relative_group_extent, "ly:relative-group-extent", 3, 0, 0, (SCM elements, SCM common, SCM axis), "Determine the extent of @var{elements} relative to @var{common} in the " "@var{axis} direction.") { - SCM_ASSERT_TYPE(scm_is_pair (elements), elements, SCM_ARG1, __FUNCTION__, "list"); + Grob_array *ga = unsmob_grob_array (elements); + + SCM_ASSERT_TYPE(ga || scm_is_pair (elements), elements, SCM_ARG1, __FUNCTION__, "list or Grob_array"); SCM_ASSERT_TYPE(unsmob_grob (common), common, SCM_ARG2, __FUNCTION__, "grob"); SCM_ASSERT_TYPE(is_axis (axis), axis, SCM_ARG3, __FUNCTION__, "axis"); - - Interval ext = Axis_group_interface::relative_group_extent (elements, + Link_array elts; + if (!ga) + { + for (SCM s = elements; scm_is_pair (s); s = scm_cdr (s)) + elts.push (unsmob_grob (scm_car (s))); + } + + Interval ext = Axis_group_interface::relative_group_extent (ga ? ga->array () : elts, unsmob_grob (common), (Axis) scm_to_int (axis)); return ly_interval2scm (ext); diff --git a/lily/axis-group-interface.cc b/lily/axis-group-interface.cc index 2c3a23601e..5de3914400 100644 --- a/lily/axis-group-interface.cc +++ b/lily/axis-group-interface.cc @@ -8,6 +8,7 @@ #include "axis-group-interface.hh" +#include "grob.hh" #include "hara-kiri-group-spanner.hh" #include "warn.hh" @@ -25,10 +26,10 @@ Axis_group_interface::add_element (Grob *me, Grob *e) if (!e->get_parent (a)) e->set_parent (me, a); - e->internal_set_property ((a == X_AXIS) - ? ly_symbol2scm ("axis-group-parent-X") + e->internal_set_object ((a == X_AXIS) + ? ly_symbol2scm ("axis-group-parent-X") : ly_symbol2scm ("axis-group-parent-Y"), - me->self_scm ()); + me->self_scm ()); } Pointer_group_interface::add_grob (me, ly_symbol2scm ("elements"), e); @@ -46,12 +47,13 @@ Axis_group_interface::has_axis (Grob *me, Axis a) } Interval -Axis_group_interface::relative_group_extent (SCM elts, Grob *common, Axis a) +Axis_group_interface::relative_group_extent (Link_array const &elts, + Grob *common, Axis a) { Interval r; - for (SCM s = elts; scm_is_pair (s); s = scm_cdr (s)) + for (int i = 0; i < elts.size(); i++) { - Grob *se = unsmob_grob (scm_car (s)); + Grob *se = elts[i]; Interval dims = se->extent (common, a); if (!dims.is_empty ()) r.unite (dims); @@ -68,8 +70,8 @@ Axis_group_interface::group_extent_callback (SCM element_smob, SCM scm_axis) Grob *me = unsmob_grob (element_smob); Axis a = (Axis) scm_to_int (scm_axis); - SCM elts = me->get_property ("elements"); - Grob *common = common_refpoint_of_list (elts, me, a); + extract_grob_set (me, "elements", elts); + Grob *common = common_refpoint_of_array (elts, me, a); Real my_coord = me->relative_coordinate (common, a); Interval r (relative_group_extent (elts, common, a)); @@ -109,23 +111,20 @@ Axis_group_interface::set_axes (Grob *me, Axis a1, Axis a2) me->set_extent_callback (Axis_group_interface::group_extent_callback_proc, a2); } -Link_array -Axis_group_interface::get_children (Grob *me) +void +Axis_group_interface::get_children (Grob *me, Link_array *found) { - Link_array childs; - childs.push (me); + found->push (me); if (!has_interface (me)) - return childs; + return; - for (SCM ep = me->get_property ("elements"); scm_is_pair (ep); ep = scm_cdr (ep)) + extract_grob_set (me, "elements", elements); + for (int i = 0; i < elements.size (); i++) { - Grob *e = unsmob_grob (scm_car (ep)); - if (e) - childs.concat (Axis_group_interface::get_children (e)); + Grob *e = elements[i]; + Axis_group_interface::get_children (e, found); } - - return childs; } ADD_INTERFACE (Axis_group_interface, "axis-group-interface", diff --git a/lily/bar-number-engraver.cc b/lily/bar-number-engraver.cc index 9b8d0bdf86..9b3eedb1bf 100644 --- a/lily/bar-number-engraver.cc +++ b/lily/bar-number-engraver.cc @@ -11,6 +11,7 @@ #include "side-position-interface.hh" #include "engraver.hh" #include "context.hh" +#include "grob-array.hh" /* TODO: detect the top staff (stavesFound), and acknowledge staff-group @@ -81,8 +82,8 @@ Bar_number_engraver::stop_translation_timestep () { if (text_) { - text_->set_property ("side-support-elements", get_property ("stavesFound")); - + text_->set_object ("side-support-elements", + grob_list_to_grob_array (get_property ("stavesFound"))); text_ = 0; } } diff --git a/lily/beam-concave.cc b/lily/beam-concave.cc index cf0653b09d..2643bfaa22 100644 --- a/lily/beam-concave.cc +++ b/lily/beam-concave.cc @@ -4,7 +4,7 @@ #include -#include "group-interface.hh" +#include "pointer-group-interface.hh" #include "array.hh" #include "stem.hh" #include "beam.hh" @@ -88,7 +88,7 @@ Beam::check_concave (SCM smob) Grob *me = unsmob_grob (smob); Link_array stems - = extract_grob_array (me, ly_symbol2scm ("stems")); + = extract_grob_array (me, "stems"); if (is_knee (me)) return SCM_UNSPECIFIED; diff --git a/lily/beam-quanting.cc b/lily/beam-quanting.cc index 929cbc385c..689cf7c2ec 100644 --- a/lily/beam-quanting.cc +++ b/lily/beam-quanting.cc @@ -16,24 +16,39 @@ #include "staff-symbol-referencer.hh" #include "stem.hh" #include "output-def.hh" -#include "group-interface.hh" +#include "pointer-group-interface.hh" #include "align-interface.hh" -const int INTER_QUANT_PENALTY = 1000; -const Real SECONDARY_BEAM_DEMERIT = 10.0; -const int STEM_LENGTH_DEMERIT_FACTOR = 5; - -/* - threshold to combat rounding errors. -*/ -const Real BEAM_EPS = 1e-3; +Real +get_detail (SCM alist, SCM sym, Real def) +{ + SCM entry = scm_assq (sym, alist); + + if (scm_is_pair (entry)) + { + return robust_scm2double (scm_cdr (entry), def); + } + return def; +} -// possibly ridiculous, but too short stems just won't do -const int STEM_LENGTH_LIMIT_PENALTY = 5000; -const int DAMPING_DIRECTION_PENALTY = 800; -const int MUSICAL_DIRECTION_FACTOR = 400; -const int IDEAL_SLOPE_FACTOR = 10; -const Real ROUND_TO_ZERO_SLOPE = 0.02; +void +Beam_quant_parameters::fill (Grob *him) +{ + SCM details = him->get_property ("details"); + + INTER_QUANT_PENALTY = get_detail (details, ly_symbol2scm ("inter-quant-penalty"), 1000.0); + SECONDARY_BEAM_DEMERIT = get_detail (details, ly_symbol2scm ("secondary-beam-demerit"), 10.0); + STEM_LENGTH_DEMERIT_FACTOR = get_detail (details, ly_symbol2scm ("stem-length-demerit-factor"), 5); + REGION_SIZE = get_detail (details, ly_symbol2scm ("region-size"), 2); + BEAM_EPS = get_detail (details, ly_symbol2scm ("beam-eps"), 1e-3); + + // possibly ridiculous, but too short stems just won't do + STEM_LENGTH_LIMIT_PENALTY = get_detail (details, ly_symbol2scm ("stem-length-limit-penalty"), 5000); + DAMPING_DIRECTION_PENALTY = get_detail (details, ly_symbol2scm ("damping-direction-penalty"), 800); + MUSICAL_DIRECTION_FACTOR = get_detail (details, ly_symbol2scm ("musical-direction-factor"), 400); + IDEAL_SLOPE_FACTOR = get_detail (details, ly_symbol2scm ("ideal-slope-factor"), 10); + ROUND_TO_ZERO_SLOPE = get_detail (details, ly_symbol2scm ("round-to-zero-slope"), 0.02); +} static Real shrink_extra_weight (Real x, Real fac) @@ -86,6 +101,10 @@ Beam::quanting (SCM smob) { Grob *me = unsmob_grob (smob); + + Beam_quant_parameters parameters; + parameters.fill (me); + SCM s = me->get_property ("positions"); Real yl = scm_to_double (scm_car (s)); Real yr = scm_to_double (scm_cdr (s)); @@ -124,7 +143,7 @@ Beam::quanting (SCM smob) precompute for every stem 2 factors. */ Link_array stems - = extract_grob_array (me, ly_symbol2scm ("stems")); + = extract_grob_array (me, "stems"); Array stem_infos; Array base_lengths; Array stem_xposns; @@ -175,7 +194,8 @@ Beam::quanting (SCM smob) Direction rdir = Direction (stem_infos.top ().dir_); bool is_knee = dirs_found[LEFT] && dirs_found[RIGHT]; - int region_size = REGION_SIZE; + int region_size = (int) parameters.REGION_SIZE; + /* Knees are harder, lets try some more possibilities for knees. */ @@ -214,7 +234,7 @@ Beam::quanting (SCM smob) Real d = score_slopes_dy (qscores[i].yl, qscores[i].yr, dy_mus, yr- yl, xr - xl, - xstaff); + xstaff, ¶meters); qscores[i].demerits += d; #if DEBUG_QUANTING @@ -235,7 +255,7 @@ Beam::quanting (SCM smob) { Real d = score_forbidden_quants (qscores[i].yl, qscores[i].yr, rad, slt, thickness, beam_translation, - edge_beam_counts, ldir, rdir); + edge_beam_counts, ldir, rdir, ¶meters); qscores[i].demerits += d; #if DEBUG_QUANTING @@ -250,7 +270,7 @@ Beam::quanting (SCM smob) base_lengths, stem_xposns, xl, xr, is_knee, - qscores[i].yl, qscores[i].yr); + qscores[i].yl, qscores[i].yr, ¶meters); qscores[i].demerits += d; #if DEBUG_QUANTING @@ -314,9 +334,12 @@ Beam::score_stem_lengths (Link_array const &stems, Array const &stem_xs, Real xl, Real xr, bool knee, - Real yl, Real yr) + Real yl, Real yr, + + Beam_quant_parameters const*parameters + ) { - Real limit_penalty = STEM_LENGTH_LIMIT_PENALTY; + Real limit_penalty = parameters->STEM_LENGTH_LIMIT_PENALTY; Drul_array score (0, 0); Drul_array count (0, 0); @@ -330,7 +353,7 @@ Beam::score_stem_lengths (Link_array const &stems, Real dx = xr - xl; Real beam_y = dx ? yr * (x - xl) / dx + yl * (xr - x) / dx : (yr + yl) / 2; Real current_y = beam_y + base_stem_ys[i]; - Real length_pen = STEM_LENGTH_DEMERIT_FACTOR; + Real length_pen = parameters->STEM_LENGTH_DEMERIT_FACTOR; Stem_info info = stem_infos[i]; Direction d = info.dir_; @@ -365,7 +388,9 @@ Real Beam::score_slopes_dy (Real yl, Real yr, Real dy_mus, Real dy_damp, Real dx, - bool xstaff) + bool xstaff, + + Beam_quant_parameters const*parameters) { Real dy = yr - yl; Real dem = 0.0; @@ -377,15 +402,15 @@ Beam::score_slopes_dy (Real yl, Real yr, TODO: find a way to incorporate the complexity of the beam in this penalty. */ - if (fabs (dy / dx) > ROUND_TO_ZERO_SLOPE + if (fabs (dy / dx) > parameters->ROUND_TO_ZERO_SLOPE && sign (dy_damp) != sign (dy)) { - dem += DAMPING_DIRECTION_PENALTY; + dem += parameters->DAMPING_DIRECTION_PENALTY; } - dem += MUSICAL_DIRECTION_FACTOR * max (0.0, (fabs (dy) - fabs (dy_mus))); + dem += parameters->MUSICAL_DIRECTION_FACTOR * max (0.0, (fabs (dy) - fabs (dy_mus))); - Real slope_penalty = IDEAL_SLOPE_FACTOR; + Real slope_penalty = parameters->IDEAL_SLOPE_FACTOR; /* Xstaff beams tend to use extreme slopes to get short stems. We put in a penalty here. */ @@ -416,16 +441,19 @@ Beam::score_forbidden_quants (Real yl, Real yr, Real slt, Real thickness, Real beam_translation, Drul_array beam_counts, - Direction ldir, Direction rdir) + Direction ldir, Direction rdir, + + Beam_quant_parameters const*parameters) { Real dy = yr - yl; Drul_array y (yl, yr); Drul_array dirs (ldir, rdir); - Real extra_demerit = SECONDARY_BEAM_DEMERIT / (max (beam_counts[LEFT], beam_counts[RIGHT])); + Real extra_demerit = parameters->SECONDARY_BEAM_DEMERIT / (max (beam_counts[LEFT], beam_counts[RIGHT])); Direction d = LEFT; Real dem = 0.0; + Real eps = parameters->BEAM_EPS; do { @@ -447,7 +475,7 @@ Beam::score_forbidden_quants (Real yl, Real yr, gap.add_point (gap2); for (Real k = -radius; - k <= radius + BEAM_EPS; k += 1.0) + k <= radius + eps; k += 1.0) if (gap.contains (k)) { Real dist = min (fabs (gap[UP] - k), fabs (gap[DOWN] - k)); @@ -478,24 +506,24 @@ Beam::score_forbidden_quants (Real yl, Real yr, if (beam_counts[d] >= 2 && fabs (y[d] - dirs[d] * beam_translation) < radius + inter) { - if (dirs[d] == UP && dy <= BEAM_EPS - && fabs (my_modf (y[d]) - sit) < BEAM_EPS) + if (dirs[d] == UP && dy <= eps + && fabs (my_modf (y[d]) - sit) < eps) dem += extra_demerit; - if (dirs[d] == DOWN && dy >= BEAM_EPS - && fabs (my_modf (y[d]) - hang) < BEAM_EPS) + if (dirs[d] == DOWN && dy >= eps + && fabs (my_modf (y[d]) - hang) < eps) dem += extra_demerit; } if (beam_counts[d] >= 3 && fabs (y[d] - 2 * dirs[d] * beam_translation) < radius + inter) { - if (dirs[d] == UP && dy <= BEAM_EPS - && fabs (my_modf (y[d]) - straddle) < BEAM_EPS) + if (dirs[d] == UP && dy <= eps + && fabs (my_modf (y[d]) - straddle) < eps) dem += extra_demerit; - if (dirs[d] == DOWN && dy >= BEAM_EPS - && fabs (my_modf (y[d]) - straddle) < BEAM_EPS) + if (dirs[d] == DOWN && dy >= eps + && fabs (my_modf (y[d]) - straddle) < eps) dem += extra_demerit; } } diff --git a/lily/beam.cc b/lily/beam.cc index ed5797fbc3..7e52a825e2 100644 --- a/lily/beam.cc +++ b/lily/beam.cc @@ -35,7 +35,7 @@ #include "stem.hh" #include "output-def.hh" #include "lookup.hh" -#include "group-interface.hh" +#include "pointer-group-interface.hh" #include "staff-symbol-referencer.hh" #include "item.hh" #include "spanner.hh" @@ -54,7 +54,7 @@ Beam::add_stem (Grob *me, Grob *s) s->add_dependency (me); assert (!Stem::get_beam (s)); - s->set_property ("beam", me->self_scm ()); + s->set_object ("beam", me->self_scm ()); add_bound_item (dynamic_cast (me), dynamic_cast (s)); } @@ -88,9 +88,11 @@ int Beam::get_beam_count (Grob *me) { int m = 0; - for (SCM s = me->get_property ("stems"); scm_is_pair (s); s = scm_cdr (s)) + + extract_grob_set (me, "stems", stems); + for (int i = 0; i < stems.size(); i++) { - Grob *stem = unsmob_grob (scm_car (s)); + Grob *stem = stems[i]; m = max (m, (Stem::beam_multiplicity (stem).length () + 1)); } return m; @@ -139,17 +141,17 @@ Beam::before_line_breaking (SCM smob) int count = visible_stem_count (me); if (count < 2) { - SCM stems = me->get_property ("stems"); - if (scm_ilength (stems) == 1) + extract_grob_set (me, "stems", stems); + if (stems.size () == 1) { me->warning (_ ("removing beam with less than two stems")); - unsmob_grob (scm_car (stems))->set_property ("beam", SCM_EOL); + stems[0]->set_object ("beam", SCM_EOL); me->suicide (); return SCM_UNSPECIFIED; } - else if (scm_ilength (stems) == 0) + else if (stems.size () == 0) { me->suicide (); return SCM_UNSPECIFIED; @@ -215,8 +217,7 @@ position_with_maximal_common_beams (SCM left_beaming, SCM right_beaming, void Beam::connect_beams (Grob *me) { - Link_array stems - = extract_grob_array (me, ly_symbol2scm ("stems")); + extract_grob_set (me, "stems", stems); Slice last_int; last_int.set_empty (); @@ -292,8 +293,7 @@ Beam::print (SCM grob) Spanner *me = unsmob_spanner (grob); position_beam (me); - Link_array stems - = extract_grob_array (me, ly_symbol2scm ("stems")); + extract_grob_set (me, "stems", stems); Grob *xcommon = common_refpoint_of_array (stems, me, X_AXIS); xcommon = me->get_bound (LEFT)->common_refpoint (xcommon, X_AXIS); @@ -523,8 +523,7 @@ Beam::get_default_dir (Grob *me) count[UP] = count[DOWN] = 0; Direction d = DOWN; - Link_array stems - = extract_grob_array (me, ly_symbol2scm ("stems")); + extract_grob_set (me, "stems", stems); for (int i = 0; i < stems.size (); i++) do @@ -563,8 +562,7 @@ Beam::get_default_dir (Grob *me) void Beam::set_stem_directions (Grob *me, Direction d) { - Link_array stems - = extract_grob_array (me, ly_symbol2scm ("stems")); + extract_grob_set (me, "stems", stems); for (int i = 0; i < stems.size (); i++) { @@ -599,8 +597,7 @@ Beam::consider_auto_knees (Grob *me) gaps.set_full (); - Link_array stems - = extract_grob_array (me, ly_symbol2scm ("stems")); + extract_grob_set (me, "stems", stems); Grob *common = common_refpoint_of_array (stems, me, Y_AXIS); Real staff_space = Staff_symbol_referencer::staff_space (me); @@ -805,8 +802,7 @@ Beam::least_squares (SCM smob) } Array x_posns; - Link_array stems - = extract_grob_array (me, ly_symbol2scm ("stems")); + extract_grob_set (me, "stems", stems); Grob *commonx = common_refpoint_of_array (stems, me, X_AXIS); Grob *commony = common_refpoint_of_array (stems, me, Y_AXIS); @@ -915,8 +911,7 @@ Beam::shift_region_to_valid (SCM grob) Code dup. */ Array x_posns; - Link_array stems - = extract_grob_array (me, ly_symbol2scm ("stems")); + extract_grob_set (me, "stems", stems); Grob *commonx = common_refpoint_of_array (stems, me, X_AXIS); Grob *commony = common_refpoint_of_array (stems, me, Y_AXIS); @@ -985,6 +980,7 @@ Beam::shift_region_to_valid (SCM grob) warning (_ ("no viable initial configuration found: may not find good beam slope")); else if (!feasible_left_point.contains (y)) { + const int REGION_SIZE = 2; // UGH UGH if (isinf (feasible_left_point[DOWN])) y = feasible_left_point[UP] - REGION_SIZE; else if (isinf (feasible_left_point[UP])) @@ -1116,9 +1112,7 @@ Beam::calc_stem_y (Grob *me, Grob *s, Grob ** common, void Beam::set_stem_lengths (Grob *me) { - Link_array stems - = extract_grob_array (me, ly_symbol2scm ("stems")); - + extract_grob_set (me, "stems", stems); if (!stems.size ()) return; @@ -1171,8 +1165,7 @@ Beam::set_stem_lengths (Grob *me) void Beam::set_beaming (Grob *me, Beaming_info_list *beaming) { - Link_array stems - = extract_grob_array (me, ly_symbol2scm ("stems")); + extract_grob_set (me, "stems", stems); Direction d = LEFT; for (int i = 0; i < stems.size (); i++) @@ -1209,8 +1202,8 @@ Beam::set_beaming (Grob *me, Beaming_info_list *beaming) int Beam::forced_stem_count (Grob *me) { - Link_array stems - = extract_grob_array (me, ly_symbol2scm ("stems")); + extract_grob_set (me, "stems", stems); + int f = 0; for (int i = 0; i < stems.size (); i++) { @@ -1231,8 +1224,7 @@ Beam::forced_stem_count (Grob *me) int Beam::visible_stem_count (Grob *me) { - Link_array stems - = extract_grob_array (me, ly_symbol2scm ("stems")); + extract_grob_set (me, "stems", stems); int c = 0; for (int i = stems.size (); i--;) { @@ -1245,8 +1237,7 @@ Beam::visible_stem_count (Grob *me) Grob * Beam::first_visible_stem (Grob *me) { - Link_array stems - = extract_grob_array (me, ly_symbol2scm ("stems")); + extract_grob_set (me, "stems", stems); for (int i = 0; i < stems.size (); i++) { @@ -1259,8 +1250,8 @@ Beam::first_visible_stem (Grob *me) Grob * Beam::last_visible_stem (Grob *me) { - Link_array stems - = extract_grob_array (me, ly_symbol2scm ("stems")); + extract_grob_set (me, "stems", stems); + for (int i = stems.size (); i--;) { if (!Stem::is_invisible (stems[i])) @@ -1291,11 +1282,11 @@ Beam::rest_collision_callback (SCM element_smob, SCM axis) assert (scm_to_int (axis) == Y_AXIS); - Grob *st = unsmob_grob (rest->get_property ("stem")); + Grob *st = unsmob_grob (rest->get_object ("stem")); Grob *stem = st; if (!stem) return scm_make_real (0.0); - Grob *beam = unsmob_grob (stem->get_property ("beam")); + Grob *beam = unsmob_grob (stem->get_object ("beam")); if (!beam || !Beam::has_interface (beam) || !Beam::visible_stem_count (beam)) @@ -1366,9 +1357,10 @@ Beam::is_knee (Grob *me) bool knee = false; int d = 0; - for (SCM s = me->get_property ("stems"); scm_is_pair (s); s = scm_cdr (s)) + extract_grob_set (me, "stems", stems); + for (int i = stems.size (); i--;) { - Direction dir = get_grob_direction (unsmob_grob (scm_car (s))); + Direction dir = get_grob_direction (stems[i]); if (d && d != dir) { knee = true; @@ -1385,8 +1377,7 @@ Beam::is_knee (Grob *me) int Beam::get_direction_beam_count (Grob *me, Direction d) { - Link_array stems - = extract_grob_array (me, ly_symbol2scm ("stems")); + extract_grob_set (me, "stems", stems); int bc = 0; for (int i = stems.size (); i--;) @@ -1408,6 +1399,6 @@ ADD_INTERFACE (Beam, "beam-interface", "knee positioning-done position-callbacks " "concaveness dir-function quant-score auto-knee-gap gap " "gap-count chord-tremolo beamed-stem-shorten shorten least-squares-dy " - "damping inspect-quants flag-width-function neutral-direction positions space-function " + "details damping inspect-quants flag-width-function neutral-direction positions space-function " "thickness"); diff --git a/lily/bezier.cc b/lily/bezier.cc index 02065b8db6..2efe5c7e07 100644 --- a/lily/bezier.cc +++ b/lily/bezier.cc @@ -77,9 +77,11 @@ Bezier::get_other_coordinate (Axis a, Real x) const Offset c = curve_point (ts[0]); +#ifdef PARANOID if (fabs (c[a] - x) > 1e-8) programming_error ("bezier intersection not correct?"); - +#endif + return c[other]; } @@ -87,17 +89,20 @@ Offset Bezier::curve_point (Real t) const { Real tj = 1; - Real one_min_tj = (1 - t) * (1 - t) * (1 - t); + Real one_min_tj[4]; + one_min_tj[0] = 1; + for (int i = 1; i < 4; i++) + { + one_min_tj[i] = one_min_tj[i-1] * (1-t); + } Offset o; for (int j = 0; j < 4; j++) { o += control_[j] * binomial_coefficient_3[j] - * pow (t, j) * pow (1 - t, 3 - j); + * tj * one_min_tj[3-j]; tj *= t; - if (1 - t) - one_min_tj /= (1 - t); } #ifdef PARANOID @@ -108,16 +113,36 @@ Bezier::curve_point (Real t) const return o; } +/* + Cache binom(3,j) t^j (1-t)^{3-j} +*/ +static struct Polynomial bezier_term_cache[4]; +static bool done_cache_init; + +void +init_polynomial_cache () +{ + for (int j = 0; j <= 3; j++) + bezier_term_cache[j] = + binomial_coefficient_3[j] + * Polynomial::power (j, Polynomial (0, 1)) + * Polynomial::power (3 - j, Polynomial (1, -1)); + done_cache_init = true; +} + Polynomial Bezier::polynomial (Axis a) const { + if (!done_cache_init) + init_polynomial_cache (); + Polynomial p (0.0); + Polynomial q ; for (int j = 0; j <= 3; j++) { - p - += (control_[j][a] * binomial_coefficient_3[j]) - * Polynomial::power (j, Polynomial (0, 1)) - * Polynomial::power (3 - j, Polynomial (1, -1)); + q = bezier_term_cache[j]; + q *= control_[j][a]; + p += q; } return p; diff --git a/lily/break-algorithm.cc b/lily/break-algorithm.cc index 3a18f16766..59236fe09e 100644 --- a/lily/break-algorithm.cc +++ b/lily/break-algorithm.cc @@ -14,7 +14,6 @@ #include "paper-column.hh" #include "cpu-timer.hh" #include "simple-spacer.hh" -#include "group-interface.hh" Array Break_algorithm::find_break_indices () const diff --git a/lily/break-align-engraver.cc b/lily/break-align-engraver.cc index 2897a1aaa8..11cfa556c4 100644 --- a/lily/break-align-engraver.cc +++ b/lily/break-align-engraver.cc @@ -89,7 +89,8 @@ Break_align_engraver::acknowledge_grob (Grob_info inf) align_ = make_item ("BreakAlignment", SCM_EOL); Context *origin = inf.origin_contexts (this)[0]; - left_edge_ = make_item_from_properties (dynamic_cast (origin->implementation ()), + left_edge_ = make_item_from_properties (dynamic_cast + (origin->implementation ()), ly_symbol2scm ("LeftEdge"), SCM_EOL, "LeftEdge"); diff --git a/lily/break-align-interface.cc b/lily/break-align-interface.cc index f1469a03f6..d9d977af51 100644 --- a/lily/break-align-interface.cc +++ b/lily/break-align-interface.cc @@ -70,11 +70,14 @@ Link_array Break_align_interface::ordered_elements (Grob *grob) { Item *me = dynamic_cast (grob); - SCM elts = me->get_property ("elements"); + extract_grob_set (me, "elements", elts); + SCM order_vec = me->get_property ("break-align-orders"); if (!scm_is_vector (order_vec) || scm_c_vector_length (order_vec) < 3) - return extract_grob_array (me, ly_symbol2scm ("elements")); + return elts; + + Link_array writable_elts (elts); SCM order = scm_vector_ref (order_vec, scm_int2num (me->break_status_dir () + 1)); @@ -86,16 +89,17 @@ Break_align_interface::ordered_elements (Grob *grob) { SCM sym = scm_car (order); - for (SCM s = elts; scm_is_pair (s); s = scm_cdr (s)) + for (int i = writable_elts.size(); i --; ) { - Grob *g = unsmob_grob (scm_car (s)); + Grob *g = writable_elts[i]; if (g && sym == g->get_property ("break-align-symbol")) { new_elts.push (g); - elts = scm_delq (g->self_scm (), elts); + writable_elts.del (i); } } } + return new_elts; } @@ -151,10 +155,11 @@ Break_align_interface::do_alignment (Grob *grob) /* Find the first grob with a space-alist entry. */ - for (SCM s = l->get_property ("elements"); - scm_is_pair (s); s = scm_cdr (s)) + extract_grob_set (l, "elements", elts); + + for (int i = elts.size(); i--; ) { - Grob *elt = unsmob_grob (scm_car (s)); + Grob *elt = elts[i]; if (edge_idx < 0 && elt->get_property ("break-align-symbol") @@ -176,12 +181,15 @@ Break_align_interface::do_alignment (Grob *grob) table, but that gets icky when that grob is suicided for some reason. */ - for (SCM s = r ? r->get_property ("elements") : SCM_EOL; - !scm_is_symbol (rsym) && scm_is_pair (s); s = scm_cdr (s)) + if (r) { - Grob *elt = unsmob_grob (scm_car (s)); - - rsym = elt->get_property ("break-align-symbol"); + extract_grob_set (r, "elements", elts); + for (int i = elts.size(); + !scm_is_symbol (rsym) && i--;) + { + Grob *elt = elts[i]; + rsym = elt->get_property ("break-align-symbol"); + } } if (rsym == ly_symbol2scm ("left-edge")) diff --git a/lily/break-substitution.cc b/lily/break-substitution.cc index e41b09c553..ce1b41c6cc 100644 --- a/lily/break-substitution.cc +++ b/lily/break-substitution.cc @@ -1,6 +1,16 @@ +/* + break-substitution.cc -- implement grob break substitution. + + source file of the GNU LilyPond music typesetter + + (c) 2001--2005 Han-Wen Nienhuys + +*/ + #include #include +#include "grob-array.hh" #include "item.hh" #include "system.hh" @@ -130,24 +140,28 @@ do_break_substitution (SCM src) /* Perform substitution on GROB_LIST using a constant amount of stack. */ -SCM -substitute_grob_list (SCM grob_list) +void +substitute_grob_array (Grob_array *grob_arr, Grob_array * new_arr) { - SCM l = SCM_EOL; - SCM *tail = &l; + Link_array &old_grobs (grob_arr->array_reference ()); + Link_array *new_grobs (new_arr == grob_arr + ? new Link_array + : &new_arr->array_reference ()); - for (SCM s = grob_list; scm_is_pair (s); s = scm_cdr (s)) + for (int i = 0; i < old_grobs.size (); i++) { - SCM n = substitute_grob (unsmob_grob (scm_car (s))); - - if (n != SCM_UNDEFINED) + Grob * orig = old_grobs[i]; + SCM new_grob = substitute_grob (orig); + if (new_grob != SCM_UNDEFINED) { - *tail = scm_cons (n, SCM_EOL); - tail = SCM_CDRLOC (*tail); + new_grobs->push (unsmob_grob (new_grob)); } } - return l; + if (new_arr == grob_arr) + { + new_arr->set_array (*new_grobs); + } } /* @@ -207,13 +221,13 @@ spanner_system_range (Spanner *sp) if (System *st = sp->get_system ()) { - rv = Slice (st->rank_, st->rank_); + rv = Slice (st->get_rank (), st->get_rank ()); } else { if (sp->broken_intos_.size ()) - rv = Slice (sp->broken_intos_[0]->get_system ()->rank_, - sp->broken_intos_.top ()->get_system ()->rank_); + rv = Slice (sp->broken_intos_[0]->get_system ()->get_rank (), + sp->broken_intos_.top ()->get_system ()->get_rank()); } return rv; } @@ -222,7 +236,7 @@ Slice item_system_range (Item *it) { if (System *st = it->get_system ()) - return Slice (st->rank_, st->rank_); + return Slice (st->get_rank (), st->get_rank ()); Slice sr; Direction d = LEFT; @@ -230,7 +244,7 @@ item_system_range (Item *it) { Item *bi = it->find_prebroken_piece (d); if (bi && bi->get_system ()) - sr.add_point (bi->get_system ()->rank_); + sr.add_point (bi->get_system ()->get_rank ()); } while (flip (&d) != LEFT); @@ -297,13 +311,13 @@ struct Substitution_entry }; bool -Spanner::fast_fubstitute_grob_list (SCM sym, - SCM grob_list) +Spanner::fast_substitute_grob_array (SCM sym, + Grob_array *grob_array) { - int len = scm_ilength (grob_list); + int len = grob_array->size(); /* - Only do this complicated thing for large lists. This has the added + Only do this complicated thing for large sets. This has the added advantage that we won't screw up the ordering for elements in alignments (which typically don't have more than 10 grobs.) */ @@ -312,7 +326,7 @@ Spanner::fast_fubstitute_grob_list (SCM sym, return false; /* - TODO : should not free it some time? + We store items on the left, spanners on the right in this vector. */ static Substitution_entry *vec; static int vec_room; @@ -325,19 +339,12 @@ Spanner::fast_fubstitute_grob_list (SCM sym, Slice system_range = spanner_system_range (this); - Array it_indices; - Array sp_indices; - for (int i = 0; i <= system_range.length (); i++) + int spanner_index = len; + int item_index = 0; + + for (int i = 0 ; i < grob_array->size (); i++) { - it_indices.push (Slice (len, 0)); - sp_indices.push (Slice (len, 0)); - } - - int sp_index = len; - int it_index = 0; - for (SCM s = grob_list; scm_is_pair (s); s = scm_cdr (s)) - { - Grob *g = unsmob_grob (scm_car (s)); + Grob *g = grob_array->grob (i); Slice sr = grob_system_range (g); sr.intersect (system_range); @@ -345,41 +352,49 @@ Spanner::fast_fubstitute_grob_list (SCM sym, int idx = 0; if (dynamic_cast (g)) { - idx =--sp_index; + idx = --spanner_index; } else if (dynamic_cast (g)) { - idx = it_index++; + idx = item_index++; } vec[idx].set (g, sr); } - qsort (vec, it_index, + qsort (vec, item_index, sizeof (Substitution_entry), &Substitution_entry::item_compare); + Array item_indices; + Array spanner_indices; + for (int i = 0; i <= system_range.length (); i++) + { + item_indices.push (Slice (len, 0)); + spanner_indices.push (Slice (len, 0)); + } + Array *arrs[] = { - &it_indices, &sp_indices + &item_indices, &spanner_indices }; - for (int i = 0; i < it_index;i++) + for (int i = 0; i < item_index;i++) { for (int j = vec[i].left_; j <= vec[i].right_; j++) { - it_indices[j - system_range[LEFT]].add_point (i); + item_indices[j - system_range[LEFT]].add_point (i); } } /* - sorting vec[sp_index.. len] + sorting vec[spanner_index.. len] is a waste of time -- the staff-spanners screw up the ordering, since they go across the entire score. */ - for (int i = sp_indices.size (); i--;) - sp_indices[i] = Slice (sp_index, len - 1); + for (int i = spanner_indices.size (); i--;) + spanner_indices[i] = Slice (spanner_index, len - 1); - assert (it_index <= sp_index); + assert (item_index <= spanner_index); assert (broken_intos_.size () == system_range.length () + 1); for (int i = 0; i < broken_intos_.size (); i++) @@ -388,43 +403,34 @@ Spanner::fast_fubstitute_grob_list (SCM sym, System *l = sc->get_system (); set_break_subsititution (l ? l->self_scm () : SCM_UNDEFINED); - SCM newval = SCM_EOL; - SCM *tail = &newval; - + SCM newval = sc->internal_get_object (sym); + if (!unsmob_grob_array (newval)) + { + newval = Grob_array::make_array (); + sc->internal_set_object (sym, newval); + } + + Grob_array *new_array = unsmob_grob_array (newval); for (int k = 0; k < 2;k++) for (int j = (*arrs[k])[i][LEFT]; j <= (*arrs[k])[i][RIGHT]; j++) { SCM subs = substitute_grob (vec[j].grob_); if (subs != SCM_UNDEFINED) { - *tail = scm_cons (subs, SCM_EOL); - - tail = SCM_CDRLOC (*tail); + new_array->add (unsmob_grob (subs)); } } #ifdef PARANOIA - printf ("%d (%d), sp %d (%d)\n", - it_indices [i].length (), it_index, - sp_indices[i].length (), len -sp_index); + item_indices [i].length (), item_index, + spanner_indices[i].length (), len -spanner_index); { SCM l1 = substitute_grob_list (grob_list); assert (scm_ilength (l1) == scm_ilength (newval)); } #endif - - /* - see below. - */ - if (sym == ly_symbol2scm ("all-elements")) - sc->mutable_property_alist_ - = scm_assq_remove_x (sc->mutable_property_alist_, - ly_symbol2scm ("all-elements")); - - sc->mutable_property_alist_ = scm_acons (sym, newval, - sc->mutable_property_alist_); } return true; @@ -444,20 +450,28 @@ Spanner::fast_fubstitute_grob_list (SCM sym, pthreads. pthreads impose small limits on the stack size. */ SCM -substitute_mutable_property_alist (SCM alist) +substitute_object_alist (SCM alist, SCM dest) { - SCM grob_list_p = ly_lily_module_constant ("grob-list?"); - SCM l = SCM_EOL; SCM *tail = &l; for (SCM s = alist; scm_is_pair (s); s = scm_cdr (s)) { SCM sym = scm_caar (s); SCM val = scm_cdar (s); - SCM type = scm_object_property (sym, ly_symbol2scm ("backend-type?")); - if (type == grob_list_p) - val = substitute_grob_list (val); + if (Grob_array * orig = unsmob_grob_array (val)) + { + SCM handle = scm_assq (sym, dest); + SCM newval = + (scm_is_pair (handle)) + ? scm_cdr (handle) + : Grob_array::make_array (); + + Grob_array *new_arr = unsmob_grob_array (newval); + + substitute_grob_array (orig, new_arr); + val = newval; + } else val = do_break_substitution (val); @@ -478,13 +492,12 @@ void Spanner::substitute_one_mutable_property (SCM sym, SCM val) { - SCM type = scm_object_property (sym, ly_symbol2scm ("backend-type?")); Spanner *s = this; bool fast_done = false; - SCM grob_list_p = ly_lily_module_constant ("grob-list?"); - if (type == grob_list_p) - fast_done = s->fast_fubstitute_grob_list (sym, val); + Grob_array * grob_array = unsmob_grob_array (val); + if (grob_array) + fast_done = s->fast_substitute_grob_array (sym, grob_array); if (!fast_done) for (int i = 0; i < s->broken_intos_.size (); i++) @@ -493,29 +506,21 @@ Spanner::substitute_one_mutable_property (SCM sym, System *l = sc->get_system (); set_break_subsititution (l ? l->self_scm () : SCM_UNDEFINED); - SCM newval = (type == grob_list_p) - ? substitute_grob_list (val) - : do_break_substitution (val); - - /* - For the substitution of a single property, we tack the result onto - mutable_property_alist_ ; mutable_property_alist_ is empty after - Grob::Grob (Grob const&), except that System has all-elements set, - as a side product of typeset_grob () on newly copied spanners. - - Here we clear that list explicitly to free some memory and - counter some of the confusion I encountered while debugging - another problem - - (hwn 4/2/04) - */ - if (sym == ly_symbol2scm ("all-elements")) - sc->mutable_property_alist_ - = scm_assq_remove_x (sc->mutable_property_alist_, - ly_symbol2scm ("all-elements")); - - sc->mutable_property_alist_ = scm_cons (scm_cons (sym, newval), - sc->mutable_property_alist_); + if (grob_array) + { + SCM newval = sc->internal_get_object (sym); + if (!unsmob_grob_array (newval)) + { + newval = Grob_array::make_array (); + sc->internal_set_object (sym, newval); + } + substitute_grob_array (grob_array, unsmob_grob_array (newval)); + } + else + { + SCM newval = do_break_substitution (val); + sc->internal_set_object (sym, newval); + } } } diff --git a/lily/chord-tremolo-engraver.cc b/lily/chord-tremolo-engraver.cc index 51140efadf..e3d3078ecc 100644 --- a/lily/chord-tremolo-engraver.cc +++ b/lily/chord-tremolo-engraver.cc @@ -176,7 +176,7 @@ Chord_tremolo_engraver::acknowledge_grob (Grob_info info) stem_tremolo_ = make_item ("StemTremolo", repeat_->self_scm ()); stem_tremolo_->set_property ("flag-count", scm_int2num (flags_)); - stem_tremolo_->set_property ("stem", + stem_tremolo_->set_object ("stem", info.grob ()->self_scm ()); stem_tremolo_->set_parent (info.grob (), X_AXIS); } diff --git a/lily/cluster-engraver.cc b/lily/cluster-engraver.cc index 261df08564..838156145b 100644 --- a/lily/cluster-engraver.cc +++ b/lily/cluster-engraver.cc @@ -10,7 +10,7 @@ #include "spanner.hh" #include "note-head.hh" #include "note-column.hh" -#include "group-interface.hh" +#include "pointer-group-interface.hh" #include "pitch.hh" class Cluster_spanner_engraver : public Engraver diff --git a/lily/cluster.cc b/lily/cluster.cc index 87030d5cbd..8391e7899b 100644 --- a/lily/cluster.cc +++ b/lily/cluster.cc @@ -19,6 +19,7 @@ #include "lookup.hh" #include "output-def.hh" #include "warn.hh" +#include "pointer-group-interface.hh" /* TODO: Add support for cubic spline segments. @@ -137,9 +138,9 @@ Cluster::print (SCM smob) Item *right_bound = spanner->get_bound (RIGHT); Grob *commonx = left_bound->common_refpoint (right_bound, X_AXIS); - SCM cols = me->get_property ("columns"); - if (!scm_is_pair (cols)) + Link_array const &cols = extract_grob_array (me, "columns"); + if (cols.is_empty ()) { me->warning (_ ("junking empty cluster")); me->suicide (); @@ -147,8 +148,8 @@ Cluster::print (SCM smob) return SCM_EOL; } - commonx = common_refpoint_of_list (cols, commonx, X_AXIS); - Grob *commony = common_refpoint_of_list (cols, me, Y_AXIS); + commonx = common_refpoint_of_array (cols, commonx, X_AXIS); + Grob *commony = common_refpoint_of_array (cols, me, Y_AXIS); Array bottom_points; Array top_points; @@ -159,9 +160,10 @@ Cluster::print (SCM smob) line with the center of the note heads? */ - for (SCM s = cols; scm_is_pair (s); s = scm_cdr (s)) + for (int i = 0; i < cols.size (); i++) { - Grob *col = unsmob_grob (scm_car (s)); + Grob *col = cols[i]; + Interval yext = col->extent (commony, Y_AXIS); Real x = col->relative_coordinate (commonx, X_AXIS) - left_coord; @@ -179,11 +181,11 @@ Cluster::print (SCM smob) if (spanner->get_break_index () < orig->broken_intos_.size () - 1) { Spanner *next = orig->broken_intos_[spanner->get_break_index () + 1]; - SCM cols = next->get_property ("columns"); - if (scm_is_pair (cols)) + Link_array const &next_cols = extract_grob_array (next, "columns"); + if (next_cols.size() > 0) { - Grob *next_commony = common_refpoint_of_list (cols, next, Y_AXIS); - Grob *col = unsmob_grob (scm_car (scm_last_pair (cols))); + Grob *next_commony = common_refpoint_of_array (next_cols, next, Y_AXIS); + Grob *col = next_cols[0]; Interval v = col->extent (next_commony, Y_AXIS); Real x = right_bound->relative_coordinate (commonx, X_AXIS) - left_coord; diff --git a/lily/coherent-ligature-engraver.cc b/lily/coherent-ligature-engraver.cc index c695b7a76a..9fd9930f7d 100644 --- a/lily/coherent-ligature-engraver.cc +++ b/lily/coherent-ligature-engraver.cc @@ -13,6 +13,7 @@ #include "spanner.hh" #include "paper-column.hh" #include "pitch.hh" +#include "pointer-group-interface.hh" /* * This abstract class serves as common superclass for all ligature @@ -127,11 +128,12 @@ Coherent_ligature_engraver::get_set_column (Item *item, Paper_column *column) // Change column not only for targeted item (NoteColumn), but // also for all associated grobs (NoteSpacing, SeparationItem). Grob *sl = Staff_symbol_referencer::get_staff_symbol (item); - for (SCM tail = parent->get_property ("elements"); - scm_is_pair (tail); - tail = scm_cdr (tail)) + + extract_item_set (parent, "elements", elements); + + for (int i = elements.size (); i--;) { - Item *sibling = unsmob_item (scm_car (tail)); + Item *sibling = elements[i]; if ((sibling) && (Staff_symbol_referencer::get_staff_symbol (sibling) == sl)) { diff --git a/lily/dot-column-engraver.cc b/lily/dot-column-engraver.cc index 0b1a5b3a85..ddbae5bf33 100644 --- a/lily/dot-column-engraver.cc +++ b/lily/dot-column-engraver.cc @@ -40,7 +40,7 @@ Dot_column_engraver::stop_translation_timestep () See [Ross, p 171] */ if (stem_ && dotcol_) - dotcol_->set_property ("stem", stem_->self_scm ()); + dotcol_->set_object ("stem", stem_->self_scm ()); dotcol_ = 0; heads_.clear (); @@ -50,7 +50,7 @@ Dot_column_engraver::stop_translation_timestep () void Dot_column_engraver::acknowledge_grob (Grob_info info) { - Grob *d = unsmob_grob (info.grob ()->get_property ("dot")); + Grob *d = unsmob_grob (info.grob ()->get_object ("dot")); if (d) { if (!dotcol_) diff --git a/lily/dot-column.cc b/lily/dot-column.cc index 2b0e59494c..69566653b2 100644 --- a/lily/dot-column.cc +++ b/lily/dot-column.cc @@ -50,7 +50,7 @@ Dot_column::side_position (SCM element_smob, SCM axis) (void) axis; assert (scm_to_int (axis) == X_AXIS); - Grob *stem = unsmob_grob (me->get_property ("stem")); + Grob *stem = unsmob_grob (me->get_object ("stem")); if (stem && !Stem::get_beam (stem) && Stem::duration_log (stem) > 2 @@ -225,7 +225,7 @@ SCM Dot_column::do_shifts (Grob *me) { Link_array dots - = extract_grob_array (me, ly_symbol2scm ("dots")); + = extract_grob_array (me, "dots"); { /* Trigger note collision resolution first, since that may kill off @@ -261,7 +261,7 @@ Dot_column::do_shifts (Grob *me) Grob *note = dots[i]->get_parent (Y_AXIS); if (note) { - Grob *stem = unsmob_grob (note->get_property ("stem")); + Grob *stem = unsmob_grob (note->get_object ("stem")); if (stem) dp.extremal_head_ = Stem::first_head (stem) == note; } @@ -290,7 +290,7 @@ Dot_column::do_shifts (Grob *me) void Dot_column::add_head (Grob *me, Grob *rh) { - Grob *d = unsmob_grob (rh->get_property ("dot")); + Grob *d = unsmob_grob (rh->get_object ("dot")); if (d) { Side_position_interface::add_support (me, rh); diff --git a/lily/drum-note-engraver.cc b/lily/drum-note-engraver.cc index 8e9386a441..f002607f35 100644 --- a/lily/drum-note-engraver.cc +++ b/lily/drum-note-engraver.cc @@ -129,7 +129,7 @@ Drum_notes_engraver::acknowledge_grob (Grob_info inf) Grob *e = scripts_[i]; if (to_dir (e->get_property ("side-relative-direction"))) - e->set_property ("direction-source", inf.grob ()->self_scm ()); + e->set_object ("direction-source", inf.grob ()->self_scm ()); /* add dep ? diff --git a/lily/dynamic-engraver.cc b/lily/dynamic-engraver.cc index ab120ab46d..2d56df20d3 100644 --- a/lily/dynamic-engraver.cc +++ b/lily/dynamic-engraver.cc @@ -382,10 +382,11 @@ Dynamic_engraver::acknowledge_grob (Grob_info info) if (script_ && !script_->get_parent (X_AXIS)) { - SCM head = scm_last_pair (info.grob ()->get_property ("note-heads")); - if (scm_is_pair (head)) + extract_grob_set (info.grob (), "note-heads", heads); + if (heads.size()) { - script_->set_parent (unsmob_grob (scm_car (head)), X_AXIS); + Grob *head = heads[0]; + script_->set_parent (head, X_AXIS); script_->add_offset_callback (Self_alignment_interface::centered_on_parent_proc, X_AXIS); diff --git a/lily/easy-notation.cc b/lily/easy-notation.cc index ab150d1621..6311e8a075 100644 --- a/lily/easy-notation.cc +++ b/lily/easy-notation.cc @@ -60,7 +60,7 @@ Note_head::brew_ez_stencil (SCM smob) Real radius = (ss + lt) / 2.0; Real stem_thick = 1.3 * lt; - if (Grob *stem = unsmob_grob (me->get_property ("stem"))) + if (Grob *stem = unsmob_grob (me->get_object ("stem"))) { stem_thick = Stem::thickness (stem); } diff --git a/lily/extender-engraver.cc b/lily/extender-engraver.cc index ac03f5c67f..e3fc6914d1 100644 --- a/lily/extender-engraver.cc +++ b/lily/extender-engraver.cc @@ -10,7 +10,7 @@ #include "context.hh" #include "engraver.hh" -#include "group-interface.hh" +#include "pointer-group-interface.hh" #include "item.hh" #include "lyric-extender.hh" #include "note-head.hh" @@ -73,7 +73,7 @@ Extender_engraver::acknowledge_grob (Grob_info i) if (pending_extender_) { - pending_extender_->set_property ("next", item->self_scm ()); + pending_extender_->set_object ("next", item->self_scm ()); completize_extender (pending_extender_); pending_extender_ = 0; } @@ -118,12 +118,10 @@ completize_extender (Spanner *sp) { if (!sp->get_bound (RIGHT)) { - SCM heads = sp->get_property ("heads"); - if (scm_is_pair (heads)) + extract_item_set (sp, "heads", heads); + if (heads.size ()) { - Item *it = dynamic_cast (unsmob_grob (scm_car (heads))); - if (it) - sp->set_bound (RIGHT, it); + sp->set_bound (RIGHT, heads.top()); } } } diff --git a/lily/grid-line-interface.cc b/lily/grid-line-interface.cc index 953fe4ab7e..087aa2ba9a 100644 --- a/lily/grid-line-interface.cc +++ b/lily/grid-line-interface.cc @@ -10,7 +10,7 @@ #include "grid-line-interface.hh" #include "grob.hh" -#include "group-interface.hh" +#include "pointer-group-interface.hh" #include "lookup.hh" #include "output-def.hh" #include "stencil.hh" @@ -21,15 +21,15 @@ SCM Grid_line_interface::print (SCM smobbed_me) { Grob *me = unsmob_grob (smobbed_me); - SCM first_elt = me->get_property ("elements"); + extract_grob_set (me, "elements", elts); /* compute common refpoint of elements */ - Grob *refp = common_refpoint_of_list (first_elt, me, Y_AXIS); + Grob *refp = common_refpoint_of_array (elts, me, Y_AXIS); Interval iv; - for (SCM elts = first_elt; scm_is_pair (elts); elts = scm_cdr (elts)) + for (int i = 0; i < elts.size(); i++) { - Grob *point = unsmob_grob (scm_car (elts)); + Grob *point = elts[i]; iv.unite (point->extent (refp, Y_AXIS)); } @@ -44,7 +44,6 @@ Grid_line_interface::print (SCM smobbed_me) Real thick = robust_scm2double (me->get_property ("thickness"), 1.0) * staffline; - iv += - me->relative_coordinate (refp, Y_AXIS); Stencil st = Lookup::filled_box (Box (Interval (0, thick), iv)); diff --git a/lily/grob-array.cc b/lily/grob-array.cc new file mode 100644 index 0000000000..c58ffd18bc --- /dev/null +++ b/lily/grob-array.cc @@ -0,0 +1,129 @@ +/* + grob-array.cc -- implement Grob_array + + source file of the GNU LilyPond music typesetter + + (c) 2005 Han-Wen Nienhuys + +*/ + +#include "grob-array.hh" +#include "item.hh" +#include "spanner.hh" + +#include "ly-smobs.icc" + +int +Grob_array::size () const +{ + return grobs_.size(); +} + +Item * +Grob_array::item (int i) +{ + return dynamic_cast (grobs_.elem (i)); +} + + +Spanner* +Grob_array::spanner (int i) +{ + return dynamic_cast (grobs_.elem (i)); +} + +Grob* +Grob_array::grob (int i) +{ + return grobs_.elem (i); +} + +void +Grob_array::add (Grob *grob) +{ + grobs_.push (grob); +} + +Link_array & +Grob_array::array_reference () +{ + return grobs_; +} + + +Link_array const & +Grob_array::array () const +{ + return grobs_; +} + + +SCM +Grob_array::mark_smob (SCM s) +{ +#if 0 + // see System::derived_mark() + Grob_array *ga = unsmob_grob_array (s); + for (int i = 0; i < ga->grobs_.size(); i++) + scm_gc_mark (ga->grobs_[i]->self_scm ()); +#endif + return SCM_UNDEFINED; +} + +int +Grob_array::print_smob (SCM arr, SCM port, scm_print_state*) +{ + scm_puts ("#size(); i++) + { + scm_display (grob_arr->grob (i)->self_scm (), port); + scm_puts (" " , port); + } + scm_puts (">", port); + return 1; +} + + +SCM +Grob_array::make_array () +{ + Grob_array ga; + return ga.smobbed_copy (); +} + +void +Grob_array::clear () +{ + grobs_.clear (); +} + +bool +Grob_array::is_empty () const +{ + return grobs_.is_empty (); +} + +void +Grob_array::set_array (Link_array const &src) +{ + grobs_ = src; +} + +IMPLEMENT_SIMPLE_SMOBS (Grob_array); +IMPLEMENT_TYPE_P (Grob_array, "ly:grob-array?"); +IMPLEMENT_DEFAULT_EQUAL_P (Grob_array); + + +SCM +grob_list_to_grob_array (SCM lst) +{ + SCM arr_scm = Grob_array::make_array (); + Grob_array *ga = unsmob_grob_array (arr_scm); + for (SCM s = lst; scm_is_pair (s); s = scm_cdr (s)) + { + ga->add (unsmob_grob (scm_car (s))); + } + return arr_scm; +} diff --git a/lily/grob-interface.cc b/lily/grob-interface.cc index b0a255d58f..3ea894b2f6 100644 --- a/lily/grob-interface.cc +++ b/lily/grob-interface.cc @@ -33,7 +33,8 @@ check_interfaces_for_property (Grob const *me, SCM sym) */ return; } - SCM ifs = me->get_property ("interfaces"); + + SCM ifs = me->interfaces_; SCM all_ifaces = ly_all_grob_interfaces (); bool found = false; diff --git a/lily/grob-property.cc b/lily/grob-property.cc index 67401f226e..a6d57b4ce0 100644 --- a/lily/grob-property.cc +++ b/lily/grob-property.cc @@ -7,7 +7,7 @@ #include "main.hh" #include "input-smob.hh" -#include "group-interface.hh" +#include "pointer-group-interface.hh" #include "misc.hh" #include "paper-score.hh" #include "output-def.hh" @@ -32,6 +32,7 @@ Grob::get_property_alist_chain (SCM def) const since it can reuse the handle returned by scm_assq (). */ +// JUNKME. void Grob::add_to_list_property (SCM sym, SCM thing) { @@ -57,32 +58,90 @@ Grob::add_to_list_property (SCM sym, SCM thing) } } + + extern void check_interfaces_for_property (Grob const *me, SCM sym); void -Grob::internal_set_property (SCM s, SCM v) +Grob::internal_set_property (SCM sym, SCM v) { +#ifndef NDEBUG + SCM grob_p = ly_lily_module_constant ("ly:grob?"); + SCM grob_list_p = ly_lily_module_constant ("grob-list?"); + SCM type = scm_object_property (sym, ly_symbol2scm ("backend-type?")); + + if (type == grob_p + || type == grob_list_p + || (unsmob_grob (v) && ly_symbol2scm ("cause") != sym)) + { + scm_display (scm_list_2 (sym, type), scm_current_output_port()); + assert (0); + } +#endif + /* Perhaps we simply do the assq_set, but what the heck. */ if (!is_live ()) return; if (do_internal_type_checking_global) { - if (!type_check_assignment (s, v, ly_symbol2scm ("backend-type?"))) + if (!type_check_assignment (sym, v, ly_symbol2scm ("backend-type?"))) abort (); - check_interfaces_for_property (this, s); + check_interfaces_for_property (this, sym); } - mutable_property_alist_ = scm_assq_set_x (mutable_property_alist_, s, v); + mutable_property_alist_ = scm_assq_set_x (mutable_property_alist_, sym, v); +} + +Protected_scm property_lookup_table; +LY_DEFINE(ly_property_lookup_stats, "ly:property-lookup-stats", + 0,0,0, (), + "") +{ + return (SCM) property_lookup_table; } + SCM Grob::internal_get_property (SCM sym) const { +#ifndef NDEBUG + SCM grob_p = ly_lily_module_constant ("ly:grob?"); + SCM grob_list_p = ly_lily_module_constant ("grob-list?"); + SCM type = scm_object_property (sym, ly_symbol2scm ("backend-type?")); + + if (type == grob_p + || type == grob_list_p) + { + scm_display (scm_list_2 (sym, type), scm_current_output_port()); + assert (0); + } +#endif + +#if 0 + /* + Statistics: which properties are looked up? + */ + if (scm_hash_table_p (property_lookup_table) != SCM_BOOL_T) + { + property_lookup_table = scm_c_make_hash_table (259); + } + + SCM hashhandle = scm_hashq_get_handle (property_lookup_table, sym); + if (hashhandle == SCM_BOOL_F) + { + scm_hashq_set_x (property_lookup_table, sym, scm_from_int (0)); + hashhandle = scm_hashq_get_handle (property_lookup_table, sym); + } + + scm_set_cdr_x (hashhandle, scm_from_int (scm_to_int (scm_cdr (hashhandle)) + 1)); +#endif + + SCM s = scm_sloppy_assq (sym, mutable_property_alist_); if (s != SCM_BOOL_F) return scm_cdr (s); - + s = scm_sloppy_assq (sym, immutable_property_alist_); if (do_internal_type_checking_global && scm_is_pair (s)) @@ -97,11 +156,31 @@ Grob::internal_get_property (SCM sym) const return (s == SCM_BOOL_F) ? SCM_EOL : scm_cdr (s); } + + +void +Grob::internal_set_object (SCM s, SCM v) +{ + /* Perhaps we simply do the assq_set, but what the heck. */ + if (!is_live ()) + return; + + object_alist_ = scm_assq_set_x (object_alist_, s, v); +} + +SCM +Grob::internal_get_object (SCM sym) const +{ + SCM s = scm_sloppy_assq (sym, object_alist_); + + return (s == SCM_BOOL_F) ? SCM_EOL : scm_cdr (s); +} + void -Grob::substitute_mutable_properties (SCM crit, SCM orig) +Grob::substitute_object_links (SCM crit, SCM orig) { set_break_subsititution (crit); - mutable_property_alist_ = substitute_mutable_property_alist (orig); + object_alist_ = substitute_object_alist (orig, object_alist_); } bool diff --git a/lily/grob-scheme.cc b/lily/grob-scheme.cc index edf700aa60..929a0dbaa7 100644 --- a/lily/grob-scheme.cc +++ b/lily/grob-scheme.cc @@ -45,6 +45,21 @@ LY_DEFINE (ly_grob_property, "ly:grob-property", return sc->internal_get_property (sym); } +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}. " + "It will return @code{' ()} (end-of-list) " + "if @var{sym} is undefined in @var{g}." + "\n\n") +{ + 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"); + + return sc->internal_get_object (sym); +} + + LY_DEFINE (ly_spanner_get_bound, "ly:spanner-get-bound", 2, 0, 0, (SCM slur, SCM dir), "Get one of the bounds of @var{spanner}. @var{dir} is @code{-1} " diff --git a/lily/grob.cc b/lily/grob.cc index 121302769d..d91e62342a 100644 --- a/lily/grob.cc +++ b/lily/grob.cc @@ -14,7 +14,7 @@ #include "main.hh" #include "input-smob.hh" #include "warn.hh" -#include "group-interface.hh" +#include "pointer-group-interface.hh" #include "misc.hh" #include "paper-score.hh" #include "stencil.hh" @@ -52,9 +52,12 @@ Grob::Grob (SCM basicprops, pscore_ = 0; status_ = 0; original_ = 0; + interfaces_ = SCM_EOL; immutable_property_alist_ = basicprops; mutable_property_alist_ = SCM_EOL; + object_alist_ = SCM_EOL; + /* We do smobify_self () as the first step. Since the object lives on the heap, none of its SCM variables are protected from GC. After smobify_self (), they are. */ @@ -68,13 +71,7 @@ Grob::Grob (SCM basicprops, SCM meta = get_property ("meta"); if (scm_is_pair (meta)) { - SCM ifs = scm_assoc (ly_symbol2scm ("interfaces"), meta); - - /* Switch off interface checks for the moment. */ - bool itc = do_internal_type_checking_global; - do_internal_type_checking_global = false; - internal_set_property (ly_symbol2scm ("interfaces"), scm_cdr (ifs)); - do_internal_type_checking_global = itc; + interfaces_ = scm_cdr (scm_assoc (ly_symbol2scm ("interfaces"), meta)); } /* TODO: @@ -129,8 +126,10 @@ Grob::Grob (Grob const &s, int copy_index) self_scm_ = SCM_EOL; immutable_property_alist_ = s.immutable_property_alist_; - mutable_property_alist_ = SCM_EOL; - + mutable_property_alist_ = ly_deep_copy (s.mutable_property_alist_); + interfaces_ = s.interfaces_; + object_alist_ = SCM_EOL; + /* No properties are copied. That is the job of handle_broken_dependencies. */ status_ = s.status_; @@ -196,9 +195,9 @@ Grob::calculate_dependencies (int final, int busy, SCM funcname) status_ = busy; - for (SCM d = get_property ("dependencies"); scm_is_pair (d); - d = scm_cdr (d)) - unsmob_grob (scm_car (d))->calculate_dependencies (final, busy, funcname); + extract_grob_set (this, "dependencies", deps); + for (int i = 0; i < deps.size (); i++) + deps[i]->calculate_dependencies (final, busy, funcname); SCM proc = internal_get_property (funcname); if (ly_is_procedure (proc)) @@ -299,19 +298,20 @@ Grob::handle_broken_dependencies () /* THIS, SP is the original spanner. We use a special function because some Spanners have enormously long lists in their properties, and a special function fixes FOO */ - for (SCM s = mutable_property_alist_; scm_is_pair (s); s = scm_cdr (s)) - sp->substitute_one_mutable_property (scm_caar (s), scm_cdar (s)); + { + for (SCM s = object_alist_; scm_is_pair (s); s = scm_cdr (s)) + sp->substitute_one_mutable_property (scm_caar (s), scm_cdar (s)); + } System *system = get_system (); if (is_live () - && system && common_refpoint (system, X_AXIS) + && system + && common_refpoint (system, X_AXIS) && common_refpoint (system, Y_AXIS)) - substitute_mutable_properties (system - ? system->self_scm () : SCM_UNDEFINED, - mutable_property_alist_); + substitute_object_links (system->self_scm (), object_alist_); else if (dynamic_cast (this)) - substitute_mutable_properties (SCM_UNDEFINED, mutable_property_alist_); + substitute_object_links (SCM_UNDEFINED, object_alist_); else /* THIS element is `invalid'; it has been removed from all dependencies, so let's junk the element itself. @@ -333,8 +333,10 @@ Grob::suicide () return; mutable_property_alist_ = SCM_EOL; + object_alist_ = SCM_EOL; immutable_property_alist_ = SCM_EOL; - + interfaces_ = SCM_EOL; + set_extent (SCM_EOL, Y_AXIS); set_extent (SCM_EOL, X_AXIS); @@ -352,12 +354,12 @@ void Grob::handle_prebroken_dependencies () { /* Don't do this in the derived method, since we want to keep access to - mutable_property_alist_ centralized. */ + object_alist_ centralized. */ if (original_) { Item *it = dynamic_cast (this); - substitute_mutable_properties (scm_int2num (it->break_status_dir ()), - original_->mutable_property_alist_); + substitute_object_links (scm_int2num (it->break_status_dir ()), + original_->object_alist_); } } @@ -578,26 +580,24 @@ Grob::set_parent (Grob *g, Axis a) dim_cache_[a].parent_ = g; } -MAKE_SCHEME_CALLBACK (Grob, fixup_refpoint, 1); -SCM -Grob::fixup_refpoint (SCM smob) +void +Grob::fixup_refpoint () { - Grob *me = unsmob_grob (smob); for (int a = X_AXIS; a < NO_AXES; a++) { Axis ax = (Axis)a; - Grob *parent = me->get_parent (ax); + Grob *parent = get_parent (ax); if (!parent) continue; - if (parent->get_system () != me->get_system () && me->get_system ()) + if (parent->get_system () != get_system () && get_system ()) { - Grob *newparent = parent->find_broken_piece (me->get_system ()); - me->set_parent (newparent, ax); + Grob *newparent = parent->find_broken_piece (get_system ()); + set_parent (newparent, ax); } - if (Item *i = dynamic_cast (me)) + if (Item *i = dynamic_cast (this)) { Item *parenti = dynamic_cast (parent); @@ -607,12 +607,11 @@ Grob::fixup_refpoint (SCM smob) if (my_dir != parenti->break_status_dir ()) { Item *newparent = parenti->find_prebroken_piece (my_dir); - me->set_parent (newparent, ax); + set_parent (newparent, ax); } } } } - return smob; } void @@ -634,76 +633,16 @@ Grob::programming_error (String s) const s = _f ("programming error: %s", s); message (s); } - -/**************************************************** - SMOB funcs -****************************************************/ - -IMPLEMENT_SMOBS (Grob); -IMPLEMENT_DEFAULT_EQUAL_P (Grob); - -SCM -Grob::mark_smob (SCM ses) -{ - Grob *s = (Grob *) SCM_CELL_WORD_1 (ses); - scm_gc_mark (s->immutable_property_alist_); - - if (s->key_) - scm_gc_mark (s->key_->self_scm ()); - for (int a = 0; a < 2; a++) - { - scm_gc_mark (s->dim_cache_[a].offset_callbacks_); - scm_gc_mark (s->dim_cache_[a].dimension_); - scm_gc_mark (s->dim_cache_[a].dimension_callback_); - - /* Do not mark the parents. The pointers in the mutable - property list form two tree like structures (one for X - relations, one for Y relations). Marking these can be done - in limited stack space. If we add the parents, we will jump - between X and Y in an erratic manner, leading to much more - recursion depth (and core dumps if we link to pthreads). */ - } - - if (s->original_) - scm_gc_mark (s->original_->self_scm ()); - - if (s->pscore_) - scm_gc_mark (s->pscore_->self_scm ()); - - s->do_derived_mark (); - return s->mutable_property_alist_; -} - -int -Grob::print_smob (SCM s, SCM port, scm_print_state *) -{ - Grob *sc = (Grob *) SCM_CELL_WORD_1 (s); - - scm_puts ("#name ().to_str0 (), port); - - /* Do not print properties, that is too much hassle. */ - scm_puts (" >", port); - return 1; -} - -SCM -Grob::do_derived_mark () const -{ - return SCM_EOL; -} - void Grob::discretionary_processing () { + } bool Grob::internal_has_interface (SCM k) { - SCM ifs = get_property ("interfaces"); - - return scm_c_memq (k, ifs) != SCM_BOOL_F; + return scm_c_memq (k, interfaces_) != SCM_BOOL_F; } Grob * @@ -745,8 +684,6 @@ ly_grobs2scm (Link_array a) return s; } -IMPLEMENT_TYPE_P (Grob, "ly:grob?"); - ADD_INTERFACE (Grob, "grob-interface", "A grob represents a piece of music notation\n" "\n" @@ -784,5 +721,5 @@ ADD_INTERFACE (Grob, "grob-interface", "axis-group-parent-X " "axis-group-parent-Y " "after-line-breaking-callback extra-Y-extent minimum-X-extent " - "minimum-Y-extent transparent tweak-count tweak-rank"); + "minimum-Y-extent transparent"); diff --git a/lily/group-interface.cc b/lily/group-interface.cc deleted file mode 100644 index 9fbd329e7c..0000000000 --- a/lily/group-interface.cc +++ /dev/null @@ -1,57 +0,0 @@ -/* - group-interface.cc -- implement Group_interface - - source file of the GNU LilyPond music typesetter - - (c) 1999--2005 Han-Wen Nienhuys -*/ - -#include "group-interface.hh" -#include "item.hh" - -void -Group_interface::add_thing (Grob *me, SCM sym, SCM thing) -{ - me->add_to_list_property (sym, thing); -} - -int -Group_interface::count (Grob *me, SCM sym) -{ - return scm_ilength (me->internal_get_property (sym)); -} - -void -Pointer_group_interface::add_grob (Grob *me, SCM name, Grob *p) -{ - Group_interface::add_thing (me, name, p->self_scm ()); -} - -Link_array -extract_grob_array (Grob const *elt, SCM symbol) -{ - Link_array arr; - - for (SCM s = elt->internal_get_property (symbol); scm_is_pair (s); s = scm_cdr (s)) - { - SCM e = scm_car (s); - arr.push (unsmob_grob (e)); - } - - arr.reverse (); - return arr; -} - -Link_array -extract_item_array (Grob const *elt, SCM symbol) -{ - Link_array arr; - for (SCM s = elt->internal_get_property (symbol); scm_is_pair (s); s = scm_cdr (s)) - { - SCM e = scm_car (s); - arr.push (dynamic_cast (unsmob_grob (e))); - } - - arr.reverse (); - return arr; -} diff --git a/lily/hairpin.cc b/lily/hairpin.cc index 0d25cf1bdf..c231c90eba 100644 --- a/lily/hairpin.cc +++ b/lily/hairpin.cc @@ -18,7 +18,7 @@ #include "paper-column.hh" #include "lookup.hh" #include "text-interface.hh" - +#include "pointer-group-interface.hh" MAKE_SCHEME_CALLBACK(Hairpin,after_line_breaking,1); SCM @@ -96,8 +96,8 @@ Hairpin::print (SCM smob) else { bool neighbor_found = false; - for (SCM adj = me->get_property ("adjacent-hairpins"); - scm_is_pair (adj); adj = scm_cdr (adj)) + extract_grob_set (me, "adjacent-hairpins", pins); + for (int i = 0; i < pins.size(); i++) { /* FIXME: this will fuck up in case of polyphonic @@ -105,7 +105,7 @@ Hairpin::print (SCM smob) in the current staff/voice. */ - Spanner *pin = unsmob_spanner (scm_car (adj)); + Spanner *pin = dynamic_cast (pins[i]); if (pin && (pin->get_bound (LEFT)->get_column () == b->get_column () || pin->get_bound (RIGHT)->get_column () == b->get_column ())) diff --git a/lily/hara-kiri-group-spanner.cc b/lily/hara-kiri-group-spanner.cc index 22975589cb..accfe9c3b9 100644 --- a/lily/hara-kiri-group-spanner.cc +++ b/lily/hara-kiri-group-spanner.cc @@ -30,8 +30,9 @@ void Hara_kiri_group_spanner::consider_suicide (Grob *me) { Spanner *sp = dynamic_cast (me); - SCM worth = me->get_property ("items-worth-living"); - if (scm_is_pair (worth)) + + extract_grob_set (me,"items-worth-living", worth); + if (worth.size ()) return; if (!to_boolean (me->get_property ("remove-first")) @@ -40,7 +41,8 @@ Hara_kiri_group_spanner::consider_suicide (Grob *me) return; } - Link_array childs = Axis_group_interface::get_children (me); + Link_array childs; + Axis_group_interface::get_children (me, &childs); for (int i = 0; i < childs.size (); i++) childs[i]->suicide (); diff --git a/lily/horizontal-bracket-engraver.cc b/lily/horizontal-bracket-engraver.cc index 2c5f39bbba..9614c0f377 100644 --- a/lily/horizontal-bracket-engraver.cc +++ b/lily/horizontal-bracket-engraver.cc @@ -10,7 +10,7 @@ #include "engraver.hh" #include "side-position-interface.hh" #include "note-column.hh" -#include "group-interface.hh" +#include "pointer-group-interface.hh" class Horizontal_bracket_engraver : public Engraver { diff --git a/lily/horizontal-bracket.cc b/lily/horizontal-bracket.cc index c4b598761a..3f318b5d68 100644 --- a/lily/horizontal-bracket.cc +++ b/lily/horizontal-bracket.cc @@ -8,7 +8,7 @@ #include "side-position-interface.hh" #include "lookup.hh" -#include "group-interface.hh" +#include "pointer-group-interface.hh" #include "directional-element-interface.hh" #include "output-def.hh" #include "staff-symbol-referencer.hh" @@ -34,8 +34,8 @@ Horizontal_bracket::print (SCM smob) { Grob *me = unsmob_grob (smob); Spanner *sp = dynamic_cast (me); - Link_array gs = extract_grob_array (me, ly_symbol2scm ("columns")); - + + extract_grob_set (me, "columns", gs); if (!gs.size ()) { me->suicide (); diff --git a/lily/hyphen-engraver.cc b/lily/hyphen-engraver.cc index 9961258729..29857100fa 100644 --- a/lily/hyphen-engraver.cc +++ b/lily/hyphen-engraver.cc @@ -8,10 +8,12 @@ Jan Nieuwenhuizen */ +#include "engraver.hh" + #include "warn.hh" #include "item.hh" -#include "engraver.hh" #include "spanner.hh" +#include "pointer-group-interface.hh" class Hyphen_engraver : public Engraver { @@ -67,12 +69,10 @@ completize_hyphen (Spanner *sp) { if (!sp->get_bound (RIGHT)) { - SCM heads = sp->get_property ("heads"); - if (scm_is_pair (heads)) + extract_item_set (sp, "heads", heads); + if (heads.size ()) { - Item *it = dynamic_cast (unsmob_grob (scm_car (heads))); - if (it) - sp->set_bound (RIGHT, it); + sp->set_bound (RIGHT, heads.top ()); } } } diff --git a/lily/include/axis-group-interface.hh b/lily/include/axis-group-interface.hh index e80e20a706..5a220237be 100644 --- a/lily/include/axis-group-interface.hh +++ b/lily/include/axis-group-interface.hh @@ -9,19 +9,20 @@ #ifndef AXIS_GROUP_INTERFACE_HH #define AXIS_GROUP_INTERFACE_HH -#include "group-interface.hh" +#include "pointer-group-interface.hh" /** */ struct Axis_group_interface { DECLARE_SCHEME_CALLBACK (group_extent_callback, (SCM smob, SCM axis)); - static Interval relative_group_extent (SCM list, Grob *common, Axis); + static Interval relative_group_extent (Link_array const &list, + Grob *common, Axis); static void add_element (Grob *me, Grob *); static void set_axes (Grob *, Axis, Axis); static bool has_axis (Grob *, Axis); - static Link_array get_children (Grob *); + static void get_children (Grob *, Link_array *); static bool has_interface (Grob *); }; diff --git a/lily/include/beam.hh b/lily/include/beam.hh index 746d7e1458..b69fc15fce 100644 --- a/lily/include/beam.hh +++ b/lily/include/beam.hh @@ -14,6 +14,32 @@ #include "lily-guile.hh" #include "stem-info.hh" + +/* + TODO: move quanting in separate file. + */ +struct Beam_quant_parameters { + Real INTER_QUANT_PENALTY; + Real SECONDARY_BEAM_DEMERIT; + Real STEM_LENGTH_DEMERIT_FACTOR; + Real REGION_SIZE; + + + /* + threshold to combat rounding errors. + */ + Real BEAM_EPS; + + // possibly ridiculous, but too short stems just won't do + Real STEM_LENGTH_LIMIT_PENALTY; + Real DAMPING_DIRECTION_PENALTY; + Real MUSICAL_DIRECTION_FACTOR; + Real IDEAL_SLOPE_FACTOR; + Real ROUND_TO_ZERO_SLOPE; + + void fill (Grob *him); +}; + class Beam { public: @@ -21,8 +47,6 @@ public: static Grob *first_visible_stem (Grob *); static Grob *last_visible_stem (Grob *); static bool has_interface (Grob *); - DECLARE_SCHEME_CALLBACK (rest_collision_callback, (SCM element, SCM axis)); - Beam (SCM); static void add_stem (Grob *, Grob *); static bool is_knee (Grob *); static void set_beaming (Grob *, Beaming_info_list *); @@ -31,8 +55,9 @@ public: static void position_beam (Grob *me); static Real get_beam_translation (Grob *me); static Real get_thickness (Grob *me); - static void connect_beams (Grob *me); + + DECLARE_SCHEME_CALLBACK (rest_collision_callback, (SCM element, SCM axis)); DECLARE_SCHEME_CALLBACK (space_function, (SCM, SCM)); DECLARE_SCHEME_CALLBACK (print, (SCM)); DECLARE_SCHEME_CALLBACK (before_line_breaking, (SCM)); @@ -44,7 +69,7 @@ public: DECLARE_SCHEME_CALLBACK (slope_damping, (SCM)); DECLARE_SCHEME_CALLBACK (shift_region_to_valid, (SCM)); DECLARE_SCHEME_CALLBACK (quanting, (SCM)); - static Real score_slopes_dy (Real, Real, Real, Real, Real, bool); + static Real score_slopes_dy (Real, Real, Real, Real, Real, bool, Beam_quant_parameters const*); static Real score_stem_lengths (Link_array const &stems, Array const &stem_infos, @@ -52,10 +77,11 @@ public: Array const &stem_xs, Real xl, Real xr, bool knee, - Real yl, Real yr); + Real yl, Real yr, Beam_quant_parameters const*); static Real score_forbidden_quants (Real, Real, Real, Real, Real, Real, - Drul_array, Direction, Direction); + Drul_array, Direction, Direction, + Beam_quant_parameters const*); static int get_direction_beam_count (Grob *me, Direction d); private: @@ -70,8 +96,6 @@ private: static int forced_stem_count (Grob *); }; -const int REGION_SIZE = 2; - #ifndef NDEBUG #define DEBUG_QUANTING 1 #endif diff --git a/lily/include/grob-array.hh b/lily/include/grob-array.hh new file mode 100644 index 0000000000..8c5c4d54e2 --- /dev/null +++ b/lily/include/grob-array.hh @@ -0,0 +1,44 @@ +/* + grob-array.hh -- declare Grob_array + + source file of the GNU LilyPond music typesetter + + (c) 2005 Han-Wen Nienhuys + +*/ + +#ifndef GROB_ARRAY_HH +#define GROB_ARRAY_HH + +#include "lily-proto.hh" +#include "smobs.hh" +#include "parray.hh" + +class Grob_array +{ + Link_array grobs_; + + DECLARE_SIMPLE_SMOBS(Grob_array,); + +public: + Item *item (int i); + Spanner *spanner (int i); + Grob * grob (int i); + int size () const; + bool is_empty () const; + void clear (); + void add (Grob *); + void set_array (Link_array const &src); + Link_array &array_reference (); + Link_array const &array () const; + static SCM make_array (); +}; + +DECLARE_UNSMOB (Grob_array, grob_array); + +Link_array const &ly_scm2link_array (SCM x); +SCM grob_list_to_grob_array (SCM lst); + + +#endif /* GROB_ARRAY_HH */ + diff --git a/lily/include/grob.hh b/lily/include/grob.hh index 9f46a06e1d..6b8d864449 100644 --- a/lily/include/grob.hh +++ b/lily/include/grob.hh @@ -14,9 +14,6 @@ #include "grob-interface.hh" #include "object-key.hh" -/** - for administration of what was done already -*/ enum Grob_status { ORPHAN = 0, // not yet added to Paper_score @@ -28,14 +25,6 @@ enum Grob_status typedef void (Grob:: *Grob_method_pointer) (void); -// looking at gtk+/pango docstrings .. WIP - -/** - * Grob: - * @internal_get_property: get property #NAME. - * - * Class structure for #Grob. - **/ class Grob { private: @@ -45,13 +34,22 @@ protected: Object_key const *key_; SCM immutable_property_alist_; SCM mutable_property_alist_; + SCM object_alist_; + + /* + If this is a property, it accounts for 25% of the property + lookups. + */ + SCM interfaces_; + + /* BARF */ friend class Spanner; friend SCM ly_grob_properties (SCM); friend SCM ly_grob_basic_properties (SCM); - - void substitute_mutable_properties (SCM, SCM); + friend void check_interfaces_for_property (Grob const*, SCM); + void substitute_object_links (SCM, SCM); char status_; public: @@ -75,8 +73,16 @@ public: Properties */ SCM internal_get_property (SCM) const; - void internal_set_property (SCM, SCM val); + SCM internal_get_object (SCM) const; + + void internal_set_property (SCM sym, SCM val); + void internal_set_object (SCM sym, SCM val); + + /* + JUNKME. + */ void add_to_list_property (SCM, SCM); + void add_to_object_list (SCM sym, SCM thing); SCM get_property_alist_chain (SCM) const; static SCM ly_grob_set_property (SCM, SCM, SCM); @@ -128,7 +134,7 @@ public: // URG Grob *get_parent (Axis a) const; - DECLARE_SCHEME_CALLBACK (fixup_refpoint, (SCM)); + void fixup_refpoint (); }; DECLARE_UNSMOB (Grob, grob); @@ -139,7 +145,7 @@ Grob *common_refpoint_of_list (SCM elt_list, Grob *, Axis a); Grob *common_refpoint_of_array (Link_array const &, Grob *, Axis a); void set_break_subsititution (SCM criterion); -SCM substitute_mutable_property_alist (SCM alist); +SCM substitute_object_alist (SCM alist, SCM dest); Link_array ly_scm2grobs (SCM ell); SCM ly_grobs2scm (Link_array a); diff --git a/lily/include/group-interface.hh b/lily/include/group-interface.hh index c8c0938e30..072ed56bf1 100644 --- a/lily/include/group-interface.hh +++ b/lily/include/group-interface.hh @@ -26,14 +26,5 @@ public: static void add_thing (Grob *, SCM, SCM); }; -struct Pointer_group_interface : public Group_interface -{ -public: - static void add_grob (Grob *, SCM nm, Grob *e); -}; - -Link_array extract_grob_array (Grob const *elt, SCM symbol); -Link_array extract_item_array (Grob const *elt, SCM symbol); - #endif /* GROUP_INTERFACE_HH */ diff --git a/lily/include/lily-guile-macros.hh b/lily/include/lily-guile-macros.hh index 3a2f63e47c..03abe6bde5 100644 --- a/lily/include/lily-guile-macros.hh +++ b/lily/include/lily-guile-macros.hh @@ -147,6 +147,8 @@ ly_add_function_documentation (SCM proc, char const *fname, VAR, ARGLIST, DOCSTRING) #define get_property(x) internal_get_property (ly_symbol2scm (x)) +#define get_object(x) internal_get_object (ly_symbol2scm (x)) #define set_property(x, y) internal_set_property (ly_symbol2scm (x), y) +#define set_object(x, y) internal_set_object (ly_symbol2scm (x), y) #endif /* LILY_GUILE_MACROS_HH */ diff --git a/lily/include/lily-proto.hh b/lily/include/lily-proto.hh index bed9339056..0270d7a751 100644 --- a/lily/include/lily-proto.hh +++ b/lily/include/lily-proto.hh @@ -59,6 +59,7 @@ class Grace_fixup; class Grace_iterator; class Grace_music; class Grob; +class Grob_array; class Hara_kiri_engraver; class Hara_kiri_line_group_engraver; class Includable_lexer; diff --git a/lily/include/music.hh b/lily/include/music.hh index 71e4d00741..abb7381ece 100644 --- a/lily/include/music.hh +++ b/lily/include/music.hh @@ -28,6 +28,8 @@ public: SCM internal_get_property (SCM) const; void internal_set_property (SCM, SCM val); + SCM internal_get_object (SCM) const; + void internal_set_object (SCM, SCM val); SCM get_property_alist (bool mutble) const; bool internal_is_music_type (SCM) const; diff --git a/lily/include/separating-group-spanner.hh b/lily/include/separating-group-spanner.hh index 8a082b8f4e..11addba593 100644 --- a/lily/include/separating-group-spanner.hh +++ b/lily/include/separating-group-spanner.hh @@ -13,7 +13,10 @@ class Separating_group_spanner { - static void find_rods (Item *, SCM, Real); + static void find_rods (Item *, + Link_array const &separators, + int idx, + Real); public: static void add_spacing_unit (Grob *me, Item *); diff --git a/lily/include/spanner.hh b/lily/include/spanner.hh index 6c0fc1cbed..b06c0a4cc0 100644 --- a/lily/include/spanner.hh +++ b/lily/include/spanner.hh @@ -37,10 +37,12 @@ public: Link_array broken_intos_; int get_break_index () const; + // todo: move to somewhere else. Real get_broken_left_end_align () const; void substitute_one_mutable_property (SCM sym, SCM val); - bool fast_fubstitute_grob_list (SCM sym, SCM grob_list); + bool fast_substitute_grob_array (SCM sym, Grob_array *); + // TODO: make virtual and do this for Items as well. Interval_t spanned_rank_iv (); void set_bound (Direction d, Grob *); diff --git a/lily/include/system.hh b/lily/include/system.hh index ea31faa752..18ef76e739 100644 --- a/lily/include/system.hh +++ b/lily/include/system.hh @@ -10,6 +10,7 @@ #include "column-x-positions.hh" #include "spanner.hh" +#include "grob-array.hh" /* If you keep following offset reference points, you will always end @@ -18,15 +19,17 @@ */ class System : public Spanner { -public: int rank_; + Grob_array *all_elements_; + void init_elements (); +public: + int get_rank () const; void post_processing (); SCM get_paper_system (); SCM get_paper_systems (); System (SCM, Object_key const *); System (System const &, int); - virtual Grob *clone (int count) const; int element_count () const; int spanner_count () const; @@ -42,6 +45,8 @@ public: void pre_processing (); protected: + virtual SCM do_derived_mark () const; + virtual Grob *clone (int count) const; }; void set_loose_columns (System *which, Column_x_positions const *posns); diff --git a/lily/include/translator-group.hh b/lily/include/translator-group.hh index ad4af88a55..ed33f010e5 100644 --- a/lily/include/translator-group.hh +++ b/lily/include/translator-group.hh @@ -9,6 +9,8 @@ #ifndef TRANSLATOR_GROUP_HH #define TRANSLATOR_GROUP_HH + + #include "translator.hh" #include "parray.hh" @@ -26,6 +28,7 @@ public: protected: SCM simple_trans_list_; + friend class Context_def; virtual void derived_mark () const; }; diff --git a/lily/instrument-name-engraver.cc b/lily/instrument-name-engraver.cc index cb59170316..8ded1dabca 100644 --- a/lily/instrument-name-engraver.cc +++ b/lily/instrument-name-engraver.cc @@ -14,6 +14,7 @@ #include "axis-group-interface.hh" #include "context.hh" #include "text-interface.hh" +#include "grob-array.hh" class Instrument_name_engraver : public Engraver { @@ -49,8 +50,8 @@ Instrument_name_engraver::stop_translation_timestep () { if (text_) { - text_->set_property ("side-support-elements", - get_property ("instrumentSupport")); + text_->set_object ("side-support-elements", + grob_list_to_grob_array (get_property ("instrumentSupport"))); text_ = 0; } diff --git a/lily/item.cc b/lily/item.cc index 1af1ef1a46..973a574c57 100644 --- a/lily/item.cc +++ b/lily/item.cc @@ -13,7 +13,7 @@ #include "paper-column.hh" #include "lily-guile.hh" #include "system.hh" -#include "group-interface.hh" +#include "pointer-group-interface.hh" Grob * Item::clone (int count) const @@ -25,7 +25,7 @@ Item::Item (SCM s, Object_key const *key) : Grob (s, key) { broken_to_drul_[LEFT] = broken_to_drul_[RIGHT] = 0; - Group_interface::add_thing (this, ly_symbol2scm ("interfaces"), ly_symbol2scm ("item-interface")); + interfaces_ = scm_cons (ly_symbol2scm ("item-interface"), interfaces_); } /** diff --git a/lily/ledger-line-engraver.cc b/lily/ledger-line-engraver.cc index 05ffa05b06..11c496b299 100644 --- a/lily/ledger-line-engraver.cc +++ b/lily/ledger-line-engraver.cc @@ -6,7 +6,7 @@ (c) 2004--2005 Han-Wen Nienhuys */ -#include "group-interface.hh" +#include "pointer-group-interface.hh" #include "spanner.hh" #include "engraver.hh" #include "staff-symbol.hh" diff --git a/lily/ledger-line-spanner.cc b/lily/ledger-line-spanner.cc index e56851fbe0..9e2a79a4aa 100644 --- a/lily/ledger-line-spanner.cc +++ b/lily/ledger-line-spanner.cc @@ -14,7 +14,7 @@ #include "staff-symbol.hh" #include "lookup.hh" #include "spanner.hh" -#include "group-interface.hh" +#include "pointer-group-interface.hh" #include "paper-column.hh" struct Ledger_line_spanner @@ -120,8 +120,6 @@ Ledger_line_spanner::set_spacing_rods (SCM smob) if (!staff) return SCM_EOL; - SCM heads = me->get_property ("note-heads"); - Real min_length_fraction = robust_scm2double (me->get_property ("minimum-length-fraction"), 0.15); @@ -130,14 +128,16 @@ Ledger_line_spanner::set_spacing_rods (SCM smob) Item *previous_column = 0; Item *current_column = 0; + int interspaces = Staff_symbol::line_count (staff) - 1; + /* - Run through heads using a loop. Since Legder_line_spanner can + Run through heads using a loop. Since Ledger_line_spanner can contain a lot of noteheads, superlinear performance is too slow. */ - int interspaces = Staff_symbol::line_count (staff) - 1; - for (SCM hp = heads; scm_is_pair (hp); hp = scm_cdr (hp)) + extract_item_set (me, "note-heads", heads); + for (int i = heads.size(); i --; ) { - Item *h = dynamic_cast (unsmob_grob (scm_car (hp))); + Item *h = heads[i]; int pos = Staff_symbol_referencer::get_rounded_position (h); if (abs (pos) <= interspaces) @@ -199,7 +199,8 @@ SCM Ledger_line_spanner::print (SCM smob) { Spanner *me = dynamic_cast (unsmob_grob (smob)); - Link_array heads (extract_grob_array (me, ly_symbol2scm ("note-heads"))); + + extract_grob_set (me, "note-heads", heads); if (heads.is_empty ()) return SCM_EOL; @@ -222,7 +223,7 @@ Ledger_line_spanner::print (SCM smob) Axis a = Axis (i); common[a] = common_refpoint_of_array (heads, me, a); for (int i = heads.size (); i--;) - if (Grob *g = unsmob_grob (me->get_property ("accidental-grob"))) + if (Grob *g = unsmob_grob (me->get_object ("accidental-grob"))) common[a] = common[a]->common_refpoint (g, a); } @@ -310,7 +311,7 @@ Ledger_line_spanner::print (SCM smob) ledger_size.intersect (max_size); Real left_shorten = 0.0; - if (Grob *g = unsmob_grob (h->get_property ("accidental-grob"))) + if (Grob *g = unsmob_grob (h->get_object ("accidental-grob"))) { Interval accidental_size = g->extent (common[X_AXIS], X_AXIS); Real d diff --git a/lily/lyric-extender.cc b/lily/lyric-extender.cc index cbe0362185..ad8b108e78 100644 --- a/lily/lyric-extender.cc +++ b/lily/lyric-extender.cc @@ -15,7 +15,7 @@ #include "paper-column.hh" #include "output-def.hh" #include "note-head.hh" -#include "group-interface.hh" +#include "pointer-group-interface.hh" MAKE_SCHEME_CALLBACK (Lyric_extender, print, 1) SCM @@ -23,7 +23,7 @@ Lyric_extender::print (SCM smob) { Spanner *me = unsmob_spanner (smob); Item *left_edge = me->get_bound (LEFT); - Item *right_text = unsmob_item (me->get_property ("next")); + Item *right_text = unsmob_item (me->get_object ("next")); Grob *common = left_edge; @@ -32,7 +32,8 @@ Lyric_extender::print (SCM smob) common = common->common_refpoint (me->get_bound (RIGHT), X_AXIS); Real sl = me->get_layout ()->get_dimension (ly_symbol2scm ("linethickness")); - Link_array heads (extract_grob_array (me, ly_symbol2scm ("heads"))); + + extract_grob_set (me, "heads", heads); if (!heads.size ()) return SCM_EOL; diff --git a/lily/mark-engraver.cc b/lily/mark-engraver.cc index 48e22c3465..a45c9c59bb 100644 --- a/lily/mark-engraver.cc +++ b/lily/mark-engraver.cc @@ -63,7 +63,7 @@ Mark_engraver::stop_translation_timestep () if (text_) { SCM lst = get_property ("stavesFound"); - text_->set_property ("side-support-elements", lst); + text_->set_object ("side-support-elements", lst); text_ = 0; } mark_ev_ = 0; diff --git a/lily/metronome-engraver.cc b/lily/metronome-engraver.cc index 897bb909fd..12020d306d 100644 --- a/lily/metronome-engraver.cc +++ b/lily/metronome-engraver.cc @@ -47,7 +47,7 @@ Metronome_mark_engraver::stop_translation_timestep () { Grob *mc = unsmob_grob (get_property ("currentMusicalColumn")); text_->set_parent (mc, X_AXIS); - text_->set_property ("side-support-elements", get_property ("stavesFound")); + text_->set_object ("side-support-elements", get_property ("stavesFound")); text_ = 0; } diff --git a/lily/music.cc b/lily/music.cc index a3a6deb437..465cfd6ae2 100644 --- a/lily/music.cc +++ b/lily/music.cc @@ -278,6 +278,19 @@ Music::internal_get_property (SCM sym) const return (s == SCM_BOOL_F) ? SCM_EOL : scm_cdr (s); } + +SCM +Music::internal_get_object (SCM s) const +{ + return internal_get_property (s); +} + +void +Music::internal_set_object (SCM s, SCM v) +{ + return internal_set_property (s,v); +} + void Music::internal_set_property (SCM s, SCM v) { diff --git a/lily/new-fingering-engraver.cc b/lily/new-fingering-engraver.cc index 7ae551bd82..a32d324f1f 100644 --- a/lily/new-fingering-engraver.cc +++ b/lily/new-fingering-engraver.cc @@ -94,7 +94,7 @@ New_fingering_engraver::acknowledge_grob (Grob_info inf) else if (m->is_mus_type ("harmonic-event")) { inf.grob ()->set_property ("style", ly_symbol2scm ("harmonic")); - Grob *d = unsmob_grob (inf.grob ()->get_property ("dot")); + Grob *d = unsmob_grob (inf.grob ()->get_object ("dot")); if (d) d->suicide (); } @@ -338,7 +338,7 @@ New_fingering_engraver::stop_translation_timestep () Side_position_interface::add_support (script, heads_[j]); if (stem_ && to_dir (script->get_property ("side-relative-direction"))) - script->set_property ("direction-source", stem_->self_scm ()); + script->set_object ("direction-source", stem_->self_scm ()); if (stem_ && to_boolean (script->get_property ("add-stem-support"))) Side_position_interface::add_support (script, stem_); diff --git a/lily/note-collision.cc b/lily/note-collision.cc index 3be575f661..9f2df90240 100644 --- a/lily/note-collision.cc +++ b/lily/note-collision.cc @@ -227,7 +227,7 @@ check_meshing_chords (Grob *me, if (dot_wipe_head) { - if (Grob *d = unsmob_grob (dot_wipe_head->get_property ("dot"))) + if (Grob *d = unsmob_grob (dot_wipe_head->get_object ("dot"))) d->suicide (); } @@ -260,7 +260,7 @@ check_meshing_chords (Grob *me, && Rhythmic_head::dot_count (nd) > Rhythmic_head::dot_count (nu) && (full_collide || close_half_collide)) { - Grob *d = unsmob_grob (nd->get_property ("dot")); + Grob *d = unsmob_grob (nd->get_object ("dot")); Grob *parent = d->get_parent (X_AXIS); /* @@ -341,17 +341,15 @@ Note_collision_interface::do_shifts (Grob *me) } } -Drul_array < Link_array -> Note_collision_interface::get_clash_groups (Grob *me) +Drul_array < Link_array > +Note_collision_interface::get_clash_groups (Grob *me) { Drul_array > clash_groups; - SCM s = me->get_property ("elements"); - for (; scm_is_pair (s); s = scm_cdr (s)) + extract_grob_set (me, "elements", elements); + for (int i = 0; i < elements.size (); i++) { - SCM car = scm_car (s); - - Grob *se = unsmob_grob (car); + Grob *se = elements[i]; if (Note_column::has_interface (se)) clash_groups[Note_column::dir (se)].push (se); } @@ -470,10 +468,10 @@ Note_collision_interface::forced_shift (Grob *me) { SCM tups = SCM_EOL; - SCM s = me->get_property ("elements"); - for (; scm_is_pair (s); s = scm_cdr (s)) + extract_grob_set (me, "elements", elements); + for (int i = 0; i < elements.size (); i++) { - Grob *se = unsmob_grob (scm_car (s)); + Grob *se = elements[i]; SCM force = se->get_property ("force-hshift"); if (scm_is_number (force)) diff --git a/lily/note-column.cc b/lily/note-column.cc index 61f7df05c5..787773019e 100644 --- a/lily/note-column.cc +++ b/lily/note-column.cc @@ -27,7 +27,7 @@ bool Note_column::has_rests (Grob *me) { - return unsmob_grob (me->get_property ("rest")); + return unsmob_grob (me->get_object ("rest")); } int @@ -44,7 +44,7 @@ Note_column::shift_compare (Grob *const &p1, Grob *const &p2) Item * Note_column::get_stem (Grob *me) { - SCM s = me->get_property ("stem"); + SCM s = me->get_object ("stem"); return unsmob_item (s); } @@ -55,10 +55,10 @@ Note_column::head_positions_interval (Grob *me) iv.set_empty (); - SCM h = me->get_property ("note-heads"); - for (; scm_is_pair (h); h = scm_cdr (h)) + extract_grob_set (me, "note-heads", heads); + for (int i = 0; i < heads.size(); i++) { - Grob *se = unsmob_grob (scm_car (h)); + Grob *se = heads[i]; int j = Staff_symbol_referencer::get_rounded_position (se); iv.unite (Slice (j, j)); @@ -69,10 +69,10 @@ Note_column::head_positions_interval (Grob *me) Direction Note_column::dir (Grob *me) { - Grob *stem = unsmob_grob (me->get_property ("stem")); + Grob *stem = unsmob_grob (me->get_object ("stem")); if (stem && Stem::has_interface (stem)) return Stem::get_direction (stem); - else if (scm_is_pair (me->get_property ("note-heads"))) + else if (scm_is_pair (me->get_object ("note-heads"))) return (Direction)sign (head_positions_interval (me).center ()); programming_error ("note column without heads and stem"); @@ -82,7 +82,7 @@ Note_column::dir (Grob *me) void Note_column::set_stem (Grob *me, Grob *stem) { - me->set_property ("stem", stem->self_scm ()); + me->set_object ("stem", stem->self_scm ()); me->add_dependency (stem); Axis_group_interface::add_element (me, stem); } @@ -90,7 +90,7 @@ Note_column::set_stem (Grob *me, Grob *stem) Grob * Note_column::get_rest (Grob *me) { - return unsmob_grob (me->get_property ("rest")); + return unsmob_grob (me->get_object ("rest")); } void @@ -99,14 +99,15 @@ Note_column::add_head (Grob *me, Grob *h) bool both = false; if (Rest::has_interface (h)) { - if (scm_is_pair (me->get_property ("note-heads"))) + extract_grob_set (me, "note-heads", heads); + if (heads.size ()) both = true; else - me->set_property ("rest", h->self_scm ()); + me->set_object ("rest", h->self_scm ()); } else if (Note_head::has_interface (h)) { - if (unsmob_grob (me->get_property ("rest"))) + if (unsmob_grob (me->get_object ("rest"))) both = true; Pointer_group_interface::add_grob (me, ly_symbol2scm ("note-heads"), h); } @@ -124,7 +125,7 @@ Note_column::add_head (Grob *me, Grob *h) void Note_column::translate_rests (Grob *me, int dy) { - Grob *r = unsmob_grob (me->get_property ("rest")); + Grob *r = unsmob_grob (me->get_object ("rest")); if (r && !scm_is_number (r->get_property ("staff-position"))) { r->translate_axis (dy * Staff_symbol_referencer::staff_space (r) / 2.0, Y_AXIS); @@ -152,12 +153,12 @@ Note_column::first_head (Grob *me) Grob * Note_column::accidentals (Grob *me) { - SCM heads = me->get_property ("note-heads"); + extract_grob_set (me, "note-heads", heads); Grob *acc = 0; - for (;scm_is_pair (heads); heads = scm_cdr (heads)) + for (int i = 0; i < heads.size(); i++) { - Grob *h = unsmob_grob (scm_car (heads)); - acc = h ? unsmob_grob (h->get_property ("accidental-grob")) : 0; + Grob *h = heads[i]; + acc = h ? unsmob_grob (h->get_object ("accidental-grob")) : 0; if (acc) break; } diff --git a/lily/note-head-line-engraver.cc b/lily/note-head-line-engraver.cc index 36af9534d2..555ac18ec1 100644 --- a/lily/note-head-line-engraver.cc +++ b/lily/note-head-line-engraver.cc @@ -7,7 +7,7 @@ */ #include "engraver.hh" -#include "group-interface.hh" +#include "pointer-group-interface.hh" #include "stem.hh" #include "rhythmic-head.hh" #include "side-position-interface.hh" diff --git a/lily/note-head.cc b/lily/note-head.cc index 67935a0a2d..abf3599ac2 100644 --- a/lily/note-head.cc +++ b/lily/note-head.cc @@ -48,7 +48,7 @@ internal_print (Grob *me, String *font_char) Font_metric *fm = Font_interface::get_default_font (me); Direction stem_dir = CENTER; - if (Grob *stem = unsmob_grob (me->get_property ("stem"))) + if (Grob *stem = unsmob_grob (me->get_object ("stem"))) { stem_dir = get_grob_direction (stem); if (stem_dir == CENTER) diff --git a/lily/note-spacing.cc b/lily/note-spacing.cc index 82640d4d62..4a089529f1 100644 --- a/lily/note-spacing.cc +++ b/lily/note-spacing.cc @@ -8,6 +8,7 @@ #include "note-spacing.hh" +#include "grob-array.hh" #include "paper-column.hh" #include "moment.hh" #include "note-column.hh" @@ -17,6 +18,8 @@ #include "staff-spacing.hh" #include "accidental-placement.hh" #include "output-def.hh" +#include "pointer-group-interface.hh" + /* TODO: detect hshifts due to collisions, and account for them in @@ -27,9 +30,8 @@ void Note_spacing::get_spacing (Grob *me, Item *right_col, Real base_space, Real increment, Real *space, Real *fixed) { - - Drul_array props (me->get_property ("left-items"), - me->get_property ("right-items")); + Drul_array props (me->get_object ("left-items"), + me->get_object ("right-items")); Direction d = LEFT; Direction col_dir = right_col->break_status_dir (); Drul_array extents; @@ -37,9 +39,10 @@ Note_spacing::get_spacing (Grob *me, Item *right_col, Interval left_head_wid; do { - for (SCM s = props[d]; scm_is_pair (s); s = scm_cdr (s)) + Link_array const &items (ly_scm2link_array (props [d])); + for (int i = items.size (); i--;) { - Item *it = dynamic_cast (unsmob_grob (scm_car (s))); + Item *it = dynamic_cast (items[i]); if (d == RIGHT && it->break_status_dir () != col_dir) { @@ -64,7 +67,7 @@ Note_spacing::get_spacing (Grob *me, Item *right_col, if (d == LEFT) { - SCM r = it->get_property ("rest"); + SCM r = it->get_object ("rest"); Grob *g = unsmob_grob (r); if (!g) g = Note_column::first_head (it); @@ -176,15 +179,15 @@ Note_spacing::right_column (Grob *me) if (!me->is_live ()) return 0; - SCM right = me->get_property ("right-items"); + Grob_array * a = unsmob_grob_array (me->get_object ("right-items")); Item *mincol = 0; int min_rank = INT_MAX; bool prune = false; - for (SCM s = right; scm_is_pair (s); s = scm_cdr (s)) + for (int i = 0; a && i < a->size (); i++) { - Item *ri = unsmob_item (scm_car (s)); - + Item *ri = a->item (i); Item *col = ri->get_column (); + int rank = Paper_column::get_rank (col); if (rank < min_rank) @@ -197,26 +200,18 @@ Note_spacing::right_column (Grob *me) } } - if (prune) + if (prune && a) { - // I'm a lazy bum. We could do this in-place. - SCM newright = SCM_EOL; - for (SCM s = right; scm_is_pair (s); s = scm_cdr (s)) + Link_array & right = a->array_reference (); + for (int i = right.size(); i--;) { - if (unsmob_item (scm_car (s))->get_column () == mincol) - newright = scm_cons (scm_car (s), newright); + if (dynamic_cast (right[i])->get_column () != mincol) + right.del (i); } - - me->set_property ("right-items", newright); } if (!mincol) { - /* - int r = Paper_column::get_rank (dynamic_cast(me)->get_column ()); - programming_error (_f ("Spacing wish column %d has no right item.", r)); - */ - return 0; } @@ -238,8 +233,8 @@ Note_spacing::stem_dir_correction (Grob *me, Item *rcolumn, Drul_array stem_dirs (CENTER, CENTER); Drul_array stem_posns; Drul_array head_posns; - Drul_array props (me->get_property ("left-items"), - me->get_property ("right-items")); + Drul_array props (me->get_object ("left-items"), + me->get_object ("right-items")); Drul_array beams_drul (0, 0); Drul_array stems_drul (0, 0); @@ -255,9 +250,10 @@ Note_spacing::stem_dir_correction (Grob *me, Item *rcolumn, do { - for (SCM s = props[d]; scm_is_pair (s); s = scm_cdr (s)) + Link_array const &items (ly_scm2link_array (props [d])); + for (int i = 0; i < items.size(); i++) { - Item *it = dynamic_cast (unsmob_grob (scm_car (s))); + Item *it = dynamic_cast (items[i]); if (d == RIGHT) acc_right = acc_right || Note_column::accidentals (it); diff --git a/lily/ottava-bracket.cc b/lily/ottava-bracket.cc index 4d6a148b4a..72f05cf592 100644 --- a/lily/ottava-bracket.cc +++ b/lily/ottava-bracket.cc @@ -19,6 +19,7 @@ #include "directional-element-interface.hh" #include "tuplet-bracket.hh" #include "rhythmic-head.hh" +#include "pointer-group-interface.hh" struct Ottava_bracket { @@ -52,11 +53,11 @@ Ottava_bracket::print (SCM smob) if (Note_column::has_interface (b)) { - SCM heads = b->get_property ("note-heads"); - common = common_refpoint_of_list (heads, common, X_AXIS); - for (SCM s = heads; scm_is_pair (s); s = scm_cdr (s)) + extract_grob_set (b, "note-heads", heads); + common = common_refpoint_of_array (heads, common, X_AXIS); + for (int i = 0; i < heads.size (); i++) { - Grob *h = unsmob_grob (scm_car (s)); + Grob *h = heads[i]; Grob *dots = Rhythmic_head::get_dots (h); if (dots) common = dots->common_refpoint (common, X_AXIS); @@ -85,9 +86,10 @@ Ottava_bracket::print (SCM smob) Interval ext; if (Note_column::has_interface (b)) { - for (SCM s = b->get_property ("note-heads"); scm_is_pair (s); s = scm_cdr (s)) + extract_grob_set (b, "note-heads", heads); + for (int i = 0; i < heads.size (); i++) { - Grob *h = unsmob_grob (scm_car (s)); + Grob *h = heads[i]; ext.unite (h->extent (common, X_AXIS)); Grob *dots = Rhythmic_head::get_dots (h); diff --git a/lily/paper-column.cc b/lily/paper-column.cc index a518e02c8f..991e58983f 100644 --- a/lily/paper-column.cc +++ b/lily/paper-column.cc @@ -17,6 +17,8 @@ #include "lookup.hh" #include "font-interface.hh" #include "output-def.hh" +#include "pointer-group-interface.hh" +#include "grob-array.hh" Grob * Paper_column::clone (int count) const @@ -103,8 +105,14 @@ Paper_column::is_musical (Grob *me) bool Paper_column::is_used (Grob *me) { - return scm_is_pair (me->get_property ("elements")) || Item::is_breakable (me) - || scm_is_pair (me->get_property ("bounded-by-me")); + extract_grob_set (me ,"elements", elts); + if (elts.size()) + return true; + + extract_grob_set (me ,"bounded-by-me", bbm); + if (bbm.size()) + return true; + return Item::is_breakable (me); } /* @@ -145,7 +153,8 @@ Paper_column::print (SCM p) /* This is all too hairy. We use bounded-by-me to make sure that some columns are kept "alive". Unfortunately, when spanners are suicided, - this falls apart again. (sigh.) + this falls apart again, because suicided spanners are still in + bounded-by-me THIS IS BROKEN KLUDGE. WE SHOULD INVENT SOMETHING BETTER. */ @@ -155,23 +164,22 @@ Paper_column::before_line_breaking (SCM grob) { Grob *me = unsmob_grob (grob); - SCM c = me->get_property ("bounded-by-me"); - SCM *ptrptr = &c; - - while (scm_is_pair (*ptrptr)) + SCM bbm = me->get_object ("bounded-by-me"); + Grob_array * ga = unsmob_grob_array (bbm); + if (!ga) + return SCM_UNSPECIFIED; + + Link_array &array (ga->array_reference ()); + + for (int i = array.size(); i--; ) { - Grob *g = unsmob_grob (scm_car (*ptrptr)); + Grob *g = array[i]; if (!g || !g->is_live ()) - { - *ptrptr = scm_cdr (*ptrptr); - } - else - { - ptrptr = SCM_CDRLOC (*ptrptr); + { // UGH . potentially quadratic. + array.del (i); } } - me->set_property ("bounded-by-me", c); return SCM_UNSPECIFIED; } diff --git a/lily/phrasing-slur-engraver.cc b/lily/phrasing-slur-engraver.cc index 5af17ec462..d4d064d451 100644 --- a/lily/phrasing-slur-engraver.cc +++ b/lily/phrasing-slur-engraver.cc @@ -102,7 +102,7 @@ Phrasing_slur_engraver::acknowledge_grob (Grob_info info) if (slur) { e->add_offset_callback (Slur::outside_slur_callback_proc, Y_AXIS); - e->set_property ("slur", slur->self_scm ()); + e->set_object ("slur", slur->self_scm ()); } } } diff --git a/lily/piano-pedal-bracket.cc b/lily/piano-pedal-bracket.cc index 75caaea3db..d11e670e78 100644 --- a/lily/piano-pedal-bracket.cc +++ b/lily/piano-pedal-bracket.cc @@ -34,7 +34,7 @@ Piano_pedal_bracket::print (SCM smob) Grob *common = me->get_bound (LEFT) ->common_refpoint (me->get_bound (RIGHT), X_AXIS); - Grob *textbit = unsmob_grob (me->get_property ("pedal-text")); + Grob *textbit = unsmob_grob (me->get_object ("pedal-text")); if (textbit) common = common->common_refpoint (textbit, X_AXIS); diff --git a/lily/piano-pedal-engraver.cc b/lily/piano-pedal-engraver.cc index c1c3bcb250..f6564f67b1 100644 --- a/lily/piano-pedal-engraver.cc +++ b/lily/piano-pedal-engraver.cc @@ -367,7 +367,7 @@ Piano_pedal_engraver::create_bracket_grobs (Pedal_info *p, bool mixed) WTF is pedal-text not the bound of the object? --hwn */ if (p->item_) - p->bracket_->set_property ("pedal-text", p->item_->self_scm ()); + p->bracket_->set_object ("pedal-text", p->item_->self_scm ()); } /* diff --git a/lily/pitched-trill-engraver.cc b/lily/pitched-trill-engraver.cc index 4651a4cc0d..2af1190d81 100644 --- a/lily/pitched-trill-engraver.cc +++ b/lily/pitched-trill-engraver.cc @@ -10,7 +10,7 @@ #include "engraver.hh" #include "dots.hh" -#include "group-interface.hh" +#include "pointer-group-interface.hh" #include "axis-group-interface.hh" #include "context.hh" #include "note-head.hh" @@ -109,7 +109,7 @@ Pitched_trill_engraver::make_trill (Music *mus) // fixme: naming -> alterations trill_accidental_->set_property ("accidentals", scm_list_1 (scm_from_int (p->get_alteration ()))); Side_position_interface::add_support (trill_accidental_, trill_head_); - trill_head_->set_property ("accidental-grob", trill_accidental_->self_scm ()); + trill_head_->set_object ("accidental-grob", trill_accidental_->self_scm ()); trill_group_->set_parent (trill_head_, Y_AXIS); Axis_group_interface::add_element (trill_group_, trill_accidental_); trill_accidental_->set_parent (trill_head_, Y_AXIS); diff --git a/lily/rest-collision.cc b/lily/rest-collision.cc index ea9dba5010..09aadd7a8e 100644 --- a/lily/rest-collision.cc +++ b/lily/rest-collision.cc @@ -16,7 +16,7 @@ #include "rhythmic-head.hh" #include "output-def.hh" #include "rest.hh" -#include "group-interface.hh" +#include "pointer-group-interface.hh" #include "staff-symbol-referencer.hh" #include "duration.hh" #include "directional-element-interface.hh" @@ -31,7 +31,7 @@ Rest_collision::force_shift_callback (SCM element_smob, SCM axis) if (Note_column::has_rests (them)) { - Grob *rc = unsmob_grob (them->get_property ("rest-collision")); + Grob *rc = unsmob_grob (them->get_object ("rest-collision")); if (rc && !to_boolean (rc->get_property ("positioning-done"))) { @@ -69,9 +69,9 @@ Rest_collision::add_column (Grob *me, Grob *p) (not?) */ p->add_offset_callback (Rest_collision::force_shift_callback_proc, Y_AXIS); - p->set_property ("rest-collision", me->self_scm ()); + p->set_object ("rest-collision", me->self_scm ()); - Grob *rest = unsmob_grob (p->get_property ("rest")); + Grob *rest = unsmob_grob (p->get_object ("rest")); if (rest) { rest->add_offset_callback (Rest_collision::force_shift_callback_rest_proc, @@ -86,7 +86,7 @@ Rest_collision::add_column (Grob *me, Grob *p) SCM Rest_collision::do_shift (Grob *me) { - SCM elts = me->get_property ("elements"); + SCM elts = me->get_object ("elements"); Link_array rests; Link_array notes; @@ -94,13 +94,13 @@ Rest_collision::do_shift (Grob *me) for (SCM s = elts; scm_is_pair (s); s = scm_cdr (s)) { Grob *e = unsmob_grob (scm_car (s)); - if (unsmob_grob (e->get_property ("rest"))) + if (unsmob_grob (e->get_object ("rest"))) { /* Ignore rests under beam. */ - Grob *st = unsmob_grob (e->get_property ("stem")); - if (st && unsmob_grob (st->get_property ("beam"))) + Grob *st = unsmob_grob (e->get_object ("stem")); + if (st && unsmob_grob (st->get_object ("beam"))) continue; rests.push (e); diff --git a/lily/rest.cc b/lily/rest.cc index 421ab1fdfe..d9c16d7327 100644 --- a/lily/rest.cc +++ b/lily/rest.cc @@ -37,7 +37,7 @@ Rest::after_line_breaking (SCM smob) me->translate_axis (ss / 2, Y_AXIS); } - Grob *d = unsmob_grob (me->get_property ("dot")); + Grob *d = unsmob_grob (me->get_object ("dot")); if (d && bt > 4) // UGH. { d->set_property ("staff-position", diff --git a/lily/rhythmic-column-engraver.cc b/lily/rhythmic-column-engraver.cc index af4f263aa1..3f059df4e2 100644 --- a/lily/rhythmic-column-engraver.cc +++ b/lily/rhythmic-column-engraver.cc @@ -11,7 +11,7 @@ #include "stem.hh" #include "note-column.hh" #include "dot-column.hh" -#include "group-interface.hh" +#include "pointer-group-interface.hh" /* this engraver glues together stems, rests and note heads into a NoteColumn @@ -75,7 +75,7 @@ Rhythmic_column_engraver::process_acknowledged_grobs () note_column_ = make_item ("NoteColumn", rheads_[0]->self_scm ()); spacing_ = make_item ("NoteSpacing", SCM_EOL); - spacing_->set_property ("left-items", scm_cons (note_column_->self_scm (), SCM_EOL)); + spacing_->set_object ("left-items", scm_cons (note_column_->self_scm (), SCM_EOL)); if (last_spacing_) { diff --git a/lily/rhythmic-head.cc b/lily/rhythmic-head.cc index 7c177452cf..27ad66cb8c 100644 --- a/lily/rhythmic-head.cc +++ b/lily/rhythmic-head.cc @@ -17,14 +17,14 @@ Item * Rhythmic_head::get_dots (Grob *me) { - SCM s = me->get_property ("dot"); + SCM s = me->get_object ("dot"); return unsmob_item (s); } Item * Rhythmic_head::get_stem (Grob *me) { - SCM s = me->get_property ("stem"); + SCM s = me->get_object ("stem"); return unsmob_item (s); } @@ -38,7 +38,7 @@ Rhythmic_head::dot_count (Grob *me) void Rhythmic_head::set_dots (Grob *me, Item *dot) { - me->set_property ("dot", dot->self_scm ()); + me->set_object ("dot", dot->self_scm ()); } int diff --git a/lily/score-engraver.cc b/lily/score-engraver.cc index 46d2078a42..985be103ae 100644 --- a/lily/score-engraver.cc +++ b/lily/score-engraver.cc @@ -173,7 +173,7 @@ Score_engraver::typeset_all () if (dynamic_cast (elem)) { if ((!elem->get_parent (X_AXIS) - || !unsmob_grob (elem->get_property ("axis-group-parent-X"))) + || !unsmob_grob (elem->get_object ("axis-group-parent-X"))) && elem != command_column_ && elem != musical_column_) { diff --git a/lily/script-column.cc b/lily/script-column.cc index 6c6f93a624..6e03fa6f72 100644 --- a/lily/script-column.cc +++ b/lily/script-column.cc @@ -10,7 +10,7 @@ #include "side-position-interface.hh" #include "warn.hh" -#include "group-interface.hh" +#include "pointer-group-interface.hh" void Script_column::add_staff_sided (Grob *me, Item *i) diff --git a/lily/script-engraver.cc b/lily/script-engraver.cc index 42a766b339..f6dec3a7c4 100644 --- a/lily/script-engraver.cc +++ b/lily/script-engraver.cc @@ -177,7 +177,7 @@ Script_engraver::acknowledge_grob (Grob_info info) Grob *e = scripts_[i].script_; if (to_dir (e->get_property ("side-relative-direction"))) - e->set_property ("direction-source", info.grob ()->self_scm ()); + e->set_object ("direction-source", info.grob ()->self_scm ()); /* FIXME: add dependency */ e->add_dependency (info.grob ()); diff --git a/lily/separating-group-spanner.cc b/lily/separating-group-spanner.cc index 1a02e6a5ea..d112fa3621 100644 --- a/lily/separating-group-spanner.cc +++ b/lily/separating-group-spanner.cc @@ -12,10 +12,13 @@ #include "paper-column.hh" #include "output-def.hh" #include "dimensions.hh" -#include "group-interface.hh" +#include "pointer-group-interface.hh" void -Separating_group_spanner::find_rods (Item *r, SCM next, Real padding) +Separating_group_spanner::find_rods (Item *r, + Link_array const &separators, + int idx, + Real padding) { /* @@ -24,12 +27,9 @@ Separating_group_spanner::find_rods (Item *r, SCM next, Real padding) most cases, the interesting L will just be the first entry of NEXT, making it linear in most of the cases. */ - if (Separation_item::width (r).is_empty ()) - return; - - for (; scm_is_pair (next); next = scm_cdr (next)) + for (; idx >= 0; idx--) { - Item *l = dynamic_cast (unsmob_grob (scm_car (next))); + Item *l = dynamic_cast (separators[idx]); Item *lb = l->find_prebroken_piece (RIGHT); if (lb) @@ -82,23 +82,23 @@ Separating_group_spanner::set_spacing_rods (SCM smob) */ Real padding = robust_scm2double (me->get_property ("padding"), 0.1); - for (SCM s = me->get_property ("elements"); scm_is_pair (s) && scm_is_pair (scm_cdr (s)); s = scm_cdr (s)) + extract_grob_set (me, "elements", elts); + for (int i = elts.size (); + i-- > 1; ) { - /* - Order of elements is reversed! - */ - SCM elt = scm_car (s); - Item *r = unsmob_item (elt); - + Item *r = dynamic_cast (elts[i]); if (!r) continue; + if (Separation_item::width (r).is_empty ()) + continue; + Item *rb = dynamic_cast (r->find_prebroken_piece (LEFT)); - find_rods (r, scm_cdr (s), padding); + find_rods (r, elts, i - 1, padding); if (rb) - find_rods (rb, scm_cdr (s), padding); + find_rods (rb, elts, i - 1, padding); } return SCM_UNSPECIFIED; diff --git a/lily/separating-line-group-engraver.cc b/lily/separating-line-group-engraver.cc index 50648340d2..b3bfe12aef 100644 --- a/lily/separating-line-group-engraver.cc +++ b/lily/separating-line-group-engraver.cc @@ -15,6 +15,7 @@ #include "note-spacing.hh" #include "accidental-placement.hh" #include "context.hh" +#include "grob-array.hh" struct Spacings { @@ -141,7 +142,8 @@ Separating_line_group_engraver::acknowledge_grob (Grob_info i) { Item *it = make_item ("StaffSpacing", SCM_EOL); current_spacings_.staff_spacing_ = it; - it->set_property ("left-items", scm_cons (break_item_->self_scm (), SCM_EOL)); + Pointer_group_interface::add_grob (it, ly_symbol2scm ("left-items"), + break_item_); if (int i = last_spacings_.note_spacings_.size ()) { @@ -152,8 +154,17 @@ Separating_line_group_engraver::acknowledge_grob (Grob_info i) } else if (last_spacings_.staff_spacing_) { - last_spacings_.staff_spacing_->set_property ("right-items", - scm_cons (break_item_->self_scm (), SCM_EOL)); + SCM ri = last_spacings_.staff_spacing_->get_object ("right-items"); + Grob_array *ga = unsmob_grob_array (ri); + if (!ga) + { + SCM ga_scm = Grob_array::make_array (); + last_spacings_.staff_spacing_->set_object ("right-items", ga_scm); + ga = unsmob_grob_array (ga_scm); + } + + ga->clear (); + ga->add (break_item_); } } } diff --git a/lily/separation-item.cc b/lily/separation-item.cc index 381647b945..97009d98c7 100644 --- a/lily/separation-item.cc +++ b/lily/separation-item.cc @@ -10,7 +10,7 @@ #include "paper-column.hh" #include "warn.hh" -#include "group-interface.hh" +#include "pointer-group-interface.hh" #include "accidental-placement.hh" void @@ -39,13 +39,10 @@ Separation_item::conditional_width (Grob *me, Grob *left) Item *item = dynamic_cast (me); Paper_column *pc = item->get_column (); - for (SCM s = me->get_property ("conditional-elements"); scm_is_pair (s); s = scm_cdr (s)) + extract_grob_set (me, "conditional-elements", elts); + for (int i = 0; i < elts.size (); i++) { - SCM elt = scm_car (s); - if (!unsmob_grob (elt)) - continue; - - Item *il = unsmob_item (elt); + Item *il = dynamic_cast (elts[i]); if (pc != il->get_column ()) { /* this shouldn't happen, but let's continue anyway. */ @@ -83,13 +80,10 @@ Separation_item::width (Grob *me) Paper_column *pc = item->get_column (); Interval w; - for (SCM s = me->get_property ("elements"); scm_is_pair (s); s = scm_cdr (s)) + extract_grob_set (me, "elements", elts); + for (int i = 0; i < elts.size (); i++) { - SCM elt = scm_car (s); - if (!unsmob_grob (elt)) - continue; - - Item *il = unsmob_item (elt); + Item *il = dynamic_cast (elts[i]); if (pc != il->get_column ()) { /* this shouldn't happen, but let's continue anyway. */ @@ -131,17 +125,18 @@ Separation_item::relative_width (Grob *me, Grob *common) sticking out at direction D. The x size is put in LAST_EXT */ Grob * -Separation_item::extremal_break_aligned_grob (Grob *separation_item, Direction d, +Separation_item::extremal_break_aligned_grob (Grob *me, + Direction d, Interval *last_ext) { - Grob *col = dynamic_cast (separation_item)->get_column (); + Grob *col = dynamic_cast (me)->get_column (); last_ext->set_empty (); Grob *last_grob = 0; - for (SCM s = separation_item->get_property ("elements"); - scm_is_pair (s); s = scm_cdr (s)) + + extract_grob_set (me, "elements", elts); + for (int i = elts.size (); i--; ) { - Grob *break_item = unsmob_grob (scm_car (s)); - + Grob *break_item = elts[i]; if (!scm_is_symbol (break_item->get_property ("break-align-symbol"))) continue; @@ -149,6 +144,7 @@ Separation_item::extremal_break_aligned_grob (Grob *separation_item, Direction d if (ext.is_empty ()) continue; + if (!last_grob || (last_grob && d * (ext[d]- (*last_ext)[d]) > 0)) { diff --git a/lily/side-position-interface.cc b/lily/side-position-interface.cc index d9689abaaa..fcdb0daf19 100644 --- a/lily/side-position-interface.cc +++ b/lily/side-position-interface.cc @@ -17,7 +17,7 @@ #include "warn.hh" #include "dimensions.hh" #include "staff-symbol-referencer.hh" -#include "group-interface.hh" +#include "pointer-group-interface.hh" #include "directional-element-interface.hh" #include "staff-symbol-referencer.hh" #include "string-convert.hh" @@ -44,7 +44,7 @@ Side_position_interface::get_direction (Grob *me) relative_dir = to_dir (reldir); } - SCM other_elt = me->get_property ("direction-source"); + SCM other_elt = me->get_object ("direction-source"); Grob *e = unsmob_grob (other_elt); if (e) { @@ -70,8 +70,10 @@ SCM Side_position_interface::general_side_position (Grob *me, Axis a, bool use_extents) { Real ss = Staff_symbol_referencer::staff_space (me); - SCM support = me->get_property ("side-support-elements"); - Grob *common = common_refpoint_of_list (support, me->get_parent (a), a); + + extract_grob_set (me, "side-support-elements", support); + + Grob *common = common_refpoint_of_array (support, me->get_parent (a), a); Grob *st = Staff_symbol_referencer::get_staff_symbol (me); bool include_staff = (st && a == Y_AXIS @@ -84,9 +86,9 @@ Side_position_interface::general_side_position (Grob *me, Axis a, bool use_exten dim = st->extent (common, Y_AXIS); } - for (SCM s = support; s != SCM_EOL; s = scm_cdr (s)) + for (int i = 0; i < support.size (); i++) { - Grob *e = unsmob_grob (scm_car (s)); + Grob *e = support[i]; if (e) if (use_extents) dim.unite (e->extent (common, a)); diff --git a/lily/simple-spacer.cc b/lily/simple-spacer.cc index fb15891542..a87846948b 100644 --- a/lily/simple-spacer.cc +++ b/lily/simple-spacer.cc @@ -385,7 +385,7 @@ Simple_spacer_wrapper::add_columns (Link_array const &icols) Link_array cols (icols); for (int i = cols.size (); i--;) - if (scm_is_pair (cols[i]->get_property ("between-cols"))) + if (scm_is_pair (cols[i]->get_object ("between-cols"))) { loose_cols_.push (cols[i]); cols.del (i); @@ -396,7 +396,7 @@ Simple_spacer_wrapper::add_columns (Link_array const &icols) { Spring_smob *spring = 0; - for (SCM s = cols[i]->get_property ("ideal-distances"); + for (SCM s = cols[i]->get_object ("ideal-distances"); !spring && scm_is_pair (s); s = scm_cdr (s)) { diff --git a/lily/slur-configuration.cc b/lily/slur-configuration.cc index b1a8013389..0cc546582b 100644 --- a/lily/slur-configuration.cc +++ b/lily/slur-configuration.cc @@ -14,7 +14,7 @@ #include "warn.hh" #include "misc.hh" #include "item.hh" -#include "group-interface.hh" +#include "pointer-group-interface.hh" #include "slur.hh" #include "slur-scoring.hh" #include "spanner.hh" diff --git a/lily/slur-engraver.cc b/lily/slur-engraver.cc index 2cdf5289c6..f87e78279d 100644 --- a/lily/slur-engraver.cc +++ b/lily/slur-engraver.cc @@ -100,7 +100,7 @@ Slur_engraver::acknowledge_grob (Grob_info info) if (slur) { e->add_offset_callback (Slur::outside_slur_callback_proc, Y_AXIS); - e->set_property ("slur", slur->self_scm ()); + e->set_object ("slur", slur->self_scm ()); } } } diff --git a/lily/slur-scoring.cc b/lily/slur-scoring.cc index 84a1beaf49..a5b81c0e95 100644 --- a/lily/slur-scoring.cc +++ b/lily/slur-scoring.cc @@ -14,7 +14,7 @@ #include "slur-configuration.hh" #include "beam.hh" #include "directional-element-interface.hh" -#include "group-interface.hh" +#include "pointer-group-interface.hh" #include "slur.hh" #include "note-column.hh" #include "output-def.hh" @@ -177,7 +177,7 @@ Slur_score_state::set_next_direction () Encompass_info Slur_score_state::get_encompass_info (Grob *col) const { - Grob *stem = unsmob_grob (col->get_property ("stem")); + Grob *stem = unsmob_grob (col->get_object ("stem")); Encompass_info ei; if (!stem) @@ -283,7 +283,7 @@ Slur_score_state::fill (Grob *me) { slur_ = dynamic_cast (me); columns_ - = extract_grob_array (me, ly_symbol2scm ("note-columns")); + = internal_extract_grob_array (me, ly_symbol2scm ("note-columns")); if (columns_.is_empty ()) { @@ -298,15 +298,16 @@ Slur_score_state::fill (Grob *me) dir_ = get_grob_direction (me); parameters_.fill (me); - SCM eltlist = me->get_property ("note-columns"); - SCM extra_list = me->get_property ("encompass-objects"); + extract_grob_set (me, "note-columns", columns); + extract_grob_set (me, "encompass-objects", extra_objects); + Spanner *sp = dynamic_cast (me); for (int i = X_AXIS; i < NO_AXES; i++) { Axis a = (Axis)i; - common_[a] = common_refpoint_of_list (eltlist, me, a); - common_[a] = common_refpoint_of_list (extra_list, common_[a], a); + common_[a] = common_refpoint_of_array (columns, me, a); + common_[a] = common_refpoint_of_array (extra_objects, common_[a], a); Direction d = LEFT; do @@ -644,8 +645,7 @@ Slur_score_state::generate_avoid_offsets () const avoid.push (Offset (inf.x_, y + dir_ * parameters_.free_head_distance_)); } - Link_array extra_encompasses - = extract_grob_array (slur_, ly_symbol2scm ("encompass-objects")); + extract_grob_set (slur_, "encompass-objects", extra_encompasses); for (int i = 0; i < extra_encompasses.size (); i++) if (Slur::has_interface (extra_encompasses[i])) { @@ -767,8 +767,7 @@ Slur_score_state::enumerate_attachments (Drul_array end_ys) const Array Slur_score_state::get_extra_encompass_infos () const { - Link_array encompasses - = extract_grob_array (slur_, ly_symbol2scm ("encompass-objects")); + extract_grob_set (slur_, "encompass-objects", encompasses); Array collision_infos; for (int i = encompasses.size (); i--;) { diff --git a/lily/slur.cc b/lily/slur.cc index dac80152cf..d218a54d19 100644 --- a/lily/slur.cc +++ b/lily/slur.cc @@ -15,7 +15,7 @@ #include "bezier.hh" #include "directional-element-interface.hh" #include "font-interface.hh" -#include "group-interface.hh" +#include "pointer-group-interface.hh" #include "lookup.hh" #include "main.hh" // DEBUG_SLUR_SCORING #include "note-column.hh" @@ -51,7 +51,8 @@ SCM Slur::print (SCM smob) { Grob *me = unsmob_grob (smob); - if (!scm_ilength (me->get_property ("note-columns"))) + extract_grob_set (me, "note-columns", encompasses); + if (encompasses.is_empty ()) { me->suicide (); return SCM_EOL; @@ -131,7 +132,7 @@ Slur::outside_slur_callback (SCM grob, SCM axis) (void) a; assert (a == Y_AXIS); - Grob *slur = unsmob_grob (script->get_property ("slur")); + Grob *slur = unsmob_grob (script->get_object ("slur")); if (!slur) return scm_from_int (0); @@ -198,8 +199,7 @@ Slur::outside_slur_callback (SCM grob, SCM axis) static Direction get_default_dir (Grob *me) { - Link_array encompasses - = extract_grob_array (me, ly_symbol2scm ("note-columns")); + extract_grob_set (me, "note-columns", encompasses); Direction d = DOWN; for (int i = 0; i < encompasses.size (); i++) @@ -218,7 +218,8 @@ SCM Slur::after_line_breaking (SCM smob) { Spanner *me = dynamic_cast (unsmob_grob (smob)); - if (!scm_ilength (me->get_property ("note-columns"))) + extract_grob_set (me, "note-columns", encompasses); + if (encompasses.is_empty ()) { me->suicide (); return SCM_UNSPECIFIED; diff --git a/lily/spaceable-grob.cc b/lily/spaceable-grob.cc index 4149e48b32..19ad14326c 100644 --- a/lily/spaceable-grob.cc +++ b/lily/spaceable-grob.cc @@ -13,12 +13,13 @@ #include "warn.hh" #include "spring.hh" -#include "group-interface.hh" +#include "pointer-group-interface.hh" +#include "grob.hh" SCM Spaceable_grob::get_minimum_distances (Grob *me) { - return me->get_property ("minimum-distances"); + return me->get_object ("minimum-distances"); } /*todo: merge code of spring & rod? @@ -47,7 +48,7 @@ Spaceable_grob::add_rod (Grob *me, Grob *p, Real d) } mins = scm_cons (scm_cons (p->self_scm (), newdist), mins); - me->set_property ("minimum-distances", mins); + me->set_object ("minimum-distances", mins); } void @@ -70,7 +71,7 @@ Spaceable_grob::add_spring (Grob *me, Grob *p, Real d, Real inverse_strength) } #ifndef NDEBUG - SCM mins = me->get_property ("ideal-distances"); + SCM mins = me->get_object ("ideal-distances"); for (SCM s = mins; scm_is_pair (s); s = scm_cdr (s)) { Spring_smob *sp = unsmob_spring (scm_car (s)); @@ -87,15 +88,17 @@ Spaceable_grob::add_spring (Grob *me, Grob *p, Real d, Real inverse_strength) spring.distance_ = d; spring.other_ = p; - Group_interface::add_thing (me, ly_symbol2scm ("ideal-distances"), spring.smobbed_copy ()); + SCM ideal = me->get_object ("ideal-distances"); + ideal = scm_cons (spring.smobbed_copy (), ideal); + me->set_object ("ideal-distances", ideal); } void Spaceable_grob::remove_interface (Grob *me) { - me->set_property ("minimum-distances", SCM_EOL); - me->set_property ("spacing-wishes", SCM_EOL); - me->set_property ("ideal-distances", SCM_EOL); + me->set_object ("minimum-distances", SCM_EOL); + me->set_object ("spacing-wishes", SCM_EOL); + me->set_object ("ideal-distances", SCM_EOL); } ADD_INTERFACE (Spaceable_grob, "spaceable-grob-interface", diff --git a/lily/spacing-engraver.cc b/lily/spacing-engraver.cc index 4aeebc586a..5637e33551 100644 --- a/lily/spacing-engraver.cc +++ b/lily/spacing-engraver.cc @@ -11,7 +11,7 @@ #include "pqueue.hh" #include "note-spacing.hh" #include "staff-spacing.hh" -#include "group-interface.hh" +#include "pointer-group-interface.hh" #include "spanner.hh" struct Rhythmic_tuple diff --git a/lily/spacing-loose-columns.cc b/lily/spacing-loose-columns.cc index 830657e6f9..e97547d602 100644 --- a/lily/spacing-loose-columns.cc +++ b/lily/spacing-loose-columns.cc @@ -6,10 +6,12 @@ (c) 2005 Han-Wen Nienhuys */ + #include "system.hh" #include "paper-column.hh" #include "column-x-positions.hh" #include "staff-spacing.hh" +#include "pointer-group-interface.hh" /* Find the loose columns in POSNS, and drape them around the columns specified in BETWEEN-COLS. */ @@ -30,7 +32,7 @@ set_loose_columns (System *which, Column_x_positions const *posns) Item *right = 0; while (1) { - SCM between = loose->get_property ("between-cols"); + SCM between = loose->get_object ("between-cols"); if (!scm_is_pair (between)) break; @@ -59,9 +61,11 @@ set_loose_columns (System *which, Column_x_positions const *posns) int count = 0; Real total_space = 0.0; Real total_fixed = 0.0; - for (SCM wish = col->get_property ("spacing-wishes"); scm_is_pair (wish); wish = scm_cdr (wish)) + + extract_grob_set (col, "spacing-wishes", wishes); + for (int i = 0; i < wishes.size (); i++) { - Grob *spacing = unsmob_grob (scm_car (wish)); + Grob *spacing = wishes[i]; if (Staff_spacing::has_interface (spacing)) { Real space = 0.0; diff --git a/lily/spacing-spanner.cc b/lily/spacing-spanner.cc index a9d9a500a8..541704eef7 100644 --- a/lily/spacing-spanner.cc +++ b/lily/spacing-spanner.cc @@ -25,6 +25,8 @@ #include "spaceable-grob.hh" #include "break-align-interface.hh" #include "spacing-interface.hh" +#include "pointer-group-interface.hh" +#include "grob-array.hh" /* TODO: this file/class is too complex. Should figure out how to chop @@ -45,8 +47,8 @@ public: static void find_loose_columns () {} static void prune_loose_columns (Grob *, Link_array *cols, Rational); static void find_loose_columns (Link_array cols); - static void set_explicit_neighbor_columns (Link_array cols); - static void set_implicit_neighbor_columns (Link_array cols); + static void set_explicit_neighbor_columns (Link_array const &cols); + static void set_implicit_neighbor_columns (Link_array const &cols); static void do_measure (Rational, Grob *me, Link_array *cols); static void musical_column_spacing (Grob *, Item *, Item *, Real, Rational); DECLARE_SCHEME_CALLBACK (set_springs, (SCM)); @@ -66,9 +68,9 @@ public: static bool loose_column (Grob *l, Grob *c, Grob *r) { - SCM rns = c->get_property ("right-neighbors"); - SCM lns = c->get_property ("left-neighbors"); - + extract_grob_set (c, "right-neighbors", rns); + extract_grob_set (c, "left-neighbors", lns); + /* If this column doesn't have a proper neighbor, we should really make it loose, but spacing it correctly is more than we can @@ -90,11 +92,11 @@ loose_column (Grob *l, Grob *c, Grob *r) such a borderline case.) */ - if (!scm_is_pair (lns) || !scm_is_pair (rns)) + if (lns.is_empty () || rns.is_empty ()) return false; - Item *l_neighbor = dynamic_cast (unsmob_grob (scm_car (lns))); - Item *r_neighbor = dynamic_cast (unsmob_grob (scm_car (rns))); + Item *l_neighbor = dynamic_cast (lns[0]); + Item *r_neighbor = dynamic_cast (rns[0]); if (!l_neighbor || !r_neighbor) return false; @@ -120,19 +122,21 @@ loose_column (Grob *l, Grob *c, Grob *r) } /* - A rather hairy check, but we really only want to move around clefs. (anything else?) + A rather hairy check, but we really only want to move around + clefs. (anything else?) in any case, we don't want to move bar lines. */ - for (SCM e = c->get_property ("elements"); scm_is_pair (e); e = scm_cdr (e)) + extract_grob_set (c, "elements", elts); + for (int i = elts.size (); i--; ) { - Grob *g = unsmob_grob (scm_car (e)); + Grob *g = elts[i]; if (g && Break_align_interface::has_interface (g)) { - for (SCM s = g->get_property ("elements"); scm_is_pair (s); - s = scm_cdr (s)) + extract_grob_set (g, "elements", gelts); + for (int j = gelts.size (); j--; ) { - Grob *h = unsmob_grob (scm_car (s)); + Grob *h = gelts[j]; /* ugh. -- fix staff-bar name? @@ -167,19 +171,20 @@ Spacing_spanner::prune_loose_columns (Grob *me, Link_array *cols, Rational Grob *c = cols->elem (i); if (loose_column (cols->elem (i - 1), c, cols->elem (i + 1))) { - SCM lns = c->get_property ("left-neighbors"); - lns = scm_is_pair (lns) ? scm_car (lns) : SCM_BOOL_F; - - SCM rns = c->get_property ("right-neighbors"); - rns = scm_is_pair (rns) ? scm_car (rns) : SCM_BOOL_F; - + extract_grob_set (c, "right-neighbors", rns_arr); + extract_grob_set (c, "left-neighbors", lns_arr); + + SCM lns = lns_arr.size () ? lns_arr.top()->self_scm () : SCM_BOOL_F; + SCM rns = rns_arr.size () ? rns_arr.top()->self_scm () : SCM_BOOL_F; + /* Either object can be non existent, if the score ends prematurely. */ - rns = scm_car (unsmob_grob (rns)->get_property ("right-items")); - c->set_property ("between-cols", scm_cons (lns, - rns)); + + rns = scm_car (unsmob_grob (rns)->get_object ("right-items")); + c->set_object ("between-cols", scm_cons (lns, + rns)); /* Set distance constraints for loose columns @@ -196,10 +201,11 @@ Spacing_spanner::prune_loose_columns (Grob *me, Link_array *cols, Rational Item *lc = dynamic_cast ((d == LEFT) ? next_door[LEFT] : c); Item *rc = dynamic_cast (d == LEFT ? c : next_door[RIGHT]); - for (SCM s = lc->get_property ("spacing-wishes"); - scm_is_pair (s); s = scm_cdr (s)) + + extract_grob_set (lc, "spacing-wishes", wishes); + for (int k = wishes.size(); k--;) { - Grob *sp = unsmob_grob (scm_car (s)); + Grob *sp = wishes[k]; if (Note_spacing::left_column (sp) != lc || Note_spacing::right_column (sp) != rc) continue; @@ -254,18 +260,18 @@ Spacing_spanner::prune_loose_columns (Grob *me, Link_array *cols, Rational Set neighboring columns determined by the spacing-wishes grob property. */ void -Spacing_spanner::set_explicit_neighbor_columns (Link_array cols) +Spacing_spanner::set_explicit_neighbor_columns (Link_array const &cols) { for (int i = 0; i < cols.size (); i++) { - SCM right_neighbors = SCM_EOL; + SCM right_neighbors = Grob_array::make_array (); + Grob_array *rn_arr = unsmob_grob_array (right_neighbors); int min_rank = 100000; // inf. - - SCM wishes = cols[i]->get_property ("spacing-wishes"); - for (SCM s = wishes; scm_is_pair (s); s = scm_cdr (s)) + extract_grob_set (cols[i], "spacing-wishes", wishes); + for (int k = wishes.size(); k--;) { - Item *wish = dynamic_cast (unsmob_grob (scm_car (s))); + Item *wish = dynamic_cast ( wishes[k]); Item *lc = wish->get_column (); Grob *right = Note_spacing::right_column (wish); @@ -287,34 +293,38 @@ Spacing_spanner::set_explicit_neighbor_columns (Link_array cols) right_neighbors = SCM_EOL; min_rank = right_rank; - right_neighbors = scm_cons (wish->self_scm (), right_neighbors); + rn_arr->add (wish); } /* update the right column of the wish. */ int maxrank = 0; - SCM left_neighs = rc->get_property ("left-neighbors"); - if (scm_is_pair (left_neighs) - && unsmob_grob (scm_car (left_neighs))) + + extract_grob_set (rc, "left-neighbors", lns_arr); + if (lns_arr.size ()) { - Item *it = dynamic_cast (unsmob_grob (scm_car (left_neighs))); + Item *it = dynamic_cast (lns_arr.top()); maxrank = Paper_column::get_rank (it->get_column ()); } if (left_rank >= maxrank) { + if (left_rank > maxrank) - left_neighs = SCM_EOL; + { + Grob_array *ga = unsmob_grob_array (rc->get_object ("left-neighbors")); + if (ga) + ga->clear (); + } - left_neighs = scm_cons (wish->self_scm (), left_neighs); - rc->set_property ("left-neighbors", right_neighbors); + Pointer_group_interface::add_grob (rc, ly_symbol2scm ("left-neighbors"), wish); } } - if (scm_is_pair (right_neighbors)) + if (rn_arr->size ()) { - cols[i]->set_property ("right-neighbors", right_neighbors); + cols[i]->set_object ("right-neighbors", right_neighbors); } } } @@ -324,7 +334,7 @@ Spacing_spanner::set_explicit_neighbor_columns (Link_array cols) yet. Only do breakable non-musical columns, and musical columns. */ void -Spacing_spanner::set_implicit_neighbor_columns (Link_array cols) +Spacing_spanner::set_implicit_neighbor_columns (Link_array const &cols) { for (int i = 0; i < cols.size (); i++) { @@ -335,18 +345,23 @@ Spacing_spanner::set_implicit_neighbor_columns (Link_array cols) // it->breakable || it->musical /* - sloppy with typnig left/right-neighbors should take list, but paper-column found instead. + sloppy with typing left/right-neighbors should take list, but paper-column found instead. */ - SCM ln = cols[i]->get_property ("left-neighbors"); - if (!scm_is_pair (ln) && i) + extract_grob_set (cols[i], "left-neighbors", lns); + if (lns.is_empty () && i ) { - cols[i]->set_property ("left-neighbors", scm_cons (cols[i - 1]->self_scm (), SCM_EOL)); + SCM ga_scm = Grob_array::make_array(); + Grob_array *ga = unsmob_grob_array (ga_scm); + ga->add (cols[i-1]); + cols[i]->set_object ("left-neighbors", ga_scm); } - - SCM rn = cols[i]->get_property ("right-neighbors"); - if (!scm_is_pair (rn) && i < cols.size () - 1) + extract_grob_set (cols[i], "right-neighbors", rns); + if (rns.is_empty () && i < cols.size () - 1) { - cols[i]->set_property ("right-neighbors", scm_cons (cols[i + 1]->self_scm (), SCM_EOL)); + SCM ga_scm = Grob_array::make_array(); + Grob_array *ga = unsmob_grob_array (ga_scm); + ga->add (cols[i+1]); + cols[i]->set_object ("right-neighbors", ga_scm); } } } @@ -549,7 +564,7 @@ Spacing_spanner::musical_column_spacing (Grob *me, Item *lc, Item *rc, Real incr Real compound_fixed_note_space = 0.0; int wish_count = 0; - SCM seq = lc->get_property ("right-neighbors"); + SCM seq = lc->get_object ("right-neighbors"); /* We adjust the space following a note only if the next note @@ -713,7 +728,7 @@ Spacing_spanner::breakable_column_spacing (Grob *me, Item *l, Item *r, Moment sh if (dt == Moment (0, 0)) { - for (SCM s = l->get_property ("spacing-wishes"); + for (SCM s = l->get_object ("spacing-wishes"); scm_is_pair (s); s = scm_cdr (s)) { Item *spacing_grob = dynamic_cast (unsmob_grob (scm_car (s))); @@ -765,11 +780,6 @@ Spacing_spanner::breakable_column_spacing (Grob *me, Item *l, Item *r, Moment sh assert (!isinf (compound_space)); compound_space = max (compound_space, compound_fixed); - /* - Hmm. we do 1/0 in the next thing. Perhaps we should check if this - works on all architectures. - */ - /* There used to be code that changed spacing depending on raggedright setting. Ugh. diff --git a/lily/span-arpeggio-engraver.cc b/lily/span-arpeggio-engraver.cc index 8495a2f5fe..5f77670b3f 100644 --- a/lily/span-arpeggio-engraver.cc +++ b/lily/span-arpeggio-engraver.cc @@ -10,7 +10,7 @@ #include "engraver.hh" #include "arpeggio.hh" -#include "group-interface.hh" +#include "pointer-group-interface.hh" #include "side-position-interface.hh" #include "staff-symbol-referencer.hh" @@ -74,20 +74,23 @@ Span_arpeggio_engraver::stop_translation_timestep () we do this very late, to make sure we also catch `extra' side-pos support like accidentals. */ - for (int i = 0; i < arpeggios_.size (); i++) + for (int j = 0; j < arpeggios_.size (); j++) { - for (SCM s = arpeggios_[i]->get_property ("stems"); - scm_is_pair (s); s = scm_cdr (s)) - Group_interface::add_thing (span_arpeggio_, ly_symbol2scm ("stems"), scm_car (s)); - for (SCM s = arpeggios_[i]->get_property ("side-support-elements"); - scm_is_pair (s); s = scm_cdr (s)) - Group_interface::add_thing (span_arpeggio_, ly_symbol2scm ("side-support-elements"), scm_car (s)); + extract_grob_set (arpeggios_[j], "stems", stems); + for (int i = stems.size() ; i--;) + Pointer_group_interface::add_grob (span_arpeggio_, ly_symbol2scm ("stems"), + stems[i]); + + extract_grob_set (arpeggios_[j], "side-support-elements", sses); + for (int i = sses.size() ; i--;) + Pointer_group_interface::add_grob (span_arpeggio_, ly_symbol2scm ("side-support-elements"), + sses[i]); /* we can't kill the children, since we don't want to the previous note to bump into the span arpeggio; so we make it transparent. */ - arpeggios_[i]->set_property ("print-function", SCM_EOL); + arpeggios_[j]->set_property ("print-function", SCM_EOL); } span_arpeggio_ = 0; diff --git a/lily/span-bar.cc b/lily/span-bar.cc index 548961d8ef..261791f1d0 100644 --- a/lily/span-bar.cc +++ b/lily/span-bar.cc @@ -15,6 +15,7 @@ #include "warn.hh" #include "axis-group-interface.hh" #include "bar-line.hh" +#include "grob.hh" void Span_bar::add_bar (Grob *me, Grob *b) @@ -28,7 +29,7 @@ MAKE_SCHEME_CALLBACK (Span_bar, print, 1); /* Limitations/Bugs: -(1) Elements from 'me->get_property ("elements")' must be +(1) Elements from 'me->get_object ("elements")' must be ordered according to their y coordinates relative to their common axis group parent. Otherwise, the computation goes mad. @@ -43,9 +44,9 @@ SCM Span_bar::print (SCM smobbed_me) { Grob *me = unsmob_grob (smobbed_me); - SCM elements = me->get_property ("elements"); + extract_grob_set (me, "elements", elements); + Grob *refp = common_refpoint_of_array (elements, me, Y_AXIS); - Grob *refp = common_refpoint_of_list (elements, me, Y_AXIS); Span_bar::evaluate_glyph (me); SCM glyph = me->get_property ("glyph"); @@ -59,9 +60,9 @@ Span_bar::print (SCM smobbed_me) /* compose span_bar_mol */ Array extents; Grob *model_bar = 0; - for (SCM elts = elements; scm_is_pair (elts); elts = scm_cdr (elts)) + for (int i = elements.size (); i--;) { - Grob *bar = unsmob_grob (scm_car (elts)); + Grob *bar = elements[i]; Interval ext = bar->extent (refp, Y_AXIS); if (ext.is_empty ()) continue; @@ -168,7 +169,9 @@ Span_bar::evaluate_empty (Grob *me) /* TODO: filter all hara-kiried out of ELEMENS list, and then optionally do suicide. Call this cleanage function from center_on_spanned_callback () as well. */ - if (!scm_is_pair (me->get_property ("elements"))) + + extract_grob_set (me, "elements", elements); + if (elements.is_empty ()) { me->suicide (); } @@ -182,11 +185,11 @@ Span_bar::evaluate_glyph (Grob *me) if (scm_is_string (gl)) return; - for (SCM s = me->get_property ("elements"); - !scm_is_string (gl) && scm_is_pair (s); s = scm_cdr (s)) + extract_grob_set (me, "elements", elements); + for (int i = elements.size(); + i-- && !scm_is_string (gl); ) { - gl = unsmob_grob (scm_car (s)) - ->get_property ("glyph"); + gl = elements[i]->get_property ("glyph"); } if (!scm_is_string (gl)) diff --git a/lily/spanner.cc b/lily/spanner.cc index adaa648a14..776f4097d1 100644 --- a/lily/spanner.cc +++ b/lily/spanner.cc @@ -10,7 +10,7 @@ #include -#include "group-interface.hh" +#include "pointer-group-interface.hh" #include "libc-extension.hh" #include "paper-column.hh" #include "paper-column.hh" @@ -210,7 +210,7 @@ Spanner::Spanner (SCM s, Object_key const *key) spanned_drul_[LEFT] = 0; spanned_drul_[RIGHT] = 0; - Group_interface::add_thing (this, ly_symbol2scm ("interfaces"), ly_symbol2scm ("spanner-interface")); + interfaces_ = scm_cons (ly_symbol2scm ("spanner-interface"), interfaces_); } Spanner::Spanner (Spanner const &s, int count) @@ -255,7 +255,7 @@ Spanner::find_broken_piece (System *l) const int Spanner::compare (Spanner *const &p1, Spanner *const &p2) { - return p1->get_system ()->rank_ - p2->get_system ()->rank_; + return p1->get_system ()->get_rank() - p2->get_system ()->get_rank(); } bool @@ -293,11 +293,13 @@ Spanner::get_broken_left_end_align () const SCM Spanner::do_derived_mark () const { +#if 0 /* We'd be fucked if this is called before spanned_drul_[] is inited. */ if (status_ == ORPHAN) return SCM_EOL; - +#endif + Direction d = LEFT; do if (spanned_drul_[d]) diff --git a/lily/staff-spacing.cc b/lily/staff-spacing.cc index 762e039dc1..c4ec3b14d6 100644 --- a/lily/staff-spacing.cc +++ b/lily/staff-spacing.cc @@ -18,6 +18,7 @@ #include "note-column.hh" #include "stem.hh" #include "accidental-placement.hh" +#include "pointer-group-interface.hh" /* Insert some more space for the next note, in case it has a stem in @@ -49,7 +50,7 @@ Staff_spacing::next_note_correction (Grob *me, max_corr = max (max_corr, (- v[LEFT])); } - if (Grob *a = unsmob_grob (g->get_property ("arpeggio"))) + if (Grob *a = unsmob_grob (g->get_object ("arpeggio"))) { max_corr = max (max_corr, - a->extent (col, X_AXIS)[LEFT]); } @@ -123,15 +124,16 @@ Staff_spacing::next_notes_correction (Grob *me, Grob *last_grob) Interval bar_size = bar_y_positions (last_grob); Real max_corr = 0.0; - for (SCM s = me->get_property ("right-items"); - scm_is_pair (s); s = scm_cdr (s)) + + extract_grob_set (me, "right-items", right_items); + for (int i = right_items.size (); i--;) { - Grob *g = unsmob_grob (scm_car (s)); + Grob *g = right_items[i]; max_corr = max (max_corr, next_note_correction (me, g, bar_size)); - for (SCM t = g->get_property ("elements"); - scm_is_pair (t); t = scm_cdr (t)) - max_corr = max (max_corr, next_note_correction (me, unsmob_grob (scm_car (t)), bar_size)); + extract_grob_set (g, "elements", elts); + for (int j = elts.size(); j--;) + max_corr = max (max_corr, next_note_correction (me, elts[j], bar_size)); } return max_corr; @@ -146,10 +148,10 @@ Staff_spacing::get_spacing_params (Grob *me, Real *space, Real *fixed) Grob *separation_item = 0; Item *me_item = dynamic_cast (me); - for (SCM s = me->get_property ("left-items"); - scm_is_pair (s); s = scm_cdr (s)) + extract_grob_set (me, "left-items", items); + for (int i = items.size(); i--;) { - Grob *cand = unsmob_grob (scm_car (s)); + Grob *cand = items[i]; if (cand && Separation_item::has_interface (cand)) separation_item = cand; } diff --git a/lily/staff-symbol-engraver.cc b/lily/staff-symbol-engraver.cc index 5bc33f68db..8725390805 100644 --- a/lily/staff-symbol-engraver.cc +++ b/lily/staff-symbol-engraver.cc @@ -104,7 +104,7 @@ Staff_symbol_engraver::acknowledge_grob (Grob_info s) if (span_ || finished_span_ ) { Spanner *my = span_ ? span_ : finished_span_; - s.grob ()->set_property ("staff-symbol", my->self_scm ()); + s.grob ()->set_object ("staff-symbol", my->self_scm ()); } } diff --git a/lily/staff-symbol-referencer.cc b/lily/staff-symbol-referencer.cc index 3bc52e10d6..ef0690fc32 100644 --- a/lily/staff-symbol-referencer.cc +++ b/lily/staff-symbol-referencer.cc @@ -44,7 +44,7 @@ Staff_symbol_referencer::get_staff_symbol (Grob *me) if (Staff_symbol::has_interface (me)) return me; - SCM st = me->get_property ("staff-symbol"); + SCM st = me->get_object ("staff-symbol"); return unsmob_grob (st); } diff --git a/lily/stanza-number-align-engraver.cc b/lily/stanza-number-align-engraver.cc index 52b18cbe11..0c9e40b6e2 100644 --- a/lily/stanza-number-align-engraver.cc +++ b/lily/stanza-number-align-engraver.cc @@ -11,7 +11,7 @@ #include "engraver.hh" #include "note-head.hh" #include "lyric-extender.hh" -#include "group-interface.hh" +#include "pointer-group-interface.hh" #include "side-position-interface.hh" class Stanza_number_align_engraver : public Engraver diff --git a/lily/stem-engraver.cc b/lily/stem-engraver.cc index a469c78cb1..36e7661242 100644 --- a/lily/stem-engraver.cc +++ b/lily/stem-engraver.cc @@ -100,8 +100,8 @@ Stem_engraver::make_stem (Grob_info gi) tremolo-type minus the number of flags of the note itself. */ tremolo_->set_property ("flag-count", scm_int2num (tremolo_flags)); tremolo_->set_parent (stem_, X_AXIS); - stem_->set_property ("tremolo-flag", tremolo_->self_scm ()); - tremolo_->set_property ("stem", stem_->self_scm ()); + stem_->set_object ("tremolo-flag", tremolo_->self_scm ()); + tremolo_->set_object ("stem", stem_->self_scm ()); } } } diff --git a/lily/stem-tremolo.cc b/lily/stem-tremolo.cc index b1daa6284b..dc7bc03573 100644 --- a/lily/stem-tremolo.cc +++ b/lily/stem-tremolo.cc @@ -52,7 +52,7 @@ Stem_tremolo::height (SCM smob, SCM ax) Stencil Stem_tremolo::raw_stencil (Grob *me) { - Grob *stem = unsmob_grob (me->get_property ("stem")); + Grob *stem = unsmob_grob (me->get_object ("stem")); Spanner *beam = Stem::get_beam (stem); Real dydx; if (beam) @@ -112,7 +112,7 @@ SCM Stem_tremolo::print (SCM grob) { Grob *me = unsmob_grob (grob); - Grob *stem = unsmob_grob (me->get_property ("stem")); + Grob *stem = unsmob_grob (me->get_object ("stem")); if (!stem) { programming_error ("no stem for stem-tremolo"); diff --git a/lily/stem.cc b/lily/stem.cc index 2bdc2fbcf5..4dc00e7bf3 100644 --- a/lily/stem.cc +++ b/lily/stem.cc @@ -28,7 +28,7 @@ #include "misc.hh" #include "beam.hh" #include "rest.hh" -#include "group-interface.hh" +#include "pointer-group-interface.hh" #include "staff-symbol-referencer.hh" #include "side-position-interface.hh" #include "dot-column.hh" @@ -131,9 +131,10 @@ Stem::set_stemend (Grob *me, Real se) Grob * Stem::support_head (Grob *me) { - if (head_count (me) == 1) - /* UGH. */ - return unsmob_grob (scm_car (me->get_property ("note-heads"))); + extract_grob_set (me, "note-heads", heads); + if (heads.size () == 1) + return heads[0]; + return first_head (me); } @@ -178,10 +179,11 @@ Stem::extremal_heads (Grob *me) extpos[UP] = -inf; Drul_array exthead (0, 0); - for (SCM s = me->get_property ("note-heads"); scm_is_pair (s); - s = scm_cdr (s)) + extract_grob_set (me, "note-heads", heads); + + for (int i = heads.size (); i--;) { - Grob *n = unsmob_grob (scm_car (s)); + Grob *n = heads[i]; int p = Staff_symbol_referencer::get_rounded_position (n); Direction d = LEFT; @@ -209,10 +211,11 @@ Array Stem::note_head_positions (Grob *me) { Array ps; - for (SCM s = me->get_property ("note-heads"); scm_is_pair (s); - s = scm_cdr (s)) + extract_grob_set (me, "note-heads", heads); + + for (int i = heads.size (); i--;) { - Grob *n = unsmob_grob (scm_car (s)); + Grob *n = heads[i]; int p = Staff_symbol_referencer::get_rounded_position (n); ps.push (p); @@ -225,7 +228,7 @@ Stem::note_head_positions (Grob *me) void Stem::add_head (Grob *me, Grob *n) { - n->set_property ("stem", me->self_scm ()); + n->set_object ("stem", me->self_scm ()); n->add_dependency (me); if (Note_head::has_interface (n)) @@ -309,8 +312,8 @@ Stem::get_default_stem_end_position (Grob *me) } /* Tremolo stuff. */ - Grob *t_flag = unsmob_grob (me->get_property ("tremolo-flag")); - if (t_flag && !unsmob_grob (me->get_property ("beam"))) + Grob *t_flag = unsmob_grob (me->get_object ("tremolo-flag")); + if (t_flag && !unsmob_grob (me->get_object ("beam"))) { /* Crude hack: add extra space if tremolo flag is there. @@ -391,9 +394,8 @@ Stem::position_noteheads (Grob *me) if (!head_count (me)) return; - Link_array heads - = extract_grob_array (me, ly_symbol2scm ("note-heads")); - + extract_grob_set (me, "note-heads", ro_heads); + Link_array heads (ro_heads); heads.sort (compare_position); Direction dir = get_direction (me); @@ -608,7 +610,7 @@ Stem::width_callback (SCM e, SCM ax) { r.set_empty (); } - else if (unsmob_grob (me->get_property ("beam")) || abs (duration_log (me)) <= 2) + else if (unsmob_grob (me->get_object ("beam")) || abs (duration_log (me)) <= 2) { r = Interval (-1, 1); r *= thickness (me) / 2; @@ -744,10 +746,10 @@ Stem::offset_callback (SCM element_smob, SCM) } else { - SCM rests = me->get_property ("rests"); - if (scm_is_pair (rests)) + extract_grob_set (me, "rests", rests); + if (rests.size ()) { - Grob *rest = unsmob_grob (scm_car (rests)); + Grob *rest = rests.top (); r = rest->extent (rest, X_AXIS).center (); } } @@ -757,7 +759,7 @@ Stem::offset_callback (SCM element_smob, SCM) Spanner * Stem::get_beam (Grob *me) { - SCM b = me->get_property ("beam"); + SCM b = me->get_object ("beam"); return dynamic_cast (unsmob_grob (b)); } @@ -878,7 +880,7 @@ Stem::calc_stem_info (Grob *me) /* stem only extends to center of beam */ - 0.5 * beam_thickness; - if (Grob *tremolo = unsmob_grob (me->get_property ("tremolo-flag"))) + if (Grob *tremolo = unsmob_grob (me->get_object ("tremolo-flag"))) { Interval y_ext = tremolo->extent (tremolo, Y_AXIS); y_ext.widen (0.5); // FIXME. Should be tunable? diff --git a/lily/system-start-delimiter-engraver.cc b/lily/system-start-delimiter-engraver.cc index 389c355a1a..4b4f33c17b 100644 --- a/lily/system-start-delimiter-engraver.cc +++ b/lily/system-start-delimiter-engraver.cc @@ -9,7 +9,7 @@ #include "system-start-delimiter.hh" #include "engraver.hh" #include "staff-symbol.hh" -#include "group-interface.hh" +#include "pointer-group-interface.hh" #include "paper-column.hh" #include "output-def.hh" #include "spanner.hh" diff --git a/lily/system-start-delimiter.cc b/lily/system-start-delimiter.cc index 8e978a4bc5..e2d323b8c8 100644 --- a/lily/system-start-delimiter.cc +++ b/lily/system-start-delimiter.cc @@ -73,11 +73,12 @@ System_start_delimiter::after_line_breaking (SCM smob) /* Get all coordinates, to trigger Hara kiri. */ - SCM elts = me->get_property ("elements"); - Grob *common = common_refpoint_of_list (elts, me, Y_AXIS); - for (SCM s = elts; scm_is_pair (s); s = scm_cdr (s)) + extract_grob_set (me, "elements", elts); + Grob *common = common_refpoint_of_array (elts, me, Y_AXIS); + + for (int i = elts.size(); i--;) { - Spanner *staff = dynamic_cast (unsmob_grob (scm_car (s))); + Spanner *staff = dynamic_cast (elts[i]); if (!staff || staff->get_bound (LEFT)->get_column () != left_column) continue; @@ -111,13 +112,14 @@ System_start_delimiter::print (SCM smob) Real staff_space = Staff_symbol_referencer::staff_space (me); - SCM elts = me->get_property ("elements"); - Grob *common = common_refpoint_of_list (elts, me, Y_AXIS); + extract_grob_set (me, "elements", elts); + Grob *common = common_refpoint_of_array (elts, me, Y_AXIS); Interval ext; - for (SCM s = elts; scm_is_pair (s); s = scm_cdr (s)) + + for (int i = elts.size(); i--;) { - Spanner *sp = unsmob_spanner (scm_car (s)); + Spanner *sp = dynamic_cast (elts[i]); if (sp && sp->get_bound (LEFT) == me->get_bound (LEFT)) { diff --git a/lily/system.cc b/lily/system.cc index 2a88a4ae3c..4cf4f13c47 100644 --- a/lily/system.cc +++ b/lily/system.cc @@ -24,19 +24,33 @@ #include "paper-book.hh" #include "paper-system.hh" #include "tweak-registration.hh" +#include "grob-array.hh" System::System (System const &src, int count) : Spanner (src, count) { + all_elements_ = 0; rank_ = 0; + init_elements (); } System::System (SCM s, Object_key const *key) : Spanner (s, key) { + all_elements_ = 0; rank_ = 0; + init_elements (); } +void +System::init_elements () +{ + SCM scm_arr = Grob_array::make_array (); + all_elements_ = unsmob_grob_array (scm_arr); + set_object ("all-elements", scm_arr); +} + + Grob * System::clone (int count) const { @@ -46,15 +60,15 @@ System::clone (int count) const int System::element_count () const { - return scm_ilength (get_property ("all-elements")); + return all_elements_->size (); } int System::spanner_count () const { int k = 0; - for (SCM s = get_property ("all-elements"); scm_is_pair (s); s = scm_cdr (s)) - if (dynamic_cast (unsmob_grob (scm_car (s)))) + for (int i = all_elements_->size(); i--;) + if (dynamic_cast (all_elements_->grob (i))) k++; return k; } @@ -67,27 +81,42 @@ System::typeset_grob (Grob *elem) else { elem->pscore_ = pscore_; - Pointer_group_interface::add_grob (this, ly_symbol2scm ("all-elements"), elem); + all_elements_->add (elem); scm_gc_unprotect_object (elem->self_scm ()); } } -// todo: use map. +SCM +System::do_derived_mark () const +{ + if (!all_elements_->is_empty ()) + { + Grob **ptr = &all_elements_->array_reference ().elem_ref (0); + Grob **end = ptr + all_elements_->size (); + while (ptr < end) + { + scm_gc_mark ((*ptr)->self_scm ()); + ptr ++; + } + } + return Spanner::do_derived_mark (); +} + static void -fixup_refpoints (SCM s) +fixup_refpoints (Link_array const &grobs) { - for (; scm_is_pair (s); s = scm_cdr (s)) + for (int i = grobs.size (); i--; ) { - Grob::fixup_refpoint (scm_car (s)); + grobs[i]->fixup_refpoint (); } } SCM System::get_paper_systems () { - for (SCM s = get_property ("all-elements"); scm_is_pair (s); s = scm_cdr (s)) + for (int i = 0; i < all_elements_->size(); i++) { - Grob *g = unsmob_grob (scm_car (s)); + Grob *g = all_elements_->grob (i); if (g->internal_has_interface (ly_symbol2scm ("only-prebreak-interface"))) { /* @@ -112,21 +141,27 @@ System::get_paper_systems () for (int i = 0; i < broken_intos_.size (); i++) { Grob *se = broken_intos_[i]; - SCM all = se->get_property ("all-elements"); - for (SCM s = all; scm_is_pair (s); s = scm_cdr (s)) - fixup_refpoint (scm_car (s)); - count += scm_ilength (all); + + extract_grob_set (se, "all-elements", all_elts); + for (int j = 0; j < all_elts.size(); j++) + { + Grob *g = all_elts[j]; + g->fixup_refpoint (); + } + + count += all_elts.size (); } /* needed for doing items. */ - fixup_refpoints (get_property ("all-elements")); + fixup_refpoints (all_elements_->array ()); + + for (int i = 0 ; i < all_elements_->size(); i++) + all_elements_->grob (i)->handle_broken_dependencies (); - for (SCM s = get_property ("all-elements"); scm_is_pair (s); s = scm_cdr (s)) - unsmob_grob (scm_car (s))->handle_broken_dependencies (); handle_broken_dependencies (); - + #if 0 /* don't do this: strange side effects. */ /* Because the this->get_property (all-elements) contains items in 3 @@ -136,7 +171,7 @@ System::get_paper_systems () makes sure that no duplicates are in the list. */ for (int i = 0; i < line_count; i++) { - SCM all = broken_intos_[i]->get_property ("all-elements"); + SCM all = broken_intos_[i]->get_object ("all-elements"); all = ly_list_qsort_uniq_x (all); } #endif @@ -189,14 +224,21 @@ void System::add_column (Paper_column *p) { Grob *me = this; - SCM cs = me->get_property ("columns"); - Grob *prev = scm_is_pair (cs) ? unsmob_grob (scm_car (cs)) : 0; - - p->rank_ = prev ? Paper_column::get_rank (prev) + 1 : 0; - - me->set_property ("columns", scm_cons (p->self_scm (), cs)); + Grob_array *ga = unsmob_grob_array (me->get_object ("columns")); + if (!ga) + { + SCM scm_ga = Grob_array::make_array (); + me->set_object ("columns", scm_ga); + ga = unsmob_grob_array (scm_ga); + } - Axis_group_interface::add_element (me, p); + p->rank_ + = ga->size() + ? Paper_column::get_rank (ga->array ().top ()) + 1 + : 0; + + ga->add (p); + Axis_group_interface::add_element (this, p); } void @@ -217,31 +259,36 @@ apply_tweaks (Grob *g, bool broken) void System::pre_processing () { - for (SCM s = get_property ("all-elements"); scm_is_pair (s); s = scm_cdr (s)) - unsmob_grob (scm_car (s))->discretionary_processing (); + for (int i = 0 ; i < all_elements_->size(); i ++) + all_elements_->grob (i)->discretionary_processing (); + if (be_verbose_global) message (_f ("Grob count %d", element_count ())); - for (SCM s = get_property ("all-elements"); scm_is_pair (s); s = scm_cdr (s)) - unsmob_grob (scm_car (s))->handle_prebroken_dependencies (); + /* + order is significant: broken grobs are added to the end of the + array, and should be processed before the original is potentially + killed. + */ + for (int i = all_elements_->size(); i --; ) + all_elements_->grob (i)->handle_prebroken_dependencies (); - fixup_refpoints (get_property ("all-elements")); + fixup_refpoints (all_elements_->array ()); - for (SCM s = get_property ("all-elements"); scm_is_pair (s); s = scm_cdr (s)) - apply_tweaks (unsmob_grob (scm_car (s)), false); + for (int i = 0 ; i < all_elements_->size(); i ++) + apply_tweaks (all_elements_->grob (i), false); - for (SCM s = get_property ("all-elements"); scm_is_pair (s); s = scm_cdr (s)) - { - Grob *sc = unsmob_grob (scm_car (s)); - sc->calculate_dependencies (PRECALCED, PRECALCING, ly_symbol2scm ("before-line-breaking-callback")); - } + for (int i = 0 ; i < all_elements_->size(); i ++) + all_elements_->grob (i)->calculate_dependencies (PRECALCED, PRECALCING, + ly_symbol2scm ("before-line-breaking-callback")); message (_ ("Calculating line breaks...")); progress_indication (" "); - for (SCM s = get_property ("all-elements"); scm_is_pair (s); s = scm_cdr (s)) + + for (int i = 0 ; i < all_elements_->size(); i ++) { - Grob *e = unsmob_grob (scm_car (s)); + Grob *e = all_elements_->grob (i); SCM proc = e->get_property ("spacing-procedure"); if (ly_is_procedure (proc)) scm_call_1 (proc, e->self_scm ()); @@ -251,12 +298,11 @@ System::pre_processing () void System::post_processing () { - for (SCM s = get_property ("all-elements"); scm_is_pair (s); s = scm_cdr (s)) + for (int i = 0 ; i < all_elements_->size(); i ++) { - Grob *g = unsmob_grob (scm_car (s)); + Grob *g = all_elements_->grob (i); apply_tweaks (g, true); - g->calculate_dependencies (POSTCALCED, POSTCALCING, ly_symbol2scm ("after-line-breaking-callback")); } @@ -270,13 +316,15 @@ System::post_processing () /* Generate all stencils to trigger font loads. This might seem inefficient, but Stencils are cached per grob anyway. */ - SCM all = get_property ("all-elements"); - all = ly_list_qsort_uniq_x (all); + + Link_array all_elts_sorted (all_elements_->array ()); + all_elts_sorted.default_sort (); + all_elts_sorted.uniq (); this->get_stencil (); - for (SCM s = all; scm_is_pair (s); s = scm_cdr (s)) + for (int i = all_elts_sorted.size (); i--;) { - Grob *g = unsmob_grob (scm_car (s)); + Grob *g = all_elts_sorted[i]; g->get_stencil (); } } @@ -290,12 +338,10 @@ System::get_paper_system () SCM *tail = &exprs; /* Output stencils in three layers: 0, 1, 2. Default layer: 1. */ - SCM all = get_property ("all-elements"); - for (int i = 0; i < LAYER_COUNT; i++) - for (SCM s = all; scm_is_pair (s); s = scm_cdr (s)) + for (int j = all_elements_->size (); j --;) { - Grob *g = unsmob_grob (scm_car (s)); + Grob *g = all_elements_->grob (j); Stencil *stil = g->get_stencil (); /* Skip empty stencils and grobs that are not in this layer. */ @@ -331,10 +377,10 @@ System::get_paper_system () Interval staff_refpoints; staff_refpoints.set_empty (); - for (SCM s = get_property ("spaceable-staves"); - scm_is_pair (s); s = scm_cdr (s)) + extract_grob_set (this, "spaceable-staves", staves); + for (int i = staves.size (); i--; ) { - Grob *g = unsmob_grob (scm_car (s)); + Grob *g = staves[i]; staff_refpoints.add_point (g->relative_coordinate (this, Y_AXIS)); } @@ -354,24 +400,25 @@ System::broken_col_range (Item const *left, Item const *right) const left = left->get_column (); right = right->get_column (); - SCM s = get_property ("columns"); - - while (scm_is_pair (s) && scm_car (s) != right->self_scm ()) - s = scm_cdr (s); - - if (scm_is_pair (s)) - s = scm_cdr (s); - while (scm_is_pair (s) && scm_car (s) != left->self_scm ()) + extract_grob_set (this, "columns", cols); + int i = 0; + while (i < cols.size() + && cols[i] != left) + i++; + + if (i < cols.size()) + i ++; + + while (i < cols.size() + && cols[i] != right) { - Paper_column *c = dynamic_cast (unsmob_grob (scm_car (s))); + Paper_column *c = dynamic_cast (cols[i]); if (Item::is_breakable (c) && !c->system_) ret.push (c); - - s = scm_cdr (s); + i++; } - ret.reverse (); return ret; } @@ -380,12 +427,13 @@ System::broken_col_range (Item const *left, Item const *right) const Link_array System::columns () const { - Link_array acs - = extract_grob_array (this, ly_symbol2scm ("columns")); + extract_grob_set (this, "columns", ro_columns); + Link_array columns (ro_columns); + bool found = false; - for (int i = acs.size (); i--;) + for (int i = columns.size (); i--;) { - bool brb = Item::is_breakable (acs[i]); + bool brb = Item::is_breakable (columns[i]); found = found || brb; /* @@ -393,12 +441,17 @@ System::columns () const seem empty. We need to retain breakable columns, in case someone forced a breakpoint. */ - if (!found || !Paper_column::is_used (acs[i])) - acs.del (i); + if (!found || !Paper_column::is_used (columns[i])) + columns.del (i); } - return acs; + return columns; } +int +System::get_rank () const +{ + return rank_; +} ADD_INTERFACE (System, "system-interface", "This is the toplevel object: each object in a score " diff --git a/lily/tie-column.cc b/lily/tie-column.cc index 9f8bf74fb9..e2e33530d4 100644 --- a/lily/tie-column.cc +++ b/lily/tie-column.cc @@ -9,7 +9,7 @@ #include "tie-column.hh" #include "paper-column.hh" #include "spanner.hh" -#include "group-interface.hh" +#include "pointer-group-interface.hh" #include "tie.hh" #include "directional-element-interface.hh" #include "rhythmic-head.hh" @@ -69,9 +69,8 @@ tie_compare (Grob *const &s1, void Tie_column::werner_directions (Grob *me) { - Link_array ties - = extract_grob_array (me, ly_symbol2scm ("ties")); - + extract_grob_set (me, "ties", ro_ties); + Link_array ties (ro_ties); if (!ties.size ()) return; diff --git a/lily/translator-group.cc b/lily/translator-group.cc index 081cd86113..1ec1f82163 100644 --- a/lily/translator-group.cc +++ b/lily/translator-group.cc @@ -97,15 +97,13 @@ Translator_group::get_simple_trans_list () return simple_trans_list_; } + void recurse_over_translators (Context *c, Translator_method ptr, Direction dir) { Translator_group *tg = dynamic_cast (c->implementation ()); - - /* - Top down: - */ + if (dir == DOWN) { translator_each (tg->get_simple_trans_list (), diff --git a/lily/tuplet-bracket.cc b/lily/tuplet-bracket.cc index 29d9916497..d7032e04ae 100644 --- a/lily/tuplet-bracket.cc +++ b/lily/tuplet-bracket.cc @@ -40,7 +40,7 @@ #include "text-interface.hh" #include "stem.hh" #include "note-column.hh" -#include "group-interface.hh" +#include "pointer-group-interface.hh" #include "directional-element-interface.hh" #include "spanner.hh" #include "staff-symbol-referencer.hh" @@ -75,7 +75,7 @@ Tuplet_bracket::parallel_beam (Grob *me, Link_array const &cols, bool *equ if (! (b1 && (b1 == b2) && !sp->is_broken ())) return 0; - Link_array beam_stems = extract_grob_array (b1, ly_symbol2scm ("stems")); + extract_grob_set (b1, "stems", beam_stems); if (beam_stems.size () == 0) { programming_error ("beam under tuplet bracket has no stems"); @@ -99,8 +99,7 @@ Tuplet_bracket::print (SCM smob) { Grob *me = unsmob_grob (smob); Stencil mol; - Link_array columns - = extract_grob_array (me, ly_symbol2scm ("note-columns")); + extract_grob_set (me, "note-columns", columns); if (!columns.size ()) return mol.smobbed_copy (); @@ -301,12 +300,9 @@ Tuplet_bracket::make_bracket (Grob *me, // for line properties. void Tuplet_bracket::calc_position_and_height (Grob *me, Real *offset, Real *dy) { - Link_array columns - = extract_grob_array (me, ly_symbol2scm ("note-columns")); - - SCM cols = me->get_property ("note-columns"); - Grob *commony = common_refpoint_of_list (cols, me, Y_AXIS); - Grob *commonx = common_refpoint_of_list (cols, me, X_AXIS); + extract_grob_set (me, "note-columns", columns); + Grob *commony = common_refpoint_of_array (columns, me, Y_AXIS); + Grob *commonx = common_refpoint_of_array (columns, me, X_AXIS); Interval staff; if (Grob *st = Staff_symbol_referencer::get_staff_symbol (me)) @@ -406,8 +402,7 @@ SCM Tuplet_bracket::before_line_breaking (SCM smob) { Grob *me = unsmob_grob (smob); - Link_array columns - = extract_grob_array (me, ly_symbol2scm ("note-columns")); + extract_grob_set (me, "note-columns", columns); for (int i = columns.size (); i--;) { @@ -425,8 +420,7 @@ SCM Tuplet_bracket::after_line_breaking (SCM smob) { Grob *me = unsmob_grob (smob); - Link_array columns - = extract_grob_array (me, ly_symbol2scm ("note-columns")); + extract_grob_set (me, "note-columns", columns); if (!columns.size ()) { @@ -503,9 +497,10 @@ Direction Tuplet_bracket::get_default_dir (Grob *me) { Drul_array dirs (0, 0); - for (SCM s = me->get_property ("note-columns"); scm_is_pair (s); s = scm_cdr (s)) + extract_grob_set (me, "note-columns", columns); + for (int i = 0 ; i < columns.size (); i++) { - Grob *nc = unsmob_grob (scm_car (s)); + Grob *nc = columns[i]; Direction d = Note_column::dir (nc); if (d) dirs[d]++; diff --git a/lily/vertical-align-engraver.cc b/lily/vertical-align-engraver.cc index 7b0b9900f6..efcb08e794 100644 --- a/lily/vertical-align-engraver.cc +++ b/lily/vertical-align-engraver.cc @@ -13,6 +13,8 @@ #include "axis-group-interface.hh" #include "engraver.hh" #include "spanner.hh" +#include "pointer-group-interface.hh" +#include "grob-array.hh" class Vertical_align_engraver : public Engraver { @@ -107,34 +109,29 @@ Vertical_align_engraver::acknowledge_grob (Grob_info i) SCM before = scm_hash_ref (id_to_group_hashtab_, before_id, SCM_BOOL_F); SCM after = scm_hash_ref (id_to_group_hashtab_, after_id, SCM_BOOL_F); - + Grob * before_grob = unsmob_grob (before); + Grob * after_grob = unsmob_grob (after); + Align_interface::add_element (valign_, i.grob (), get_property ("verticalAlignmentChildCallback")); - if (unsmob_grob (before) || unsmob_grob (after)) + if (before_grob || after_grob) { - SCM elts = valign_->get_property ("elements"); - SCM new_order = scm_cdr (elts); - SCM *current = &new_order; - - for (SCM s = new_order; scm_is_pair (s); s = scm_cdr (s)) + Grob_array * ga = unsmob_grob_array (valign_->get_object ("elements")); + Link_array &arr = ga->array_reference (); + + Grob *added = arr.pop(); + for (int i = 0 ; i < arr.size (); i++) { - if (scm_car (s) == after) + if (arr[i] == before_grob) { - *current = scm_cons (i.grob ()->self_scm(), s); - break; + arr.insert (added, i); } - else if (scm_car (s) == before) + else if (arr[i] == after_grob) { - scm_set_cdr_x (s, scm_cons (i.grob ()->self_scm (), - scm_cdr (s))); - break; + arr.insert (added, i + 1); } - - current = SCM_CDRLOC (s); } - - valign_->set_property ("elements", new_order); } } } diff --git a/lily/volta-bracket.cc b/lily/volta-bracket.cc index 76cce1605e..3609470758 100644 --- a/lily/volta-bracket.cc +++ b/lily/volta-bracket.cc @@ -15,7 +15,7 @@ #include "output-def.hh" #include "text-interface.hh" #include "volta-bracket.hh" -#include "group-interface.hh" +#include "pointer-group-interface.hh" #include "side-position-interface.hh" #include "directional-element-interface.hh" #include "lookup.hh" @@ -42,8 +42,9 @@ Volta_bracket_interface::print (SCM smob) bool no_vertical_start = orig_span && !broken_first_bracket; bool no_vertical_end = orig_span && !broken_last_bracket; - SCM s = me->get_property ("bars"); - Grob *endbar = scm_is_pair (s) ? unsmob_grob (scm_car (s)) : 0; + + extract_grob_set (me, "bars", bars); + Grob *endbar = bars.size() ? bars.top () : 0; SCM glyph = endbar ? endbar->get_property ("glyph") : SCM_EOL; String str; diff --git a/ly/engraver-init.ly b/ly/engraver-init.ly index 2edf00f312..ed3c6134fb 100644 --- a/ly/engraver-init.ly +++ b/ly/engraver-init.ly @@ -613,9 +613,6 @@ AncientRemoveEmptyStaffContext = \context { \remove "New_fingering_engraver" \description "Context for drawing notes in a Tab staff. " - \override Slur #'font-family = #'roman - \override Slur #'print-function = #hammer-print-function - \override Slur #'direction = #-1 %% Draws all stems/beams out of the staff (and not in the middle of the staff !) %% This feature is now disabled because most of the tab does not use it. diff --git a/scm/define-grob-properties.scm b/scm/define-grob-properties.scm index 86de012065..99480d245e 100644 --- a/scm/define-grob-properties.scm +++ b/scm/define-grob-properties.scm @@ -523,11 +523,6 @@ sizes (like the dynamic @b{p} and @b{f}) on their baselines.") function is to protect objects from being garbage collected.") (arpeggio ,ly:grob? "pointer to arpeggio object.") (beam ,ly:grob? "pointer to the beam, if applicable.") - (center-element ,ly:grob? "grob which will be at the center of -the group after aligning (when using -Align_interface::center_on_element).") - (tweak-count ,number? "Number of otherwise unique Grobs.") - (tweak-rank ,number? "Identify otherwise unique Grobs.") (direction-source ,ly:grob? "in case side-relative-direction is set, which grob to get the direction from .") (dot ,ly:grob? "reference to Dots object.") diff --git a/scm/lily-library.scm b/scm/lily-library.scm index ca682375c7..fefab95947 100644 --- a/scm/lily-library.scm +++ b/scm/lily-library.scm @@ -395,6 +395,9 @@ possibly turned off." (define-public (symbolstring lst) (symbol->string r))) +(define-public (symbol-keystring (car lst)) (symbol->string (car r)))) + ;; ;; don't confuse users with # syntax. ;; diff --git a/scm/output-lib.scm b/scm/output-lib.scm index 14f40f8d57..52ccd660ad 100644 --- a/scm/output-lib.scm +++ b/scm/output-lib.scm @@ -38,44 +38,6 @@ (+ fret 5)) (else fret))))))) -(define-public (hammer-print-function grob) - (let* ((note-collums (ly:grob-property grob 'note-columns)) - (note-column1 (cadr note-collums)) - (note-column2 (car note-collums)) - (note1 (car (ly:grob-property note-column1 'note-heads))) - (note2 (car (ly:grob-property note-column2 'note-heads))) - (text1 (ly:grob-property note1 'text)) - (text2 (ly:grob-property note2 'text)) - (fret1 (if (string? text1) (string->number text1) 0)) - (fret2 (if (string? text2) (string->number text2) 0)) - (letter (cond - ((< fret1 fret2) "H") - ((> fret1 fret2) "P") - (else "")))) - (let* ((slur - ;; (Slur::print grob) - - ;; - ;; FIXME: a hammer is not a slur. - ;; - (ly:make-stencil '() '(0 . 0) '(0 . 0))) - (layout (ly:grob-layout grob)) - (text (interpret-markup - layout - (ly:grob-alist-chain grob (ly:output-def-lookup layout 'text-font-defaults)) - letter))) - - (let ((x (/ (- (cdr (ly:stencil-extent slur 0)) - (/ (cdr (ly:stencil-extent text 0)) 2.0)) - -2.0))) - - (set! text - (ly:make-stencil (ly:stencil-expr text) - (cons x x) - (ly:stencil-extent text Y))) - - (ly:stencil-aligned-to text X RIGHT))))) - (define-public guitar-tuning '(4 -1 -5 -10 -15 -20)) (define-public bass-tuning '(-17 -22 -27 -32)) @@ -288,7 +250,7 @@ centered, X==1 is at the right, X == -1 is at the left." (define (parenthesize-elements grob) (let* - ((elts (ly:grob-property grob 'elements)) + ((elts (ly:grob-object grob 'elements)) (x-ext (ly:relative-group-extent elts grob X)) (font (ly:grob-default-font grob)) (lp (ly:font-get-glyph font "accidentals.leftparen")) -- 2.39.2