summaryrefslogtreecommitdiff
path: root/lily/include/grob.hh
blob: 8e8cde5890d8b73d295224b45348b9524c57cd74 (about) (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/*
  grob.hh -- declare Grob

  (c) 1996-1999--2002 Han-Wen Nienhuys
*/

#ifndef STAFFELEM_HH
#define STAFFELEM_HH

#include "parray.hh"
#include "virtual-methods.hh"
#include "lily-guile.hh"
#include "lily-proto.hh"
#include "smobs.hh"
#include "dimension-cache.hh"
#include "grob-interface.hh"

/**
    for administration of what was done already
    */
enum Grob_status {
  ORPHAN=0,			// not yet added to Paper_score
  VIRGIN,	
  PRECALCING,
  PRECALCED,		// calcs before spacing done
  POSTCALCING,		// busy calculating. This is used to trap cyclic deps.
  POSTCALCED,		// after spacing calcs done
};

typedef void (Grob::*Grob_method_pointer) (void);


#define get_grob_property(x) internal_get_grob_property(ly_symbol2scm(x))
#define set_grob_property(x,y) internal_set_grob_property(ly_symbol2scm(x),y)

/*
   Basic output object.
*/
class Grob  {
public:
  SCM immutable_property_alist_;
  SCM mutable_property_alist_;
  
  Grob *original_l_;

  /**
    Administration: Where are we?. This is mainly used by Super_element and
    Grob::calcalute_dependencies ()

    0 means ORPHAN,
   */
  char status_c_;


  /*
    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_;
  Dimension_cache dim_cache_[NO_AXES];

  Grob (SCM basic_props);
  Grob (Grob const&);
  String name () const;
  
  /*
    properties
   */
  SCM internal_get_grob_property (SCM) const;
  void internal_set_grob_property (SCM, SCM val);
  
  void warning (String)const;
  void programming_error (String)const;
  
  void set_elt_pointer (const char*, SCM val);
  friend class Property_engraver; //  UGHUGHUGH.
  SCM remove_grob_property (const char* nm);

  /*
    related classes.
   */
  Paper_def *paper_l () const;

  /**
    add a dependency. It may be the 0 pointer, in which case, it is ignored.
    */
  void add_dependency (Grob*);    
  virtual System * line_l () const;
  bool linked_b () const;


  VIRTUAL_COPY_CONS (Grob);
 
  /**
     Recursively track all dependencies of this Grob.  The
     status_c_ field is used as a mark-field.  It is marked with
     #busy# during execution of this function, and marked with #final#
     when finished.

     #funcptr# is the function to call to update this element.
   */
  void calculate_dependencies (int final, int busy, SCM funcname);


  virtual void do_break_processing ();
  virtual Grob *find_broken_piece (System*) const;
  virtual void discretionary_processing ();
  virtual SCM do_derived_mark ();

  Molecule * get_molecule () const;
  SCM get_uncached_molecule () const;
  
  void suicide ();
  
  DECLARE_SCHEME_CALLBACK (preset_extent, (SCM smob, SCM axis));
  DECLARE_SCHEME_CALLBACK (point_dimension_callback, (SCM smob, SCM axis));
  DECLARE_SCHEME_CALLBACK (molecule_extent, (SCM smob, SCM axis));

  static SCM ly_set_grob_property (SCM, SCM,SCM);
  static SCM ly_get_grob_property (SCM, SCM);  

  bool internal_has_interface (SCM intf);
  static bool has_interface (Grob*me);  

  virtual void handle_broken_dependencies ();
  virtual void handle_prebroken_dependencies ();

  DECLARE_SMOBS (Grob,foo);

  void init ();
public:
  bool empty_b (Axis a) const;

  Interval extent (Grob * refpoint, Axis) const;
 
  void translate_axis (Real, Axis);
  Real relative_coordinate (Grob const* refp, Axis) const;
  Grob*common_refpoint (Grob const* s, Axis a) const;


  // duh. slim down interface here. (todo)
  bool has_offset_callback_b (SCM callback, Axis)const;
  void add_offset_callback (SCM callback, Axis);
  bool has_extent_callback_b (SCM, Axis)const;  
  void set_extent (SCM , Axis);
  Real get_offset (Axis a) const;
  
  void set_parent (Grob* e, Axis);
  
  Grob *get_parent (Axis a) const {   return  dim_cache_[a].parent_l_; }
  DECLARE_SCHEME_CALLBACK (fixup_refpoint, (SCM));
};

DECLARE_UNSMOB(Grob,grob);
Spanner* unsmob_spanner (SCM );
Item* unsmob_item (SCM );

Grob*common_refpoint_of_list (SCM elt_list, Grob * , Axis a);
Grob*common_refpoint_of_array (Link_array<Grob> const&, Grob * , Axis a);

void set_break_subsititution (SCM criterion);
SCM do_break_substitution (SCM);

#endif // STAFFELEM_HH