lilypond-1.3.7
[lilypond.git] / lily / item.cc
blobeba020f52b8440a63922493cdfefac429123b4eb
1 /*
2 item.cc -- implement Item
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
8 #include "dimension-cache.hh"
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"
17 Item::Item ()
19 broken_to_drul_[LEFT] = broken_to_drul_[RIGHT]=0;
22 bool
23 Item::breakable_b () const
25 if (original_l_ )
26 return false;
28 Item * i =dynamic_cast<Item*> (parent_l (X_AXIS));
29 return (i) ? i->breakable_b () : get_elt_property( "breakable") != SCM_UNDEFINED;
32 void
33 Item::do_print() const
38 Real
39 Item::hpos_f() const
41 return relative_coordinate (0, X_AXIS);
44 Line_of_score *
45 Item::line_l() const
47 Graphical_element *g = parent_l (X_AXIS);
48 if (!g)
49 return 0;
50 return dynamic_cast<Score_element *> (g)-> line_l ();
54 void
55 Item::copy_breakable_items()
57 if (broken_to_drul_[LEFT] || broken_to_drul_[RIGHT]
58 || !breakable_b ())
59 return ;
61 Drul_array<Item *> new_copies;
62 Direction i=LEFT;
63 do
65 Score_element * dolly = clone();
66 Item * item_p = dynamic_cast<Item*>(dolly);
67 pscore_l_->typeset_element (item_p);
68 new_copies[i] =item_p;
70 while (flip(&i) != LEFT);
71 broken_to_drul_= new_copies;
73 do
75 broken_to_drul_[i]->handle_prebroken_dependencies();
76 broken_to_drul_[i]->try_visibility_lambda();
78 while (flip(&i) != LEFT);
79 try_visibility_lambda ();
82 void
83 Item::try_visibility_lambda ()
85 SCM vis = remove_elt_property ("visibility-lambda");
86 if (vis != SCM_UNDEFINED)
88 SCM args = scm_listify (gh_int2scm (break_status_dir ()), SCM_UNDEFINED);
89 SCM result = gh_apply (vis, args);
90 int trans = gh_scm2bool (gh_car (result));
91 int empty = gh_scm2bool (gh_cdr (result));
93 if (empty)
94 set_empty (true, X_AXIS, Y_AXIS);
95 if (trans)
96 set_elt_property ("transparent", SCM_BOOL_T);
100 void
101 Item::do_break ()
103 copy_breakable_items();
104 handle_prebroken_dependencies();
107 Otherwise the broken items won't be pre_process()'ed.
109 add_dependency (broken_to_drul_[LEFT]);
110 add_dependency (broken_to_drul_[RIGHT]);
113 void
114 Item::do_breakable_col_processing()
116 if (breakable_b ())
117 do_break ();
118 else
119 try_visibility_lambda ();
122 Score_element*
123 Item::find_broken_piece (Line_of_score*l) const
125 if (line_l() == l)
126 return (Item*)(this);
127 else if (broken_to_drul_[LEFT] && broken_to_drul_[LEFT]->line_l() == l)
128 return broken_to_drul_[LEFT];
129 else if (broken_to_drul_[RIGHT] && broken_to_drul_[RIGHT]->line_l() == l)
130 return broken_to_drul_[RIGHT];
132 return 0;
135 Item*
136 Item::find_broken_piece (Direction d) const
138 if (!d)
139 return (Item *) (this); // ugh
140 else
141 return dynamic_cast<Item*> (broken_to_drul_[d]);
144 void
145 Item::handle_prebroken_dependencies()
147 if (original_l_)
148 Score_element::handle_prebroken_dependencies();
151 bool
152 Item::broken_original_b () const
154 return broken_to_drul_[LEFT] || broken_to_drul_[RIGHT];
158 Item::left_right_compare(Item const *l, Item const *r)
160 Paper_column *p1 = l->column_l ();
161 Paper_column* p2 = r->column_l ();
162 return p1->rank_i () - p2->rank_i ();
165 Paper_column *
166 Item::column_l () const
168 return dynamic_cast<Item*> (parent_l (X_AXIS))->column_l ();
171 Item::Item (Item const &s)
172 : Score_element (s)
174 broken_to_drul_[LEFT] = broken_to_drul_[RIGHT] =0;
178 void
179 Item::handle_prebroken_dependents ()
181 Item * parent = dynamic_cast<Item*> (parent_l (X_AXIS));
182 if (breakable_b () && parent)
184 if(!(broken_to_drul_[LEFT] || broken_to_drul_[RIGHT]))
185 do_break ();
187 Direction d = LEFT;
190 Item * broken_self = find_broken_piece (d);
191 Item * broken_parent = parent->find_broken_piece (d);
193 broken_self->set_parent (broken_parent, X_AXIS);
196 ugh. Should do this is after breaking?
198 if (!broken_self->parent_l (Y_AXIS))
200 Score_element * yparent =dynamic_cast<Score_element*>(parent_l (Y_AXIS));
201 Item *yparenti = dynamic_cast<Item*> (yparent);
202 Item *broken_yparent = yparenti ?
203 yparenti->find_broken_piece (d) : 0;
205 if (!yparent)
206 programming_error ("Vertical refpoint lost!");
207 else if (yparenti)
209 broken_self->set_parent (broken_yparent, Y_AXIS);
213 while ((flip (&d))!=LEFT);
217 Direction
218 Item::break_status_dir () const
220 if (original_l_)
222 Item * i = dynamic_cast<Item*> (original_l_);
224 return (i->broken_to_drul_[LEFT] == this) ? LEFT : RIGHT;
226 else
227 return CENTER;