]> git.donarmstrong.com Git - lilypond.git/blob - lily/mark-engraver.cc
*** empty log message ***
[lilypond.git] / lily / mark-engraver.cc
1 /*
2   mark-engraver.cc -- implement Mark_engraver
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1998--2003 Jan Nieuwenhuizen <janneke@gnu.org>
7 */
8
9 #include <ctype.h>
10 #include "bar-line.hh"
11
12 #include "staff-symbol.hh"
13 #include "engraver-group-engraver.hh"
14 #include "engraver.hh"
15 #include "lily-guile.hh"
16 #include "paper-column.hh"
17 #include "paper-def.hh"
18 #include "side-position-interface.hh"
19 #include "staff-symbol-referencer.hh"
20 #include "item.hh"
21 #include "group-interface.hh"
22 #include "text-item.hh"
23
24 /**
25   put stuff over or next to  bars.  Examples: bar numbers, marginal notes,
26   rehearsal marks.
27  */
28 class Mark_engraver : public Engraver
29 {
30 public:
31   TRANSLATOR_DECLARATIONS(Mark_engraver);
32 protected:
33   Item* text_;
34   
35 protected:
36   virtual void stop_translation_timestep ();
37   virtual void acknowledge_grob (Grob_info);
38   void create_items (Music*);
39   virtual bool try_music (Music *req);
40   virtual void process_music ();
41   
42 private:
43   Music * mark_req_;
44 };
45
46
47
48
49
50 Mark_engraver::Mark_engraver ()
51 {
52   text_ =0;
53   mark_req_ = 0;
54 }
55
56 void
57 Mark_engraver::acknowledge_grob (Grob_info inf)
58 {
59   Grob * s = inf.grob_;
60   if (text_ && Bar_line::has_interface (s))
61     {
62       /*
63       TODO: make this configurable. RehearsalMark cannot be
64       break-aligned, since the width of the object should not be taken
65       into alignment considerations.
66       */
67       text_->set_parent (s, X_AXIS);
68     }
69 }
70
71 void 
72 Mark_engraver::stop_translation_timestep ()
73 {
74   if (text_)
75     {
76       text_->set_grob_property ("side-support-elements" , get_property ("stavesFound"));
77       typeset_grob (text_);
78       text_ =0;
79     }
80   mark_req_ = 0;
81 }
82
83
84 void
85 Mark_engraver::create_items (Music *rq)
86 {
87   if (text_)
88     return;
89
90   text_ = new Item (get_property ("RehearsalMark"));
91   announce_grob(text_, rq->self_scm());
92 }
93
94
95 bool
96 Mark_engraver::try_music (Music* r)
97 {
98   mark_req_ = r;
99   return true;
100 }
101
102
103 /*
104
105   TODO: make the increment function in Scheme.
106
107
108   TODO: junk the number type for rehearsalMark
109 */
110 void
111 Mark_engraver::process_music ()
112 {
113   if (mark_req_)
114     {
115       create_items (mark_req_);
116
117       /*
118         automatic marks.
119        */
120       
121       SCM m = mark_req_->get_mus_property ("label");
122       if (Text_item::markup_p (m))
123         {
124           text_->set_grob_property ("text",m);
125         }
126       else 
127         {
128           String t ;
129           
130           if (!gh_string_p (m) && !gh_number_p (m)) 
131             m =  get_property ("rehearsalMark");
132           
133           if (gh_number_p (m))
134             {
135               int mark_count = gh_scm2int (m);
136               t = to_string (mark_count);
137               mark_count ++;
138               m = gh_int2scm (mark_count);
139             }
140           else if (gh_string_p (m))
141             {
142               t = ly_scm2string (m);
143               String next;
144               if (t.length ())
145                 {
146                   char c = t[0];
147                   c++;
148                   t = to_string (c);
149                 }
150               m = scm_makfrom0str (t.to_str0 ());
151             }
152           else
153             {
154               m = gh_int2scm (1);
155               t = to_string (1);
156             }
157           
158           text_->set_grob_property ("text",
159                                     scm_makfrom0str (t.to_str0 ()));
160
161           SCM series = SCM_EOL;
162           SCM family = ly_symbol2scm ("number");
163           for (int i=0; i < t.length (); i++)
164             {
165               if (!isdigit (t[i])) 
166                 {
167                   /*
168                     This looks strange, since \mark "A"
169                     isn't printed in bold.
170                     
171                    */
172                   
173                   // series = ly_symbol2scm ("bold");
174                   family = ly_symbol2scm ("roman");
175                   break;
176                 }
177             }
178           if (gh_symbol_p (series))
179             text_->set_grob_property ("font-series",  series);
180           if (gh_symbol_p (family))
181             text_->set_grob_property ("font-family",  family);
182         }
183
184       if (gh_number_p (m) || gh_string_p (m))
185         daddy_trans_->set_property ("rehearsalMark", m);
186     }
187 }
188
189 ENTER_DESCRIPTION(Mark_engraver,
190 /* descr */       "",
191 /* creats*/       "RehearsalMark",
192 /* accepts */     "mark-event",
193 /* acks  */       "bar-line-interface",
194 /* reads */       "rehearsalMark stavesFound",
195 /* write */       "");