CVSROOT: /cvsroot/lilypond Module name: lilypond Branch: lilypond_2_6 Changes by: Han-Wen Nienhuys <[EMAIL PROTECTED]> 05/08/04 11:11:31
Modified files: . : ChangeLog THANKS VERSION lily : auto-beam-engraver.cc clef-engraver.cc hara-kiri-engraver.cc stanza-number-engraver.cc time-signature-engraver.cc volta-engraver.cc Log message: (derived_mark): new method. Yes. We have to protect even those unlikely-to-be-corrupted data members. CVSWeb URLs: http://savannah.gnu.org/cgi-bin/viewcvs/lilypond/lilypond/ChangeLog.diff?only_with_tag=lilypond_2_6&tr1=1.3836.2.16&tr2=1.3836.2.17&r1=text&r2=text http://savannah.gnu.org/cgi-bin/viewcvs/lilypond/lilypond/THANKS.diff?only_with_tag=lilypond_2_6&tr1=1.128&tr2=1.128.2.1&r1=text&r2=text http://savannah.gnu.org/cgi-bin/viewcvs/lilypond/lilypond/VERSION.diff?only_with_tag=lilypond_2_6&tr1=1.645.2.2&tr2=1.645.2.3&r1=text&r2=text http://savannah.gnu.org/cgi-bin/viewcvs/lilypond/lilypond/lily/auto-beam-engraver.cc.diff?only_with_tag=lilypond_2_6&tr1=1.145&tr2=1.145.2.1&r1=text&r2=text http://savannah.gnu.org/cgi-bin/viewcvs/lilypond/lilypond/lily/clef-engraver.cc.diff?only_with_tag=lilypond_2_6&tr1=1.123&tr2=1.123.2.1&r1=text&r2=text http://savannah.gnu.org/cgi-bin/viewcvs/lilypond/lilypond/lily/hara-kiri-engraver.cc.diff?only_with_tag=lilypond_2_6&tr1=1.11&tr2=1.11.2.1&r1=text&r2=text http://savannah.gnu.org/cgi-bin/viewcvs/lilypond/lilypond/lily/stanza-number-engraver.cc.diff?only_with_tag=lilypond_2_6&tr1=1.38&tr2=1.38.2.1&r1=text&r2=text http://savannah.gnu.org/cgi-bin/viewcvs/lilypond/lilypond/lily/time-signature-engraver.cc.diff?only_with_tag=lilypond_2_6&tr1=1.62&tr2=1.62.2.1&r1=text&r2=text http://savannah.gnu.org/cgi-bin/viewcvs/lilypond/lilypond/lily/volta-engraver.cc.diff?only_with_tag=lilypond_2_6&tr1=1.60&tr2=1.60.2.1&r1=text&r2=text Patches: Index: lilypond/ChangeLog diff -u lilypond/ChangeLog:1.3836.2.16 lilypond/ChangeLog:1.3836.2.17 --- lilypond/ChangeLog:1.3836.2.16 Wed Aug 3 14:28:03 2005 +++ lilypond/ChangeLog Thu Aug 4 11:11:29 2005 @@ -1,3 +1,8 @@ +2005-08-04 Han-Wen Nienhuys <[EMAIL PROTECTED]> + + * lily/auto-beam-engraver.cc (derived_mark): new method. Yes. We + have to protect even those unlikely-to-be-corrupted data members. + 2005-08-03 Mats Bengtsson <[EMAIL PROTECTED]> * Documentation/user/lilypond-book.itely (An example of a Index: lilypond/THANKS diff -u /dev/null lilypond/THANKS:1.128.2.1 --- /dev/null Thu Aug 4 11:11:31 2005 +++ lilypond/THANKS Thu Aug 4 11:11:30 2005 @@ -0,0 +1,318 @@ +Release 2.6 +*********** + +DEVELOPMENT TEAM + +Han-Wen Nienhuys - Core development +Jan Nieuwenhuizen - Core development +Erik Sandberg - Bug Meister +Pedro Kroger - Build Meister +Graham Percival - Documentation Editor + +CONTRIBUTORS + +Andreas Scherer +Arno Waschk +Bertalan Fodor +Carl Sorensen +Christian Hitz +David Jedlinsky +Erlend Aasland +Heikki Junes +John Williams +Jonatan Liljedahl +Jürgen Reuter +Mats Bengtsson +Matthias Neeracher +Mathieu Giraud +Nicolas Sceaux +Pal Benko +Sebastiano Vigna +Tatsuya Ono +Vicente Solsona Della +Werner Lemberg +Yuval Harel + +TRANSLATORS + +Abel Cheung +John Mandereau +Olcay Yıldırım +Roland Stigge +Steven Michael Murphy + + +WEBSITE TRANSLATORS + +Gauvain Pocentek +Jean-Charles Malahieude +John Mandereau +Tineke de Munnik + + +SPONSORS + +Bertalan Fodor +Chris Sawer +Gunther Strube +Hans Forbrich +Jonathan Walther +Marcus Macauley +Steve Doonan + +BUG HUNTERS/SUGGESTIONS + +Alexandre Beneteau +Andreas Scherer +Anthony W. Youngman +Antti Kaihola +Arjan Bos +David Bobroff +Bernard Hurley +Bruce Fairchild +Bruce McIntyre +Bruce Fairchild +Daniel Johnson +David Rogers +Donald Axel +Dylan Nicholson +Ed Jackson +Erik Ronström +Fernando Pablo Lopez-Lezcano +Gilles Sadowski +Jack O'Quin +Jeff Smith +Johannes Schindelin +John Mandereau +Jose Miguel Pasini +Josiah Boothby +Juergen Reuter +Karl Hammar +Laura Conrad +Olivier Guéry +Paul Scott +Richard Schoeller +Rob Platt +Roman Stöckl-Schmidt +Russ Jorgensen +Simon Bailey +Stephen McCarthy +Sven Axelsson +Tapio Tuovila +Tom Cato Amundsen +Will Oram +Wolfgang Hoffmann + + +Release 2.4 +*********** + +DEVELOPMENT TEAM + +Han-Wen Nienhuys - Core development +Jan Nieuwenhuizen - Core development +Erik Sandberg - Bug Meister +Pedro Kroger - Build Meister +Graham Percival - Documentation Editor + + +CONTRIBUTORS + +Carl Sorensen +David Svoboda +Guy Gascoigne-Piggford +Heikki Junes +Hendrik Maryns +Kristof Bastiaensen +Lisa Opus Goldstein +Mats Bengtsson +Michael Welsh Duggan +Peter Lutek +Werner Lemberg + +BUG HUNTERS/SUGGESTIONS + + +Antti Kaihola +Bertalan Fodor +Brian Clements +Christian Hitz +Christoph Ludwig +Christophe Papazian +Daniel Berjón DÃez +Dave Phillips +David Bobroff +David Brandon +Doug Asherman +Ed Jackson +Fernando Pablo Lopez-Lezcano +Heinz Stolba +Jack O'Quin +Jefferson dos Santos Felix +Karl Hammar +Marco Gusy +Martin Norbäck +Matthias Neeracher +Maurizio Tomasi +Michael Kiermaier +Pascal Legris +Peter Rosenbeck +Russ Ross +Stephen Pollei +Thomas Scharlowski +Will Oram +Yuval Harel + + +Release 2.2 +*********** + +HEAD HACKERS + +Han-Wen Nienhuys +Jan Nieuwenhuizen + +CONTRIBUTORS + +David Bobroff +Edward Sanford Sutton +Heikki Junes +Nicolas Sceaux + +BUG HUNTERS/SUGGESTIONS + +Alexandre Beneteau +Andrew McNabb +Atte Andre Jensen +Bertalan Fodor +Bruce McIntyre +Dave Symonds +David Bobroff +Darius +Delma Avers +Doug Linhardt +Eric Wurbel +Erik Sandberg +Ferenc Wagner +Hans Forbrich +John Williams +José Luis Cruz +Jürgen Reuter +Kieren Richard MacMillan +Laurent Martelli +Mats Bengtsson +Matthias Kilian +Nancho Alvarez +Nick Busigin +Nicolas Sceaux +Olivier Guéry +Patrick Atamaniuk +Paul Scott +Pawel D +Pedro Kroger +Ray McKinney +Reuben Thomas +Rob V +Stef Epardaud +Thomas Willhalm +Thomas Scharkowski +Tom Bäckström +Werner Lemberg +Will Oram + + +Release 2.0 +*********** + +HEAD HACKERS + +Han-Wen Nienhuys +Jan Nieuwenhuizen + +CONTRIBUTORS + +Mats Bengtsson +Heikki Junes +Jürgen Reuter + +BUG HUNTERS/SUGGESTIONS + +Antonio Palama +Benjamin Milde +Daniel Berjon Diez +David Bobroff +David Rayleigh Arnold +Erik Ronstroem +Fabio dos Santos +Fodor Bertalan +Frederic Bron +Graham Percival +Ian Bailey-Mortimer +John Williams +Josza Marton +Marco Caliari +Matthieu Amiguet +Michael Welsh Duggan +Patrick Atamaniuk +Paul Scott +Pedro Kroeger +Peter Lutek +Richard Schoeller +Thorkil Wolvendans +Werner Trobin + + +Release 1.8 +*********** + +HEAD HACKERS + +Han-Wen Nienhuys +Jan Nieuwenhuizen + +CONTRIBUTORS + +Graham Percival +Heikki Junes +Jügen Reuter +Kim Shrier +Rune Zedeler +Werner Lemberg + + +BUG HUNTERS + +Amelie Zapf +Andrew Schaaf +Atte Andre Jensen +Bob Harrington +Chris Jackson +Chris Sawer +David Bobroff +Erik Sandberg +Fernando Pablo Lopez-Lezcano +Hans Kieserman +Jeremie Lumbroso +John Potelle +John Williams +Karl Berry +Karl-Johan Karlsson +Klaus Zimmermann +Koblinger Egmont +Paul Scott +Pedro Kroger +Richard Shann +Roland Stigge +Ryan O'Neil +Simon Bailey +Simon Weatherill +Stanislav Brabec +Thomas Rijniers +Werner Lemberg +Yotam Medini + + +#Local variables: +#coding: utf-8 +#End: + Index: lilypond/VERSION diff -u lilypond/VERSION:1.645.2.2 lilypond/VERSION:1.645.2.3 --- lilypond/VERSION:1.645.2.2 Thu Jul 28 12:07:31 2005 +++ lilypond/VERSION Thu Aug 4 11:11:30 2005 @@ -1,6 +1,6 @@ PACKAGE_NAME=LilyPond MAJOR_VERSION=2 MINOR_VERSION=6 -PATCH_LEVEL=2 +PATCH_LEVEL=3 MY_PATCH_LEVEL= Index: lilypond/lily/auto-beam-engraver.cc diff -u /dev/null lilypond/lily/auto-beam-engraver.cc:1.145.2.1 --- /dev/null Thu Aug 4 11:11:32 2005 +++ lilypond/lily/auto-beam-engraver.cc Thu Aug 4 11:11:30 2005 @@ -0,0 +1,422 @@ +/* + auto-beam-engraver.cc -- implement Auto_beam_engraver + + source file of the GNU LilyPond music typesetter + + (c) 1999--2005 Jan Nieuwenhuizen <[EMAIL PROTECTED]> +*/ + +#include "engraver.hh" +#include "beaming.hh" +#include "beam.hh" +#include "stem.hh" +#include "warn.hh" +#include "bar-line.hh" +#include "rest.hh" +#include "item.hh" +#include "spanner.hh" +#include "context.hh" + +class Auto_beam_engraver : public Engraver +{ + TRANSLATOR_DECLARATIONS (Auto_beam_engraver); + +protected: + virtual void stop_translation_timestep (); + virtual void start_translation_timestep (); + virtual void process_music (); + virtual bool try_music (Music *); + virtual void finalize (); + virtual void acknowledge_grob (Grob_info); + virtual void process_acknowledged_grobs (); + virtual void derived_mark () const; + +private: + bool test_moment (Direction, Moment); + void consider_begin (Moment); + void consider_end (Moment); + Spanner *create_beam (); + void begin_beam (); + void end_beam (); + void junk_beam (); + bool is_same_grace_state (Grob *e); + void typeset_beam (); + + Music *forbid_; + /* + shortest_mom is the shortest note in the beam. + */ + Moment shortest_mom_; + Spanner *finished_beam_; + Link_array<Item> *stems_; + + int process_acknowledged_count_; + Moment last_add_mom_; + /* + Projected ending of the beam we're working on. + */ + Moment extend_mom_; + Moment beam_start_moment_; + Moment beam_start_location_; + + bool subdivide_beams_; + Moment beat_length_; + + // We act as if beam were created, and start a grouping anyway. + Beaming_info_list *grouping_; + SCM beam_settings_; + + Beaming_info_list *finished_grouping_; +}; + +void +Auto_beam_engraver::derived_mark () const +{ + scm_gc_mark (beam_settings_); +} + + +void +Auto_beam_engraver::process_music () +{ + if (scm_is_string (get_property ("whichBar"))) + { + consider_end (shortest_mom_); + junk_beam (); + } + + if (forbid_) + { + consider_end (shortest_mom_); + junk_beam (); + } +} + +Auto_beam_engraver::Auto_beam_engraver () +{ + forbid_ = 0; +process_acknowledged_count_ = 0; + stems_ = 0; + shortest_mom_ = Moment (Rational (1, 8)); + finished_beam_ = 0; + finished_grouping_ = 0; + grouping_ = 0; + beam_settings_ = SCM_EOL; +} + +bool +Auto_beam_engraver::try_music (Music *m) +{ + if (m->is_mus_type ("beam-forbid-event")) + { + forbid_ = m; + return true; + } + + return false; +} + +bool +Auto_beam_engraver::test_moment (Direction dir, Moment test) +{ + return scm_call_3 (get_property ("autoBeamCheck"), + context ()->self_scm (), + scm_from_int (dir), + test.smobbed_copy ()) + != SCM_BOOL_F; +} + +void +Auto_beam_engraver::consider_begin (Moment test_mom) +{ + bool on = to_boolean (get_property ("autoBeaming")); + if (!stems_ && on + && !forbid_) + { + bool b = test_moment (START, test_mom); + if (b) + begin_beam (); + } +} + +void +Auto_beam_engraver::consider_end (Moment test_mom) +{ + if (stems_) + { + /* Allow already started autobeam to end: + don't check for autoBeaming */ + bool b = test_moment (STOP, test_mom); + if (b) + end_beam (); + } +} + +Spanner * +Auto_beam_engraver::create_beam () +{ + if (to_boolean (get_property ("skipTypesetting"))) + return 0; + + /* + Can't use make_spanner_from_properties() because we have to use + beam_settings_. + */ + Spanner *beam = new Spanner (beam_settings_, + context ()->get_grob_key ("Beam")); + + for (int i = 0; i < stems_->size (); i++) + { + /* + watch out for stem tremolos and abbreviation beams + */ + if (Stem::get_beam ((*stems_)[i])) + { + scm_gc_unprotect_object (beam->self_scm ()); + return 0; + } + Beam::add_stem (beam, (*stems_)[i]); + } + + announce_grob (beam, (*stems_)[0]->self_scm ()); + + return beam; +} + +void +Auto_beam_engraver::begin_beam () +{ + if (stems_ || grouping_) + { + programming_error ("already have autobeam"); + return; + } + + stems_ = new Link_array<Item>; + grouping_ = new Beaming_info_list; + beam_settings_ = updated_grob_properties (context (), ly_symbol2scm ("Beam")); + + beam_start_moment_ = now_mom (); + beam_start_location_ + = robust_scm2moment (get_property ("measurePosition"), Moment (0)); + subdivide_beams_ = ly_scm2bool (get_property ("subdivideBeams")); + beat_length_ = robust_scm2moment (get_property ("beatLength"), Moment (1, 4)); +} + +void +Auto_beam_engraver::junk_beam () +{ + if (!stems_) + return; + + delete stems_; + stems_ = 0; + delete grouping_; + grouping_ = 0; + beam_settings_ = SCM_EOL; + + shortest_mom_ = Moment (Rational (1, 8)); +} + +void +Auto_beam_engraver::end_beam () +{ + if (stems_->size () < 2) + { + junk_beam (); + } + else + { + finished_beam_ = create_beam (); + if (finished_beam_) + finished_grouping_ = grouping_; + delete stems_; + stems_ = 0; + grouping_ = 0; + beam_settings_ = SCM_EOL; + } + + shortest_mom_ = Moment (Rational (1, 8)); +} + +void +Auto_beam_engraver::typeset_beam () +{ + if (finished_beam_) + { + finished_grouping_->beamify (beat_length_, subdivide_beams_); + Beam::set_beaming (finished_beam_, finished_grouping_); + finished_beam_ = 0; + + delete finished_grouping_; + finished_grouping_ = 0; + } +} + +void +Auto_beam_engraver::start_translation_timestep () +{ + process_acknowledged_count_ = 0; + /* + don't beam over skips + */ + if (stems_) + { + Moment now = now_mom (); + if (extend_mom_ < now) + { + end_beam (); + } + } + forbid_ = 0; +} + +void +Auto_beam_engraver::stop_translation_timestep () +{ + typeset_beam (); +} + +void +Auto_beam_engraver::finalize () +{ + /* finished beams may be typeset */ + typeset_beam (); + /* but unfinished may need another announce/acknowledge pass */ + if (stems_) + junk_beam (); +} + +void +Auto_beam_engraver::acknowledge_grob (Grob_info info) +{ + /* Duplicated from process_music (), since + Repeat_acknowledge_engraver::process_music () may also set whichBar. */ + + Moment now = now_mom (); + if (scm_is_string (get_property ("whichBar")) + && beam_start_moment_ < now) + { + consider_end (shortest_mom_); + junk_beam (); + } + + if (stems_) + { + if (Beam::has_interface (info.grob ())) + { + end_beam (); + } + else if (Bar_line::has_interface (info.grob ())) + { + end_beam (); + } + else if (Rest::has_interface (info.grob ())) + { + end_beam (); + } + } + + if (Stem::has_interface (info.grob ())) + { + Item *stem = dynamic_cast<Item *> (info.grob ()); + Music *m = info.music_cause (); + if (!m->is_mus_type ("rhythmic-event")) + { + programming_error ("stem must have rhythmic structure"); + return; + } + + /* + Don't (start) auto-beam over empty stems; skips or rests + */ + if (!Stem::head_count (stem)) + { + if (stems_) + end_beam (); + return; + } + + if (Stem::get_beam (stem)) + { + if (stems_) + junk_beam (); + return; + } + + int durlog = unsmob_duration (m->get_property ("duration"))->duration_log (); + + if (durlog <= 2) + { + if (stems_) + end_beam (); + return; + } + + /* + ignore grace notes. + */ + if (bool (beam_start_location_.grace_part_) != bool (now.grace_part_)) + return; + + Moment dur = unsmob_duration (m->get_property ("duration"))->get_length (); + + consider_end (dur); + consider_begin (dur); + + if (dur < shortest_mom_) + shortest_mom_ = dur; + + if (!stems_) + return; + + grouping_->add_stem (now - beam_start_moment_ + beam_start_location_, + durlog - 2); + stems_->push (stem); + last_add_mom_ = now; + extend_mom_ = max (extend_mom_, now) + m->get_length (); + } +} + +void +Auto_beam_engraver::process_acknowledged_grobs () +{ + if (extend_mom_ > now_mom ()) + return ; + + if (!process_acknowledged_count_) + { + consider_end (shortest_mom_); + consider_begin (shortest_mom_); + } + else if (process_acknowledged_count_ > 1) + { + if (stems_) + { + Moment now = now_mom (); + if ((extend_mom_ < now) + || ((extend_mom_ == now) && (last_add_mom_ != now))) + { + end_beam (); + } + else if (!stems_->size ()) + { + junk_beam (); + } + } + } + + process_acknowledged_count_++; +} + +ADD_TRANSLATOR (Auto_beam_engraver, + /* descr */ "Generate beams based on measure characteristics and observed " + "Stems. Uses beatLength, measureLength and measurePosition to decide " + "when to start and stop a beam. Overriding beaming is done through " + "@ref{Stem_engraver} properties @code{stemLeftBeamCount} and " + "@code{stemRightBeamCount}. ", + /* creats*/ "Beam", + /* accepts */ "beam-forbid-event", + /* acks */ "stem-interface rest-interface beam-interface bar-line-interface", + /* reads */ "autoBeaming autoBeamSettings beatLength subdivideBeams", + /* write */ ""); Index: lilypond/lily/clef-engraver.cc diff -u /dev/null lilypond/lily/clef-engraver.cc:1.123.2.1 --- /dev/null Thu Aug 4 11:11:32 2005 +++ lilypond/lily/clef-engraver.cc Thu Aug 4 11:11:31 2005 @@ -0,0 +1,201 @@ +/* + clef-engraver.cc -- implement Clef_engraver + + source file of the GNU LilyPond music typesetter + + (c) 1997--2005 Han-Wen Nienhuys <[EMAIL PROTECTED]>, + + Mats Bengtsson <[EMAIL PROTECTED]> +*/ + +#include <cctype> + +#include "context.hh" +#include "bar-line.hh" +#include "staff-symbol-referencer.hh" +#include "engraver.hh" +#include "direction.hh" +#include "side-position-interface.hh" + +class Clef_engraver : public Engraver +{ +public: + TRANSLATOR_DECLARATIONS (Clef_engraver); + + Direction octave_dir_; + +protected: + + virtual void derived_mark () const; + virtual void stop_translation_timestep (); + virtual void process_music (); + virtual void acknowledge_grob (Grob_info); +private: + Item *clef_; + Item *octavate_; + + SCM prev_glyph_; + SCM prev_cpos_; + SCM prev_octavation_; + void create_clef (); + void set_glyph (); + void inspect_clef_properties (); +}; + +void +Clef_engraver::derived_mark () const +{ + scm_gc_mark (prev_octavation_); + scm_gc_mark (prev_cpos_); + scm_gc_mark (prev_glyph_); +} + +Clef_engraver::Clef_engraver () +{ + clef_ = 0; + octave_dir_ = CENTER; + octavate_ = 0; + + /* + will trigger a clef at the start since #f != ' () + */ + prev_octavation_ = prev_cpos_ = prev_glyph_ = SCM_BOOL_F; +} + +void +Clef_engraver::set_glyph () +{ + SCM glyph_sym = ly_symbol2scm ("glyph-name"); + SCM glyph = get_property ("clefGlyph"); + + SCM basic = ly_symbol2scm ("Clef"); + + execute_pushpop_property (context (), basic, glyph_sym, SCM_UNDEFINED); + execute_pushpop_property (context (), basic, glyph_sym, glyph); +} + +/** + Generate a clef at the start of a measure. (when you see a Bar, + ie. a breakpoint) +*/ +void +Clef_engraver::acknowledge_grob (Grob_info info) +{ + Item *item = dynamic_cast<Item *> (info.grob ()); + if (item) + { + if (Bar_line::has_interface (info.grob ()) + && scm_is_string (get_property ("clefGlyph"))) + create_clef (); + } +} + +void +Clef_engraver::create_clef () +{ + if (!clef_) + { + Item *c = make_item ("Clef", SCM_EOL); + + clef_ = c; + SCM cpos = get_property ("clefPosition"); + + if (scm_is_number (cpos)) + clef_->set_property ("staff-position", cpos); + + SCM oct = get_property ("clefOctavation"); + if (scm_is_number (oct) && scm_to_int (oct)) + { + Item *g = make_item ("OctavateEight", SCM_EOL); + + int abs_oct = scm_to_int (oct); + int dir = sign (abs_oct); + abs_oct = abs (abs_oct) + 1; + + SCM txt = scm_number_to_string (scm_int2num (abs_oct), + scm_from_int (10)); + + g->set_property ("text", + scm_list_n (ly_lily_module_constant ("vcenter-markup"), + txt, SCM_UNDEFINED)); + Side_position_interface::add_support (g, clef_); + + g->set_parent (clef_, Y_AXIS); + g->set_parent (clef_, X_AXIS); + g->set_property ("direction", scm_int2num (dir)); + octavate_ = g; + } + } +} +void +Clef_engraver::process_music () +{ + inspect_clef_properties (); +} + +void +Clef_engraver::inspect_clef_properties () +{ + SCM glyph = get_property ("clefGlyph"); + SCM clefpos = get_property ("clefPosition"); + SCM octavation = get_property ("clefOctavation"); + SCM force_clef = get_property ("forceClef"); + + if (clefpos == SCM_EOL + || scm_equal_p (glyph, prev_glyph_) == SCM_BOOL_F + || scm_equal_p (clefpos, prev_cpos_) == SCM_BOOL_F + || scm_equal_p (octavation, prev_octavation_) == SCM_BOOL_F + || to_boolean (force_clef)) + { + set_glyph (); + if (prev_cpos_ != SCM_BOOL_F || to_boolean (get_property ("firstClef"))) + create_clef (); + + if (clef_) + clef_->set_property ("non-default", SCM_BOOL_T); + + prev_cpos_ = clefpos; + prev_glyph_ = glyph; + prev_octavation_ = octavation; + } + + if (to_boolean (force_clef)) + { + Context *w = context ()->where_defined (ly_symbol2scm ("forceClef")); + w->set_property ("forceClef", SCM_EOL); + } +} + +void +Clef_engraver::stop_translation_timestep () +{ + if (clef_) + { + SCM vis = 0; + if (to_boolean (clef_->get_property ("non-default"))) + { + vis = get_property ("explicitClefVisibility"); + } + + if (vis) + { + clef_->set_property ("break-visibility", vis); + if (octavate_) + { + octavate_->set_property ("break-visibility", vis); + } + } + + clef_ = 0; + + octavate_ = 0; + } +} + +ADD_TRANSLATOR (Clef_engraver, + /* descr */ "Determine and set reference point for pitches", + /* creats*/ "Clef OctavateEight", + /* accepts */ "", + /* acks */ "bar-line-interface", + /* reads */ "clefPosition clefGlyph middleCPosition clefOctavation explicitClefVisibility forceClef", + /* write */ ""); Index: lilypond/lily/hara-kiri-engraver.cc diff -u /dev/null lilypond/lily/hara-kiri-engraver.cc:1.11.2.1 --- /dev/null Thu Aug 4 11:11:32 2005 +++ lilypond/lily/hara-kiri-engraver.cc Thu Aug 4 11:11:31 2005 @@ -0,0 +1,85 @@ +/* + hara-kiri-engraver.cc -- implement Hara_kiri_engraver + + source file of the GNU LilyPond music typesetter + + (c) 2005 Han-Wen Nienhuys <[EMAIL PROTECTED]> + +*/ + +#include "axis-group-engraver.hh" +#include "hara-kiri-group-spanner.hh" +#include "rhythmic-head.hh" +#include "spanner.hh" + +class Hara_kiri_engraver : public Axis_group_engraver +{ +protected: + virtual Spanner *get_spanner (); + virtual void acknowledge_grob (Grob_info); + virtual void add_element (Grob *e); + virtual void start_translation_timestep (); + + virtual void derived_mark () const; + + SCM interesting_; +public: + TRANSLATOR_DECLARATIONS (Hara_kiri_engraver); +}; +void +Hara_kiri_engraver::derived_mark () const +{ + scm_gc_mark (interesting_); +} + + +void +Hara_kiri_engraver::start_translation_timestep () +{ + Axis_group_engraver::start_translation_timestep (); + interesting_ = get_property ("keepAliveInterfaces"); +} + + +void +Hara_kiri_engraver::add_element (Grob *e) +{ + Hara_kiri_group_spanner::add_element (staffline_, e); +} + +Spanner * +Hara_kiri_engraver::get_spanner () +{ + Spanner *sp = make_spanner ("RemoveEmptyVerticalGroup", SCM_EOL); + + return sp; +} + +void +Hara_kiri_engraver::acknowledge_grob (Grob_info i) +{ + Axis_group_engraver::acknowledge_grob (i); + if (staffline_) + { + for (SCM s = interesting_; scm_is_pair (s); s = scm_cdr (s)) + { + if (i.grob ()->internal_has_interface (scm_car (s))) + Hara_kiri_group_spanner::add_interesting_item (staffline_, i.grob ()); + } + } +} + +Hara_kiri_engraver::Hara_kiri_engraver () +{ + interesting_ = SCM_EOL; +} + +ADD_TRANSLATOR (Hara_kiri_engraver, + /* descr */ "Like Axis_group_engraver, but make a hara-kiri spanner, and add " + "interesting items (ie. note heads, lyric syllables and normal rests) ", + /* creats*/ "RemoveEmptyVerticalGroup", + /* accepts */ "", + /* acks */ "grob-interface", + /* reads */ "keepAliveInterfaces", + /* write */ ""); + Index: lilypond/lily/stanza-number-engraver.cc diff -u /dev/null lilypond/lily/stanza-number-engraver.cc:1.38.2.1 --- /dev/null Thu Aug 4 11:11:32 2005 +++ lilypond/lily/stanza-number-engraver.cc Thu Aug 4 11:11:31 2005 @@ -0,0 +1,84 @@ +/* + lyric-number-engraver.cc -- implement Stanza_number_engraver + + source file of the GNU LilyPond music typesetter + + (c) 2000--2005 Han-Wen Nienhuys <[EMAIL PROTECTED]>, Glen Prideaux <[EMAIL PROTECTED]> +*/ + +#include "engraver.hh" +#include "side-position-interface.hh" + +class Stanza_number_engraver : public Engraver +{ + Item *text_; + + /* + This is naughty, since last_stanza_ may be GCd from under us. But + since we don't look at the contents, we are/should be (knock on + wood) OK. + */ + SCM last_stanza_; +public: + TRANSLATOR_DECLARATIONS (Stanza_number_engraver); + virtual void process_music (); + virtual void stop_translation_timestep (); + virtual void acknowledge_grob (Grob_info); +}; + +void +Stanza_number_engraver::derived_mark () const +{ + scm_gc_mark (last_stanza_); +} + +/* + TODO: should make engraver that collects all the stanzas on a higher + level, and then groups them to the side. Stanza numbers should be + all aligned. +*/ + +Stanza_number_engraver::Stanza_number_engraver () +{ + last_stanza_ = SCM_EOL; + + text_ = 0; +} + +void +Stanza_number_engraver::process_music () +{ + SCM stanza = get_property ("stanza"); + + if (scm_is_string (stanza) && stanza != last_stanza_) + { + last_stanza_ = stanza; + + text_ = make_item ("StanzaNumber", SCM_EOL); + text_->set_property ("text", stanza); + } +} + +void +Stanza_number_engraver::acknowledge_grob (Grob_info inf) +{ + if (text_ + && inf.grob ()->internal_has_interface (ly_symbol2scm ("lyric-syllable-interface"))) + { + Side_position_interface::add_support (text_, inf.grob ()); + } +} + +void +Stanza_number_engraver::stop_translation_timestep () +{ + text_ = 0; +} + +ADD_TRANSLATOR (Stanza_number_engraver, + /* descr */ "", + /* creats*/ "StanzaNumber", + /* accepts */ "", + /* acks */ "lyric-syllable-interface", + /* reads */ "stanza", + /* write */ ""); Index: lilypond/lily/time-signature-engraver.cc diff -u /dev/null lilypond/lily/time-signature-engraver.cc:1.62.2.1 --- /dev/null Thu Aug 4 11:11:32 2005 +++ lilypond/lily/time-signature-engraver.cc Thu Aug 4 11:11:31 2005 @@ -0,0 +1,85 @@ +/* + time-signature-engraver.cc -- implement Time_signature_engraver + + source file of the GNU LilyPond music typesetter + + (c) 1997--2005 Han-Wen Nienhuys <[EMAIL PROTECTED]> +*/ + +#include "time-signature.hh" +#include "warn.hh" +#include "engraver-group-engraver.hh" +#include "misc.hh" + +/** + generate time_signatures. +*/ +class Time_signature_engraver : public Engraver +{ + Item *time_signature_; + SCM last_time_fraction_; + +protected: + virtual void derived_mark () const; + virtual void stop_translation_timestep (); + virtual void process_music (); +public: + TRANSLATOR_DECLARATIONS (Time_signature_engraver); +}; + +void +Time_signature_engraver::derived_mark () const +{ + scm_gc_mark (last_time_fraction_); +} + + +Time_signature_engraver::Time_signature_engraver () +{ + time_signature_ = 0; + last_time_fraction_ = SCM_BOOL_F; +} + +void +Time_signature_engraver::process_music () +{ + /* + not rigorously safe, since the value might get GC'd and + reallocated in the same spot */ + SCM fr = get_property ("timeSignatureFraction"); + if (!time_signature_ + && last_time_fraction_ != fr + && scm_is_pair (fr)) + { + int den = scm_to_int (scm_cdr (fr)); + if (den != (1 << intlog2 (den))) + { + /* + Todo: should make typecheck? + + OTOH, Tristan Keuris writes 8/20 in his Intermezzi. + */ + warning (_f ("strange time signature found: %d/%d", + den, + scm_to_int (scm_car (fr)))); + } + + last_time_fraction_ = fr; + time_signature_ = make_item ("TimeSignature", SCM_EOL); + time_signature_->set_property ("fraction", fr); + } +} + +void +Time_signature_engraver::stop_translation_timestep () +{ + time_signature_ = 0; +} + +ADD_TRANSLATOR (Time_signature_engraver, + /* descr */ "Create a TimeSignature whenever @code{timeSignatureFraction} changes", + /* creats*/ "TimeSignature", + /* accepts */ "", + /* acks */ "", + /* reads */ "", + /* write */ ""); Index: lilypond/lily/volta-engraver.cc diff -u /dev/null lilypond/lily/volta-engraver.cc:1.60.2.1 --- /dev/null Thu Aug 4 11:11:32 2005 +++ lilypond/lily/volta-engraver.cc Thu Aug 4 11:11:31 2005 @@ -0,0 +1,249 @@ +/* + volta-engraver.cc -- implement Volta_engraver + + source file of the GNU LilyPond music typesetter + + (c) 2000--2005 Han-Wen Nienhuys <[EMAIL PROTECTED]> +*/ + +#include "engraver.hh" +#include "context.hh" +#include "volta-bracket.hh" +#include "note-column.hh" +#include "bar-line.hh" +#include "side-position-interface.hh" +#include "warn.hh" +#include "staff-symbol.hh" + +/* + Create Volta spanners, by reading repeatCommands property, usually + set by Unfolded_repeat_iterator. +*/ +class Volta_engraver : public Engraver +{ +public: + TRANSLATOR_DECLARATIONS (Volta_engraver); +protected: + + virtual void acknowledge_grob (Grob_info); + virtual void finalize (); + virtual void stop_translation_timestep (); + virtual void process_music (); + + virtual void derived_mark () const; + Moment started_mom_; + Spanner *volta_span_; + Spanner *end_volta_span_; + SCM staff_; + SCM start_string_; + + bool staff_eligible (); +}; + +void +Volta_engraver::derived_mark () const +{ + scm_gc_mark (staff_); + scm_gc_mark (start_string_); +} + +Volta_engraver::Volta_engraver () +{ + start_string_ = SCM_EOL; + staff_ = SCM_EOL; + volta_span_ = 0; + end_volta_span_ = 0; +} + +/* + TODO: this logic should be rewritten, it is buggy. + + One of the problems is that we can't determine wether or not to + print the volta bracket during the first step, since that requires + acknowledging the staff. +*/ +bool +Volta_engraver::staff_eligible () +{ + SCM doit = get_property ("voltaOnThisStaff"); + if (scm_is_bool (doit)) + { + return to_boolean (doit); + } + + if (!unsmob_grob (staff_)) + return false; + + /* + TODO: this does weird things when you open a piece with a + volta spanner. + */ + SCM staffs = get_property ("stavesFound"); + + /* Only put a volta on the top staff. + Maybe this is a bit convoluted, and we should have a single + volta engraver in score context or somesuch. */ + if (!scm_is_pair (staffs)) + { + programming_error ("volta engraver can't find staffs"); + return false; + } + else if (scm_car (scm_last_pair (staffs)) != staff_) + return false; + return true; +} + +void +Volta_engraver::process_music () +{ + SCM cs = get_property ("repeatCommands"); + + if (!staff_eligible ()) + return; + + bool end = false; + start_string_ = SCM_EOL; + while (scm_is_pair (cs)) + { + SCM c = scm_car (cs); + + if (scm_is_pair (c) + && scm_car (c) == ly_symbol2scm ("volta") + && scm_is_pair (scm_cdr (c))) + { + if (scm_cadr (c) == SCM_BOOL_F) + end = true; + else + start_string_ = scm_cadr (c); + } + + cs = scm_cdr (cs); + } + + if (volta_span_) + { + SCM l (get_property ("voltaSpannerDuration")); + Moment now = now_mom (); + + bool early_stop = unsmob_moment (l) + && *unsmob_moment (l) <= now - started_mom_; + + end = end || early_stop; + } + + if (end && !volta_span_) + /* fixme: be more verbose. */ + warning (_ ("can't end volta spanner")); + else if (end) + { + end_volta_span_ = volta_span_; + volta_span_ = 0; + } + + if (volta_span_ + && (scm_is_string (start_string_) || scm_is_pair (start_string_))) + { + warning (_ ("already have a volta spanner, ending that one prematurely")); + + if (end_volta_span_) + { + warning (_ ("also already have an ended spanner")); + warning (_ ("giving up")); + return; + } + + end_volta_span_ = volta_span_; + volta_span_ = 0; + } + + if (!volta_span_ + && (scm_is_string (start_string_) || scm_is_pair (start_string_))) + { + started_mom_ = now_mom (); + + volta_span_ = make_spanner ("VoltaBracket", SCM_EOL); + + volta_span_->set_property ("text", start_string_); + } +} + +void +Volta_engraver::acknowledge_grob (Grob_info i) +{ + if (Item *item = dynamic_cast<Item *> (i.grob ())) + { + if (Note_column::has_interface (item)) + { + if (volta_span_) + Volta_bracket_interface::add_column (volta_span_, item); + } + if (Bar_line::has_interface (item)) + { + if (volta_span_) + Volta_bracket_interface::add_bar (volta_span_, item); + if (end_volta_span_) + Volta_bracket_interface::add_bar (end_volta_span_, item); + } + } + else if (Staff_symbol::has_interface (i.grob ())) + { + /* + We only want to know about a single staff: then we add to the + support. */ + if (staff_ != SCM_EOL) + staff_ = SCM_UNDEFINED; + + if (staff_ != SCM_UNDEFINED) + staff_ = i.grob ()->self_scm (); + } +} + +void +Volta_engraver::finalize () +{ +} + +void +Volta_engraver::stop_translation_timestep () +{ + if (volta_span_ && !staff_eligible ()) + { + /* + THIS IS A KLUDGE. + + we need to do this here, because STAFF_ is not initialized yet + in the 1st call of process_music () + */ + + volta_span_->suicide (); + volta_span_ = 0; + } + + if (end_volta_span_ && !end_volta_span_->get_bound (RIGHT)) + { + Grob *cc = unsmob_grob (get_property ("currentCommandColumn")); + Item *ci = dynamic_cast<Item *> (cc); + end_volta_span_->set_bound (RIGHT, ci); + } + + end_volta_span_ = 0; + + if (volta_span_ && !volta_span_->get_bound (LEFT)) + { + Grob *cc = unsmob_grob (get_property ("currentCommandColumn")); + Item *ci = dynamic_cast<Item *> (cc); + volta_span_->set_bound (LEFT, ci); + } +} + +/* + TODO: should attach volta to paper-column if no bar is found. +*/ + +ADD_TRANSLATOR (Volta_engraver, + /* descr */ "Make volta brackets.", + /* creats*/ "VoltaBracket", + /* accepts */ "", + /* acks */ "bar-line-interface staff-symbol-interface note-column-interface", + /* reads */ "repeatCommands voltaSpannerDuration stavesFound", + /* write */ ""); _______________________________________________ Lilypond-cvs mailing list Lilypond-cvs@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-cvs