X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fscore-element.cc;h=4a4c59d60da5972de8767809233786472562ac12;hb=8ecd09ad7514d57630fb611d38c161f3c3c708db;hp=e1c218d1bf4440dbd66ae30e4b1772dda7fde75a;hpb=9c8bcb9a2a1fedb5459e593b18a8c550318e6800;p=lilypond.git diff --git a/lily/score-element.cc b/lily/score-element.cc index e1c218d1bf..4a4c59d60d 100644 --- a/lily/score-element.cc +++ b/lily/score-element.cc @@ -31,6 +31,8 @@ #include "side-position-interface.hh" #include "item.hh" +#include "ly-smobs.icc" + /* TODO: @@ -43,8 +45,9 @@ remove dynamic_cast and put this code into respective Score_element::Score_element(SCM basicprops) { - set_extent_callback (molecule_extent, X_AXIS); - set_extent_callback (molecule_extent, Y_AXIS); + /* + fixme: default should be no callback. + */ pscore_l_=0; lookup_l_ =0; @@ -54,10 +57,38 @@ Score_element::Score_element(SCM basicprops) mutable_property_alist_ = SCM_EOL; smobify_self (); - set_elt_property ("dependencies", SCM_EOL); - if (get_elt_property ("interfaces") == SCM_UNDEFINED) - set_elt_property ("interfaces", SCM_EOL); + char const*onames[] = {"X-offset-callbacks", "Y-offset-callbacks"}; + char const*enames[] = {"X-extent-callback", "Y-extent-callback"}; + + for (int a = X_AXIS; a <= Y_AXIS; a++){ + SCM l = get_elt_property (onames[a]); + + if (scm_ilength (l) >=0) + { + dim_cache_[a].offset_callbacks_ = l; + dim_cache_[a].offsets_left_ = scm_ilength (l); + } + else + { + programming_error ("[XY]-offset-callbacks must be a list"); + } + + SCM cb = get_elt_property (enames[a]); + + /* + Should change default to be empty? + */ + if (!gh_procedure_p (cb) && !gh_pair_p (cb)) + cb = molecule_extent_proc; + + dim_cache_[a].dimension_ = cb; + } + + SCM meta = get_elt_property ("meta"); + SCM ifs = scm_assoc (ly_symbol2scm ("interfaces"), meta); + + set_elt_property ("interfaces",gh_cdr (ifs)); } @@ -147,16 +178,25 @@ Score_element::set_elt_property (SCM s, SCM v) } -Interval -Score_element::molecule_extent (Score_element *s, Axis a) +MAKE_SCHEME_CALLBACK(Score_element,molecule_extent,2); +SCM +Score_element::molecule_extent (SCM element_smob, SCM scm_axis) { + Score_element *s = unsmob_element (element_smob); + Axis a = (Axis) gh_scm2int (scm_axis); + Molecule m = s->get_molecule (); - return m.extent(a); + return ly_interval2scm ( m.extent(a)); } -Interval -Score_element::preset_extent (Score_element *s , Axis a) +MAKE_SCHEME_CALLBACK(Score_element,preset_extent,2); + +SCM +Score_element::preset_extent (SCM element_smob, SCM scm_axis) { + Score_element *s = unsmob_element (element_smob); + Axis a = (Axis) gh_scm2int (scm_axis); + SCM ext = s->get_elt_property ((a == X_AXIS) ? "extent-X" : "extent-Y"); @@ -167,10 +207,10 @@ Score_element::preset_extent (Score_element *s , Axis a) 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 ly_interval2scm (Interval (l, r)); } - return Interval (); + return ly_interval2scm ( Interval ()); } @@ -184,10 +224,13 @@ Score_element::paper_l () const Lookup const * Score_element::lookup_l () const { + /* + URG junkthis, caching is clumsy. + */ if (!lookup_l_) { Score_element * urg = (Score_element*)this; - SCM sz = urg->remove_elt_property ("fontsize"); + SCM sz = urg->remove_elt_property ("font-size"); int i = (gh_number_p (sz)) ? gh_scm2int (sz) : 0; @@ -197,17 +240,6 @@ Score_element::lookup_l () const return lookup_l_; } -void -Score_element::add_processing() -{ - assert (status_i_ >=0); - if (status_i_) - return; - status_i_ ++; - - do_add_processing(); -} - void Score_element::calculate_dependencies (int final, int busy, SCM funcname) { @@ -249,7 +281,7 @@ Score_element::get_molecule () const if (gh_procedure_p (proc)) mol = gh_apply (proc, gh_list (this->self_scm (), SCM_UNDEFINED)); - + SCM origin =get_elt_property ("origin"); if (!unsmob_input (origin)) origin =ly_symbol2scm ("no-origin"); @@ -260,8 +292,17 @@ Score_element::get_molecule () const mol = gh_cons (gh_list (origin, gh_car (mol), SCM_UNDEFINED), gh_cdr (mol)); } - - return create_molecule (mol); + + Molecule m (create_molecule (mol)); + + /* + This is almost the same as setting molecule-callback to #f, but + this retains the dimensions of this element, which means that you + can erase elements individually. */ + if (to_boolean (get_elt_property ("transparent"))) + m = Molecule (m.extent_box (), SCM_EOL); + + return m; } @@ -276,13 +317,10 @@ Score_element::do_break_processing() } -void -Score_element::do_add_processing() -{ -} -MAKE_SCHEME_CALLBACK(Score_element,brew_molecule) + +MAKE_SCHEME_CALLBACK(Score_element,brew_molecule,1) /* ugh. @@ -314,8 +352,8 @@ Score_element::add_dependency (Score_element*e) { if (e) { - Pointer_group_interface gi (this, "dependencies"); - gi.add_element (e); + Pointer_group_interface ::add_element (this, "dependencies",e); + } else programming_error ("Null dependency added"); @@ -459,12 +497,14 @@ Score_element::suicide () { mutable_property_alist_ = SCM_EOL; immutable_property_alist_ = SCM_EOL; - set_extent_callback (0, Y_AXIS); - set_extent_callback (0, X_AXIS); + + set_extent_callback (SCM_EOL, Y_AXIS); + set_extent_callback (SCM_EOL, X_AXIS); for (int a= X_AXIS; a <= Y_AXIS; a++) { - dim_cache_[a].off_callbacks_.clear (); + dim_cache_[a].offset_callbacks_ = SCM_EOL; + dim_cache_[a].offsets_left_ = 0; } } @@ -511,15 +551,17 @@ Real Score_element::get_offset (Axis a) const { Score_element *me = (Score_element*) this; - while (dim_cache_[a].off_callbacks_.size ()) + while (dim_cache_[a].offsets_left_) { - Offset_callback c = dim_cache_[a].off_callbacks_[0]; - me->dim_cache_[a].off_callbacks_.del (0); - Real r = (*c) (me,a ); + int l = --me->dim_cache_[a].offsets_left_; + SCM cb = scm_list_ref (dim_cache_[a].offset_callbacks_, gh_int2scm (l)); + SCM retval = gh_call2 (cb, self_scm (), gh_int2scm (a)); + + Real r = gh_scm2double (retval); if (isinf (r) || isnan (r)) { - r = 0.0; programming_error (INFINITY_MSG); + r = 0.0; } me->dim_cache_[a].offset_ +=r; } @@ -527,36 +569,51 @@ Score_element::get_offset (Axis a) const } -Interval -Score_element::point_dimension_callback (Score_element* , Axis) +MAKE_SCHEME_CALLBACK(Score_element,point_dimension_callback,2); +SCM +Score_element::point_dimension_callback (SCM , SCM ) { - return Interval (0,0); + return ly_interval2scm ( Interval (0,0)); } bool Score_element::empty_b (Axis a)const { - return !dim_cache_[a].extent_callback_l_; + return ! (gh_pair_p (dim_cache_[a].dimension_ ) || + gh_procedure_p (dim_cache_[a].dimension_ )); } +/* + TODO: add + + Score_element *refpoint + + to arguments? + */ Interval -Score_element::extent (Axis a) const +Score_element::extent (Score_element * refp, Axis a) const { + Real x = relative_coordinate (refp, a); + + Dimension_cache * d = (Dimension_cache *)&dim_cache_[a]; - if (!d->extent_callback_l_) - { - d->dim_.set_empty (); - } - else if (!d->valid_b_) + Interval ext ; + if (gh_pair_p (d->dimension_)) + ; + else if (gh_procedure_p (d->dimension_)) { - d->dim_= (*d->extent_callback_l_ ) ((Score_element*)this, a); - d->valid_b_ = true; + /* + FIXME: add doco on types, and should typecheck maybe? + */ + d->dimension_= gh_call2 (d->dimension_, self_scm(), gh_int2scm (a)); } + else + return ext; - Interval ext = d->dim_; - - if (empty_b (a)) + if (!gh_pair_p (d->dimension_)) return ext; + + ext = ly_scm2interval (d->dimension_); SCM extra = get_elt_property (a == X_AXIS ? "extra-extent-X" @@ -580,6 +637,8 @@ Score_element::extent (Axis a) const ext.unite (Interval (s * gh_scm2double (gh_car (extra)), s * gh_scm2double (gh_cdr (extra)))); } + + ext.translate (x); return ext; } @@ -621,49 +680,57 @@ Score_element::common_refpoint (SCM elist, Axis a) const return common; } -char const * +String Score_element::name () const { - return classname (this); + SCM meta = get_elt_property ("meta"); + SCM nm = scm_assoc (ly_symbol2scm ("name"), meta); + nm = (gh_pair_p (nm)) ? gh_cdr (nm) : SCM_EOL; + return gh_string_p (nm) ?ly_scm2string (nm) : classname (this); } void -Score_element::add_offset_callback (Offset_callback cb, Axis a) +Score_element::add_offset_callback (SCM cb, Axis a) { - dim_cache_[a].off_callbacks_.push (cb); + if (!has_offset_callback_b (cb, a)) + { + dim_cache_[a].offset_callbacks_ = gh_cons (cb, dim_cache_[a].offset_callbacks_ ); + dim_cache_[a].offsets_left_ ++; + } } bool -Score_element::has_extent_callback_b (Extent_callback cb, Axis a)const +Score_element::has_extent_callback_b (SCM cb, Axis a)const { - return cb == dim_cache_[a].extent_callback_l_; + return scm_equal_p (cb, dim_cache_[a].dimension_); } + bool -Score_element::has_offset_callback_b (Offset_callback cb, Axis a)const +Score_element::has_extent_callback_b (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; + return gh_procedure_p (dim_cache_[a].dimension_); +} + +bool +Score_element::has_offset_callback_b (SCM cb, Axis a)const +{ + return scm_memq (cb, dim_cache_[a].offset_callbacks_) != SCM_BOOL_F; } void -Score_element::set_extent_callback (Dim_cache_callback dc, Axis a) +Score_element::set_extent_callback (SCM dc, Axis a) { - dim_cache_[a].extent_callback_l_ = dc ; + dim_cache_[a].dimension_ =dc; } - void Score_element::set_parent (Score_element *g, Axis a) { dim_cache_[a].parent_l_ = g; } -MAKE_SCHEME_CALLBACK(Score_element,fixup_refpoint); +MAKE_SCHEME_CALLBACK(Score_element,fixup_refpoint,1); SCM Score_element::fixup_refpoint (SCM smob) { @@ -706,7 +773,6 @@ Score_element::fixup_refpoint (SCM smob) SMOB funcs ****************************************************/ -#include "ly-smobs.icc" IMPLEMENT_UNSMOB(Score_element, element); IMPLEMENT_SMOBS(Score_element); @@ -718,6 +784,12 @@ Score_element::mark_smob (SCM ses) Score_element * s = (Score_element*) SCM_CELL_WORD_1(ses); scm_gc_mark (s->immutable_property_alist_); scm_gc_mark (s->mutable_property_alist_); + + for (int a =0 ; a < 2; a++) + { + scm_gc_mark (s->dim_cache_[a].offset_callbacks_); + scm_gc_mark (s->dim_cache_[a].dimension_); + } if (s->parent_l (Y_AXIS)) scm_gc_mark (s->parent_l (Y_AXIS)->self_scm ()); @@ -735,7 +807,7 @@ Score_element::print_smob (SCM s, SCM port, scm_print_state *) Score_element *sc = (Score_element *) gh_cdr (s); scm_puts ("#name (), port); + scm_puts ((char *)sc->name ().ch_C(), port); /* don't try to print properties, that is too much hassle. @@ -811,23 +883,19 @@ spanner_get_bound (SCM slur, SCM dir) static SCM interfaces_sym; - static void init_functions () { interfaces_sym = scm_permanent_object (ly_symbol2scm ("interfaces")); - - scm_make_gsubr ("ly-get-elt-property", 2, 0, 0, (SCM(*)(...))ly_get_elt_property); - scm_make_gsubr ("ly-set-elt-property", 3, 0, 0, (SCM(*)(...))ly_set_elt_property); - scm_make_gsubr ("ly-get-spanner-bound", 2 , 0, 0, (SCM(*)(...)) spanner_get_bound); + + scm_make_gsubr ("ly-get-elt-property", 2, 0, 0, (Scheme_function_unknown)ly_get_elt_property); + scm_make_gsubr ("ly-set-elt-property", 3, 0, 0, (Scheme_function_unknown)ly_set_elt_property); + scm_make_gsubr ("ly-get-spanner-bound", 2 , 0, 0, (Scheme_function_unknown) spanner_get_bound); } bool Score_element::has_interface (SCM k) { - if (mutable_property_alist_ == SCM_EOL) - return false; - SCM ifs = get_elt_property (interfaces_sym); return scm_memq (k, ifs) != SCM_BOOL_F; @@ -847,4 +915,4 @@ Score_element::set_interface (SCM k) ADD_SCM_INIT_FUNC(scoreelt, init_functions); - +IMPLEMENT_TYPE_P(Score_element, "ly-element?");