]> git.donarmstrong.com Git - lilypond.git/blob - lily/include/score-element.hh
release: 1.3.62
[lilypond.git] / lily / include / score-element.hh
1 /*
2   score-element.hh -- declare Score_element
3
4   (c) 1996-1999--2000 Han-Wen Nienhuys
5 */
6
7 #ifndef STAFFELEM_HH
8 #define STAFFELEM_HH
9
10 #include "parray.hh"
11 #include "virtual-methods.hh"
12 #include "lily-guile.hh"
13 #include "lily-proto.hh"
14 #include "smobs.hh"
15 #include "dimension-cache.hh"
16
17 typedef Interval (*Extent_callback)(Score_element const *,Axis);
18 typedef Real (*Offset_callback)(Score_element const *,Axis);
19
20 #define READONLY_PROPS          // FIXME.
21
22
23 /**
24     for administration of what was done already
25     */
26 enum Score_element_status {
27   ORPHAN=0,                     // not yet added to pstaff
28   VIRGIN,                       // added to pstaff
29   PRECALCING,
30   PRECALCED,            // calcs before spacing done
31   POSTCALCING,          // busy calculating. This is used to trap cyclic deps.
32   POSTCALCED,           // after spacing calcs done
33   BREWING,
34   BREWED,
35 };
36
37 typedef void (Score_element::*Score_element_method_pointer) (void);
38
39 /**
40    Basic output object.
41
42     Element Properties:
43
44    transparent -- boolean: if true, do not print anything black.
45
46    dependencies -- list of score-element pointers that indicate who to
47    compute first.
48
49    interfaces -- list of symbols indicating the interfaces supported
50    by this object.
51
52    extra-offset -- pair of reals (a cons) forcing an extra offset
53    before outputting
54
55    glyph -- afm character name to output.
56    
57 */
58 class Score_element  {
59   /**
60      The lookup, determined by the font size. Cache this value.
61    */
62   Lookup * lookup_l_;
63
64   /**
65      properties specific for this element. Destructor will not call
66      scm_unprotect, so as to allow more flexible GC arrangements.  The
67      real alist is in (cdr element_property_alist_), to reduce the
68      need for more scm_protect calls.
69
70   */
71 public:                         // ugh.
72   SCM property_alist_;
73   SCM pointer_alist_;
74 #ifndef READONLY_PROPS
75   SCM basic_property_list_;
76 #endif
77 public:
78   Score_element *original_l_;
79
80   /**
81     Administration: Where are we?. This is mainly used by Super_element and
82     Score_element::calcalute_dependencies ()
83
84     0 means ORPHAN,
85    */
86   char status_i_;
87   char const * name () const;
88
89   /*
90     IDEA: make this a global variable. This is the same for all
91     elements, I think it is safe to assume that we will not have
92     scores being formatted multithreadedly.
93    */
94   Paper_score *pscore_l_;
95
96   Score_element (SCM basic_props);
97   Score_element (Score_element const&);
98
99   /*
100     properties
101    */
102   SCM get_elt_property (String nm) const;
103   void set_elt_property (String, SCM val);
104
105   /**
106      Pointers are like properties, but they are subject to    a substitution
107      after line breaking.
108    */
109   SCM get_elt_pointer (const char*) const;
110   void set_elt_pointer (const char*, SCM val);
111   friend class Property_engraver; //  UGHUGHUGH.
112   /**
113      UGH! JUNKME ?
114
115      This gets messy because it changes state
116
117      calling 
118
119      Bar::proc ()
120      {
121        s->remove_elt_property ("foo")
122      } 
123
124      twice may do weird things if Bar::foo has a default set.
125      
126    */
127   SCM remove_elt_property (const char* nm);
128
129   /*
130     related classes.
131    */
132   Paper_def *paper_l () const;
133   Lookup const *lookup_l () const;
134
135   void add_processing ();
136
137   /**
138     add a dependency. It may be the 0 pointer, in which case, it is ignored.
139     */
140   void add_dependency (Score_element*);    
141   virtual Line_of_score * line_l () const;
142   bool linked_b () const;
143
144
145   VIRTUAL_COPY_CONS(Score_element);
146  
147   /**
148      Recursively track all dependencies of this Score_element.  The
149      status_i_ field is used as a mark-field.  It is marked with
150      #busy# during execution of this function, and marked with #final#
151      when finished.
152
153      #funcptr# is the function to call to update this element.
154    */
155   void calculate_dependencies (int final, int busy, SCM funcname);
156
157
158   static SCM handle_broken_smobs (SCM, SCM criterion);
159
160   virtual void do_break_processing ();
161   virtual Score_element *find_broken_piece (Line_of_score*) const;
162   /// generate rods & springs
163   virtual void do_space_processing ();
164   virtual void discretionary_processing ();
165   virtual void do_derived_mark ();
166
167   Molecule get_molecule () const;
168   void suicide ();
169   
170   static Interval preset_extent (Score_element const*,Axis);
171   static Interval point_dimension_callback (Score_element const*,Axis );
172   static Interval molecule_extent (Score_element const*,Axis);
173
174 protected:
175   /**
176     Junk score element. This is protected because this is supposed to
177     be handled by GUILE gc.  */
178   virtual ~Score_element ();
179   
180   ///executed directly after the item is added to the Paper_score
181   virtual void do_add_processing ();
182   static Interval dim_cache_callback (Dimension_cache const*);
183   
184 public:
185   SCM member_brew_molecule ()const;
186   
187   static SCM ly_set_elt_property (SCM, SCM,SCM);
188   static SCM ly_get_elt_property (SCM, SCM);  
189   static SCM brew_molecule (SCM);
190   virtual void handle_broken_dependencies ();
191   virtual void handle_prebroken_dependencies ();
192
193
194   DECLARE_SMOBS;
195
196   void init ();
197
198   Dimension_cache dim_cache_[NO_AXES];
199
200 public:
201   bool empty_b (Axis a) const;
202   Interval extent (Axis) const;
203  
204   /**
205     translate in one direction
206     */
207     
208   void translate_axis (Real, Axis);
209
210   /**
211      Find the offset relative to D.  If   D equals THIS, then it is 0.
212      Otherwise, it recursively defd as
213
214      OFFSET_ + PARENT_L_->relative_coordinate (D)
215    */
216   Real relative_coordinate (Score_element const* refp, Axis) const;
217   /**
218     Find the group-element which has both #this# and #s#
219    */
220   Score_element*common_refpoint (Score_element const* s, Axis a) const;
221   Score_element*common_refpoint (SCM elt_list, Axis a) const;
222
223   bool has_offset_callback_b (Offset_callback, Axis)const;
224   void add_offset_callback (Offset_callback, Axis);
225   bool has_extent_callback_b (Extent_callback, Axis)const;  
226   void set_extent_callback (Extent_callback , Axis);
227
228   /**
229     Invoke callbacks to get offset relative to parent.
230    */
231   Real get_offset (Axis a) const;
232   /**
233      Set the  parent refpoint of THIS to E
234    */
235   void set_parent (Score_element* e, Axis);
236   
237   Score_element *parent_l (Axis a) const;
238   void fixup_refpoint ();
239 };
240
241 Score_element * unsmob_element (SCM);
242
243 #define MAKE_SCHEME_SCORE_ELEMENT_CALLBACK(TYPE, FUNC) \
244 void                                                            \
245 TYPE ## _ ## FUNC ## _init_functions ()                                 \
246 {                                                               \
247   scm_make_gsubr (#TYPE "::" #FUNC, 1, 0, 0,            \
248   (SCM(*)(...))TYPE :: FUNC);                           \
249 }                                                               \
250                                                                 \
251 ADD_SCM_INIT_FUNC(TYPE ## _ ## FUNC ## _scelt, TYPE ## _ ## FUNC ## _init_functions);   \
252
253 #define GLUE_SCORE_ELEMENT(TYPE, FUNC) \
254 MAKE_SCHEME_SCORE_ELEMENT_CALLBACK(TYPE,FUNC);\
255 SCM \
256 TYPE::FUNC (SCM smob) \
257 {  \
258   TYPE * b = dynamic_cast<TYPE*> (unsmob_element (smob));       \
259   return b ?   b->member_ ## FUNC () : SCM_UNDEFINED; \
260 }  \
261
262
263 #endif // STAFFELEM_HH
264