#include "dimension-cache.hh"
#include "side-position-interface.hh"
#include "item.hh"
+/*
+TODO:
+
+remove dynamic_cast<Spanner,Item> and put this code into respective
+ subclass.
+*/
Score_element::Score_element()
{
- output_p_ =0;
dim_cache_[X_AXIS] = new Dimension_cache;
dim_cache_[Y_AXIS] = new Dimension_cache;
dim_cache_[X_AXIS]->elt_l_ = dim_cache_[Y_AXIS]->elt_l_ = this;
-
+
+ // junkme.
used_b_ = false;
- dim_cache_[X_AXIS]->set_callback (molecule_extent);
- dim_cache_[Y_AXIS]->set_callback (molecule_extent);
+ dim_cache_[X_AXIS]->set_extent_callback (molecule_extent);
+ dim_cache_[Y_AXIS]->set_extent_callback (molecule_extent);
used_b_ = false;
pscore_l_=0;
lookup_l_ =0;
set_elt_property ("dependencies", SCM_EOL);
-}
-
-SCM ly_deep_copy (SCM);
-
-SCM
-ly_deep_copy (SCM l)
-{
- if (gh_pair_p (l))
- {
- return gh_cons (ly_deep_copy (gh_car (l)), ly_deep_copy (gh_cdr (l)));
- }
- else
- return l;
+ set_elt_property ("interfaces", SCM_EOL);
}
self_scm_ = SCM_EOL;
used_b_ = true;
original_l_ =(Score_element*) &s;
+ element_property_alist_ = SCM_EOL; // onstack;
- /*
- should protect because smobify_self () might trigger GC.
- */
- element_property_alist_ = scm_protect_object (ly_deep_copy (s.element_property_alist_));
-
- output_p_ =0;
status_i_ = s.status_i_;
lookup_l_ = s.lookup_l_;
pscore_l_ = s.pscore_l_;
Score_element::~Score_element()
{
- assert (!output_p_);
assert (status_i_ >=0);
status_i_ = -1;
delete dim_cache_[Y_AXIS];
}
-
-Real
-Score_element::get_real (String s) const
-{
- return gh_scm2double (get_elt_property (s));
-}
-
-void
-Score_element::set_real (String s, Real r)
-{
- set_elt_property (s, gh_double2scm (r));
-}
-
// should also have one that takes SCM arg.
SCM
Score_element::get_elt_property (String nm) const
}
Interval
-Score_element::molecule_extent(Dimension_cache const *c)
+Score_element::molecule_extent (Dimension_cache const *c)
+{
+ Score_element *s = dynamic_cast<Score_element*>(c->element_l());
+ Molecule m = s->do_brew_molecule();
+ return m.extent()[c->axis ()];
+}
+
+Interval
+Score_element::preset_extent (Dimension_cache const *c)
{
Score_element *s = dynamic_cast<Score_element*>(c->element_l());
- Molecule*m = s->do_brew_molecule_p();
- return m->extent()[c->axis ()];
+ SCM ext = s->get_elt_property ((c->axis () == X_AXIS)
+ ? "extent-X"
+ : "extent-Y");
+
+ if (gh_pair_p (ext))
+ {
+ Real l = gh_scm2double (gh_car (ext));
+ Real r = gh_scm2double (gh_cdr (ext));
+ l *= s->paper_l ()->get_var ("staffspace");
+ r *= s->paper_l ()->get_var ("staffspace");
+ return Interval (l, r);
+ }
+
+ return Interval ();
}
if (get_elt_property ("self-alignment-X") != SCM_UNDEFINED
&& !dim_cache_[X_AXIS]->off_callback_l_)
{
- dim_cache_[X_AXIS]->off_callbacks_.push (Side_position_interface::self_alignment);
+ add_offset_callback (Side_position_interface::aligned_on_self,X_AXIS);
}
if (get_elt_property ("self-alignment-Y") != SCM_UNDEFINED
&& !dim_cache_[X_AXIS]->off_callback_l_)
{
- dim_cache_[Y_AXIS]->set_offset_callback (Side_position_interface::self_alignment);
+ add_offset_callback (Side_position_interface::aligned_on_self, Y_AXIS);
}
#endif
if (status_i_ >= final)
return;
- assert (status_i_!= busy);
+ if (status_i_== busy)
+ {
+ programming_error ("Element is busy, come back later");
+ return;
+ }
+
status_i_= busy;
- Link_array<Score_element> dependency_arr =
- Group_interface__extract_elements (this, (Score_element*)0, "dependencies");
-
- for (int i=0; i < dependency_arr.size(); i++)
- dependency_arr[i]->calculate_dependencies (final, busy, funcptr);
+ for (SCM d= get_elt_property ("dependencies"); d != SCM_EOL; d = gh_cdr (d))
+ {
+ unsmob_element (gh_car (d))
+ ->calculate_dependencies (final, busy, funcptr);
+ }
- Link_array<Score_element> extra (get_extra_dependencies());
- for (int i=0; i < extra.size(); i++)
- extra[i]->calculate_dependencies (final, busy, funcptr);
-
(this->*funcptr)();
status_i_= final;
}
void
Score_element::output_processing ()
{
- if (to_boolean (get_elt_property ("transparent")))
+ if (to_boolean (get_elt_property ("transparent")))
return;
- // we're being silly here.
- if (output_p_)
- delete output_p_;
-
- output_p_ = do_brew_molecule_p ();
+ Molecule m (do_brew_molecule ());
Offset o (relative_coordinate (0, X_AXIS), relative_coordinate (0, Y_AXIS));
SCM s = get_elt_property ("extra-offset");
o[Y_AXIS] += il * gh_scm2double (gh_cdr (s));
}
- pscore_l_->outputter_l_->output_molecule (output_p_,
- o,
- classname(this));
-
- delete output_p_;
- output_p_ =0;
+ line_l ()->output_molecule (m.expr_, o);
}
/*
}
void
-Score_element::do_post_processing()
+Score_element::after_line_breaking ()
{
}
-void
-Score_element::do_breakable_col_processing()
-{
- handle_prebroken_dependencies();
-}
void
-Score_element::do_pre_processing()
+Score_element::before_line_breaking ()
{
}
-Molecule*
-Score_element::do_brew_molecule_p() const
+Molecule
+Score_element::do_brew_molecule() const
{
SCM glyph = get_elt_property ("glyph");
if (gh_string_p (glyph))
{
- Molecule*output = new Molecule (lookup_l ()->afm_find (String (ly_scm2string (glyph))));
+ return lookup_l ()->afm_find (String (ly_scm2string (glyph)));
- return output;
}
else
{
- Interval emp;
- emp.set_empty ();
- Molecule a (lookup_l ()->fill (Box (emp,emp)));
- return new Molecule (a);
+ Molecule m ;
+ m.set_empty (true);
+ return m;
}
}
/**
Do break substitution in S, using CRITERION. Return new value.
- CRITERION is either a SMOB pointer to the desired line, or a number
- representing the break direction. */
+ CRITERION is either a SMOB pointer to the desired line, or a number
+ representing the break direction. Do not modify SRC.
+*/
SCM
-Score_element::handle_broken_smobs (SCM s, SCM criterion)
+Score_element::handle_broken_smobs (SCM src, SCM criterion)
{
again:
- Score_element *sc = unsmob_element ( s);
+ Score_element *sc = unsmob_element (src);
if (sc)
{
if (criterion == SCM_UNDEFINED)
return SCM_UNDEFINED;
}
}
- else if (gh_pair_p (s))
+ else if (gh_pair_p (src))
{
/*
UGH! breaks on circular lists.
*/
- SCM car = handle_broken_smobs (gh_car (s), criterion);
- SCM cdr = gh_cdr (s);
+ SCM car = handle_broken_smobs (gh_car (src), criterion);
+ SCM cdr = gh_cdr (src);
if (car == SCM_UNDEFINED
&& (gh_pair_p (cdr) || cdr == SCM_EOL))
return handle_broken_smobs (cdr, criterion);
We don't want to rely on the compiler to do this. */
- s = cdr;
+ src = cdr;
goto again;
}
- gh_set_car_x (s, car);
- gh_set_cdr_x (s, handle_broken_smobs (cdr, criterion));
- return s;
+ return gh_cons (car, handle_broken_smobs (cdr, criterion));
}
- return s;
+ else
+ return src;
+
+ return src;
}
void
Score_element::handle_broken_dependencies()
{
- Line_of_score *line = line_l();
- element_property_alist_ = handle_broken_smobs (element_property_alist_,
- line ? line->self_scm_ : SCM_UNDEFINED);
-
- if (!line)
+ Spanner * s= dynamic_cast<Spanner*> (this);
+ if (original_l_ && s)
return;
+
+ if (s)
+ {
+ for (int i = 0; i< s->broken_into_l_arr_ .size (); i++)
+ {
+ Score_element * sc = s->broken_into_l_arr_[i];
+ Line_of_score * l = sc->line_l ();
+ s->broken_into_l_arr_[i]->element_property_alist_ =
+ handle_broken_smobs (element_property_alist_,
+ l ? l->self_scm_ : SCM_UNDEFINED);
+ }
+ }
+
+ Line_of_score *line = line_l();
+ element_property_alist_
+ = handle_broken_smobs (element_property_alist_,
+ line ? line->self_scm_ : SCM_UNDEFINED);
}
{
if (Item*i =dynamic_cast<Item*> (this))
{
- element_property_alist_
- = handle_broken_smobs (element_property_alist_,
+ if (original_l_)
+ {
+ element_property_alist_
+ = handle_broken_smobs (original_l_->element_property_alist_,
gh_int2scm (i->break_status_dir ()));
+ }
}
}
-
-
-
-
-Link_array<Score_element>
-Score_element::get_extra_dependencies() const
-{
- Link_array<Score_element> empty;
- return empty;
-}
-
bool
Score_element::linked_b() const
{
return 0;
}
-
-
void
Score_element::translate_axis (Real y, Axis a)
{
return dim ? dim->element_l () : 0;
}
-void
-Score_element::set_empty (Axis a)
-{
- dim_cache_[a]->callback_l_ =0;
-}
-
bool
Score_element::empty_b (Axis a)const
{
- return !dim_cache_[a]->callback_l_;
+ return !dim_cache_[a]->extent_callback_l_;
}
Interval
Score_element::extent (Axis a) const
{
Dimension_cache const * d = dim_cache_[a];
+ Interval ext = d->get_dim ();
- return d->get_dim ();
+ if (empty_b (a))
+ return ext;
+
+ SCM extra = get_elt_property (a == X_AXIS ? "extra-extent-X"
+ : "extra-extent-Y");
+
+ /*
+ signs ?
+ */
+ Real s = paper_l ()->get_var ("staffspace");
+ if (gh_pair_p (extra))
+ {
+ ext[BIGGER] += s * gh_scm2double (gh_cdr (extra));
+ ext[SMALLER] += s * gh_scm2double (gh_car (extra));
+ }
+
+ extra = get_elt_property (a == X_AXIS
+ ? "minimum-extent-X"
+ : "minimum-extent-Y");
+ if (gh_pair_p (extra))
+ {
+ ext.unite (Interval (s * gh_scm2double (gh_car (extra)),
+ s * gh_scm2double (gh_cdr (extra))));
+ }
+
+ return ext;
}
return classname (this);
}
+void
+Score_element::add_offset_callback (Offset_cache_callback cb, Axis a)
+{
+ dim_cache_[a]->off_callbacks_.push (cb);
+}
+
+bool
+Score_element::has_offset_callback_b (Offset_cache_callback cb, Axis a)const
+{
+ for (int i= dim_cache_[a]->off_callbacks_.size (); i--;)
+ {
+ if (dim_cache_[a]->off_callbacks_[i] == cb)
+ return true;
+ }
+ return false;
+}
+
+void
+Score_element::set_extent_callback (Dim_cache_callback dc, Axis a)
+{
+ dim_cache_[a]->extent_callback_l_ = dc ;
+}
+
void
Score_element::set_parent (Score_element *g, Axis a)
{
for (int a = X_AXIS; a < NO_AXES; a ++)
{
Axis ax = (Axis)a;
- Score_element * par = parent_l (ax);
+ Score_element * parent = parent_l (ax);
- if (!par)
+ if (!parent)
continue;
- if (par->line_l () != line_l ())
+ if (parent->line_l () != line_l () && line_l ())
{
- Score_element * newpar = par->find_broken_piece (line_l ());
- set_parent (newpar, ax);
+ Score_element * newparent = parent->find_broken_piece (line_l ());
+ set_parent (newparent, ax);
+ if (!newparent)
+ {
+ programming_error ("Orphaned score-element.");
+ }
}
if (Item * i = dynamic_cast<Item*> (this))
{
- Item *pari = dynamic_cast<Item*> (par);
+ Item *parenti = dynamic_cast<Item*> (parent);
- if (pari && i)
+ if (parenti && i)
{
Direction my_dir = i->break_status_dir () ;
- if (my_dir!= pari->break_status_dir())
+ if (my_dir!= parenti->break_status_dir())
{
- Item *newpar = pari->find_broken_piece (my_dir);
- set_parent (newpar, ax);
+ Item *newparent = parenti->find_broken_piece (my_dir);
+ set_parent (newparent, ax);
}
}
}
#include "ly-smobs.icc"
-IMPLEMENT_SMOBS(Score_element);
IMPLEMENT_UNSMOB(Score_element, element);
+IMPLEMENT_SMOBS(Score_element);
SCM
Score_element::mark_smob (SCM ses)
{
scm_puts ("#<Score_element ", port);
scm_puts ((char *)sc->name (), port);
- // scm_puts (" properties = ", port);
- // scm_display (sc->element_property_alist_, port);
+ /*
+ don't try to print properties, that is too much hassle.
+ */
scm_puts (" >", port);
return 1;
}
void
Score_element::do_smobify_self ()
{
- scm_unprotect_object (element_property_alist_); // ugh
}
SCM
{
return gh_cdr(a) == gh_cdr(b) ? SCM_BOOL_T : SCM_BOOL_F;
}
+
+
+SCM
+Score_element::ly_set_elt_property (SCM elt, SCM sym, SCM val)
+{
+ Score_element * sc = unsmob_element (elt);
+
+ if (!gh_symbol_p (sym))
+ {
+ error ("Not a symbol");
+ ly_display_scm (sym);
+ return SCM_UNDEFINED;
+ }
+
+ if (sc)
+ {
+ sc->element_property_alist_ = scm_assoc_set_x (sc->element_property_alist_, sym, val);
+ }
+ else
+ {
+ error ("Not a score element");
+ ly_display_scm (elt);
+ }
+
+ return SCM_UNDEFINED;
+}
+
+
+SCM
+Score_element::ly_get_elt_property (SCM elt, SCM sym)
+{
+ Score_element * sc = unsmob_element (elt);
+
+ if (sc)
+ {
+ SCM s = scm_assq(sym, sc->element_property_alist_);
+
+ if (s != SCM_BOOL_F)
+ return gh_cdr (s);
+ else
+ return SCM_UNDEFINED;
+ }
+ else
+ {
+ error ("Not a score element");
+ ly_display_scm (elt);
+ }
+ return SCM_UNDEFINED;
+}
+
+
+static void
+init_functions ()
+{
+ scm_make_gsubr ("ly-get-elt-property", 2, 0, 0, (SCM(*)(...))Score_element::ly_get_elt_property);
+ scm_make_gsubr ("ly-set-elt-property", 3, 0, 0, (SCM(*)(...))Score_element::ly_set_elt_property);
+}
+
+ADD_SCM_INIT_FUNC(scoreelt, init_functions);
+
+void
+Score_element::do_breakable_col_processing ()
+{
+}