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