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>
*/
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;
-
- /*
- should protect because smobify_self () might trigger GC.
- */
- element_property_alist_ = scm_protect_object (ly_deep_copy (s.element_property_alist_));
+ element_property_alist_ = SCM_EOL; // onstack;
output_p_ =0;
status_i_ = s.status_i_;
{
Score_element *s = dynamic_cast<Score_element*>(c->element_l());
Molecule*m = s->do_brew_molecule_p();
- return m->extent()[c->axis ()];
+
+ Interval iv = m->extent()[c->axis ()];
+
+ delete m;
+ return iv;
}
{
#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.
Molecule*
Score_element::do_brew_molecule_p() 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))
+ {
+ Molecule*output = new Molecule (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);
+ }
}
/**
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;
+ 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));
}
- 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
{
return 0;
}
-SCM
-Score_element::mark_smob (SCM ses)
-{
- void * mp = (void*) gh_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 *) gh_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 gh_cdr(a) == gh_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;
-}
-
Score_element*
Score_element::parent_l (Axis a) const
}
}
}
+
+
+
+/****************************************************
+ SMOB funcs
+ ****************************************************/
+
+
+#include "ly-smobs.icc"
+
+IMPLEMENT_SMOBS(Score_element);
+IMPLEMENT_UNSMOB(Score_element, 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);