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.
-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.
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);
}
\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
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
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;
{
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);
#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"
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)
accs = scm_assq_set_x (accs, key, entry);
- me->set_property ("accidental-grobs", accs);
+ me->set_object ("accidental-grobs", 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);
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;
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);
}
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);
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 ();
#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);
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;
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);
"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
{
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]);
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
{
}
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
#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
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)
{
*/
#include "engraver.hh"
-#include "group-interface.hh"
+
+#include "pointer-group-interface.hh"
#include "arpeggio.hh"
#include "stem.hh"
#include "rhythmic-head.hh"
}
else if (Note_column::has_interface (info.grob ()))
{
- info.grob ()->set_property ("arpeggio", arpeggio_->self_scm ());
+ info.grob ()->set_object ("arpeggio", arpeggio_->self_scm ());
}
}
}
#include "warn.hh"
#include "font-interface.hh"
#include "lookup.hh"
+#include "pointer-group-interface.hh"
MAKE_SCHEME_CALLBACK (Arpeggio, print, 1);
SCM
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);
}
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;
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);
}
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;
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])
#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);
#include "axis-group-interface.hh"
+#include "grob.hh"
#include "hara-kiri-group-spanner.hh"
#include "warn.hh"
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);
}
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);
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));
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",
#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
{
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;
}
}
#include <math.h>
-#include "group-interface.hh"
+#include "pointer-group-interface.hh"
#include "array.hh"
#include "stem.hh"
#include "beam.hh"
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;
#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)
{
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));
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;
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.
*/
Real d = score_slopes_dy (qscores[i].yl, qscores[i].yr,
dy_mus, yr- yl,
xr - xl,
- xstaff);
+ xstaff, ¶meters);
qscores[i].demerits += d;
#if DEBUG_QUANTING
{
Real d = score_forbidden_quants (qscores[i].yl, qscores[i].yr,
rad, slt, thickness, beam_translation,
- edge_beam_counts, ldir, rdir);
+ edge_beam_counts, ldir, rdir, ¶meters);
qscores[i].demerits += d;
#if DEBUG_QUANTING
base_lengths, stem_xposns,
xl, xr,
is_knee,
- qscores[i].yl, qscores[i].yr);
+ qscores[i].yl, qscores[i].yr, ¶meters);
qscores[i].demerits += d;
#if DEBUG_QUANTING
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);
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_;
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;
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. */
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
{
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));
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;
}
}
#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"
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));
}
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;
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;
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 ();
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);
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
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++)
{
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);
}
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);
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);
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]))
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;
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++)
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++)
{
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--;)
{
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++)
{
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]))
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))
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;
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--;)
"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");
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];
}
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
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;
#include "paper-column.hh"
#include "cpu-timer.hh"
#include "simple-spacer.hh"
-#include "group-interface.hh"
Array<int>
Break_algorithm::find_break_indices () const
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");
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));
{
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;
}
/*
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")
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"))
+/*
+ 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"
/*
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);
+ }
}
/*
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;
}
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;
{
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);
};
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.)
*/
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;
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);
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++)
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;
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);
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++)
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);
+ }
}
}
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);
}
#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
#include "lookup.hh"
#include "output-def.hh"
#include "warn.hh"
+#include "pointer-group-interface.hh"
/*
TODO: Add support for cubic spline segments.
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 ();
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;
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;
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;
#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
// 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))
{
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 ();
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_)
(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
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
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;
}
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);
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 ?
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);
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);
}
#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"
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;
}
{
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());
}
}
}
#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"
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));
}
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));
--- /dev/null
+/*
+ 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;
+}
*/
return;
}
- SCM ifs = me->get_property ("interfaces");
+
+ SCM ifs = me->interfaces_;
SCM all_ifaces = ly_all_grob_interfaces ();
bool found = false;
#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"
since it can reuse the handle returned by scm_assq ().
*/
+// JUNKME.
void
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))
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
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} "
#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"
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. */
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:
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_;
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))
/* 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.
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);
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_);
}
}
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);
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
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 *
return s;
}
-IMPLEMENT_TYPE_P (Grob, "ly:grob?");
-
ADD_INTERFACE (Grob, "grob-interface",
"A grob represents a piece of music notation\n"
"\n"
"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");
+++ /dev/null
-/*
- 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;
-}
#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
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
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 ()))
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"))
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 ();
#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
{
#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"
{
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 ();
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
{
{
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 ());
}
}
}
#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 *);
};
#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:
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 *);
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));
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,
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:
static int forced_stem_count (Grob *);
};
-const int REGION_SIZE = 2;
-
#ifndef NDEBUG
#define DEBUG_QUANTING 1
#endif
--- /dev/null
+/*
+ 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 */
+
#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
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:
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:
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);
// URG
Grob *get_parent (Axis a) const;
- DECLARE_SCHEME_CALLBACK (fixup_refpoint, (SCM));
+ void fixup_refpoint ();
};
DECLARE_UNSMOB (Grob, grob);
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);
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 */
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 */
class Grace_iterator;
class Grace_music;
class Grob;
+class Grob_array;
class Hara_kiri_engraver;
class Hara_kiri_line_group_engraver;
class Includable_lexer;
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;
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 *);
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 *);
#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;
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);
#ifndef TRANSLATOR_GROUP_HH
#define TRANSLATOR_GROUP_HH
+
+
#include "translator.hh"
#include "parray.hh"
protected:
SCM simple_trans_list_;
+
friend class Context_def;
virtual void derived_mark () const;
};
#include "axis-group-interface.hh"
#include "context.hh"
#include "text-interface.hh"
+#include "grob-array.hh"
class Instrument_name_engraver : public Engraver
{
{
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;
}
#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
: 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_);
}
/**
(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"
#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
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);
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)
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;
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);
}
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
#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
{
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;
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;
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;
{
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;
}
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)
{
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 ();
}
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_);
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 ();
}
&& 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);
/*
}
}
-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);
}
{
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))
bool
Note_column::has_rests (Grob *me)
{
- return unsmob_grob (me->get_property ("rest"));
+ return unsmob_grob (me->get_object ("rest"));
}
int
Item *
Note_column::get_stem (Grob *me)
{
- SCM s = me->get_property ("stem");
+ SCM s = me->get_object ("stem");
return unsmob_item (s);
}
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));
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");
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);
}
Grob *
Note_column::get_rest (Grob *me)
{
- return unsmob_grob (me->get_property ("rest"));
+ return unsmob_grob (me->get_object ("rest"));
}
void
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);
}
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);
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;
}
*/
#include "engraver.hh"
-#include "group-interface.hh"
+#include "pointer-group-interface.hh"
#include "stem.hh"
#include "rhythmic-head.hh"
#include "side-position-interface.hh"
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)
#include "note-spacing.hh"
+#include "grob-array.hh"
#include "paper-column.hh"
#include "moment.hh"
#include "note-column.hh"
#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
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;
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)
{
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);
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)
}
}
- 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;
}
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);
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);
#include "directional-element-interface.hh"
#include "tuplet-bracket.hh"
#include "rhythmic-head.hh"
+#include "pointer-group-interface.hh"
struct Ottava_bracket
{
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);
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);
#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
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);
}
/*
/*
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.
*/
{
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;
}
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 ());
}
}
}
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);
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 ());
}
/*
#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"
// 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);
#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"
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")))
{
(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,
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;
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);
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",
#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
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_)
{
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);
}
void
Rhythmic_head::set_dots (Grob *me, Item *dot)
{
- me->set_property ("dot", dot->self_scm ());
+ me->set_object ("dot", dot->self_scm ());
}
int
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_)
{
#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)
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 ());
#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)
{
/*
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)
*/
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;
#include "note-spacing.hh"
#include "accidental-placement.hh"
#include "context.hh"
+#include "grob-array.hh"
struct Spacings
{
{
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 ())
{
}
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_);
}
}
}
#include "paper-column.hh"
#include "warn.hh"
-#include "group-interface.hh"
+#include "pointer-group-interface.hh"
#include "accidental-placement.hh"
void
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. */
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. */
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;
if (ext.is_empty ())
continue;
+
if (!last_grob
|| (last_grob && d * (ext[d]- (*last_ext)[d]) > 0))
{
#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"
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)
{
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
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));
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);
{
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))
{
#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"
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 ());
}
}
}
#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"
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)
{
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 ())
{
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
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]))
{
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--;)
{
#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"
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;
(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);
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++)
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;
#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?
}
mins = scm_cons (scm_cons (p->self_scm (), newdist), mins);
- me->set_property ("minimum-distances", mins);
+ me->set_object ("minimum-distances", mins);
}
void
}
#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));
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",
#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
(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. */
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;
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;
#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
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));
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
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;
}
/*
- 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?
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
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;
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);
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);
}
}
}
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++)
{
// 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);
}
}
}
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
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)));
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.
#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"
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;
#include "warn.hh"
#include "axis-group-interface.hh"
#include "bar-line.hh"
+#include "grob.hh"
void
Span_bar::add_bar (Grob *me, Grob *b)
/* 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.
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");
/* 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;
/* 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 ();
}
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))
#include <math.h>
-#include "group-interface.hh"
+#include "pointer-group-interface.hh"
#include "libc-extension.hh"
#include "paper-column.hh"
#include "paper-column.hh"
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)
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
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])
#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
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]);
}
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;
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;
}
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 ());
}
}
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);
}
#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
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 ());
}
}
}
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)
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");
#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"
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);
}
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;
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);
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))
}
/* 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.
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);
{
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;
}
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 ();
}
}
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));
}
/* 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?
#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"
/*
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;
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))
{
#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
{
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;
}
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")))
{
/*
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
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
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
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 ());
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"));
}
/* 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 ();
}
}
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. */
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));
}
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;
}
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;
/*
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 "
#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"
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;
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 (),
#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"
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");
{
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 ();
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))
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--;)
{
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 ())
{
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]++;
#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
{
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);
}
}
}
#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"
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;
\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.
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.")
(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.
;;
(+ 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))
(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"))