]> git.donarmstrong.com Git - lilypond.git/blob - lily/property-engraver.cc
release: 1.5.44
[lilypond.git] / lily / property-engraver.cc
1 /*   
2   property-engraver.cc --  implement Property engraver
3   
4   source file of the GNU LilyPond music typesetter
5   
6   (c) 1999--2002 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7   
8  */
9
10 #include "lily-guile.hh"
11 #include "engraver.hh"
12 #include "dictionary.hh"
13 #include "grob.hh"
14 #include "scm-hash.hh"
15 #include "translator-group.hh"
16 #include "warn.hh" 
17
18 /*
19   This is deprecated, since revert/override should be used
20  */
21 class Property_engraver : public Engraver
22 {
23   Scheme_hash_table *prop_dict_;        // junkme
24   void apply_properties (SCM, Grob*, Translator_group *origin);
25
26 protected:
27   virtual void acknowledge_grob (Grob_info ei);
28   virtual void initialize ();
29   virtual void finalize ();
30 public:
31   ~Property_engraver ();
32   TRANSLATOR_DECLARATIONS(Property_engraver);
33 };
34
35
36
37 Property_engraver::Property_engraver ()
38 {
39   prop_dict_ = 0;
40 }
41 void
42 Property_engraver::finalize ()
43 {
44   
45 }
46
47 Property_engraver::~Property_engraver ()
48 {
49   if (prop_dict_)
50     scm_gc_unprotect_object (prop_dict_->self_scm ());
51 }
52
53 void
54 Property_engraver::initialize ()
55 {
56   prop_dict_ = new Scheme_hash_table;
57
58   SCM plist = get_property ("Generic_property_list");
59   for (; gh_pair_p (plist); plist = ly_cdr (plist))
60     {
61       SCM elt_props = ly_car (plist);
62       prop_dict_->set (ly_car (elt_props), ly_cdr (elt_props));
63     }
64 }
65
66 void
67 Property_engraver::acknowledge_grob (Grob_info i)
68 {
69   SCM ifs = i.grob_l_->get_grob_property ("interfaces");
70   SCM props;
71   for (; gh_pair_p (ifs); ifs = ly_cdr (ifs))
72     {      
73       if (prop_dict_->try_retrieve (ly_car (ifs), &props))
74         {
75           apply_properties (props,i.grob_l_, i.origin_trans_l_->daddy_trans_l_);
76         }
77     }
78
79   if (prop_dict_->try_retrieve (ly_symbol2scm ("all"), &props))
80     {
81       apply_properties (props, i.grob_l_, i.origin_trans_l_->daddy_trans_l_);
82     }
83 }
84
85
86 void
87 Property_engraver::apply_properties (SCM p, Grob *e, Translator_group*origin)
88 {
89   for (; gh_pair_p (p); p = ly_cdr (p))
90     {
91       /*
92         Try each property in order; earlier descriptions take
93         precedence over later ones, and we don't touch elt-properties if
94         they're already set.
95       */
96       
97       SCM entry = ly_car (p);
98       SCM prop_sym = ly_car (entry);
99       SCM type_p   = ly_cadr (entry);
100       SCM elt_prop_sym = ly_caddr (entry);
101
102       SCM preset = scm_assq (elt_prop_sym, e->mutable_property_alist_);
103       if (preset != SCM_BOOL_F)
104         continue;
105   
106       SCM val = internal_get_property (prop_sym);
107
108       if (val == SCM_EOL)
109         ;                       // Not defined in context.
110       else if (gh_apply (type_p, scm_list_n (val, SCM_UNDEFINED))
111                == SCM_BOOL_T)   // defined and  right type: do it
112         {
113           e->internal_set_grob_property (elt_prop_sym, val);
114
115           SCM meta = e->get_grob_property ("meta");
116           SCM name = scm_assoc (ly_symbol2scm ("name"), meta);
117           warning (_f ("`%s' is deprecated.  Use\n \\property %s.%s \\override #'%s = #%s",
118                        ly_symbol2string (prop_sym).ch_C (),
119                        origin->type_str_.ch_C (),
120                        ly_scm2string (ly_cdr (name)).ch_C (),
121                        ly_symbol2string (elt_prop_sym).ch_C (),
122                        ly_scm2string (ly_write2scm (val)).ch_C ()));
123         }
124       else
125
126         /*
127             we don't print a warning if VAL == (), because we would
128             get lots of warnings when we restore stuff to default, eg.
129
130             slurDash = #1 [...] slurDash = ()
131
132             should not cause "type error: slurDash expects number not
133             boolean
134
135         */
136         if (val != SCM_EOL)
137           {                     // not the right type: error message.
138             SCM errport = scm_current_error_port ();
139             SCM typefunc = scm_primitive_eval (ly_symbol2scm ("type-name"));
140             SCM type_name = gh_call1 (typefunc, type_p);
141             warning (_f ("Wrong type for property: %s, type: %s, value found: %s, type: %s",
142                          ly_symbol2string (prop_sym).ch_C (),
143                          ly_scm2string (type_name).ch_C (),
144                          ly_scm2string (ly_write2scm (val)).ch_C (),
145                          ly_scm2string (ly_type (val)).ch_C ()));
146             scm_puts ("\n", errport);
147           }
148     }
149 }
150
151
152 ENTER_DESCRIPTION(Property_engraver,
153 /* descr */       "This is a engraver that converts property settings into
154 back-end grob-property settings. Example: Voice.stemLength will set
155 #'length in all Stem objects.
156
157 Due to CPU and memory requirements, the use of this engraver is deprecated.",
158 /* creats*/       "",
159 /* acks  */       "grob-interface",
160 /* reads */       "Generic_property_list",
161 /* write */       "");