]> git.donarmstrong.com Git - lilypond.git/commitdiff
* lily/system.cc (do_derived_mark): don't mark from object_alist_
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Sat, 16 Jul 2005 12:23:33 +0000 (12:23 +0000)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Sat, 16 Jul 2005 12:23:33 +0000 (12:23 +0000)
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.

120 files changed:
ChangeLog
flower/include/parray.hh
input/typography-demo.ly
lily/GNUmakefile
lily/accidental-engraver.cc
lily/accidental-placement.cc
lily/accidental.cc
lily/align-interface.cc
lily/ambitus-engraver.cc
lily/ambitus.cc
lily/arpeggio-engraver.cc
lily/arpeggio.cc
lily/axis-group-engraver.cc
lily/axis-group-interface-scheme.cc
lily/axis-group-interface.cc
lily/bar-number-engraver.cc
lily/beam-concave.cc
lily/beam-quanting.cc
lily/beam.cc
lily/bezier.cc
lily/break-algorithm.cc
lily/break-align-engraver.cc
lily/break-align-interface.cc
lily/break-substitution.cc
lily/chord-tremolo-engraver.cc
lily/cluster-engraver.cc
lily/cluster.cc
lily/coherent-ligature-engraver.cc
lily/dot-column-engraver.cc
lily/dot-column.cc
lily/drum-note-engraver.cc
lily/dynamic-engraver.cc
lily/easy-notation.cc
lily/extender-engraver.cc
lily/grid-line-interface.cc
lily/grob-array.cc [new file with mode: 0644]
lily/grob-interface.cc
lily/grob-property.cc
lily/grob-scheme.cc
lily/grob.cc
lily/group-interface.cc [deleted file]
lily/hairpin.cc
lily/hara-kiri-group-spanner.cc
lily/horizontal-bracket-engraver.cc
lily/horizontal-bracket.cc
lily/hyphen-engraver.cc
lily/include/axis-group-interface.hh
lily/include/beam.hh
lily/include/grob-array.hh [new file with mode: 0644]
lily/include/grob.hh
lily/include/group-interface.hh
lily/include/lily-guile-macros.hh
lily/include/lily-proto.hh
lily/include/music.hh
lily/include/separating-group-spanner.hh
lily/include/spanner.hh
lily/include/system.hh
lily/include/translator-group.hh
lily/instrument-name-engraver.cc
lily/item.cc
lily/ledger-line-engraver.cc
lily/ledger-line-spanner.cc
lily/lyric-extender.cc
lily/mark-engraver.cc
lily/metronome-engraver.cc
lily/music.cc
lily/new-fingering-engraver.cc
lily/note-collision.cc
lily/note-column.cc
lily/note-head-line-engraver.cc
lily/note-head.cc
lily/note-spacing.cc
lily/ottava-bracket.cc
lily/paper-column.cc
lily/phrasing-slur-engraver.cc
lily/piano-pedal-bracket.cc
lily/piano-pedal-engraver.cc
lily/pitched-trill-engraver.cc
lily/rest-collision.cc
lily/rest.cc
lily/rhythmic-column-engraver.cc
lily/rhythmic-head.cc
lily/score-engraver.cc
lily/script-column.cc
lily/script-engraver.cc
lily/separating-group-spanner.cc
lily/separating-line-group-engraver.cc
lily/separation-item.cc
lily/side-position-interface.cc
lily/simple-spacer.cc
lily/slur-configuration.cc
lily/slur-engraver.cc
lily/slur-scoring.cc
lily/slur.cc
lily/spaceable-grob.cc
lily/spacing-engraver.cc
lily/spacing-loose-columns.cc
lily/spacing-spanner.cc
lily/span-arpeggio-engraver.cc
lily/span-bar.cc
lily/spanner.cc
lily/staff-spacing.cc
lily/staff-symbol-engraver.cc
lily/staff-symbol-referencer.cc
lily/stanza-number-align-engraver.cc
lily/stem-engraver.cc
lily/stem-tremolo.cc
lily/stem.cc
lily/system-start-delimiter-engraver.cc
lily/system-start-delimiter.cc
lily/system.cc
lily/tie-column.cc
lily/translator-group.cc
lily/tuplet-bracket.cc
lily/vertical-align-engraver.cc
lily/volta-bracket.cc
ly/engraver-init.ly
scm/define-grob-properties.scm
scm/lily-library.scm
scm/output-lib.scm

