]> git.donarmstrong.com Git - lilypond.git/blob - lily/include/score-element.hh
2ded67f8cc51fa228fd41fe17b408b9bff2c9ae9
[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, Score_element_method_pointer funcptr);
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   /// do calculations before determining horizontal spacing
167   virtual void before_line_breaking ();
168   /// do calculations after determining horizontal spacing
169   virtual void after_line_breaking ();
170
171   Molecule get_molecule () const;
172   void suicide ();
173   
174   static Interval preset_extent (Score_element const*,Axis);
175   static Interval point_dimension_callback (Score_element const*,Axis );
176   static Interval molecule_extent (Score_element const*,Axis);
177
178 protected:
179
180   /**
181     Junk score element. This is protected because this is supposed to
182     be handled by GUILE gc.  */
183   virtual ~Score_element ();
184   
185   ///executed directly after the item is added to the Paper_score
186   virtual void do_add_processing ();
187   Molecule do_brew_molecule ()const;
188   
189   static Interval dim_cache_callback (Dimension_cache const*);
190   
191 public:
192   static SCM ly_set_elt_property (SCM, SCM,SCM);
193   static SCM ly_get_elt_property (SCM, SCM);  
194   static SCM scheme_molecule (SCM);
195   virtual void handle_broken_dependencies ();
196   virtual void handle_prebroken_dependencies ();
197
198
199   DECLARE_SMOBS;
200
201   void init ();
202
203   Dimension_cache dim_cache_[NO_AXES];
204
205 public:
206   bool empty_b (Axis a) const;
207   Interval extent (Axis) const;
208  
209   /**
210     translate in one direction
211     */
212     
213   void translate_axis (Real, Axis);
214
215   /**
216      Find the offset relative to D.  If   D equals THIS, then it is 0.
217      Otherwise, it recursively defd as
218
219      OFFSET_ + PARENT_L_->relative_coordinate (D)
220    */
221   Real relative_coordinate (Score_element const* refp, Axis) const;
222   /**
223     Find the group-element which has both #this# and #s#
224    */
225   Score_element*common_refpoint (Score_element const* s, Axis a) const;
226   Score_element*common_refpoint (SCM elt_list, Axis a) const;
227
228   bool has_offset_callback_b (Offset_callback, Axis)const;
229   void add_offset_callback (Offset_callback, Axis);
230   bool has_extent_callback_b (Extent_callback, Axis)const;  
231   void set_extent_callback (Extent_callback , Axis);
232
233   /**
234     Invoke callbacks to get offset relative to parent.
235    */
236   Real get_offset (Axis a) const;
237   /**
238      Set the  parent refpoint of THIS to E
239    */
240   void set_parent (Score_element* e, Axis);
241   
242   Score_element *parent_l (Axis a) const;
243   void fixup_refpoint ();
244 };
245
246 Score_element * unsmob_element (SCM);
247
248 #define MAKE_SCHEME_SCORE_ELEMENT_NON_DEFAULT_CALLBACKS(TYPE)                           \
249 void                                                            \
250 TYPE ## __init_functions ()                                     \
251 {                                                               \
252   scm_make_gsubr (#TYPE "::scheme_molecule", 1, 0, 0,           \
253   (SCM(*)(...))TYPE::scheme_molecule);                          \
254 }                                                               \
255                                                                 \
256 ADD_SCM_INIT_FUNC(TYPE ## _molecule, TYPE ## __init_functions); \
257
258 #define MAKE_SCHEME_SCORE_ELEMENT_CALLBACKS(TYPE)                               \
259 MAKE_SCHEME_SCORE_ELEMENT_NON_DEFAULT_CALLBACKS(TYPE);\
260 SCM                                                             \
261 TYPE::scheme_molecule (SCM smob)                                \
262 {                                                               \
263   TYPE * b = dynamic_cast<TYPE*> (unsmob_element (smob));       \
264   return b ?  b->do_brew_molecule ().create_scheme () : SCM_EOL; \
265 }                                                               \
266                                                                 \
267
268
269
270 #endif // STAFFELEM_HH
271