]> git.donarmstrong.com Git - lilypond.git/blob - lily/grace-engraver.cc
5afe21e00275561886650dc9ae91e36cbb02d96e
[lilypond.git] / lily / grace-engraver.cc
1 /*
2   This file is part of LilyPond, the GNU music typesetter.
3
4   Copyright (C) 2004--2014 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.hh"
21 #include "context.hh"
22 #include "warn.hh"
23 #include "grob-properties.hh"
24
25 class Grace_engraver : public Engraver
26 {
27   void consider_change_grace_settings ();
28 protected:
29   void start_translation_timestep ();
30   virtual void derived_mark () const;
31   virtual void initialize ();
32
33   TRANSLATOR_DECLARATIONS (Grace_engraver);
34   Moment last_moment_;
35   SCM grace_settings_;
36 public:
37 };
38
39 Grace_engraver::Grace_engraver ()
40 {
41   grace_settings_ = SCM_EOL;
42   last_moment_ = Moment (Rational (-1, 1));
43 }
44
45 void
46 Grace_engraver::initialize ()
47 {
48   consider_change_grace_settings ();
49 }
50
51 void
52 Grace_engraver::consider_change_grace_settings ()
53 {
54   Moment now = now_mom ();
55   if (last_moment_.grace_part_ && !now.grace_part_)
56     {
57       for (SCM s = grace_settings_; scm_is_pair (s); s = scm_cdr (s))
58         {
59           SCM elt = scm_car (s);
60           SCM context = scm_car (elt);
61           SCM grob = scm_cadr (elt);
62           SCM cell = scm_cddr (elt);
63
64           Grob_property_info (Context::unsmob (context), grob).matched_pop (cell);
65         }
66
67       grace_settings_ = SCM_EOL;
68     }
69   else if (!last_moment_.grace_part_ && now.grace_part_)
70     {
71       SCM settings = get_property ("graceSettings");
72
73       grace_settings_ = SCM_EOL;
74       for (SCM s = settings; scm_is_pair (s); s = scm_cdr (s))
75         {
76           SCM entry = scm_car (s);
77           SCM context_name = scm_car (entry);
78           SCM grob = scm_cadr (entry);
79           SCM sym = scm_caddr (entry);
80           SCM val = scm_cadr (scm_cddr (entry));
81
82           if (!scm_is_pair (sym))
83             sym = scm_list_1 (sym);
84
85           Context *c = context ();
86           while (c && !c->is_alias (context_name))
87             c = c->get_parent_context ();
88
89           if (c)
90             {
91               SCM cell = Grob_property_info (c, grob).push (sym, val);
92               grace_settings_
93                 = scm_cons (scm_cons2 (c->self_scm (), grob, cell), grace_settings_);
94             }
95           else
96             programming_error ("cannot find context from graceSettings: "
97                                + ly_symbol2string (context_name));
98         }
99     }
100
101   last_moment_ = now_mom ();
102 }
103
104 void
105 Grace_engraver::derived_mark () const
106 {
107   scm_gc_mark (grace_settings_);
108   Engraver::derived_mark ();
109 }
110
111 void
112 Grace_engraver::start_translation_timestep ()
113 {
114   consider_change_grace_settings ();
115 }
116
117 #include "translator.icc"
118
119 ADD_TRANSLATOR (Grace_engraver,
120                 /* doc */
121                 "Set font size and other properties for grace notes.",
122
123                 /* create */
124                 "",
125
126                 /* read */
127                 "graceSettings ",
128
129                 /* write */
130                 ""
131                );