index f98e1df0687ef877457d0979f526e0000d736c90..e18074172c73ec2879ac6f626a8685cc7cf9c16f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,15 +1,36 @@
-2005-07-15  Graham Percival  <gperlist@shaw.ca>
+2005-07-16  Han-Wen Nienhuys  <hanwen@xs4all.nl>
 
-       * Documentation/user/lilypond-book.itely: fixes example.
+       * lily/system.cc (do_derived_mark): don't mark from object_alist_
+       anymore, but do it centrally.  Speedup: approximately 3-5 %.
 
-2005-07-15  Nicolas Sceaux  <nicolas.sceaux@free.fr>
+       * ly/engraver-init.ly (AncientRemoveEmptyStaffContext): remove
+       hammer hack.
 
-       * Documentation/user/global.itely (Creating titles):    
-       * Documentation/user/examples.itely (All headers): change the
-       place of \header in \score blocks (after music block) to make
-       examples compile (cf. changes on parser.yy on 2005-07-10)
+       * lily/grob-scheme.cc (LY_DEFINE): new function ly:grob-object
+
+       * scm/output-lib.scm: remove hammer-print-function.
+
+       * lily/include/pointer-group-interface.hh (extract_grob_set): new
+       macro. Declare a Link_array<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.
 
-2005-07-15  Han-Wen Nienhuys  <hanwen@xs4all.nl>
+       * lily/beam-quanting.cc (fill): read details property from beam.
+
+       * lily/beam.cc: support details property.
+
+       * total speedups below: approx 10%.
 
        * lily/include/beam.hh: new struct, softcode beam quanting parameters
 
        alist. This saves processing time, since properties aren't
        break-substituted, and the per grob namespace is smaller, both for
        grobs and non-grob properties.
-       
 
        * scm/define-grob-properties.scm (all-internal-grob-properties):
        remove center-element.
 
        * lily/grob.cc: remove tweak-count, tweak-rank.
 
+2005-07-15  Graham Percival  <gperlist@shaw.ca>
+
+       * Documentation/user/lilypond-book.itely: fixes example.
+
+2005-07-15  Nicolas Sceaux  <nicolas.sceaux@free.fr>
+
+       * Documentation/user/global.itely (Creating titles):    
+       * Documentation/user/examples.itely (All headers): change the
+       place of \header in \score blocks (after music block) to make
+       examples compile (cf. changes on parser.yy on 2005-07-10)
+
 2005-07-13  Graham Percival  <gperlist@shaw.ca>
 
        * python/convertrules.py: add exc -> ecc rule.
index 6395cd493e025364e92aae85c701ea4e33db214a..bc51bda5a00d3fc9f303614ae7b1e54ee9f2919f 100644 (file)
@@ -159,7 +159,7 @@ public:
     return (T *) Array<void *>::get (i);
   }
   Link_array<T>
-  slice (int l, int u)
+  slice (int l, int u) const
   {
     return Array<void *>::slice (l, u);
   }
