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