]> git.donarmstrong.com Git - lilypond.git/blob - lily/score-engraver.cc
(Module): strip AFM handling completely.
[lilypond.git] / lily / score-engraver.cc
1 /*
2   score-engraver.cc -- implement Score_engraver
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1997--2005 Han-Wen Nienhuys <hanwen@xs4all.nl>
7 */
8
9 #include "all-font-metrics.hh"
10 #include "warn.hh"
11 #include "main.hh"
12 #include "system.hh"
13 #include "score-engraver.hh"
14 #include "paper-score.hh"
15 #include "paper-column.hh"
16 #include "output-def.hh"
17 #include "axis-group-interface.hh"
18 #include "context-def.hh"
19 #include "global-context.hh"
20 #include "open-type-font.hh"
21 #include "paper-column-engraver.hh"
22
23 Score_engraver::Score_engraver ()
24 {
25   system_ = 0;
26   pscore_ = 0;
27 }
28
29 void
30 Score_engraver::derived_mark () const
31 {
32   if (pscore_)
33     scm_gc_mark (pscore_->self_scm ());
34   Score_translator::derived_mark ();
35   Engraver_group::derived_mark ();
36 }
37
38 void
39 Score_engraver::prepare (Moment m)
40 {
41   (void) m;
42
43   precomputed_recurse_over_translators (context (), START_TRANSLATION_TIMESTEP, DOWN);
44 }
45
46 void
47 Score_engraver::finish ()
48 {
49   recurse_over_translators (context (), &Translator::finalize,
50                             &Translator_group::finalize,
51                             UP);
52 }
53
54 #define MUSIC_FONT "emmentaler-20"
55
56 /*
57   use start/finish?
58 */
59 void
60 Score_engraver::initialize ()
61 {
62   Font_metric *fm = all_fonts_global->find_otf (MUSIC_FONT);
63   if (!fm)
64     {
65       error (_f ("cannot find `%s'", MUSIC_FONT ".otf")
66              + "\n"
67              + _ ("Music font has not been installed properly.")
68              + "\n"
69              + _f ("Search path `%s'", global_path.to_string ().to_str0 ())
70              + "\n"
71              + _ ("Aborting"));
72     }
73
74   pscore_ = new Paper_score (dynamic_cast<Output_def *> (context ()->get_output_def ()));
75   pscore_->unprotect ();
76
77   SCM props = updated_grob_properties (context (), ly_symbol2scm ("System"));
78
79   Object_key const *sys_key = context ()->get_grob_key ("System");
80   pscore_->typeset_system (new System (props, sys_key));
81   system_ = pscore_->root_system ();
82   context ()->set_property ("rootSystem", system_->self_scm ());
83
84   Engraver_group::initialize ();
85 }
86
87 void
88 Score_engraver::finalize ()
89 {
90   Score_translator::finalize ();
91
92   typeset_all ();
93 }
94
95 void
96 Score_engraver::one_time_step ()
97 {
98   if (!to_boolean (context ()->get_property ("skipTypesetting")))
99     {
100       precomputed_recurse_over_translators (context (), PROCESS_MUSIC, UP);
101       Engraver_group::do_announces ();
102     }
103
104   precomputed_recurse_over_translators (context (), STOP_TRANSLATION_TIMESTEP, UP);
105   typeset_all ();
106 }
107
108 void
109 Score_engraver::announce_grob (Grob_info info)
110 {
111   announce_infos_.push (info);
112   pscore_->root_system ()->typeset_grob (info.grob ());
113   elems_.push (info.grob ());
114 }
115
116 void
117 Score_engraver::typeset_all ()
118 {
119   for (int i = 0; i < elems_.size (); i++)
120     {
121       Grob *elem = elems_[i];
122
123       if (!elem->get_parent (Y_AXIS))
124         Axis_group_interface::add_element (system_, elem);
125     }
126   elems_.clear ();
127 }
128
129 SCM
130 Score_engraver::get_output ()
131 {
132   Music_output *o = pscore_;
133   return o->self_scm ();
134 }
135
136 /*
137   UGH UGH
138 */
139 void
140 Score_engraver::forbid_breaks ()
141 {
142   for (SCM s = simple_trans_list_; scm_is_pair (s); s = scm_cdr (s))
143     {
144       Translator *tr = unsmob_translator (scm_car (s));
145       if (Paper_column_engraver *pce = dynamic_cast<Paper_column_engraver *> (tr))
146         pce->forbid_breaks ();
147     }
148 }
149
150 bool
151 Score_engraver::try_music (Music *m)
152 {
153   if (Engraver_group::try_music (m))
154     return true;
155
156   return false;
157 }
158
159 ADD_TRANSLATOR_GROUP (Score_engraver,
160                       /* doc */ "Top level engraver. Takes care of generating columns and the complete  system (ie. System) "
161                       "\n\n "
162                       "This engraver decides whether a column is breakable. The default is "
163                       "that a column is always breakable. However, when every Bar_engraver "
164                       "that does not have a barline at a certain point will call "
165                       "Score_engraver::forbid_breaks to stop linebreaks.  In practice, this "
166                       "means that you can make a breakpoint by creating a barline (assuming "
167                       "that there are no beams or notes that prevent a breakpoint.) ",
168                       /* create */
169                       "System ",
170
171                       /* accept */
172                       "break-event",
173                       /* read */
174                       "currentMusicalColumn "
175                       "currentCommandColumn "
176                       "verticallySpacedContexts",
177                       /* write */
178                       "");