/*
This file is part of LilyPond, the GNU music typesetter.
- Copyright (C) 2001--2009 Han-Wen Nienhuys <hanwen@xs4all.nl>
+ Copyright (C) 2001--2015 Han-Wen Nienhuys <hanwen@xs4all.nl>
LilyPond is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Item *i = dynamic_cast<Item *> (sc);
Direction d = to_dir (break_criterion);
if (i && i->break_status_dir () != d)
- {
- Item *br = i->find_prebroken_piece (d);
- return br;
- }
+ {
+ Item *br = i->find_prebroken_piece (d);
+ return br;
+ }
}
else
{
System *line
- = dynamic_cast<System *> (unsmob_grob (break_criterion));
+ = unsmob<System> (break_criterion);
if (sc->get_system () != line)
- sc = sc->find_broken_piece (line);
+ sc = sc->find_broken_piece (line);
/* now: !sc || (sc && sc->get_system () == line) */
if (!sc)
- return 0;
+ return 0;
/* now: sc && sc->get_system () == line */
if (!line)
- return sc;
+ return sc;
/*
- We don't return SCM_UNDEFINED for
- suicided grobs, for two reasons
+ We don't return SCM_UNDEFINED for
+ suicided grobs, for two reasons
- - it doesn't work (strange disappearing objects)
+ - it doesn't work (strange disappearing objects)
- - it forces us to mark the parents of a grob, leading to
- a huge recursion in the GC routine.
+ - it forces us to mark the parents of a grob, leading to
+ a huge recursion in the GC routine.
*/
if (sc->common_refpoint (line, X_AXIS)
- && sc->common_refpoint (line, Y_AXIS))
- return sc;
+ && sc->common_refpoint (line, Y_AXIS))
+ return sc;
return 0;
}
SCM
do_break_substitution (SCM src)
{
- again:
+again:
- if (unsmob_grob (src))
+ if (unsmob<Grob> (src))
{
- Grob *new_ptr = substitute_grob (unsmob_grob (src));
+ Grob *new_ptr = substitute_grob (unsmob<Grob> (src));
return new_ptr ? new_ptr->self_scm () : SCM_UNDEFINED;
}
else if (scm_is_vector (src))
int len = scm_c_vector_length (src);
SCM nv = scm_c_make_vector (len, SCM_UNDEFINED);
for (int i = 0; i < len; i++)
- {
- SCM si = scm_from_int (i);
- scm_vector_set_x (nv, si,
- do_break_substitution (scm_vector_ref (src, si)));
- }
+ {
+ SCM si = scm_from_int (i);
+ scm_vector_set_x (nv, si,
+ do_break_substitution (scm_vector_ref (src, si)));
+ }
}
else if (scm_is_pair (src))
{
/*
- UGH! breaks on circular lists.
+ UGH! breaks on circular lists.
*/
SCM newcar = do_break_substitution (scm_car (src));
SCM oldcdr = scm_cdr (src);
- if (newcar == SCM_UNDEFINED
- && (scm_is_pair (oldcdr) || oldcdr == SCM_EOL))
- {
- /*
- This is tail-recursion, ie.
+ if (SCM_UNBNDP (newcar)
+ && (scm_is_pair (oldcdr) || scm_is_null (oldcdr)))
+ {
+ /*
+ This is tail-recursion, ie.
- return do_break_substution (cdr);
+ return do_break_substution (cdr);
- We don't want to rely on the compiler to do this. Without
- tail-recursion, this easily crashes with a stack overflow. */
- src = oldcdr;
- goto again;
- }
+ We don't want to rely on the compiler to do this. Without
+ tail-recursion, this easily crashes with a stack overflow. */
+ src = oldcdr;
+ goto again;
+ }
return scm_cons (newcar, do_break_substitution (oldcdr));
}
return src;
}
-/*
- Perform substitution on GROB_LIST using a constant amount of stack.
-*/
-vector<Grob*> temporary_substition_array;
-void
-substitute_grob_array (Grob_array *grob_arr, Grob_array *new_arr)
-{
- vector<Grob*> &old_grobs (grob_arr->array_reference ());
- vector<Grob*> *new_grobs (new_arr == grob_arr
- ? & temporary_substition_array
- : &new_arr->array_reference ());
-
- new_grobs->resize (old_grobs.size ());
- Grob **array = (Grob **) new_grobs->data ();
- Grob **ptr = array;
- for (vsize i = 0; i < old_grobs.size (); i++)
- {
- Grob *orig = old_grobs[i];
- Grob *new_grob = substitute_grob (orig);
- if (new_grob)
- *ptr++ = new_grob;
- }
-
- new_grobs->resize (ptr - array);
- if (new_arr == grob_arr)
- new_arr->set_array (*new_grobs);
-}
-
/*
We don't do
else
{
if (sp->broken_intos_.size ())
- rv = Slice (sp->broken_intos_[0]->get_system ()->get_rank (),
- sp->broken_intos_.back ()->get_system ()->get_rank ());
+ rv = Slice (sp->broken_intos_[0]->get_system ()->get_rank (),
+ sp->broken_intos_.back ()->get_system ()->get_rank ());
}
return rv;
}
return Slice (st->get_rank (), st->get_rank ());
Slice sr;
- Direction d = LEFT;
- do
+ for (LEFT_and_RIGHT (d))
{
Item *bi = it->find_prebroken_piece (d);
if (bi && bi->get_system ())
- sr.add_point (bi->get_system ()->get_rank ());
+ sr.add_point (bi->get_system ()->get_rank ());
}
- while (flip (&d) != LEFT);
return sr;
}
*/
if (sr.is_empty ())
{
- /*
- overflow if we don't treat this specially.
- */
- left_ = 1;
- right_ = -1;
+ /*
+ overflow if we don't treat this specially.
+ */
+ left_ = 1;
+ right_ = -1;
}
else
{
- left_ = sr[LEFT];
- right_ = sr[RIGHT];
+ left_ = (short) sr[LEFT];
+ right_ = (short) sr[RIGHT];
}
}
Substitution_entry ()
item_compare (void const *a, void const *b)
{
return ((Substitution_entry *)a)->left_
- - ((Substitution_entry *)b)->left_;
+ - ((Substitution_entry *)b)->left_;
}
static int
spanner_compare (void const *a, void const *b)
{
return ((Substitution_entry *)a)->length ()
- - ((Substitution_entry *)b)->length ();
+ - ((Substitution_entry *)b)->length ();
}
};
bool
Spanner::fast_substitute_grob_array (SCM sym,
- Grob_array *grob_array)
+ Grob_array *grob_array)
{
int len = grob_array->size ();
int idx = 0;
if (dynamic_cast<Spanner *> (g))
- idx = --spanner_index;
+ idx = --spanner_index;
else if (dynamic_cast<Item *> (g))
- idx = item_index++;
+ idx = item_index++;
vec[idx].set (g, sr);
}
qsort (vec, item_index,
- sizeof (Substitution_entry), &Substitution_entry::item_compare);
+ sizeof (Substitution_entry), &Substitution_entry::item_compare);
vector<Slice> item_indices;
vector<Slice> spanner_indices;
}
vector<Slice> *arrs[]
- = {
+ =
+ {
&item_indices, &spanner_indices
};
- for (int i = 0; i < item_index;i++)
+ for (int i = 0; i < item_index; i++)
{
for (int j = vec[i].left_; j <= vec[i].right_; j++)
- item_indices[j - system_range[LEFT]].add_point (i);
+ item_indices[j - system_range[LEFT]].add_point (i);
}
/*
assert (item_index <= spanner_index);
assert ((broken_intos_.size () == (vsize)system_range.length () + 1)
- || (broken_intos_.empty () && system_range.length () == 0));
+ || (broken_intos_.empty () && system_range.length () == 0));
for (vsize i = 0; i < broken_intos_.size (); i++)
{
Grob *sc = broken_intos_[i];
set_break_subsititution (l ? l->self_scm () : SCM_UNDEFINED);
SCM newval = sc->internal_get_object (sym);
- if (!unsmob_grob_array (newval))
- {
- newval = Grob_array::make_array ();
- sc->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++)
- {
- Grob *substituted = substitute_grob (vec[j].grob_);
- if (substituted)
- new_array->add (substituted);
- }
+ if (!unsmob<Grob_array> (newval))
+ {
+ newval = Grob_array::make_array ();
+ sc->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++)
+ {
+ Grob *substituted = substitute_grob (vec[j].grob_);
+ if (substituted)
+ new_array->add (substituted);
+ }
#ifdef PARANOIA
printf ("%d (%d), sp %d (%d)\n",
- item_indices [i].length (), item_index,
- spanner_indices[i].length (), len -spanner_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));
+ SCM l1 = substitute_grob_list (grob_list);
+ assert (scm_ilength (l1) == scm_ilength (newval));
}
#endif
}
SCM sym = scm_caar (s);
SCM val = scm_cdar (s);
- 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;
- }
+ 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);
+ // TODO: What if new_arr is null?
+ new_arr->filter_map_assign (*orig, substitute_grob);
+ val = newval;
+ }
else
- val = do_break_substitution (val);
-
- if (val != SCM_UNDEFINED)
- {
- /*
- for ly:grob? properties, SCM_UNDEFINED could leak out
- through ly:grob-property
- */
- *tail = scm_cons (scm_cons (sym, val), SCM_EOL);
- tail = SCM_CDRLOC (*tail);
- }
+ val = do_break_substitution (val);
+
+ if (!SCM_UNBNDP (val))
+ {
+ /*
+ for ly:grob? properties, SCM_UNDEFINED could leak out
+ through ly:grob-property
+ */
+ *tail = scm_cons (scm_cons (sym, val), SCM_EOL);
+ tail = SCM_CDRLOC (*tail);
+ }
}
return l;
}
void
Spanner::substitute_one_mutable_property (SCM sym,
- SCM val)
+ SCM val)
{
Spanner *s = this;
bool fast_done = false;
- Grob_array *grob_array = unsmob_grob_array (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 (vsize i = 0; i < s->broken_intos_.size (); i++)
{
- Grob *sc = s->broken_intos_[i];
- System *l = sc->get_system ();
- set_break_subsititution (l ? l->self_scm () : SCM_UNDEFINED);
-
- if (grob_array)
- {
- SCM newval = sc->internal_get_object (sym);
- if (!unsmob_grob_array (newval))
- {
- newval = Grob_array::make_array ();
- sc->set_object (sym, newval);
- }
- substitute_grob_array (grob_array, unsmob_grob_array (newval));
- }
- else
- {
- SCM newval = do_break_substitution (val);
- sc->set_object (sym, newval);
- }
+ Grob *sc = s->broken_intos_[i];
+ System *l = sc->get_system ();
+ set_break_subsititution (l ? l->self_scm () : SCM_UNDEFINED);
+
+ if (grob_array)
+ {
+ SCM newval = sc->internal_get_object (sym);
+ if (!unsmob<Grob_array> (newval))
+ {
+ newval = Grob_array::make_array ();
+ sc->set_object (sym, newval);
+ }
+ Grob_array *new_arr = unsmob<Grob_array> (newval);
+ new_arr->filter_map_assign (*grob_array, substitute_grob);
+ }
+ else
+ {
+ SCM newval = do_break_substitution (val);
+ sc->set_object (sym, newval);
+ }
}
}