]> git.donarmstrong.com Git - lilypond.git/blob - lily/grace-engraver.cc
2b02020f62314526d4b93ddec861cf3f5fd91622
[lilypond.git] / lily / grace-engraver.cc
1 /*
2   grace-engraver.cc -- implement Grace_engraver
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 2004--2007 Han-Wen Nienhuys <hanwen@xs4all.nl>
7 */
8
9 #include "engraver.hh"
10 #include "context.hh"
11 #include "warn.hh"
12
13 class Grace_engraver : public Engraver
14 {
15   void consider_change_grace_settings ();
16 protected:
17   void start_translation_timestep ();
18   virtual void derived_mark () const;
19   virtual void initialize ();
20
21   TRANSLATOR_DECLARATIONS (Grace_engraver);
22   Moment last_moment_;
23   SCM grace_settings_;
24 public:
25 };
26
27 Grace_engraver::Grace_engraver ()
28 {
29   grace_settings_ = SCM_EOL;
30   last_moment_ = Moment (Rational (-1, 1));
31 }
32
33 void
34 Grace_engraver::initialize ()
35 {
36   consider_change_grace_settings ();
37 }
38
39 void
40 Grace_engraver::consider_change_grace_settings ()
41 {
42   Moment now = now_mom ();
43   if (last_moment_.grace_part_ && !now.grace_part_)
44     {
45       for (SCM s = grace_settings_; scm_is_pair (s); s = scm_cdr (s))
46         {
47           SCM context = scm_caar (s);
48           SCM entry = scm_cdar (s);
49           SCM grob = scm_cadr (entry);
50           SCM sym = scm_caddr (entry);
51
52           execute_pushpop_property (unsmob_context (context),
53                                     grob, sym, SCM_UNDEFINED);
54         }
55
56       grace_settings_ = SCM_EOL;
57     }
58   else if (!last_moment_.grace_part_ && now.grace_part_)
59     {
60       SCM settings = get_property ("graceSettings");
61
62       grace_settings_ = SCM_EOL;
63       for (SCM s = settings; scm_is_pair (s); s = scm_cdr (s))
64         {
65           SCM entry = scm_car (s);
66           SCM context_name = scm_car (entry);
67           SCM grob = scm_cadr (entry);
68           SCM sym = scm_caddr (entry);
69           SCM val = scm_cadr (scm_cddr (entry));
70
71           Context *c = context ();
72           while (c && !c->is_alias (context_name))
73             c = c->get_parent_context ();
74
75           if (c)
76             {
77               execute_pushpop_property (c,
78                                         grob, sym, val);
79               grace_settings_
80                 = scm_cons (scm_cons (c->self_scm (), entry), grace_settings_);
81             }
82           else
83             {
84               programming_error ("cannot find context: ");
85               scm_display (context_name, scm_current_error_port ());
86             }
87         }
88     }
89
90   last_moment_ = now_mom ();
91 }
92
93 void
94 Grace_engraver::derived_mark () const
95 {
96   scm_gc_mark (grace_settings_);
97   Engraver::derived_mark ();
98 }
99
100 void
101 Grace_engraver::start_translation_timestep ()
102 {
103   consider_change_grace_settings ();
104 }
105
106 #include "translator.icc"
107
108 ADD_TRANSLATOR (Grace_engraver,
109                 /* doc */
110                 "Set font size and other properties for grace notes.",
111
112                 /* create */
113                 "",
114
115                 /* read */
116                 "graceSettings ",
117
118                 /* write */
119                 ""
120                 );