index 83d4c11acfd780444de2f852b60ad79fc382a27f..d0ad8ebc613b2433a36177356d65fb3b4c766af9 100644 (file)
@@ -127,7 +127,7 @@ pianoLH =  \relative c'' \repeat volta 2\new Voice {
               \context Staff #(set-accidental-style 'modern)
               \melody >>
           \lyricsto "singer" \new Lyrics \firstVerse
-          \lyricsto "singer" \new Lyrics \secondVerse
+%         \lyricsto "singer" \new Lyrics \secondVerse
           \new PianoStaff << 
               \set PianoStaff.instrument = \markup {
                   \bold
index 6bf022fc80e57235afaec6de44c70bdbfd83712e..9d34a9b3f0215b386cb56499672df49d189b6688 100644 (file)
@@ -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
index 9dc3010382af821df5c91153e73eff355736ac96..971f976239282837587b8f2ff169892427780882 100644 (file)
@@ -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);
index dc39d5a1aa7917c412bbe723dccae17ad4a6989d..43055409cb0ad2d4eb339edab2289534ff59bc1e 100644 (file)
@@ -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);
index 9f08691f10614e3bd59ee6588df4c5dff14bf71b..61536c4ed44d3df9f6848d067228e0d89ce2b5da 100644 (file)
@@ -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 ();
index 59575bba43fdd4cd02bfd6525ce1d6b7b9a21907..8d09d98dca8a418c58a79b7b99e11f0370ac357d 100644 (file)
@@ -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
 {
index a84f9d65ec35b4d7d2d7855ef693049a332c76ca..a07b04fa052af5f08a956e5fdde5ebe73cfe8ed5 100644 (file)
@@ -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
index a702fffb501d1c82175bcb47aa1cf3ecc25fc780..472df25037b0ffec19543273a52092dceabe86e2 100644 (file)
@@ -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)
     {
index 494326f47ffd1871cca000c7ca3ca80c01c3ee76..fc324c1582766a5cc652837f1e288cebe7a2ad39 100644 (file)
@@ -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 ());
        }
     }
 }
index 7fede4a5ab306af32ca63d7671f3ff90729efa8b..a578ac5d5069800419b67c914d91057f42c02100 100644 (file)
@@ -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;
index 21e3abc7f774ad44bd48bf8f0ccc9c83855b1784..965d16db4cd07b01a4179f44c4ce23a2dda39247 100644 (file)
@@ -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])
index c53b5aebb4785467d061ad39f16b56f689933fbd..a5e00341b97aa260f5051889f4abb7004e9e182c 100644 (file)
@@ -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);
index 2c3a23601e12fea229d1fad7275bb1c17c02659d..5de391440030710cbb94ed27950b3ac21527aa2e 100644 (file)
@@ -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",
index 9b8d0bdf86ae5071090912f941a304a10df1800f..9b3eedb1bf244da86737b4b1bc3e3f70b64bf60e 100644 (file)
@@ -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;
     }
 }
index cf0653b09d0a7d281bb62c95dd9b9043ab8931c7..2643bfaa22817416ac391241d347b236e4d0f2d1 100644 (file)
@@ -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;
index 929cbc385c482574853f53e032f5fbc2e7b54e1c..689cf7c2ec3d6a81c9f578643e3d7676ca27acc7 100644 (file)
 #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, &parameters);
       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, &parameters);
        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, &parameters);
        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;
            }
        }
index ed5797fbc3722bf2aa8740fc026643ce45f11969..7e52a825e2f03cc171f03750328d55785b04eb3f 100644 (file)
@@ -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");
 
index 02065b8db6c43c8e0e5a1ca0a89162a09ea5d96f..2efe5c7e07431fc38d56a3d6c23ce0c4c46560b0 100644 (file)
@@ -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;
index 3a18f16766c21aa30b31b53302ddce48909d8a3c..59236fe09ec58f65538968aedb885dd22d4fa8a5 100644 (file)
@@ -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
index 2897a1aaa8b570998a9f6e00e975d9266fc5fe7a..11cfa556c43beac77dfff82df940be5c14afc66e 100644 (file)
@@ -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");
index f1469a03f6de56ee454856e1daa8a36d2caf07d0..d9d977af51b3f6d9a60d1e16f57771da36327478 100644 (file)
@@ -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"))
index e41b09c553a775277ce0858665d79f9184a24211..ce1b41c6cc4c23bf665b9540f352da4af5be9a5b 100644 (file)
@@ -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);
+         }
       }
 }
 
index 51140efadf8dd3b799612c63db1477d8908e921e..e3d3078eccb9a800836b52175af4ce2d765517bc 100644 (file)
@@ -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);
     }
