lilypond-1.5.9
[lilypond.git] / lily / item.cc
blobeeed9d86ccaddd7a928a78a13eaacc76a39bc48c
1 /*
2 item.cc -- implement Item
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--2001 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 : Grob (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 : Grob (s)
30 broken_to_drul_[LEFT] = broken_to_drul_[RIGHT] =0;
34 bool
35 Item::breakable_b (Grob*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_grob_property ("breakable"));
47 Paper_column *
48 Item::column_l () const
50 Item *parent = dynamic_cast<Item*> (parent_l (X_AXIS));
51 return parent ? parent->column_l () : 0;
54 Line_of_score *
55 Item::line_l () const
57 Grob *g = parent_l (X_AXIS);
58 return g ? g->line_l () : 0;
62 void
63 Item::copy_breakable_items ()
65 Drul_array<Item *> new_copies;
66 Direction i=LEFT;
67 do
69 Grob * dolly = clone ();
70 Item * item_p = dynamic_cast<Item*> (dolly);
71 pscore_l_->line_l_->typeset_grob (item_p);
72 new_copies[i] =item_p;
74 while (flip (&i) != LEFT);
75 broken_to_drul_= new_copies;
79 bool
80 Item::broken_b () const
82 return broken_to_drul_[LEFT] || broken_to_drul_[RIGHT];
87 Generate items for begin and end-of line.
89 void
90 Item::discretionary_processing ()
92 if (broken_b ())
93 return;
95 if (Item::breakable_b (this))
96 copy_breakable_items ();
99 Grob*
100 Item::find_broken_piece (Line_of_score*l) const
102 if (line_l () == l)
103 return (Item*) (this);
105 Direction d = LEFT;
106 do {
107 Grob *s = broken_to_drul_[d];
108 if (s && s->line_l () == l)
109 return s;
111 while (flip (&d) != LEFT);
113 return 0;
117 Item*
118 Item::find_prebroken_piece (Direction d) const
120 Item * me = (Item *) (this);
121 if (!d)
122 return me;
123 return dynamic_cast<Item*> (broken_to_drul_[d]);
127 Direction
128 Item::break_status_dir () const
130 if (original_l_)
132 Item * i = dynamic_cast<Item*> (original_l_);
134 return (i->broken_to_drul_[LEFT] == this) ? LEFT : RIGHT;
136 else
137 return CENTER;
140 void
141 Item::handle_prebroken_dependencies ()
143 if (original_l_)
145 mutable_property_alist_
146 = handle_broken_grobs(original_l_->mutable_property_alist_,
147 gh_int2scm (break_status_dir ()));
151 Can't do this earlier, because try_visibility_lambda () might set
152 the elt property transparent, which would then be copied.
154 TODO:
156 handle visibility-lambda the item itself iso. breakstatusdir, so
157 the function can do more complicated things.
160 SCM vis = get_grob_property ("visibility-lambda");
161 if (gh_procedure_p (vis))
163 SCM args = scm_list_n (gh_int2scm (break_status_dir ()), SCM_UNDEFINED);
164 SCM result = gh_apply (vis, args);
165 bool trans = gh_scm2bool (gh_car (result));
166 bool empty = gh_scm2bool (gh_cdr (result));
168 if (empty && trans)
169 suicide ();
170 else if (empty)
172 set_extent_callback (SCM_EOL, X_AXIS);
173 set_extent_callback (SCM_EOL, Y_AXIS);
175 else if (trans)
176 set_grob_property ("molecule-callback", SCM_BOOL_T);
181 Item::do_derived_mark ()
183 if (broken_to_drul_[LEFT])
184 scm_gc_mark (broken_to_drul_[LEFT]->self_scm ());
185 if (broken_to_drul_[RIGHT])
186 scm_gc_mark (broken_to_drul_[RIGHT]->self_scm ());
187 return SCM_EOL;