]> git.donarmstrong.com Git - lilypond.git/blob - lily/item.cc
release: 1.1.24
[lilypond.git] / lily / item.cc
1 /*
2   item.cc -- implement Item
3
4   source file of the GNU LilyPond music typesetter
5
6   (c)  1997--1998 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
8
9 #include "p-score.hh"
10 #include "debug.hh"
11 #include "item.hh"
12 #include "p-col.hh"
13 #include "spanner.hh"
14
15 Item::Item ()
16 {
17   unbroken_original_l_ =0;
18   break_priority_i_ = 0;
19   breakable_b_ = false;
20   break_status_dir_ = CENTER;
21   broken_to_drul_[LEFT] = broken_to_drul_[RIGHT]=0;
22 }
23
24 void
25 Item::do_print() const
26 {
27 #ifndef NPRINT
28   DOUT << "breakable_b_: " << breakable_b_ << 
29     " break_status_dir_: " << break_status_dir_;
30 #endif
31 }
32
33
34 Real 
35 Item::hpos_f() const
36 {
37   return absolute_coordinate (X_AXIS);
38 }
39
40 Line_of_score *
41 Item::line_l() const
42 {
43   Graphical_element *g = parent_l (X_AXIS);
44   if (!g)
45     return 0;
46   return dynamic_cast <Score_element *> (g)-> line_l ();
47 }
48
49 Direction
50 Item::break_status_dir() const
51 {
52   return break_status_dir_;
53 }
54
55 void
56 Item::copy_breakable_items()
57 {
58   if (broken_to_drul_[LEFT] || broken_to_drul_[RIGHT])
59     return;
60   Drul_array<Item *> new_copies;
61   Direction  i=LEFT;
62   do 
63     {
64       Score_element * dolly = clone();
65       Item * item_p = dynamic_cast<Item*>(dolly);
66
67       item_p->break_status_dir_ =  i;
68       pscore_l_->typeset_element (item_p);
69       new_copies[i] =item_p;
70     }
71   while (flip(&i) != LEFT);
72   broken_to_drul_= new_copies;
73
74   do 
75     {
76        broken_to_drul_[i]->handle_prebroken_dependencies();
77        broken_to_drul_[i]->try_visibility_lambda();
78     }
79   while (flip(&i) != LEFT);
80   try_visibility_lambda ();
81 }
82
83 void
84 Item::try_visibility_lambda ()
85 {
86   if (visibility_lambda_)
87     {
88       SCM args = scm_listify (gh_int2scm (break_status_dir_), SCM_UNDEFINED);
89       SCM result = gh_apply (visibility_lambda_, args);
90       int trans = gh_scm2bool (gh_car (result));
91       int empty = gh_scm2bool (gh_cdr (result));
92
93       if (empty)
94         set_empty (true);
95       if (trans)
96         transparent_b_ = true;
97     }
98 }
99
100 void
101 Item::do_break ()
102 {
103   copy_breakable_items();
104   handle_prebroken_dependencies();
105   
106   /*
107     Otherwise the broken items won't be pre_process()'ed.
108   */
109   add_dependency (broken_to_drul_[LEFT]);
110   add_dependency (broken_to_drul_[RIGHT]);
111
112 }
113
114 void
115 Item::do_breakable_col_processing()
116 {
117   if (breakable_b_)
118     do_break ();
119
120 }
121 Item*
122 Item::find_prebroken_piece (Line_of_score*l) const
123 {
124   if (line_l() == l) 
125     return (Item*)this;
126   else if (broken_to_drul_[LEFT] && broken_to_drul_[LEFT]->line_l() == l)
127     return broken_to_drul_[LEFT];
128   else if (broken_to_drul_[RIGHT] && broken_to_drul_[RIGHT]->line_l() == l)
129     return broken_to_drul_[RIGHT];
130
131   return 0;
132 }
133
134 Item*
135 Item::find_prebroken_piece (Direction breakstatus) const
136 {
137   if (!breakstatus)
138     return (Item *) this;       // ugh
139   else
140     return (Item*) broken_to_drul_[breakstatus];
141 }
142
143 void
144 Item::handle_prebroken_dependencies()
145 {
146   if (breakable_b_)
147     Score_element::handle_prebroken_dependencies();
148 }
149
150 int
151 Item::left_right_compare(Item const *l, Item const *r)
152 {
153   Paper_column *p1 = l->column_l ();
154   Paper_column* p2 = r->column_l ();
155   return p1->rank_i () - p2->rank_i ();
156 }
157
158
159 bool
160 Item::linked_b() const
161 {
162   return Score_element::linked_b() || attached_span_l_arr_.size();
163 }
164
165 void
166 Item::do_junk_links()
167 {
168   attached_span_l_arr_.set_size(0);
169 }
170
171 void
172 Item::do_unlink()
173 {
174   Link_array<Spanner> attached=attached_span_l_arr_;
175   for (int i=0; i < attached.size (); i++)
176     {
177       Spanner *s= attached[i];
178
179       Direction d= LEFT;
180       do {
181         if (s->spanned_drul_[d] == this)
182           s->set_bounds (d, 0);
183         if (unbroken_original_l_
184             && unbroken_original_l_-> broken_to_drul_[d] == this)
185           unbroken_original_l_->broken_to_drul_[d] = 0;
186       } while (flip (&d) != LEFT);
187     }
188   assert (!attached_span_l_arr_.size ());
189   unbroken_original_l_ =0;
190 }
191
192 Paper_column *
193 Item::column_l () const
194 {
195   return dynamic_cast<Item*> (parent_l (X_AXIS))->column_l ();
196 }
197
198 Item::Item (Item const &s)
199   : Score_element (s)
200 {
201   unbroken_original_l_ = &s;
202   /* do not copy attached_span_l_arr_ */
203   breakable_b_ = s.breakable_b_;
204   visibility_lambda_ = s.visibility_lambda_;
205   broken_to_drul_[LEFT] = broken_to_drul_[RIGHT] =0;
206   break_status_dir_ = s.break_status_dir_;
207   break_priority_i_ = s.break_priority_i_;
208 }
209
210
211 void
212 Item::handle_prebroken_dependents ()
213 {
214   Dimension_cache * dim = dim_cache_[X_AXIS].parent_l_;
215   if (!dim)
216     return;
217   
218   Item * parent =  dynamic_cast<Item*> (dim->element_l ());
219   if (parent && parent->broken_to_drul_[LEFT])
220     {
221       if(!(broken_to_drul_[LEFT] || broken_to_drul_[RIGHT]))
222         do_break ();
223
224       Direction d = LEFT;
225       do
226         {
227           broken_to_drul_[d]->dim_cache_[X_AXIS].parent_l_ =
228             &parent->broken_to_drul_[d]->dim_cache_[X_AXIS];
229           parent->broken_to_drul_[d]->add_dependency (broken_to_drul_[d]);
230         }
231       while ((flip (&d))!=LEFT);
232     }
233 }
234