index 261df08564050de6ed35c34b072e2531deb3e57b..838156145bcbf003c9cd9dcfe431ca27cb038fa0 100644 (file)
@@ -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
index 87030d5cbdf90a16b60c47d86af51454d1eb4457..8391e7899b01179ac514fcbbeb384b7cc84bd3b3 100644 (file)
@@ -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;
index c695b7a76a3e8d83243b995e1b812cfd26192aa4..9fd9930f7de1aef560d0282f1860b99133fe398c 100644 (file)
@@ -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))
            {
index 0b1a5b3a858c5bdd3cf17e705d172a680bfedaa8..ddbae5bf33f6bdd6cf2b71896348bc50d196ecc4 100644 (file)
@@ -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_)
index 2b0e59494c1802f0566c74cb8e12babe31e195fd..69566653b2958eeff319253e93d410de3ad7bdc0 100644 (file)
@@ -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);
index 8e9386a441774ea98bdd6fb995d609560f3aeddd..f002607f355ff654fa6f9e3c62ecc7b45904837c 100644 (file)
@@ -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 ?
index ab120ab46dd8c45ab2945dc35f0c8b2b06526b9e..2d56df20d3e8e036df27a29a3d0e0262f0b0a68f 100644 (file)
@@ -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);
 
index ab150d16215fd0494e074d1e6fec6cb8177288e4..6311e8a07522e3ac47223839e841fd8541773f5a 100644 (file)
@@ -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);
     }
index ac03f5c67f6a26d52149f7d13880b5b368103e30..e3fc6914d1951622b291761c8442e9b12e7887f2 100644 (file)
@@ -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());
        }
     }
 }
index 953fe4ab7e302a619deadceba11ac764e011683d..087aa2ba9a274b970889131f8a1322b6c6a36c58 100644 (file)
@@ -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 (file)
index 0000000..c58ffd1
--- /dev/null
@@ -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;
+}
index b0a255d58f9f09f97d436afb4b26a3a8b4ad1fff..3ea894b2f6623e487e07d422fd046bdf69baa084 100644 (file)
@@ -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;
index 67401f226e881a1e19fccf28377aec6d8f309bd6..a6d57b4ce084dfb0463e5c2130aeac73a5adc265 100644 (file)
@@ -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
index edf700aa6095583e0b9aae663b3de86a78ea2523..929a0dbaa7cef571ab03dfe6c4ab3d626701703f 100644 (file)
@@ -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} "
index 121302769d8da6c6505b6389412bb14e25440645..d91e62342a8d55a6c8484a9b2c58a01a264a7864 100644 (file)
@@ -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 (file)
index 9fbd329..0000000
+++ /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;
-}
index 0d25cf1bdf9860701c3c55484c622b0293853129..c231c90eba2a3bbac68d950a13bde66a81b5a9d0 100644 (file)
@@ -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 ()))
index 22975589cbe2df8aad1482ac6f0da63da81c4b1e..accfe9c3b9a53f9d30d541ffe9a6cb68ff7437ca 100644 (file)
@@ -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 ();
 
index 2c5f39bbbac46c60d7d3568af3f2a9419a1d9789..9614c0f3773307bb11be049325d3b8d0a202822d 100644 (file)
@@ -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
 {
index c4b598761ab52078d853e53d9ad1842078111df7..3f318b5d68135af1048133a74c265c0d94f06ce3 100644 (file)
@@ -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 ();
index 99612587295acca798c4e65c2081844e7092ff43..29857100fa5d3e701a5f85123f5175bd3e8c6132 100644 (file)
@@ -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 ());
        }
     }
 }
index e80e20a706a94fa5d3c349f67fd07fbca561dd5a..5a220237bef1334730a18c3b7cde1dab8efeee4d 100644 (file)
@@ -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 *);
 };
 
index 746d7e14581f024b8d1367932aae200470d8fa70..b69fc15fce936c809c956768f74da4b33ae80d29 100644 (file)
 #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 (file)
index 0000000..8c5c4d5
--- /dev/null
@@ -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 */
+
index 9f46a06e1d87d2903bdc15696017ddbaa675a32b..6b8d86444974ecd5d9608e811b46f4c18ea2540c 100644 (file)
@@ -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);
index c8c0938e307c992192ce2d5cf19c014ed5af4647..072ed56bf1be2eb2b434d1f313482215e6832be8 100644 (file)
@@ -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 */
 
