]> git.donarmstrong.com Git - lilypond.git/blob - lily/time-signature-engraver.cc
1c6cd69bd4518b4571caf4b1e931c2bb8a612b9e
[lilypond.git] / lily / time-signature-engraver.cc
1 /*
2   This file is part of LilyPond, the GNU music typesetter.
3
4   Copyright (C) 1997--2012 Han-Wen Nienhuys <hanwen@xs4all.nl>
5
6   LilyPond is free software: you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation, either version 3 of the License, or
9   (at your option) any later version.
10
11   LilyPond is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "engraver-group.hh"
21
22 #include "item.hh"
23 #include "international.hh"
24 #include "misc.hh"
25 #include "time-signature.hh"
26 #include "warn.hh"
27
28 /**
29    generate time_signatures.
30 */
31 class Time_signature_engraver : public Engraver
32 {
33   Item *time_signature_;
34   SCM last_time_fraction_;
35
36 protected:
37   virtual void derived_mark () const;
38   void stop_translation_timestep ();
39   void process_music ();
40 public:
41   TRANSLATOR_DECLARATIONS (Time_signature_engraver);
42 };
43
44 void
45 Time_signature_engraver::derived_mark () const
46 {
47   scm_gc_mark (last_time_fraction_);
48 }
49
50 Time_signature_engraver::Time_signature_engraver ()
51 {
52   time_signature_ = 0;
53   last_time_fraction_ = SCM_BOOL_F;
54 }
55
56 void
57 Time_signature_engraver::process_music ()
58 {
59   /*
60     not rigorously safe, since the value might get GC'd and
61     reallocated in the same spot */
62   SCM fr = get_property ("timeSignatureFraction");
63   if (!time_signature_
64       && last_time_fraction_ != fr
65       && scm_is_pair (fr))
66     {
67       int den = scm_to_int (scm_cdr (fr));
68       if (den != (1 << intlog2 (den)))
69         {
70           /*
71             Todo: should make typecheck?
72
73             OTOH, Tristan Keuris writes 8/20 in his Intermezzi.
74           */
75           warning (_f ("strange time signature found: %d/%d",
76                        int (scm_to_int (scm_car (fr))),
77                        den));
78         }
79
80       time_signature_ = make_item ("TimeSignature", SCM_EOL);
81       time_signature_->set_property ("fraction", fr);
82
83       if (last_time_fraction_ == SCM_BOOL_F)
84         time_signature_->set_property ("break-visibility",
85                                        get_property ("implicitTimeSignatureVisibility"));
86
87       last_time_fraction_ = fr;
88     }
89 }
90
91 void
92 Time_signature_engraver::stop_translation_timestep ()
93 {
94   time_signature_ = 0;
95 }
96
97 #include "translator.icc"
98
99 ADD_TRANSLATOR (Time_signature_engraver,
100                 /* doc */
101                 "Create a @ref{TimeSignature} whenever"
102                 " @code{timeSignatureFraction} changes.",
103
104                 /* create */
105                 "TimeSignature ",
106
107                 /* read */
108                 "implicitTimeSignatureVisibility "
109                 "timeSignatureFraction ",
110
111                 /* write */
112                 ""
113                );