source file of the GNU LilyPond music typesetter
- (c) 1997--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+ (c) 1997--2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
*/
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;
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;
SCM s = scm_assq(sym, element_property_alist_);
if (s != SCM_BOOL_F)
- return SCM_CDR (s);
+ return gh_cdr (s);
if (pscore_l_)
{
Score_element::molecule_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 ()];
+ Molecule m = s->do_brew_molecule();
+ return m.extent()[c->axis ()];
}
{
#ifndef NPRINT
DEBUG_OUT << classname(this) << "{\n";
-
-
+
if (flower_dstream && !flower_dstream->silent_b ("Score_element"))
ly_display_scm (element_property_alist_);
{
Score_element * urg = (Score_element*)this;
SCM sz = urg->remove_elt_property ("fontsize");
- int i = (sz != SCM_UNDEFINED)
+ int i = (gh_number_p (sz))
? gh_scm2int (sz)
: 0;
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);
+ dim_cache_[X_AXIS]->off_callbacks_.push (Side_position_interface::aligned_on_self);
}
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);
+ dim_cache_[Y_AXIS]->set_offset_callback (Side_position_interface::aligned_on_self);
}
#endif
void
Score_element::output_processing ()
{
- if (get_elt_property ("transparent") != SCM_UNDEFINED)
+ 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;
+ pscore_l_->outputter_l_->output_molecule (m.expr_, o, classname(this));
}
/*
}
void
-Score_element::do_post_processing()
+Score_element::after_line_breaking ()
{
}
}
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
{
- Interval emp;
- emp.set_empty ();
- Molecule a (lookup_l ()->fill (Box (emp,emp)));
- return new Molecule (a);
+ SCM glyph = get_elt_property ("glyph");
+ if (gh_string_p (glyph))
+ {
+ return lookup_l ()->afm_find (String (ly_scm2string (glyph)));
+
+ }
+ else
+ {
+ 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)
{
- Score_element *sc = unsmob_element ( s);
+ again:
+
+
+ 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.
*/
- gh_set_car_x (s, handle_broken_smobs (gh_car (s), criterion));
- gh_set_cdr_x (s, handle_broken_smobs (gh_cdr (s), criterion));
-
- SCM c = gh_cdr(s);
-
- // gh_list_p () is linear, this is O(1)
- bool list = gh_pair_p (c) || c == SCM_EOL;
+ SCM car = handle_broken_smobs (gh_car (src), criterion);
+ SCM cdr = gh_cdr (src);
- if (gh_car (s) == SCM_UNDEFINED && list)
- return c;
- }
- return s;
-}
-#if 0
-void
-Score_element::recurse_into_smobs (SCM s, void (Score_element::*meth_ptr)())
-{
- Score_element * sc = unsmob_element ( s);
- if (sc)
- {
- (sc->*meth_ptr) ();
- }
- else if (gh_pair_p (s))
- {
- recurse_into_smobs (gh_car (s), meth_ptr);
- recurse_into_smobs (gh_cdr (s), meth_ptr);
+ if (car == SCM_UNDEFINED
+ && (gh_pair_p (cdr) || cdr == SCM_EOL))
+ {
+ /*
+ This is tail-recursion, ie.
+
+ return handle_broken_smobs (cdr, criterion);
+
+ We don't want to rely on the compiler to do this. */
+ src = cdr;
+ goto again;
+ }
+
+ return gh_cons (car, handle_broken_smobs (cdr, criterion));
}
+ else
+ return src;
+
+ return src;
}
-#endif
void
Score_element::handle_broken_dependencies()
{
- Line_of_score *line = line_l();
-
- SCM rec = get_elt_property ("handle-broken-deps");
- if (gh_boolean_p (rec) && gh_scm2bool (rec))
+ Spanner * s= dynamic_cast<Spanner*> (this);
+ if (original_l_ && s)
return;
-
- set_elt_property ("handle-broken-deps", SCM_BOOL_T);
- element_property_alist_ = handle_broken_smobs (element_property_alist_,
- line ? line->self_scm_ : SCM_UNDEFINED);
+ 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);
+ }
+ }
- if (!line)
- return;
+ 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
{
return 0;
}
-SCM
-Score_element::mark_smob (SCM ses)
-{
- void * mp = (void*) SCM_CDR(ses);
- Score_element * s = (Score_element*) mp;
-
- assert (s->self_scm_ == ses);
- return s->element_property_alist_;
-}
-
-
-int
-Score_element::print_smob (SCM s, SCM port, scm_print_state *)
-{
- Score_element *sc = (Score_element *) SCM_CDR (s);
-
- scm_puts ("#<Score_element ", port);
- scm_puts ((char *)sc->name (), port);
-
- // scm_puts (" properties = ", port);
- // scm_display (sc->element_property_alist_, port);
- scm_puts (" >", port);
- return 1;
-}
-
-void
-Score_element::do_smobify_self ()
-{
- scm_unprotect_object (element_property_alist_); // ugh
-}
-#include "ly-smobs.icc"
-IMPLEMENT_SMOBS(Score_element);
-
-SCM
-Score_element::equal_p (SCM a, SCM b)
-{
- return SCM_CDR(a) == SCM_CDR(b) ? SCM_BOOL_T : SCM_BOOL_F;
-}
-
void
Score_element::translate_axis (Real y, Axis a)
{
Score_element::common_refpoint (Score_element const* s, Axis a) const
{
Dimension_cache *dim = dim_cache_[a]->common_refpoint (s->dim_cache_[a]);
- if (!dim)
- programming_error ("No common reference point");
return dim ? dim->element_l () : 0;
}
return d->get_dim ();
}
-Score_element*
-unsmob_element (SCM s)
-{
- if (SMOB_IS_TYPE_B (Score_element, s))
- return SMOB_TO_TYPE(Score_element,s);
- else
- return 0;
-}
-
-
-/*
- JUNKME
- */
-void
-Score_element::invalidate_cache (Axis a)
-{
- // dim_cache_[a]->invalidate ();
-}
Score_element*
Score_element::parent_l (Axis a) const
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 ())
{
- 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 (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);
}
}
}
}
}
+
+
+
+/****************************************************
+ SMOB funcs
+ ****************************************************/
+
+
+#include "ly-smobs.icc"
+
+IMPLEMENT_UNSMOB(Score_element, element);
+IMPLEMENT_SMOBS(Score_element);
+SCM
+Score_element::mark_smob (SCM ses)
+{
+ Score_element * s = SMOB_TO_TYPE (Score_element, ses);
+ if (s->self_scm_ != ses)
+ {
+ programming_error ("SMOB marking gone awry");
+ return SCM_EOL;
+ }
+ return s->element_property_alist_;
+}
+
+int
+Score_element::print_smob (SCM s, SCM port, scm_print_state *)
+{
+ Score_element *sc = (Score_element *) gh_cdr (s);
+
+ scm_puts ("#<Score_element ", port);
+ scm_puts ((char *)sc->name (), port);
+
+ /*
+ don't try to print properties, that is too much hassle.
+ */
+ scm_puts (" >", port);
+ return 1;
+}
+
+void
+Score_element::do_smobify_self ()
+{
+}
+
+SCM
+Score_element::equal_p (SCM a, SCM b)
+{
+ 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);