index 3a2f63e47c3dad1bea8a9b5436e08a2373027aaf..03abe6bde5eac278d91f1aa93772aaaf730b0b73 100644 (file)
@@ -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 */
index bed9339056d58f9fd64e7d591fda4503615637e0..0270d7a75136a3dc22150780e030475ed8a104f2 100644 (file)
@@ -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;
index 71e4d00741a4b05abfa12542cfe1dae149e3f8dc..abb7381ece0fefc284913e161256030c22b7c7d4 100644 (file)
@@ -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;
 
index 8a082b8f4ed7707db15aea2b0ce2c85288000abc..11addba59342356c670abc88105e19780dd074ae 100644 (file)
 
 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 *);
 
index 6c0fc1cbed436b0a4bebb5dcefc381663033df00..b06c0a4cc009da320f33c2fc58f855476993c441 100644 (file)
@@ -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 *);
index ea31faa752100070cbf80eadc5f8b1879e391b43..18ef76e739c21f78b63381d8c44c8653f3505be9 100644 (file)
@@ -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
 */
 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);
index ad4af88a55ecd14a44682be331652d5a43a2c4f4..ed33f010e5b19ae287ea36c8877e63b4f3e22b33 100644 (file)
@@ -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;
 };
index cb59170316359cc18c77760acd235c287fc7266a..8ded1dabca55aec1579f4d7d5abfa1cf91d75077 100644 (file)
@@ -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;
     }
   
