]> git.donarmstrong.com Git - lilypond.git/blob - lily/text-engraver.cc
patch::: 1.5.30.uu1
[lilypond.git] / lily / text-engraver.cc
1 /*   
2   text-engraver.cc --  implement Text_engraver
3   
4   source file of the GNU LilyPond music typesetter
5   
6   (c) 1998--2002 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7   
8  */
9
10
11 #include "engraver.hh"
12 #include "side-position-interface.hh"
13 #include "item.hh"
14 #include "musical-request.hh"
15 #include "stem.hh"
16 #include "rhythmic-head.hh"
17
18
19 /**
20    typeset directions that are  plain text.
21  */
22 class Text_engraver : public Engraver
23 {
24   Link_array<Text_script_req> reqs_;
25   Link_array<Item> texts_;
26 public:
27   TRANSLATOR_DECLARATIONS(Text_engraver);
28 protected:
29   virtual bool try_music (Music* m);
30   virtual void stop_translation_timestep ();
31   virtual void start_translation_timestep ();
32   virtual void create_grobs ();
33   virtual void acknowledge_grob (Grob_info);
34 };
35
36 bool
37 Text_engraver::try_music (Music *m)
38 {
39   if (dynamic_cast<Text_script_req*> (m)
40       && m->get_mus_property ("text-type") != ly_symbol2scm ("dynamic"))
41     {
42       reqs_.push (dynamic_cast<Text_script_req*> (m));
43       return true;
44     }
45   return false;
46 }
47
48 void
49 Text_engraver::acknowledge_grob (Grob_info inf)
50 {
51   if (Rhythmic_head::has_interface (inf.grob_l_))
52     {
53       for (int i=0; i < texts_.size (); i++)
54         {
55           Grob*t = texts_[i];
56           Side_position_interface::add_support (t,inf.grob_l_);
57
58           /*
59             ugh.
60            */
61           if (Side_position_interface::get_axis (t) == X_AXIS
62               && !t->get_parent (Y_AXIS))
63             t->set_parent (inf.grob_l_, Y_AXIS);
64           else if (Side_position_interface::get_axis (t) == Y_AXIS
65               && !t->get_parent (X_AXIS))
66             t->set_parent (inf.grob_l_, X_AXIS);
67         }
68     }
69   
70   if (Stem::has_interface (inf.grob_l_))
71     {
72       for (int i=0; i < texts_.size (); i++)
73         {
74           Side_position_interface::add_support (texts_[i],inf.grob_l_);
75         }
76     }
77 }
78
79 void
80 Text_engraver::create_grobs ()
81 {
82   if (texts_.size ())
83     return;
84   for (int i=0; i < reqs_.size (); i++)
85     {
86       Text_script_req * r = reqs_[i];
87       
88       // URG: Text vs TextScript
89       String basic = "TextScript";
90
91       if (r->get_mus_property ("text-type") == ly_symbol2scm ("finger"))
92         {
93           basic = "Fingering";
94         }
95
96       Item *text = new Item (get_property (basic.ch_C ()));
97
98       /*
99         FIXME -> need to use basic props.
100        */
101       SCM axisprop = get_property ("scriptHorizontal");
102       
103       Axis ax = to_boolean (axisprop) ? X_AXIS : Y_AXIS;
104       Side_position_interface::set_axis (text, ax);
105
106 #if 0
107       if (r->style_str_ == "finger" && ax == Y_AXIS)
108         {
109           /*
110             nicely center the scripts.
111            */ 
112           text->add_offset_callback (Side_position_interface::aligned_on_self_proc, X_AXIS);
113           text->add_offset_callback (Side_position_interface::centered_on_parent_proc, X_AXIS);
114         }
115 #endif
116       
117
118       
119       /*
120         make sure they're in order by adding i to the priority field.
121         */
122       text->set_grob_property ("script-priority",
123                               gh_int2scm (200 + i));
124
125       if (r->get_direction ())
126         Side_position_interface::set_direction (text, r->get_direction ());
127       
128       text->set_grob_property ("text", r->get_mus_property ("text"));
129       
130       SCM nonempty = get_property ("textNonEmpty");
131
132       if (gh_boolean_p (nonempty))
133         if (gh_scm2bool (nonempty))
134           /*
135             empty text: signal that no rods should be applied.
136             Default nowadays.
137           */
138           text->set_grob_property ("no-spacing-rods" , SCM_BOOL_F);
139         else
140           text->set_grob_property ("no-spacing-rods" , SCM_BOOL_T);
141        
142       announce_grob (text, r->self_scm ());
143       texts_.push (text);
144     }
145 }
146
147 void
148 Text_engraver::stop_translation_timestep ()
149 {
150   for (int i=0; i < texts_.size (); i++)
151     {
152       Item *ti = texts_[i];
153       if (!to_boolean (get_property ("scriptHorizontal")))
154         Side_position_interface::add_staff_support (ti);
155       typeset_grob (ti);
156     }
157   texts_.clear ();
158 }
159
160 void
161 Text_engraver::start_translation_timestep ()
162 {
163   reqs_.clear ();
164 }
165
166
167 Text_engraver::Text_engraver(){}
168
169 ENTER_DESCRIPTION(Text_engraver,
170 /* descr */       "Create text-scripts",
171 /* creats*/       "TextScript",
172 /* acks  */       "rhythmic-head-interface stem-interface",
173 /* reads */       "scriptHorizontal textNonEmpty",
174 /* write */       "");