]> git.donarmstrong.com Git - lilypond.git/blob - lily/ottava-engraver.cc
60c3fb178a987cb0a373a15f9e00ea48331ca3f9
[lilypond.git] / lily / ottava-engraver.cc
1 /*
2   ottava-engraver.cc -- implement Ottava_spanner_engraver
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 2000--2007 Han-Wen Nienhuys
7 */
8
9 #include "text-interface.hh"
10 #include "protected-scm.hh"
11 #include "note-column.hh"
12 #include "side-position-interface.hh"
13 #include "engraver.hh"
14 #include "spanner.hh"
15 #include "text-interface.hh"
16 #include "item.hh"
17
18 class Ottava_spanner_engraver : public Engraver
19 {
20 public:
21   TRANSLATOR_DECLARATIONS (Ottava_spanner_engraver);
22 protected:
23   virtual void finalize ();
24
25   DECLARE_ACKNOWLEDGER (note_column);
26
27   void process_music ();
28   void stop_translation_timestep ();
29   virtual void derived_mark () const;
30 private:
31   Spanner *span_;
32   Spanner *finished_;
33
34   SCM last_ottavation_;
35
36   void typeset_all ();
37 };
38
39 void
40 Ottava_spanner_engraver::derived_mark () const
41 {
42   scm_gc_mark (last_ottavation_);
43 }
44
45 Ottava_spanner_engraver::Ottava_spanner_engraver ()
46 {
47   finished_ = 0;
48   span_ = 0;
49   last_ottavation_ = SCM_EOL;
50 }
51
52 void
53 Ottava_spanner_engraver::process_music ()
54 {
55   SCM ott = get_property ("ottavation");
56   if (ott != last_ottavation_)
57     {
58       finished_ = span_;
59       span_ = 0;
60       if (Text_interface::is_markup (ott))
61         {
62           span_ = make_spanner ("OttavaBracket", SCM_EOL);
63           span_->set_property ("text", ott);
64
65           SCM offset (get_property ("middleCOffset"));
66           if (robust_scm2double (offset, 0) > 0)
67             span_->set_property ("direction", scm_from_int (DOWN));
68         }
69     }
70   last_ottavation_ = ott;
71 }
72
73 void
74 Ottava_spanner_engraver::acknowledge_note_column (Grob_info info)
75 {
76   Item *it = info.item ();
77   if (span_ && it)
78     {
79       Side_position_interface::add_support (span_, it);
80
81       if (!span_->get_bound (LEFT))
82         span_->set_bound (LEFT, it);
83       span_->set_bound (RIGHT, it);
84     }
85 }
86
87 void
88 Ottava_spanner_engraver::typeset_all ()
89 {
90   if (finished_)
91     {
92       Direction d = LEFT;
93       do
94         {
95           if (!finished_->get_bound (RIGHT))
96             {
97               Grob *e = unsmob_grob (get_property ("currentMusicalColumn"));
98               finished_->set_bound (d, e);
99             }
100         }
101       while (flip (&d) != LEFT);
102
103       finished_ = 0;
104     }
105 }
106
107 void
108 Ottava_spanner_engraver::stop_translation_timestep ()
109 {
110   if (span_ && !span_->get_bound (LEFT))
111     {
112       Grob *e = unsmob_grob (get_property ("currentMusicalColumn"));
113       span_->set_bound (LEFT, e);
114     }
115
116   typeset_all ();
117 }
118
119 void
120 Ottava_spanner_engraver::finalize ()
121 {
122   typeset_all ();
123   if (span_)
124     finished_ = span_;
125   typeset_all ();
126   last_ottavation_ = SCM_EOL;
127 }
128
129 #include "translator.icc"
130
131 ADD_ACKNOWLEDGER (Ottava_spanner_engraver, note_column);
132
133 ADD_TRANSLATOR (Ottava_spanner_engraver,
134                 /* doc */
135                 "Create a text spanner when the ottavation property changes.",
136
137                 /* create */
138                 "OttavaBracket ",
139
140                 /* read */
141                 "ottavation "
142                 "originalMiddleCPosition "
143                 "currentMusicalColumn ",
144                 
145                 /* write */
146                 ""
147                 );