]> git.donarmstrong.com Git - lilypond.git/blob - lily/item.cc
release: 1.1.34
[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--1999 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 #include "lily-guile.hh"
15
16 Item::Item ()
17 {
18   unbroken_original_l_ =0;
19   break_priority_i_ = 0;
20   breakable_b_ = false;
21   break_status_dir_ = CENTER;
22   broken_to_drul_[LEFT] = broken_to_drul_[RIGHT]=0;
23 }
24
25 bool
26 Item::breakable_b () const
27 {
28   return !unbroken_original_l_ 
29     && dynamic_cast<Item*> (parent_l (X_AXIS))->breakable_b ();
30 }
31
32 void
33 Item::do_print() const
34 {
35 #ifndef NPRINT
36   DOUT << "breakable_b_: " << breakable_b_ << 
37     " break_status_dir_: " << break_status_dir_;
38 #endif
39 }
40
41
42 Real 
43 Item::hpos_f() const
44 {
45   return absolute_coordinate (X_AXIS);
46 }
47
48 Line_of_score *
49 Item::line_l() const
50 {
51   Graphical_element *g = parent_l (X_AXIS);
52   if (!g)
53     return 0;
54   return dynamic_cast<Score_element *> (g)-> line_l ();
55 }
56
57 Direction
58 Item::break_status_dir() const
59 {
60   return break_status_dir_;
61 }
62
63 void
64 Item::copy_breakable_items()
65 {
66   if (broken_to_drul_[LEFT] || broken_to_drul_[RIGHT] 
67       || ! breakable_b ())
68     return;
69
70   Drul_array<Item *> new_copies;
71   Direction  i=LEFT;
72   do 
73     {
74       Score_element * dolly = clone();
75       Item * item_p = dynamic_cast<Item*>(dolly);
76       item_p->unbroken_original_l_ = this;
77       item_p->break_status_dir_ =  i;
78       pscore_l_->typeset_element (item_p);
79       new_copies[i] =item_p;
80     }
81   while (flip(&i) != LEFT);
82   broken_to_drul_= new_copies;
83
84   do 
85     {
86        broken_to_drul_[i]->handle_prebroken_dependencies();
87        broken_to_drul_[i]->try_visibility_lambda();
88     }
89   while (flip(&i) != LEFT);
90   try_visibility_lambda ();
91 }
92
93 void
94 Item::try_visibility_lambda ()
95 {
96   SCM vis = get_elt_property (ly_symbol ("visibility_lambda"));
97   if (vis != SCM_BOOL_F)
98     {
99       SCM args = scm_listify (gh_int2scm (break_status_dir_), SCM_UNDEFINED);
100       SCM result = gh_apply ( SCM_CDR(vis), args);
101       int trans = gh_scm2bool (gh_car (result));
102       int empty = gh_scm2bool (gh_cdr (result));
103
104       if (empty)
105         set_empty (true);
106       if (trans)
107         transparent_b_ = true;
108     }
109 }
110
111 void
112 Item::do_break ()
113 {
114   copy_breakable_items();
115   handle_prebroken_dependencies();
116   
117   /*
118     Otherwise the broken items won't be pre_process()'ed.
119   */
120   add_dependency (broken_to_drul_[LEFT]);
121   add_dependency (broken_to_drul_[RIGHT]);
122 }
123
124 void
125 Item::do_breakable_col_processing()
126 {
127   if (breakable_b ())
128     do_break ();
129
130 }
131 Item*
132 Item::find_prebroken_piece (Line_of_score*l) const
133 {
134   if (line_l() == l) 
135     return (Item*)(this);
136   else if (broken_to_drul_[LEFT] && broken_to_drul_[LEFT]->line_l() == l)
137     return broken_to_drul_[LEFT];
138   else if (broken_to_drul_[RIGHT] && broken_to_drul_[RIGHT]->line_l() == l)
139     return broken_to_drul_[RIGHT];
140
141   return 0;
142 }
143
144 Item*
145 Item::find_prebroken_piece (Direction d) const
146 {
147   if (!d)
148     return (Item *) (this);     // ugh
149   else
150     return dynamic_cast<Item*> (broken_to_drul_[d]);
151 }
152
153 void
154 Item::handle_prebroken_dependencies()
155 {
156   if (breakable_b_)
157     Score_element::handle_prebroken_dependencies();
158 }
159
160 int
161 Item::left_right_compare(Item const *l, Item const *r)
162 {
163   Paper_column *p1 = l->column_l ();
164   Paper_column* p2 = r->column_l ();
165   return p1->rank_i () - p2->rank_i ();
166 }
167
168
169 bool
170 Item::linked_b() const
171 {
172   return Score_element::linked_b() || attached_span_l_arr_.size();
173 }
174
175
176
177 Paper_column *
178 Item::column_l () const
179 {
180   return dynamic_cast<Item*> (parent_l (X_AXIS))->column_l ();
181 }
182
183 Item::Item (Item const &s)
184   : Score_element (s)
185 {
186   unbroken_original_l_ = 0;
187   /* do not copy attached_span_l_arr_ */
188   breakable_b_ = s.breakable_b_;
189   broken_to_drul_[LEFT] = broken_to_drul_[RIGHT] =0;
190   break_status_dir_ = s.break_status_dir_;
191   break_priority_i_ = s.break_priority_i_;
192 }
193
194
195 void
196 Item::handle_prebroken_dependents ()
197 {
198   Item * parent =  dynamic_cast<Item*> (parent_l( X_AXIS));
199   if (breakable_b () && parent)
200     {
201        if(!(broken_to_drul_[LEFT] || broken_to_drul_[RIGHT]))
202         do_break ();
203
204       Direction d = LEFT;
205       do
206         {
207           broken_to_drul_[d]->dim_cache_[X_AXIS].parent_l_ =
208             &parent->broken_to_drul_[d]->dim_cache_[X_AXIS];
209           parent->broken_to_drul_[d]->add_dependency (broken_to_drul_[d]);
210         }
211       while ((flip (&d))!=LEFT);
212     }
213 }
214