/*
score-element.hh -- declare Score_element
- (c) 1996-1999 Han-Wen Nienhuys
+ (c) 1996-1999--2000 Han-Wen Nienhuys
*/
#ifndef STAFFELEM_HH
#include "lily-guile.hh"
#include "lily-proto.hh"
#include "smobs.hh"
+#include "dimension-cache.hh"
-typedef void (Score_element::*Score_element_method_pointer) (void);
+typedef Interval (*Extent_callback)(Score_element const *,Axis);
+typedef Real (*Offset_callback)(Score_element const *,Axis);
+
+#define READONLY_PROPS // FIXME.
-/** Both Spanner and Item are Score_element's. Most Score_element's depend
- on other Score_element's, eg, Beam needs to know and set direction of
- Stem. So the Beam has to be calculated *before* Stem. This is
- accomplished with the dependencies fields of struct Score_element,
- which are implemented in the Directed_graph_node class: all elements
- form an acyclic graph.
- (elem)
+/**
+ for administration of what was done already
+ */
+enum Score_element_status {
+ ORPHAN=0, // not yet added to pstaff
+ VIRGIN, // added to pstaff
+ PRECALCING,
+ PRECALCED, // calcs before spacing done
+ POSTCALCING, // busy calculating. This is used to trap cyclic deps.
+ POSTCALCED, // after spacing calcs done
+ BREWING,
+ BREWED,
+};
+
+typedef void (Score_element::*Score_element_method_pointer) (void);
+
+/**
+ Basic output object.
+ Element Properties:
-Element Properties:
+ transparent -- boolean: if true, do not print anything black.
-Boolean (true iff defined)
+ dependencies -- list of score-element pointers that indicate who to
+ compute first.
- break_helper_only -- if defined try to junk this after calcing breakpoints.
+ interfaces -- list of symbols indicating the interfaces supported
+ by this object.
- transparent -- do not calc. output
+ extra-offset -- pair of reals (a cons) forcing an extra offset
+ before outputting
+ glyph -- afm character name to output.
+
*/
class Score_element {
/**
The lookup, determined by the font size. Cache this value.
*/
Lookup * lookup_l_;
-public:
+
/**
properties specific for this element. Destructor will not call
scm_unprotect, so as to allow more flexible GC arrangements. The
need for more scm_protect calls.
*/
- SCM element_property_alist_;
-
+public: // ugh.
+ SCM property_alist_;
+ SCM pointer_alist_;
+#ifndef READONLY_PROPS
+ SCM basic_property_list_;
+#endif
+public:
Score_element *original_l_;
/**
Score_element::calcalute_dependencies ()
0 means ORPHAN,
- -1 means deleted
-
*/
- int status_i_;
+ char status_i_;
+ char const * name () const;
+ /*
+ IDEA: make this a global variable. This is the same for all
+ elements, I think it is safe to assume that we will not have
+ scores being formatted multithreadedly.
+ */
Paper_score *pscore_l_;
- Molecule * output_p_;
- Score_element ();
+
+ Score_element (SCM basic_props);
Score_element (Score_element const&);
- virtual void print () const;
/*
properties
SCM get_elt_property (String nm) const;
void set_elt_property (String, SCM val);
+ /**
+ Pointers are like properties, but they are subject to a substitution
+ after line breaking.
+ */
+ SCM get_elt_pointer (const char*) const;
+ void set_elt_pointer (const char*, SCM val);
+ friend class Property_engraver; // UGHUGHUGH.
/**
UGH! JUNKME ?
twice may do weird things if Bar::foo has a default set.
*/
- SCM remove_elt_property (String nm);
-
- void Score_element::set_real (String, Real);
- Real Score_element::get_real (String s) const;
+ SCM remove_elt_property (const char* nm);
/*
related classes.
void add_dependency (Score_element*);
virtual Line_of_score * line_l () const;
bool linked_b () const;
+
+
VIRTUAL_COPY_CONS(Score_element);
/**
*/
void calculate_dependencies (int final, int busy, Score_element_method_pointer funcptr);
+
static SCM handle_broken_smobs (SCM, SCM criterion);
- void recurse_into_smobs (SCM s, void (Score_element::*meth_ptr)());
virtual void do_break_processing ();
virtual Score_element *find_broken_piece (Line_of_score*) const;
+ /// generate rods & springs
+ virtual void do_space_processing ();
+ virtual void discretionary_processing ();
+ virtual void do_derived_mark ();
+ /// do calculations before determining horizontal spacing
+ virtual void before_line_breaking ();
+ /// do calculations after determining horizontal spacing
+ virtual void after_line_breaking ();
+
+ Molecule get_molecule () const;
+ void suicide ();
+
+ static Interval preset_extent (Score_element const*,Axis);
+ static Interval point_dimension_callback (Score_element const*,Axis );
+ static Interval molecule_extent (Score_element const*,Axis);
+
protected:
/**
be handled by GUILE gc. */
virtual ~Score_element ();
- virtual void output_processing ();
- static Interval molecule_extent (Dimension_cache const*);
-
- /// do printing of derived info.
- virtual void do_print () const;
- /// generate the molecule
- virtual Molecule* do_brew_molecule_p () const;
///executed directly after the item is added to the Paper_score
virtual void do_add_processing ();
- /// do calculations before determining horizontal spacing
- virtual void do_pre_processing ();
-
- /// generate rods & springs
- virtual void do_space_processing ();
-
- virtual void do_breakable_col_processing ();
- /// do calculations after determining horizontal spacing
- virtual void do_post_processing ();
-
- virtual Link_array<Score_element> get_extra_dependencies () const;
-
+ Molecule do_brew_molecule ()const;
+
static Interval dim_cache_callback (Dimension_cache const*);
+
public:
static SCM ly_set_elt_property (SCM, SCM,SCM);
static SCM ly_get_elt_property (SCM, SCM);
-
+ static SCM scheme_molecule (SCM);
virtual void handle_broken_dependencies ();
virtual void handle_prebroken_dependencies ();
void init ();
-public:
- Dimension_cache *dim_cache_[NO_AXES];
+ Dimension_cache dim_cache_[NO_AXES];
- /**
- Set this if anyone points to me, or if I point to anyone.
- */
- bool used_b_;
-
- char const * name () const;
- /**
- Set empty in direction A.
- */
- void set_empty (Axis a);
+public:
bool empty_b (Axis a) const;
Interval extent (Axis) const;
void translate_axis (Real, Axis);
+ /**
+ Find the offset relative to D. If D equals THIS, then it is 0.
+ Otherwise, it recursively defd as
+
+ OFFSET_ + PARENT_L_->relative_coordinate (D)
+ */
Real relative_coordinate (Score_element const* refp, Axis) const;
/**
Find the group-element which has both #this# and #s#
*/
Score_element*common_refpoint (Score_element const* s, Axis a) const;
- Score_element*common_refpoint (Link_array<Score_element> elems, Axis a) const;
+ Score_element*common_refpoint (SCM elt_list, Axis a) const;
+
+ bool has_offset_callback_b (Offset_callback, Axis)const;
+ void add_offset_callback (Offset_callback, Axis);
+ bool has_extent_callback_b (Extent_callback, Axis)const;
+ void set_extent_callback (Extent_callback , Axis);
+ /**
+ Invoke callbacks to get offset relative to parent.
+ */
+ Real get_offset (Axis a) const;
/**
Set the parent refpoint of THIS to E
*/
Score_element * unsmob_element (SCM);
+#define MAKE_SCHEME_SCORE_ELEMENT_NON_DEFAULT_CALLBACKS(TYPE) \
+void \
+TYPE ## __init_functions () \
+{ \
+ scm_make_gsubr (#TYPE "::scheme_molecule", 1, 0, 0, \
+ (SCM(*)(...))TYPE::scheme_molecule); \
+} \
+ \
+ADD_SCM_INIT_FUNC(TYPE ## _molecule, TYPE ## __init_functions); \
+
+#define MAKE_SCHEME_SCORE_ELEMENT_CALLBACKS(TYPE) \
+MAKE_SCHEME_SCORE_ELEMENT_NON_DEFAULT_CALLBACKS(TYPE);\
+SCM \
+TYPE::scheme_molecule (SCM smob) \
+{ \
+ TYPE * b = dynamic_cast<TYPE*> (unsmob_element (smob)); \
+ return b ? b->do_brew_molecule ().create_scheme () : SCM_EOL; \
+} \
+ \
+
#endif // STAFFELEM_HH