]> git.donarmstrong.com Git - lilypond.git/blob - lily/item.cc
release: 1.3.55
[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--2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
8
9 #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"
16 #include "line-of-score.hh"
17
18 Item::Item (SCM s)
19   : Score_element (s)
20
21 {
22   broken_to_drul_[LEFT] = broken_to_drul_[RIGHT]=0;
23 }
24
25 /**
26    Item copy ctor.  Copy nothing: everything should be a elt property
27    or a special purpose pointer (such as broken_to_drul_[]) */
28 Item::Item (Item const &s)
29   : Score_element (s)
30 {
31   broken_to_drul_[LEFT] = broken_to_drul_[RIGHT] =0;
32 }
33
34
35
36 bool
37 Item::breakable_b () const
38 {
39   if (original_l_ )
40     return false;
41   
42   Item * i  =dynamic_cast<Item*> (parent_l (X_AXIS));
43   return (i) ?  i->breakable_b () : to_boolean (get_elt_property ("breakable"));
44 }
45
46 Line_of_score *
47 Item::line_l() const
48 {
49   Score_element *g = parent_l (X_AXIS);
50   return g ?  g->line_l () : 0;
51 }
52
53
54 void
55 Item::copy_breakable_items()
56 {
57   Drul_array<Item *> new_copies;
58   Direction  i=LEFT;
59   do 
60     {
61       Score_element * dolly = clone();
62       Item * item_p = dynamic_cast<Item*>(dolly);
63       pscore_l_->line_l_->typeset_element (item_p);
64       new_copies[i] =item_p;
65     }
66   while (flip(&i) != LEFT);
67   broken_to_drul_= new_copies;
68 }
69
70
71 bool
72 Item::broken_b () const
73 {
74   return broken_to_drul_[LEFT] || broken_to_drul_[RIGHT];
75 }
76
77
78 /*
79   Generate items for begin and end-of line.
80  */
81 void
82 Item::discretionary_processing()
83 {
84   if (broken_b ())
85     return;
86
87   if (breakable_b ())
88     copy_breakable_items();
89 }
90
91 Score_element*
92 Item::find_broken_piece (Line_of_score*l) const
93 {
94   if (line_l() == l) 
95     return (Item*)(this);
96
97   Direction d = LEFT;
98   do {
99     Score_element *s = broken_to_drul_[d];
100     if (s && s->line_l () == l)
101       return s;
102   }
103   while (flip (&d) != LEFT);
104
105   return 0;
106 }
107
108
109 Item*
110 Item::find_prebroken_piece (Direction d) const
111 {
112   Item * me = (Item *) (this);  
113   if (!d)
114     return me;
115   return dynamic_cast<Item*> (broken_to_drul_[d]);
116 }
117
118 Paper_column *
119 Item::column_l () const
120 {
121   return dynamic_cast<Item*> (parent_l (X_AXIS))->column_l ();
122 }
123
124 Direction
125 Item::break_status_dir () const
126 {
127   if (original_l_)
128     {
129       Item * i = dynamic_cast<Item*> (original_l_);
130
131       return (i->broken_to_drul_[LEFT] == this) ? LEFT : RIGHT;
132     }
133   else
134     return CENTER;
135 }
136
137 void
138 Item::handle_prebroken_dependencies ()
139 {
140   if (original_l_)
141     {
142       pointer_alist_
143         = handle_broken_smobs (original_l_->pointer_alist_,
144                                gh_int2scm (break_status_dir ()));
145     }
146   
147   /*
148     Can't do this earlier, because try_visibility_lambda () might set
149     the elt property transparent, which would then be copied.
150   */
151   SCM vis = get_elt_property ("visibility-lambda");
152   if (gh_procedure_p (vis))
153     {
154       SCM args = scm_listify (gh_int2scm (break_status_dir ()), SCM_UNDEFINED);
155       SCM result = gh_apply (vis, args);
156       bool trans = gh_scm2bool (gh_car (result));
157       bool empty = gh_scm2bool (gh_cdr (result));
158
159       if (empty)
160         {
161           set_extent_callback (0, X_AXIS);
162           set_extent_callback (0,  Y_AXIS);
163         }
164       if (trans)
165         set_elt_property ("transparent", SCM_BOOL_T);
166     }
167 }