diff options
author | Han-Wen Nienhuys <hanwen@xs4all.nl> | 2005-07-16 12:23:33 +0000 |
---|---|---|
committer | Han-Wen Nienhuys <hanwen@xs4all.nl> | 2005-07-16 12:23:33 +0000 |
commit | e6caaa132f59006e5c47d0007b24bfedd07ad145 (patch) | |
tree | 03f0a133060b58c4c8cabbf0eef16e999718d919 /lily | |
parent | 2ea45e18f92b208067f7a88bdca481e00e93a504 (diff) |
* 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<Grob> 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.
Diffstat (limited to 'lily')
113 files changed, 1343 insertions, 971 deletions
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<Grob> *break_reminder, Link_array<Grob> *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<Grob> 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<Grob> elems - = extract_grob_array (me, ly_symbol2scm ("elements")); + extract_grob_set (me, "elements", elem_source); + Link_array<Grob> 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<Interval> dims; Link_array<Grob> elems; - Link_array<Grob> 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<Grob> 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<Grob> 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<Grob> 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<Grob> -Axis_group_interface::get_children (Grob *me) +void +Axis_group_interface::get_children (Grob *me, Link_array<Grob> *found) { - Link_array<Grob> 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 <math.h> -#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<Grob> 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<Grob> stems - = extract_grob_array (me, ly_symbol2scm ("stems")); + = extract_grob_array (me, "stems"); Array<Stem_info> stem_infos; Array<Real> base_lengths; Array<Real> 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<Grob> const &stems, Array<Real> 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<Real> score (0, 0); Drul_array<int> count (0, 0); @@ -330,7 +353,7 @@ Beam::score_stem_lengths (Link_array<Grob> 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<int> beam_counts, - Direction ldir, Direction rdir) + Direction ldir, Direction rdir, + + Beam_quant_parameters const*parameters) { Real dy = yr - yl; Drul_array<Real> y (yl, yr); Drul_array<Direction> 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<Spanner *> (me), dynamic_cast<Item *> (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<Grob> 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<Grob> 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<Grob> 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<Grob> 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<Grob> 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<Real> x_posns; - Link_array<Grob> 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<Real> x_posns; - Link_array<Grob> 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<Grob> 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<Grob> 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<Grob> 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<Grob> 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<Grob> 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<Grob> 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<Grob> 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<int> 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<Engraver *> (origin->implementation ()), + left_edge_ = make_item_from_properties (dynamic_cast<Engraver *> + (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<Grob> Break_align_interface::ordered_elements (Grob *grob) { Item *me = dynamic_cast<Item *> (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<Grob> 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 <hanwen@xs4all.nl> + +*/ + #include <cstdio> #include <cstdlib> +#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<Grob> &old_grobs (grob_arr->array_reference ()); + Link_array<Grob> *new_grobs (new_arr == grob_arr + ? new Link_array<Grob> + : &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<Slice> it_indices; - Array<Slice> 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<Spanner *> (g)) { - idx =--sp_index; + idx = --spanner_index; } else if (dynamic_cast<Item *> (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<Slice> item_indices; + Array<Slice> spanner_indices; + for (int i = 0; i <= system_range.length (); i++) + { + item_indices.push (Slice (len, 0)); + spanner_indices.push (Slice (len, 0)); + } + Array<Slice> *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<Grob> 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<Offset> bottom_points; Array<Offset> 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<Grob> 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<Grob> 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<Item *> (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 <hanwen@xs4all.nl> + +*/ + +#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<Item*> (grobs_.elem (i)); +} + + +Spanner* +Grob_array::spanner (int i) +{ + return dynamic_cast<Spanner*> (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> & +Grob_array::array_reference () +{ + return grobs_; +} + + +Link_array<Grob> 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 ("#<Grob_array", port); + + Grob_array * grob_arr = unsmob (arr); + for (int i = 0; i < grob_arr->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<Grob> 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<System *> (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<Item *> (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<Item *> (me)) + if (Item *i = dynamic_cast<Item *> (this)) { Item *parenti = dynamic_cast<Item *> (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 ("#<Grob ", port); - scm_puts ((char *) sc->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<Grob> 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 <hanwen@cs.uu.nl> -*/ - -#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<Grob> -extract_grob_array (Grob const *elt, SCM symbol) -{ - Link_array<Grob> 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<Item> -extract_item_array (Grob const *elt, SCM symbol) -{ - Link_array<Item> 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<Item *> (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<Spanner*> (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<Spanner *> (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<Grob> childs = Axis_group_interface::get_children (me); + Link_array<Grob> 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<Spanner *> (me); - Link_array<Grob> 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 <janneke@gnu.org> */ +#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<Item *> (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<Grob> 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<Grob> get_children (Grob *); + static void get_children (Grob *, Link_array<Grob> *); 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<Grob> const &stems, Array<Stem_info> const &stem_infos, @@ -52,10 +77,11 @@ public: Array<Real> 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<int>, Direction, Direction); + Drul_array<int>, 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 <hanwen@xs4all.nl> + +*/ + +#ifndef GROB_ARRAY_HH +#define GROB_ARRAY_HH + +#include "lily-proto.hh" +#include "smobs.hh" +#include "parray.hh" + +class Grob_array +{ + Link_array<Grob> 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<Grob> const &src); + Link_array<Grob> &array_reference (); + Link_array<Grob> const &array () const; + static SCM make_array (); +}; + +DECLARE_UNSMOB (Grob_array, grob_array); + +Link_array<Grob> 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<Grob> 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<Grob> ly_scm2grobs (SCM ell); SCM ly_grobs2scm (Link_array<Grob> 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<Grob> extract_grob_array (Grob const *elt, SCM symbol); -Link_array<Item> 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<Grob> 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<Spanner> 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<int> 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 <hanwen@xs4all.nl> */ -#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<Item *> (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<Spanner *> (unsmob_grob (smob)); - Link_array<Grob> 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<Grob> 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<Grob> -> Note_collision_interface::get_clash_groups (Grob *me) +Drul_array < Link_array<Grob> > +Note_collision_interface::get_clash_groups (Grob *me) { Drul_array<Link_array<Grob> > 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<SCM> props (me->get_property ("left-items"), - me->get_property ("right-items")); + Drul_array<SCM> props (me->get_object ("left-items"), + me->get_object ("right-items")); Direction d = LEFT; Direction col_dir = right_col->break_status_dir (); Drul_array<Interval> 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<Grob> const &items (ly_scm2link_array (props [d])); + for (int i = items.size (); i--;) { - Item *it = dynamic_cast<Item *> (unsmob_grob (scm_car (s))); + Item *it = dynamic_cast<Item *> (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<Grob> & 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<Item*> (right[i])->get_column () != mincol) + right.del (i); } - - me->set_property ("right-items", newright); } if (!mincol) { - /* - int r = Paper_column::get_rank (dynamic_cast<Item*>(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<Direction> stem_dirs (CENTER, CENTER); Drul_array<Interval> stem_posns; Drul_array<Interval> head_posns; - Drul_array<SCM> props (me->get_property ("left-items"), - me->get_property ("right-items")); + Drul_array<SCM> props (me->get_object ("left-items"), + me->get_object ("right-items")); Drul_array<Spanner *> beams_drul (0, 0); Drul_array<Grob *> 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<Grob> const &items (ly_scm2link_array (props [d])); + for (int i = 0; i < items.size(); i++) { - Item *it = dynamic_cast<Item *> (unsmob_grob (scm_car (s))); + Item *it = dynamic_cast<Item *> (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<Grob> &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<Grob> rests; Link_array<Grob> 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<Item *> (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<Grob> 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<Item *> (unsmob_grob (scm_car (next))); + Item *l = dynamic_cast<Item *> (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<Item*> (elts[i]); if (!r) continue; + if (Separation_item::width (r).is_empty ()) + continue; + Item *rb = dynamic_cast<Item *> (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<Item *> (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<Item*> (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<Item*> (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<Item *> (separation_item)->get_column (); + Grob *col = dynamic_cast<Item *> (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<Grob> const &icols) Link_array<Grob> 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<Grob> 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<Spanner *> (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<Spanner *> (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<Grob> 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<Real> end_ys) const Array<Extra_collision_info> Slur_score_state::get_extra_encompass_infos () const { - Link_array<Grob> encompasses - = extract_grob_array (slur_, ly_symbol2scm ("encompass-objects")); + extract_grob_set (slur_, "encompass-objects", encompasses); Array<Extra_collision_info> 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<Grob> 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<Spanner *> (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 <hanwen@xs4all.nl> */ + #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<Grob> *cols, Rational); static void find_loose_columns (Link_array<Grob> cols); - static void set_explicit_neighbor_columns (Link_array<Grob> cols); - static void set_implicit_neighbor_columns (Link_array<Grob> cols); + static void set_explicit_neighbor_columns (Link_array<Grob> const &cols); + static void set_implicit_neighbor_columns (Link_array<Grob> const &cols); static void do_measure (Rational, Grob *me, Link_array<Grob> *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<Item *> (unsmob_grob (scm_car (lns))); - Item *r_neighbor = dynamic_cast<Item *> (unsmob_grob (scm_car (rns))); + Item *l_neighbor = dynamic_cast<Item *> (lns[0]); + Item *r_neighbor = dynamic_cast<Item *> (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<Grob> *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<Grob> *cols, Rational Item *lc = dynamic_cast<Item *> ((d == LEFT) ? next_door[LEFT] : c); Item *rc = dynamic_cast<Item *> (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<Grob> *cols, Rational Set neighboring columns determined by the spacing-wishes grob property. */ void -Spacing_spanner::set_explicit_neighbor_columns (Link_array<Grob> cols) +Spacing_spanner::set_explicit_neighbor_columns (Link_array<Grob> 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<Item *> (unsmob_grob (scm_car (s))); + Item *wish = dynamic_cast<Item *> ( 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<Grob> 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<Item *> (unsmob_grob (scm_car (left_neighs))); + Item *it = dynamic_cast<Item *> (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<Grob> cols) yet. Only do breakable non-musical columns, and musical columns. */ void -Spacing_spanner::set_implicit_neighbor_columns (Link_array<Grob> cols) +Spacing_spanner::set_implicit_neighbor_columns (Link_array<Grob> const &cols) { for (int i = 0; i < cols.size (); i++) { @@ -335,18 +345,23 @@ Spacing_spanner::set_implicit_neighbor_columns (Link_array<Grob> 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<Item *> (unsmob_grob (scm_car (s))); @@ -766,11 +781,6 @@ Spacing_spanner::breakable_column_spacing (Grob *me, Item *l, Item *r, Moment sh 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<Interval> 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 <math.h> -#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<Item *> (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<Grob *> 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<int> Stem::note_head_positions (Grob *me) { Array<int> 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<Grob> heads - = extract_grob_array (me, ly_symbol2scm ("note-heads")); - + extract_grob_set (me, "note-heads", ro_heads); + Link_array<Grob> 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<Spanner *> (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<Spanner*> (unsmob_grob (scm_car (s))); + Spanner *staff = dynamic_cast<Spanner*> (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<Spanner*> (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<Spanner *> (unsmob_grob (scm_car (s)))) + for (int i = all_elements_->size(); i--;) + if (dynamic_cast<Spanner *> (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<Grob> 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<Grob> 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<Paper_column *> (unsmob_grob (scm_car (s))); + Paper_column *c = dynamic_cast<Paper_column *> (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<Grob> System::columns () const { - Link_array<Grob> acs - = extract_grob_array (this, ly_symbol2scm ("columns")); + extract_grob_set (this, "columns", ro_columns); + Link_array<Grob> 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<Grob> ties - = extract_grob_array (me, ly_symbol2scm ("ties")); - + extract_grob_set (me, "ties", ro_ties); + Link_array<Grob> 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<Translator_group *> (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<Grob> const &cols, bool *equ if (! (b1 && (b1 == b2) && !sp->is_broken ())) return 0; - Link_array<Grob> 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<Grob> 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<Grob> 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<Grob> 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<Grob> 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<int> 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<Grob> &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; |