lilypond-1.3.74
[lilypond.git] / lily / item.cc
blobeac4533b4c9eee8898b416c994bff2e43e7ba7da
1 /*
2 item.cc -- implement Item
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
10 #include "paper-score.hh"
11 #include "debug.hh"
12 #include "item.hh"
13 #include "paper-column.hh"
14 #include "spanner.hh"
15 #include "lily-guile.hh"
16 #include "line-of-score.hh"
18 Item::Item (SCM s)
19 : Score_element (s)
21 broken_to_drul_[LEFT] = broken_to_drul_[RIGHT]=0;
24 /**
25 Item copy ctor. Copy nothing: everything should be a elt property
26 or a special purpose pointer (such as broken_to_drul_[]) */
27 Item::Item (Item const &s)
28 : Score_element (s)
30 broken_to_drul_[LEFT] = broken_to_drul_[RIGHT] =0;
34 bool
35 Item::breakable_b (Score_element*me)
37 if (me->original_l_)
38 return false;
40 if (!dynamic_cast<Item*>(me))
41 programming_error ("only items can be breakable.");
43 Item * i =dynamic_cast<Item*> (me->parent_l (X_AXIS));
44 return (i) ? Item::breakable_b (i) : to_boolean (me->get_elt_property ("breakable"));
47 Paper_column *
48 Item::column_l () const
50 return dynamic_cast<Item*> (parent_l (X_AXIS))->column_l ();
53 Line_of_score *
54 Item::line_l() const
56 Score_element *g = parent_l (X_AXIS);
57 return g ? g->line_l () : 0;
61 void
62 Item::copy_breakable_items()
64 Drul_array<Item *> new_copies;
65 Direction i=LEFT;
66 do
68 Score_element * dolly = clone();
69 Item * item_p = dynamic_cast<Item*>(dolly);
70 pscore_l_->line_l_->typeset_element (item_p);
71 new_copies[i] =item_p;
73 while (flip(&i) != LEFT);
74 broken_to_drul_= new_copies;
78 bool
79 Item::broken_b () const
81 return broken_to_drul_[LEFT] || broken_to_drul_[RIGHT];
86 Generate items for begin and end-of line.
88 void
89 Item::discretionary_processing()
91 if (broken_b ())
92 return;
94 if (Item::breakable_b (this))
95 copy_breakable_items();
98 Score_element*
99 Item::find_broken_piece (Line_of_score*l) const
101 if (line_l() == l)
102 return (Item*)(this);
104 Direction d = LEFT;
105 do {
106 Score_element *s = broken_to_drul_[d];
107 if (s && s->line_l () == l)
108 return s;
110 while (flip (&d) != LEFT);
112 return 0;
116 Item*
117 Item::find_prebroken_piece (Direction d) const
119 Item * me = (Item *) (this);
120 if (!d)
121 return me;
122 return dynamic_cast<Item*> (broken_to_drul_[d]);
126 Direction
127 Item::break_status_dir () const
129 if (original_l_)
131 Item * i = dynamic_cast<Item*> (original_l_);
133 return (i->broken_to_drul_[LEFT] == this) ? LEFT : RIGHT;
135 else
136 return CENTER;
139 void
140 Item::handle_prebroken_dependencies ()
142 if (original_l_)
144 mutable_property_alist_
145 = handle_broken_smobs (original_l_->mutable_property_alist_,
146 gh_int2scm (break_status_dir ()));
150 Can't do this earlier, because try_visibility_lambda () might set
151 the elt property transparent, which would then be copied.
153 TODO:
155 handle visibility-lambda the item itself iso. breakstatusdir, so
156 the function can do more complicated things.
159 SCM vis = get_elt_property ("visibility-lambda");
160 if (gh_procedure_p (vis))
162 SCM args = scm_listify (gh_int2scm (break_status_dir ()), SCM_UNDEFINED);
163 SCM result = gh_apply (vis, args);
164 bool trans = gh_scm2bool (gh_car (result));
165 bool empty = gh_scm2bool (gh_cdr (result));
167 if (empty && trans)
168 suicide ();
169 else if (empty)
171 set_extent_callback (0, X_AXIS);
172 set_extent_callback (0, Y_AXIS);
174 else if (trans)
175 set_elt_property ("molecule-callback", SCM_BOOL_T);
180 Item::do_derived_mark ()
182 if (broken_to_drul_[LEFT])
183 scm_gc_mark (broken_to_drul_[LEFT]->self_scm ());
184 if (broken_to_drul_[RIGHT])
185 scm_gc_mark (broken_to_drul_[RIGHT]->self_scm ());
186 return SCM_EOL;