index 1af1ef1a462ce6973a5dc74811d9ea2015ccdfb6..973a574c5736ceb76ed8ca65ddcc1028647b5774 100644 (file)
@@ -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_);
 }
 
 /**
index 05ffa05b0659f64f305a4f81b4f5e0985aa06862..11c496b299f82bb2f58a941341873b19da8ee4ce 100644 (file)
@@ -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"
index e56851fbe0601b9fadeb321cd69d00b77f873e85..9e2a79a4aa6baf95fa74a79260af56c5b3a73005 100644 (file)
@@ -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
index cbe036218512c2b6eab77b659954ea86c3d7834d..ad8b108e78320c0b64128265ce5825ac1a079ea2 100644 (file)
@@ -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;
index 48e22c3465e9f841aae53ddbec649f7e4cb08777..a45c9c59bb5808c483fdcc4cfd8e46dc80330e2a 100644 (file)
@@ -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;
index 897bb909fd70a5a2c6f5e426af754a2b8ad59d79..12020d306d5db969eae707519581b88f1e423fea 100644 (file)
@@ -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;
     }
index a3a6deb437e2f0549a73820e3fccd4eca77d75d8..465cfd6ae22f3a588c43112142c53e0b45275db6 100644 (file)
@@ -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)
 {
index 7ae551bd825d0e1cc0fa65c118211b9e0bb531c4..a32d324f1f39249af20a6cff98075ffeec41beb9 100644 (file)
@@ -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_);
index 3be575f66128c9f06c29a6f04c9464774b7d5033..9f2df9024081b5d5eaac5d09af8d0c39ab7773b9 100644 (file)
@@ -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))
index 61f7df05c5dede746f106193998ec34b71711937..787773019ed7f7eadf5684989807f9dd6ccde98c 100644 (file)
@@ -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;
     }
index 36af9534d26f65eab698be3e0f4f4ce78c1bec9f..555ac18ec19ba3bc149ca61dd097c9ef61b064c5 100644 (file)
@@ -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"
index 67935a0a2d53ac0da35657a52f139537a107f38e..abf3599ac2a37838e3b89bae5bb430aa9e1f1ff8 100644 (file)
@@ -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)
index 82640d4d626c9db8841537815756c68498fe9263..4a089529f118c319792e8e780b5ca5dc6df12fc6 100644 (file)
@@ -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);
index 4d6a148b4a424201977ad3379197d33dbf905f8e..72f05cf59244e0b7cc90e1efd1b9d12ba4251bea 100644 (file)
@@ -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);
 
index a518e02c8f384d9ee36f8cab5f13ab2a70961984..991e58983fe84cd00ccb101ca86ddb8fecfb5236 100644 (file)
@@ -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;
 }
index 5af17ec462a74444a7e96d862d3d96e0ba4cd374..d4d064d451ef523e7a7f4a55efcdad1fa19762ba 100644 (file)
@@ -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 ());
            }
        }
     }
index 75caaea3db1ffd39c8084a2e1ab185506507871f..d11e670e78fbdd8e19ba743fc6fa89b9fa7a5b83 100644 (file)
@@ -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);
index c1c3bcb250e4440cafc07bc448a770f45afb6703..f6564f67b1ce9d9c0b24c824f32271b69a7ade41 100644 (file)
@@ -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 ());
        }
 
       /*
index 4651a4cc0dfb683ffaad7b47428695d931cb5de1..2af1190d8169ed1d36b5a1e0930207672db4a4f8 100644 (file)
@@ -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);
index ea9dba5010deaf58d060ac1a81998029ac254b72..09aadd7a8e5cce2181e201ed7239dfeab7181140 100644 (file)
@@ -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);
index 421ab1fdfe06f98091b58c5c96e5e4b109af9cdd..d9c16d732767a557e6dbd866f7daf9942abd6921 100644 (file)
@@ -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",
index af4f263aa15e29b0283d11c17581bd31d1daa4d8..3f059df4e29c402e37b63815d3321e34c9f33d74 100644 (file)
@@ -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_)
            {
index 7c177452cf290383e9ee96f6086d596e785ce119..27ad66cb8c5bcd0803b9d9fd57d14f93c129bd84 100644 (file)
 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
index 46d2078a424e19c056417917e9581abfb239ff7d..985be103ae359d066116a2d61cc074d87a8b4fbb 100644 (file)
@@ -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_)
            {
index 6c6f93a62491c012215aec9d01c441550ebc685e..6e03fa6f726e3ff76ed20f8e13a8821ee08d1f90 100644 (file)
@@ -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)
index 42a766b33945d66e4cab80b860861eb2da091481..f6dec3a7c4372d368c47f6720be40145b51ed452 100644 (file)
@@ -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 ());
index 1a02e6a5ea1958da6a7bb55985ac56a97a41f74b..d112fa3621c56e1d070484b6b1443039a7d1087b 100644 (file)
 #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;
index 50648340d2b7edfef46feb1b80eb4aae75aed86f..b3bfe12aef26341b65f526653d8410af24d5c5df 100644 (file)
@@ -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_);
            }
        }
     }
index 381647b94554ea6ddb3e073536b7a8d607dac6a4..97009d98c72ef2a4f98b797c4c7155aa8a0bc43d 100644 (file)
@@ -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))
        {
index d9689abaaa5466af9a5bd5db4b7f5faac3ebf75f..fcdb0daf198b17e563bedfb915ad3605dc90a08f 100644 (file)
@@ -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));
index fb158915422a3b7d182407a1cb25ae9e89422020..a87846948bed8bbe74d090da66d42cf7441defe4 100644 (file)
@@ -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))
        {
index b1a8013389f0a32966808db620ba78953cd509fc..0cc546582bb8e7a0fdee92637d13e89bd5449d6a 100644 (file)
@@ -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"
index 2cdf5289c6dbbc03e8a84f1373f9b8627c312a50..f87e78279dd76f71037e1b1ea6b0a194e68bdbd6 100644 (file)
@@ -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 ());
            }
        }
     }
index 84a1beaf493317c732571899554a9d9574f02608..a5b81c0e95f8523a10ae9a3545a273f17a698986 100644 (file)
@@ -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--;)
     {
index dac80152cf88c04994f7fc242212d674633af568..d218a54d19a755c84b5c426e7666c8a0ea6980c9 100644 (file)
@@ -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;
index 4149e48b323a704c01ab04133a0507a7c6692cfe..19ad14326c28915999b53c6db24b1a29e9c519a8 100644 (file)
 
 #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",
index 4aeebc586a74437cb19134e810808aaa32b542f7..5637e335511c92676733cda15aa0f08c38d09c85 100644 (file)
@@ -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
index 830657e6f9f5e5f70e0fbea180943d2f972f0ff8..e97547d602ce96d6cbe2c9ff016bcf2090c0594a 100644 (file)
@@ -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;
index a9d9a500a8ee217dfdf103bae1c2bff6f023f465..541704eef7c2a569aa8361e6a5dedf3dd29971c6 100644 (file)
@@ -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)));
@@ -765,11 +780,6 @@ Spacing_spanner::breakable_column_spacing (Grob *me, Item *l, Item *r, Moment sh
   assert (!isinf (compound_space));
   compound_space = max (compound_space, compound_fixed);
 
-  /*
-    Hmm.  we do 1/0 in the next thing. Perhaps we should check if this
-    works on all architectures.
-  */
-
   /*
     There used to be code that changed spacing depending on
     raggedright setting.  Ugh.
index 8495a2f5fecb594beb2942e07d3a26cd5d509dfd..5f77670b3f0afdcd668c6e1bb937ffaf2280508a 100644 (file)
@@ -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;
index 548961d8efe7e398ce09787c7fc47d12cdd9072d..261791f1d041e4f938797a56b2a41fcf749cec61 100644 (file)
@@ -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))
index adaa648a1485277b92d5ec6bff37a0fdbdb04f9b..776f4097d111dbacf3b809f0b9138f7eeeca6c02 100644 (file)
@@ -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])
index 762e039dc1338080a4f938fd9d8a96b0c4d1e26d..c4ec3b14d605a289962805e1127315c59ad30eb8 100644 (file)
@@ -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;
     }
index 5bc33f68db535b023489b84070d31b43f9a4c000..8725390805016dbb94ebcc5d306f41f0e8cd6f90 100644 (file)
@@ -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 ());
     }
 }
 
index 3bc52e10d6810cc7a52c689217b5120573d82440..ef0690fc329d193ba0619539ab9f89d250b8ec00 100644 (file)
@@ -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);
 }
 
index 52b18cbe1159e866de529bdd1eb5a8357faf0455..0c9e40b6e2cf5fc473964a2f7d08510ea00e4dd1 100644 (file)
@@ -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
index a469c78cb1a66b70063ab37bd71cc1ea07f97845..36e7661242c5c0edb3be981ef39f9c54d820b1be 100644 (file)
@@ -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 ());
        }
     }
 }
index b1daa6284bc8cc1e14dc61eb4ed10f1018c48bc9..dc7bc0357349effde51578c6723095e624a41f39 100644 (file)
@@ -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");
index 2bdc2fbcf53dd0d0857e70e6f0e7db39ed680a69..4dc00e7bf31e9fcfa682c13fc4ab24ef678e7fa3 100644 (file)
@@ -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? 
index 389c355a1ae89816b50e1c8b90da5bfd77450808..4b4f33c17be572a1349a72aeb7bdf58f2005d5f9 100644 (file)
@@ -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"
index 8e978a4bc5a43e06bf4dfe8fdf4d20fef0bb1c24..e2d323b8c8f2c235a0514a37bf0cc8f9f02483c2 100644 (file)
@@ -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))
        {
index 2a88a4ae3c8968a2d532aa4cac33e2d908ddeeaf..4cf4f13c47d8590ce265f2bb73b52906963884bc 100644 (file)
 #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 "
index 9f8bf74fb949502925090cb01df5279142768080..e2e33530d40c306e455329b3cb5f58444b8191e5 100644 (file)
@@ -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;
 
index 081cd8611359d2f894f31b1beee27a18b37b834d..1ec1f8216335e2393ece2f7af15f127c1121a4c9 100644 (file)
@@ -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 (),
index 29d9916497baa66a0a9f3a47acb6633fda11b5e3..d7032e04ae8d0fb0d4b41e9c86b86508a8883391 100644 (file)
@@ -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]++;
index 7b0b9900f69ab5808d0aebc08c8a2558ad1f83a1..efcb08e794a951e0ef11a33d91a179bd6efff102 100644 (file)
@@ -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);
        }
     }
 }
index 76cce1605ec9501fb25312ea02ab77be0c1da84d..3609470758aef352402f4986e25d69fba9c6767a 100644 (file)
@@ -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;
index 2edf00f3128868ce60726af90150a17b1f15a84c..ed3c6134fb8c29869f7307fd4bfca3ccd55f90b8 100644 (file)
@@ -613,9 +613,6 @@ AncientRemoveEmptyStaffContext = \context {
   \remove "New_fingering_engraver"
 
   \description "Context for drawing notes in a Tab staff. "
-  \override Slur #'font-family    = #'roman
-  \override Slur #'print-function = #hammer-print-function
-  \override Slur #'direction = #-1
 
   %% Draws all stems/beams out of the staff (and not in the middle of the staff !)
   %% This feature is now disabled because most of the tab does not use it.
index 86de012065880054a8dde80dea0432b16d2009e7..99480d245ef301ab953dd0eadd2106e38d62b197 100644 (file)
@@ -523,11 +523,6 @@ sizes (like the dynamic @b{p} and @b{f}) on their baselines.")
 function is to protect objects from being garbage collected.")
      (arpeggio ,ly:grob? "pointer to arpeggio object.")
      (beam ,ly:grob? "pointer to the beam, if applicable.")
-     (center-element ,ly:grob? "grob which will be at the center of
-the group after aligning (when using
-Align_interface::center_on_element).")
-     (tweak-count ,number? "Number of otherwise unique Grobs.")
-     (tweak-rank ,number? "Identify otherwise unique Grobs.")
      (direction-source ,ly:grob? "in case side-relative-direction is
 set, which grob to get the direction from .")
      (dot ,ly:grob? "reference to Dots object.")
index ca682375c71cf250d66490743f786188ad50be43..fefab95947c158002034413db6770dfd0e1cf7a0 100644 (file)
@@ -395,6 +395,9 @@ possibly turned off."
 (define-public (symbol<? lst r)
   (string<? (symbol->string lst) (symbol->string r)))
 
+(define-public (symbol-key<? lst r)
+  (string<? (symbol->string (car lst)) (symbol->string (car r))))
+
 ;;
 ;; don't confuse users with #<procedure .. > syntax. 
 ;; 
index 14f40f8d57430aa61bd6c5894cdf9f9ac42a9460..52ccd660ad1660197d7cc52f44ad1d1da6cd5bd9 100644 (file)
                        (+ fret 5))
                       (else fret)))))))
 
-(define-public (hammer-print-function grob)
-  (let* ((note-collums (ly:grob-property grob 'note-columns))
-         (note-column1 (cadr note-collums))
-         (note-column2 (car  note-collums))
-         (note1 (car (ly:grob-property note-column1 'note-heads)))
-         (note2 (car (ly:grob-property note-column2 'note-heads)))
-        (text1 (ly:grob-property note1 'text))
-        (text2 (ly:grob-property note2 'text))
-         (fret1 (if (string? text1) (string->number text1) 0))
-         (fret2 (if (string? text2) (string->number text2) 0))
-         (letter (cond
-                 ((< fret1 fret2) "H")
-                 ((> fret1 fret2) "P")
-                 (else ""))))
-    (let* ((slur
-           ;; (Slur::print grob)
-
-           ;; 
-           ;; FIXME: a hammer is not a slur.
-           ;; 
-           (ly:make-stencil '() '(0 . 0) '(0 . 0)))
-          (layout (ly:grob-layout grob))
-          (text (interpret-markup
-                 layout
-                 (ly:grob-alist-chain grob (ly:output-def-lookup layout 'text-font-defaults))
-                 letter)))
-      
-      (let ((x (/ (- (cdr (ly:stencil-extent slur 0)) 
-                     (/ (cdr (ly:stencil-extent text 0)) 2.0))
-                  -2.0)))
-
-       (set! text
-             (ly:make-stencil (ly:stencil-expr text)
-                              (cons x x)
-                              (ly:stencil-extent text Y)))
-       
-        (ly:stencil-aligned-to text X RIGHT)))))
-
 
 (define-public guitar-tuning '(4 -1 -5 -10 -15 -20))
 (define-public bass-tuning '(-17 -22 -27 -32))
@@ -288,7 +250,7 @@ centered, X==1 is at the right, X == -1 is at the left."
 
 (define (parenthesize-elements grob)
   (let*
-      ((elts (ly:grob-property grob 'elements))
+      ((elts (ly:grob-object grob 'elements))
        (x-ext (ly:relative-group-extent elts grob X))
        (font (ly:grob-default-font grob))
        (lp (ly:font-get-glyph font "accidentals.leftparen"))