]> git.donarmstrong.com Git - lilypond.git/blob - lily/text-engraver.cc
patch::: 1.3.98.jcn2
[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--2000 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   VIRTUAL_COPY_CONS(Translator);
28 protected:
29   virtual bool do_try_music (Music* m);
30   virtual void do_pre_move_processing ();
31   virtual void do_post_move_processing ();
32   virtual void do_process_music ();
33   virtual void acknowledge_element (Score_element_info);
34 };
35
36 bool
37 Text_engraver::do_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_element (Score_element_info inf)
50 {
51   if (Rhythmic_head::has_interface (inf.elem_l_))
52     {
53       for (int i=0; i < texts_.size (); i++)
54         {
55           Score_element*t = texts_[i];
56           Side_position::add_support (t,inf.elem_l_);
57
58           /*
59             ugh.
60            */
61           if (Side_position::get_axis( t) == X_AXIS
62               && !t->parent_l (Y_AXIS))
63             t->set_parent (inf.elem_l_, Y_AXIS);
64           else if (Side_position::get_axis(t) == Y_AXIS
65               && !t->parent_l (X_AXIS))
66             t->set_parent (inf.elem_l_, X_AXIS);
67         }
68     }
69   
70   if (Stem::has_interface (inf.elem_l_))
71     {
72       for (int i=0; i < texts_.size (); i++)
73         {
74           Side_position::add_support(texts_[i],inf.elem_l_);
75         }
76     }
77 }
78
79 void
80 Text_engraver::do_process_music ()
81 {
82   for (int i=0; i < reqs_.size (); i++)
83     {
84       Text_script_req * r = reqs_[i];
85       
86       // URG: Text vs TextScript
87       String basic = "TextScript";
88
89       if (r->get_mus_property ("text-type") == ly_symbol2scm ("finger"))
90         {
91           basic = "Fingering";
92         }
93
94       Item *text = new Item (get_property (basic.ch_C ()));
95
96       /*
97         FIXME -> need to use basic props.
98        */
99       SCM axisprop = get_property ("scriptHorizontal");
100       
101       Axis ax = to_boolean (axisprop) ? X_AXIS : Y_AXIS;
102       Side_position::set_axis (text, ax);
103
104 #if 0
105       if (r->style_str_ == "finger" && ax == Y_AXIS)
106         {
107           /*
108             nicely center the scripts.
109            */ 
110           text->add_offset_callback (Side_position::aligned_on_self_proc, X_AXIS);
111           text->add_offset_callback (Side_position::centered_on_parent_proc, X_AXIS);
112         }
113 #endif
114       
115
116       
117       /*
118         make sure they're in order by adding i to the priority field.
119         */
120       text->set_elt_property ("script-priority",
121                               gh_int2scm (200 + i));
122
123       if (r->get_direction ())
124         Side_position::set_direction (text, r->get_direction ());
125       
126       text->set_elt_property ("text", r->get_mus_property ("text"));
127       
128       SCM nonempty = get_property ("textNonEmpty");
129       if (to_boolean (nonempty))
130         /*
131           empty text: signal that no rods should be applied.  
132          */
133         text->set_elt_property ("no-spacing-rods" , SCM_BOOL_F);
134                 
135       announce_element (text, r);
136       texts_.push (text);
137     }
138 }
139
140 void
141 Text_engraver::do_pre_move_processing ()
142 {
143   for (int i=0; i < texts_.size (); i++)
144     {
145       Item *ti = texts_[i];
146       Side_position::add_staff_support (ti);
147       typeset_element (ti);
148     }
149   texts_.clear ();
150 }
151
152 void
153 Text_engraver::do_post_move_processing ()
154 {
155   reqs_.clear ();
156 }
157
158 ADD_THIS_TRANSLATOR(Text_engraver);
159