--- /dev/null
+/*
+ musicalrequests.hh -- declare Musical requests
+
+ source file of the LilyPond music typesetter
+
+ (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
+*/
+
+
+#ifndef MUSICALREQUESTS_HH
+#define MUSICALREQUESTS_HH
+
+#include "request.hh"
+
+
+/**
+ A request which is coupled to a #Voice_element# with nonzero duration.
+ Base class only
+ */
+struct Musical_req : virtual Request {
+ virtual Skip_req* skip() { return 0; }
+ REQUESTMETHODS(Musical_req, musical);
+};
+
+
+struct Skip_req : Musical_req {
+ Moment duration_;
+
+ virtual Moment duration() const;
+ REQUESTMETHODS(Skip_req, skip);
+};
+/** a request with a duration.
+ This request is used only a base class.
+ */
+struct Rhythmic_req : virtual Musical_req {
+ int balltype;
+ int dots;
+ Moment plet_factor;
+ /* *************** */
+ static int compare(const Rhythmic_req &, const Rhythmic_req &);
+ virtual Moment duration() const;
+ Rhythmic_req();
+ Rhythmic_req(int,int);
+ REQUESTMETHODS(Rhythmic_req, rhythmic);
+};
+
+struct Spacing_req :virtual Request {
+ Moment next;
+ Real distance;
+ Real strength;
+ /* *************** */
+ Spacing_req();
+ REQUESTMETHODS(Spacing_req, spacing);
+};
+
+struct Blank_req : Spacing_req, Rhythmic_req {
+ REQUESTMETHODS(Spacing_req, spacing);
+
+};
+
+/// Put a text above or below (?) this staff.
+struct Text_req : virtual Musical_req {
+ /// preferred position (above/below)
+ int dir_i_;
+ /// the characteristics of the text
+ Text_def *tdef_p_;
+ /* *************** */
+ Text_req(int d, Text_def*);
+ ~Text_req();
+ Text_req(Text_req const&);
+ static int compare(const Text_req&,const Text_req&);
+ REQUESTMETHODS(Text_req,text);
+};
+
+/** Put a text in lyric_staff
+ @see Lyric_staff
+ */
+struct Lyric_req : public Rhythmic_req, Text_req {
+ Lyric_req(Text_def* t_p);
+ REQUESTMETHODS(Lyric_req, lreq_l);
+};
+
+/// request which has some kind of pitch
+struct Melodic_req :virtual Musical_req
+{
+ /// 0 is c, 6 is b
+ int notename_i_;
+ /// 0 is central c
+ int octave_i_;
+
+ /// 0 natural, 1 sharp, etc
+ int accidental_i_;
+
+ /// force/supress printing of accidental.
+ bool forceacc_b_;
+
+ /// return height from central c (in halflines)
+ int height()const;
+ Melodic_req();
+
+ REQUESTMETHODS(Melodic_req,melodic);
+};
+
+/// Put a note of specified type, height, and with accidental on the staff.
+struct Note_req : Rhythmic_req, virtual Melodic_req {
+
+
+ Rhythmic_req* rhythmic() { return Rhythmic_req::rhythmic(); }
+ REQUESTMETHODS(Note_req, note);
+ };
+
+/**
+Put a rest on the staff. Why a request? It might be a good idea to not typeset the rest, if the paper is too crowded.
+*/
+class Rest_req : public Rhythmic_req {
+public:
+ REQUESTMETHODS(Rest_req,rest);
+};
+
+/**
+ attach a stem to the noteball.
+ Rhythmic_req parent needed to determine if it will fit inside a beam.
+ */
+struct Stem_req : Rhythmic_req {
+ /// preferred direction for the stem
+ int dir_i_;
+ Stem_req(int s, int dots);
+ REQUESTMETHODS(Stem_req,stem);
+};
+
+/**
+ Requests to start or stop something.
+ This type of request typically results in the creation of a #Spanner#
+*/
+struct Span_req : Musical_req {
+ /// should the spanner start or stop, or is it unwanted?
+ enum {
+ NOSPAN, START, STOP
+ } spantype ;
+ static int compare(const Span_req &r1, const Span_req &r2);
+ REQUESTMETHODS(Span_req,span);
+
+ Span_req();
+
+};
+
+
+/** Start / stop a beam at this note. if #nplet# is set, the staff will try to put an
+appropriate number over the beam
+ */
+struct Beam_req : Span_req {
+ int nplet;
+
+ /* *************** */
+ REQUESTMETHODS(Beam_req,beam);
+
+ Beam_req();
+};
+
+/// a slur
+struct Slur_req : Span_req {
+ REQUESTMETHODS(Slur_req,slur);
+
+};
+
+
+/**Put a script above or below this ``note''. eg upbow, downbow. Why a
+request? These symbols may conflict with slurs and brackets, so this
+also a request */
+struct Script_req : Musical_req {
+ int dir_i_;
+ Script_def *scriptdef_p_;
+
+ /* *************** */
+ static int compare(const Script_req &, const Script_req &);
+ Script_req(int d, Script_def*);
+ REQUESTMETHODS(Script_req,script);
+ ~Script_req();
+ Script_req(Script_req const&);
+};
+
+
+
+
+#endif // MUSICALREQUESTS_HH
#ifndef REGISTER_HH
#define REGISTER_HH
+
#include "proto.hh"
#include "varray.hh"
#include "request.hh"
+#include "staffeleminfo.hh"
-/// data container.
-struct Staff_elem_info {
- Staff_elem * elem_p_;
- Request*req_l_;
- const Voice * voice_l_;
- Voice_group_registers * group_regs_l_;
- Request_register * origin_reg_l_;
-
- /* *** */
- Staff_elem_info(Staff_elem*, Request*, Request_register*);
- Staff_elem_info();
-};
-/// Hungarian postfix: reg
/**
- a struct which processes requests, and creates the Staff_elems
+ a struct which processes requests, and creates the #Staff_elem#s.
+ Hungarian postfix: reg
*/
-struct Request_register {
+class Request_register {
+public:
Complex_walker * walk_l_;
Array<Request*> accepted_req_arr_;
- /* *************** */
/**
- Warning: you can't copy a Request_register
+ Warning: you can't copy a #Request_register#
*/
Request_register(Request_register const &);
Request_register(Complex_walker*);
Request_register();
virtual ~Request_register(){}
- /** take note of item/spaanner
- put item in spanner. Adjust local key; etc.
- */
- virtual void acknowledge_element(Staff_elem_info){}
/**
- Announce element to walker
- */
- void announce_element(Staff_elem_info);
+ take note of item/spanner
+ put item in spanner. Adjust local key; etc.
- /**
- invoke walker method to typeset element
+ Default: ignore the info
*/
- void typeset_element(Staff_elem*elem_p);
-
+ virtual void acknowledge_element(Staff_elem_info){}
+
/**
try to fit the request in this register
@return
false: not noted, not taken.
- true: request swallowed. Don't try to put elsewhere
+ true: request swallowed. Don't try to put the request elsewhere.
(may be we could use C++ exceptions.. :-)
+
+ #Request_register::try_request# always returns false
*/
- virtual bool try_request(Request *req_l) =0;
+ virtual bool try_request(Request *req_l);
/// make items/spanners with the requests you got
- virtual void process_request()=0;
- Paperdef * paper() const;
- /// typeset any spanners. Empty accepted_req_arr_
+ virtual void process_request(){}
+
+ /// typeset any spanners. Empty #accepted_req_arr_#
void pre_move_processing();
+ /// reset any appropriate data.
void post_move_processing();
+
virtual void set_dir(int){}
protected:
- /// virtual, called by pre_move_process()
+ /// utility
+ Paperdef * paper() const;
+
+
+ /**
+ invoke walker method to typeset element
+ */
+ void typeset_element(Staff_elem*elem_p);
+
+
+ /**
+ typeset a "command" item.
+ If the column is not breakable, #pre_p# and #post_p# are junked
+ */
+ void typeset_breakable_item(Item * pre_p , Item * nobreak_p, Item * post_p);
+ /** virtual, called by #pre_move_processing()#
+ #Request_register::do_pre_move_process()# defaults to NOP
+ */
virtual void do_pre_move_process(){}
+ /** virtual, called by #post_move_processing#,
+ #Request_register::do_post_move_process()# defaults to NOP */
virtual void do_post_move_process(){}
+ /**
+ Announce element to walker. Utility
+ */
+ void announce_element(Staff_elem_info);
};
-// LilyPond's second egg of columbus!
+/*
+ request.hh -- declare Request baseclasses.
+
+ source file of the LilyPond music typesetter
+
+ (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
+*/
+
#ifndef REQUEST_HH
#define REQUEST_HH
+// LilyPond's second egg of columbus!
#include "glob.hh"
#include "string.hh"
#include "moment.hh"
-/// Hungarian postfix: req
/**
a voice element wants something printed.
-see lilygut page
+ Hungarian postfix: req
+ @see lilygut manpage
*/
-
struct Request {
Voice_element*elt_l_;
- char const* defined_ch_c_l_m;
+ char const* defined_ch_c_l_;
/* *************** */
Request();
virtual ~Request(){}
virtual const char * name() const { return "Request";}
- virtual Request* clone() const =0;
+ virtual Request* clone() const { return new Request(*this); }
void print()const ;
virtual Moment duration() const { return 0; }
maybe checkout RTTI
*/
virtual Barcheck_req *barcheck() { return 0; }
- virtual Note_req *note() {return 0;}
- virtual Script_req *script() {return 0;}
- virtual Stem_req *stem() {return 0;}
+ virtual Note_req *note() { return 0;}
+ virtual Script_req *script() { return 0;}
+ virtual Stem_req *stem() { return 0;}
virtual Text_req*text() { return 0; }
- virtual Rest_req *rest() {return 0;}
- virtual Span_req *span() {return 0;}
+ virtual Rest_req *rest() { return 0; }
+ virtual Span_req *span() { return 0; }
virtual Beam_req *beam() { return 0 ; }
virtual Slur_req *slur() { return 0 ; }
virtual Rhythmic_req*rhythmic() { return 0; }
virtual Lyric_req* lreq_l() { return 0; }
virtual Melodic_req *melodic() { return 0; }
- virtual Mark_req * mark() { return 0; }
- virtual Staff_command_req* command() { return 0;}
virtual Terminate_voice_req *terminate() {return 0;}
virtual Group_change_req * groupchange() { return 0;}
virtual Group_feature_req * groupfeature() { return 0; }
virtual Spacing_req * spacing() { return 0; }
virtual Blank_req * blank() { return 0; }
+ virtual Musical_req *musical() { return 0; }
+ virtual Nonmusical_req * nonmus() { return 0; }
protected:
virtual void do_print()const ;
};
virtual const char* name() const { return #T; }\
virtual Request *clone() const { return new T(*this); } \
virtual void do_print() const
-
-struct Barcheck_req : Request {
- REQUESTMETHODS(Barcheck_req,barcheck);
-};
-
-struct Terminate_voice_req : Request {
- REQUESTMETHODS(Terminate_voice_req,terminate);
-};
-
-struct Group_feature_req : Request {
- int stemdir_i_;
- Group_feature_req();
- REQUESTMETHODS(Group_feature_req, groupfeature);
-};
-
-struct Group_change_req : Request {
- String newgroup_str_;
- REQUESTMETHODS(Group_change_req, groupchange);
-};
-
-/// a request with a duration
-struct Rhythmic_req : virtual Request {
- int balltype;
- int dots;
- Moment plet_factor;
- /* *************** */
- static int compare(const Rhythmic_req &, const Rhythmic_req &);
- Moment duration() const;
- Rhythmic_req();
- Rhythmic_req(int,int);
- REQUESTMETHODS(Rhythmic_req, rhythmic);
-};
-
-struct Spacing_req :virtual Request {
- Moment next;
- Real distance;
- Real strength;
- /* *************** */
- Spacing_req();
- REQUESTMETHODS(Spacing_req, spacing);
-};
-
-struct Blank_req : Spacing_req, Rhythmic_req {
- REQUESTMETHODS(Spacing_req, spacing);
-
-};
-
-///Put a text above or below (?) this staff.
-struct Text_req : virtual Request {
- int dir_i_;
- Text_def *tdef_p_;
- /* *************** */
- Text_req(int d, Text_def*);
- ~Text_req();
- Text_req(Text_req const&);
- static int compare(const Text_req&,const Text_req&);
- REQUESTMETHODS(Text_req,text);
-};
-
-
-struct Lyric_req : public Rhythmic_req, Text_req {
-
- Lyric_req(Text_def* t_p);
- REQUESTMETHODS(Lyric_req, lreq_l);
-};
-
-/// request which has some kind of pitch
-struct Melodic_req :virtual Request
-{
- /// 0 is c
- int notename;
- int octave;
- int accidental;
- bool forceacc;
-
- // return height from central c (in halflines)
- int height()const;
- Melodic_req();
-
- REQUESTMETHODS(Melodic_req,melodic);
-};
-
-/// Put a note of specified type, height, and with accidental on the staff.
-struct Note_req : Rhythmic_req, virtual Melodic_req {
-
-
- Rhythmic_req* rhythmic() { return Rhythmic_req::rhythmic(); }
- REQUESTMETHODS(Note_req, note);
- };
-/**
-*/
-
-
-///Put a rest on the staff.
-/**
-Why a request? It might be a good idea to not typeset the rest, if the paper is too crowded.
-*/
-
-struct Rest_req : Rhythmic_req {
-
- REQUESTMETHODS(Rest_req,rest);
-};
-/// attach a stem to the noteball
-/**
- Rhythmic_req parent needed to determine if it will fit inside a beam.
- */
-
-struct Stem_req : Rhythmic_req {
- int dir_i_;
- Stem_req(int s, int dots);
- REQUESTMETHODS(Stem_req,stem);
-};
-
-/// requests to start or stop something.
-/**
- This type of request typically results in the creation of a #Spanner#
-*/
-struct Span_req : Request {
- /// should the spanner start or stop, or is it unwanted?
- enum {
- NOSPAN, START, STOP
- } spantype ;
- static int compare(const Span_req &r1, const Span_req &r2);
- REQUESTMETHODS(Span_req,span);
-
- Span_req();
-
-};
-
-
-///Start / stop a beam at this note.
-
-/** if #nplet# is set, the staff will try to put an
-appropriate number over the beam
- */
-struct Beam_req : Span_req {
- int nplet;
-
- /* *************** */
- REQUESTMETHODS(Beam_req,beam);
-
- Beam_req();
-};
-
-/// a slur
-struct Slur_req : Span_req {
- REQUESTMETHODS(Slur_req,slur);
-
-};
-
-
-///Put a script above or below this ``note''
-/** eg upbow, downbow. Why a request? These symbols may conflict with
-slurs and brackets, so this also a request */
-struct Script_req : Request {
- int dir_i_;
- Script_def *scriptdef_p_;
-
- /* *************** */
- static int compare(const Script_req &, const Script_req &);
- Script_req(int d, Script_def*);
- REQUESTMETHODS(Script_req,script);
- ~Script_req();
- Script_req(Script_req const&);
-};
-
-
-/// designate this spot with a name.
-struct Mark_req : Request {
- String mark_str_;
- /* *************** */
- Mark_req(String);
- REQUESTMETHODS(Mark_req,mark);
-};
-
-struct Staff_command_req : Request {
- Input_command * com_p_;
- /* *************** */
- Staff_command_req(Staff_command_req const&);
- ~Staff_command_req();
- Staff_command_req(Input_command*);
- REQUESTMETHODS(Staff_command_req,command);
-};
-
-#if 0
-
-
-///Draw a (Guitar) chord above or below this ``note''
-/**
-Why a request?
-Because everything else is done in requests.
-*/
-struct Chord : Request {
- // don't know how this looks.
-};
-
-/// for absolute dynamics
-enum Loudness {
- FFF, FF, F, MF, MP, P, PP, PPP
-} ;
-
-
-///Start / stop a slur or a bracket.
-/**
-Start/stop a bracket at this note. if #nplet# is set, the staff will
-try to put an appropriate number over the bracket
-*/
-struct Bracket_req : Span_req {
- int nplet; // print a number over the beam.
-};
-
-struct Subtle_req {
- Moment subtime;
-};
-
-/// helper in the hierarchy
-/** Each dynamic is bound to one note ( a crescendo spanning multiple
- notes is thought to be made of two "dynamics": a start and a stop).
- Dynamic changes can occur in a smaller time than the length of its
- note, therefore fore each Dynamic request carries a time, measured
- from the start of its note.
-
- This subfield would come in handy, if mpp96 was adapted for midi
- support.
-
- Dynamic should have been derived from request, but I don't want to
- fuss with virtual baseclasses. */
-
-struct Dynamic:Subtle_req {
-
-};
-/// do a crescendo
-struct Cresc_req : Span_req, Dynamic {
-
-};
-
-/// do a decrescendo
-struct Decresc_req : Span_req, Dynamic {
-
-};
-
-/// do a dynamic like "fff" or "mp"
-struct Absdynamic_req : Request, Dynamic {
- Loudness loudness;
-};
-
-struct Grace_req : Subtle_req {
-
-};
-
-struct Grace_turn_req : Grace_turn {
-
-};
-
-struct Grace_note : Melodic_req {
-
-};
-
-struct Grace_notes {
-
-};
-
-struct Glissando_req : Span_req {
-
-};
-#endif
#endif
#include "headreg.hh"
#include "paperdef.hh"
#include "complexwalker.hh"
-
+#include "musicalrequest.hh"
Notehead_register::Notehead_register(Complex_walker*w_l)
:Request_register(w_l)
note_p_ = n_p;
n_p->set_rhythmic(req_l->rhythmic());
n_p->position = req_l->note()->height() +
- walk_l_->clef_.c0_position_i_;
+ walk_l_->c0_position_i();
} else {
note_p_ = new Rest ( req_l->rhythmic()->balltype,
req_l->rhythmic()->dots);
(c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
*/
+#include "musicalrequest.hh"
#include "complexwalker.hh"
#include "slurreg.hh"
#include "slur.hh"
#include "debug.hh"
+
+
void
Slur_register::set_dir(int i)
{
if (slur_req_l->spantype == Span_req::STOP) {
if (slur_l_stack_.empty())
warning("can't find slur to end",
- slur_req_l->defined_ch_c_l_m);
+ slur_req_l->defined_ch_c_l_);
else {
end_slur_l_arr_.push(slur_l_stack_.pop());
requests_arr_.pop();
Slur_register::~Slur_register()
{
for (int i=0; i < requests_arr_.size(); i++) {
- warning("unterminated slur", requests_arr_[i]->defined_ch_c_l_m);
+ warning("unterminated slur", requests_arr_[i]->defined_ch_c_l_);
}
}
+/*
+ stcol.cc -- implement Staff_column
+
+ source file of the LilyPond music typesetter
+
+ (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
+*/
+
#include "voice.hh"
#include "timedescription.hh"
#include "sccol.hh"
-#include "staffcommands.hh"
#include "stcol.hh"
+#include "commandrequest.hh"
+#include "musicalrequest.hh"
void
Staff_column::OK() const
{
#ifndef NDEBUG
- if (tdescription_) {
- assert(tdescription_->when == when());
- assert(*tdescription_ == staff_commands_p_->tdescription_);
- }
+ assert (command_column_l_->when() == musical_column_l_->when());
#endif
}
-bool
-Staff_column::musical_b() const
-{
- return score_column_l_->musical_;
-}
-
Moment
Staff_column::when() const
{
- return score_column_l_->when();
+ return (command_column_l_)?
+ command_column_l_->when():
+ musical_column_l_->when();
}
void
Staff_column::add(Voice_element*ve)
{
- Moment d= ve->duration;
- if (d){
- score_column_l_->add_duration(d);
+ for (iter_top(ve->reqs,j); j.ok(); j++) {
+ if (j->nonmus()) {
+ if (j->nonmus()->timing()) {
+ timing_req_l_arr_.push(j->nonmus()->timing());
+ }
+ if (!j->barcheck() && !j->nonmus()->measuregrouping())
+ setup_one_request(j); // no need to bother children
+ } else {
+ if (j->rhythmic()) {
+ musical_column_l_->add_duration(j->rhythmic()->duration());
+ }
+ setup_one_request(j);
+ }
}
-
- v_elts.push(ve);
}
-Staff_column::Staff_column(Score_column * cur)
-
+Staff_column::Staff_column()
{
- tdescription_ =0;
- score_column_l_=cur;
- staff_commands_p_ = 0;
+ musical_column_l_ = 0;
+ command_column_l_ = 0;
}
+
+
+
Staff_column::~Staff_column()
{
- delete tdescription_;
+}
+
+void
+Staff_column::set_cols(Score_column*c1, Score_column*c2)
+{
+ command_column_l_ = c1;
+ musical_column_l_ = c2;
}
(c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
*/
+#include "musicalrequest.hh"
#include "textreg.hh"
#include "textitem.hh"
+/*
+ voice.cc -- implement Voice
+
+ source file of the LilyPond music typesetter
+
+ (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
+*/
+
#include "debug.hh"
#include "voice.hh"
-#include "request.hh"
+#include "musicalrequest.hh"
+#include "commandrequest.hh"
void
Voice::set_default_group(String s)
l += i->duration;
return l;
}
-/* *************************************************************** */
-void
-Voice_element::print() const
-{
-#ifndef NPRINT
- mtor << "voice_element { dur :"<< duration <<"\n";
- for (iter_top(reqs,rc); rc.ok(); rc++) {
- rc->print();
- }
- mtor << "}\n";
-#endif
-}
-void
-Voice_element::add(Request*r)
-{
- if (r->rhythmic()) {
- assert (!duration || duration == r->duration());
- duration = r->duration();
- }
-
- r->elt_l_ = this;
- reqs.bottom().add(r);
-}
-
-
-Voice_element::Voice_element()
-{
- voice_l_ = 0;
- duration = 0;
- defined_ch_c_l_m = 0;
-}
-Voice_element::Voice_element(Voice_element const&src)
-{
- defined_ch_c_l_m = src.defined_ch_c_l_m;
- // are you sure? They can be modified after copying.
- voice_l_=0;
- for (iter_top(src.reqs, i); i.ok(); i++)
- add(i->clone());
-
-}
-void
-Voice_element::set_default_group(String s)
-{
- for (iter_top(reqs, i); i.ok(); i++)
- if (i->groupchange())
- return ;
- Group_change_req *greq = new Group_change_req;
- greq->newgroup_str_ = s;
- add(greq);
-}
--- /dev/null
+/*
+ voiceelt.cc -- implement Voice_element
+
+ source file of the LilyPond music typesetter
+
+ (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
+*/
+
+#include "debug.hh"
+#include "voice.hh"
+#include "musicalrequest.hh"
+#include "commandrequest.hh"
+
+
+void
+Voice_element::print() const
+{
+#ifndef NPRINT
+ mtor << "voice_element { dur :"<< duration <<"\n";
+ for (iter_top(reqs,rc); rc.ok(); rc++) {
+ rc->print();
+ }
+ mtor << "}\n";
+#endif
+}
+
+void
+Voice_element::add(Request*r)
+{
+ if (r->duration()) {
+ assert (!duration || duration == r->duration());
+ duration = r->duration();
+ }
+
+ r->elt_l_ = this;
+ reqs.bottom().add(r);
+}
+
+
+Voice_element::Voice_element()
+{
+ voice_l_ = 0;
+ duration = 0;
+ defined_ch_c_l_ = 0;
+}
+
+Voice_element::Voice_element(Voice_element const&src)
+{
+ defined_ch_c_l_ = src.defined_ch_c_l_;
+
+ voice_l_=0;
+ for (iter_top(src.reqs, i); i.ok(); i++)
+ add(i->clone());
+
+}
+void
+Voice_element::set_default_group(String s)
+{
+ for (iter_top(reqs, i); i.ok(); i++)
+ if (i->groupchange())
+ return ;
+ Group_change_req *greq = new Group_change_req;
+ greq->newgroup_str_ = s;
+ add(greq);
+}