# class name silence?
-My_flex_lexer 0
+My_flex_lexer 1
yyFlexLexer 1
PCol 1
Score_column 1
Ineq_constrained_qp 1
-Spacing_problem 1
-Colinfo 1
+Spacing_problem 0
+Colinfo 0
Mixed_qp 1
PScore 1
Idealspacing 1
Rhythmic_req 1
Rest_req 1
delete_identifiers 1
-Command 0
-Staff_commands 0
-Stem 0
-Staff 0
-Score 0
-Voice 0
+Command 1
+Staff_commands 1
+Stem 1
+Staff 1
+Score 1
+Voice 1
Voice_element 1
Input_cursor 1
Commands_at 1
Input_command 1
-Moment 0
\ No newline at end of file
+Time_description 1
\ No newline at end of file
=head1 OPTIONS
-=item B<-d,--debug>
+=item B<-d,--debug>,
debugging
-=item B<-w,--warranty>
+=item B<-w,--warranty>,
warranty
-=item B<-o,--output>
+=item B<-o,--output>,
default output file
-=item B<-h,--help>
+=item B<-h,--help>,
help
=head1 LICENSE
=item - bison/yacc
-=item - The "flower" library, which should be available from the
- same source you got this from.
+=item - The "flower" library,
+which should be available from the
+same source you got this from.
=item - perl
=over 5
-=item - TeX
+=item TeX
-=item - the MusixTeX fonts
+=item the MusixTeX fonts
=back
why G++ >= 2.7? LilyPond & flower lib uses:
- builtin bool
- typeof
- operator <?, operator >?
- the new for-scope
- class Rational (libg++)
+=over 5
+
+=item builtin bool
+
+=item typeof
+
+=item operator <?, operator >?
+
+=item the new for-scope
+
+=item class Rational (libg++)
+
+=item named return values
+
+=back
=head1 AUTHOR
=head1 FILES
-F<symbol.ini> The initialisation file with symbol tables etc.
+F<symbol.ini> The initialisation file with symbol tables etc. It
+includes files from the directory F<init/>.
=head1 HOW DOES IT WORK
Use The Source, Luke. If you don't know C++, you can try editing
the file F<.dstreamrc> for copious debugging output. (use B<-d>)
-the subdir Documentation/ contains some more-in-depth matter on LilyPond
-
-The source is commented in the DOC++ style.
-Check out doc++ at
+the subdir F<Documentation/> contains some more-in-depth matter on LilyPond
- http://www.ZIB-Berlin.DE/VisPar/doc++/doc++.html
+The source is commented in the DOC++ style. Check out doc++ at
+F<http://www.ZIB-Berlin.DE/VisPar/doc++/doc++.html>
=back
=head1 DESCRIPTION
-This page documents some aspects of the internals of LilyPond
+This page documents some aspects of the internals of LilyPond. Some of
+this stuff comes from e-mail I wrote, some from e-mail others wrote, some are large comments taken away from the headers
=head1 OVERVIEW
=back
+=head1 REQUESTS
+
+[see F<request.hh>]
+
+Any Voice_element can do a number of requests. A request is done
+to the C<Staff> which contains the C<Voice_element>. The staff decides
+whether to to honor the request, ignore it, or merge it with other
+requests. Merging of requests is preferably done with other
+requests done by members of the same voicegroups (beams, brackets, stems)
+
+Please refer to the documentation of the Child classes of
+C<Request> for explanation of each request type.
+
+The result of a request will be an C<Item> or a C<Spanner>, which
+will be put on a C<PStaff>. Note that the C<PStaff> and the original
+C<Staff> need not have anything in common. For example, the
+``double'' piano Staff could interpret commands which juggle
+melodies across the left and right hand, and may put the result in
+two five-line PStaffs (maybe with extra PStaffs to carry the dynamic
+signs and any lyric.
+
+The class C<Staff> should be thought as a container for the
+C<Voice>s, and an interpreter for C<Request>s and C<Command>s.
+Different staffs can produce different outputs; a melodious voice
+which is put into a percussion-Staff, will be typeset as the rythm of
+that voice.
+
+After C<Staff> made up her mind (Would C<Staff> be a smart
+name? How about C<struct Susan {}> :-), the resultant items and
+spanners are put on the PScore, and pointers to these items are
+stored in the C<Voice_element>. This construction enables the
+beams/stems to look up the balls it has to connect to.
+
+=over 5
+
+=item Note_req
+
+Staff has to decide if the ball should be hanging left or right. This
+influences the horizontal dimensions of a column, and this is why
+request processing should be done before horizontal spacing.
+
+Other voices' frivolities may cause the need for accidentals, so this
+is also for the Staff to decide. The Staff can decide on positioning
+based on ottava commands and the appropriate clef.
+
+=item Rest_req
+
+Why a request? It might be a good idea to not typeset the rest, if the
+paper is too crowded.
+
+=item Span_req
+
+This type of request typically results in the creation of a C<Spanner>
+
+=item Beam_req
+
+Staff has to combine this request with the stem_request, since the
+number of flags that a stem wants to carry will determine the
+number of beams.
+
+=item Dynamic
+
+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.
+
+=back
+
=head1 COMMANDS
+
This table decribes the proper order for the different commands:
=head2 References
+[partly by Mark Basinski <basinski@arizona.edu>]
+
+
Herbert Chlapik,
W.A. Hegazy and J. S. Gourlay. Optimal line breaking in music. In
Ross, Ted. ``Teach yourself the art of music engraving and processing''
(3rd edition). Hansen House, Miami Beach, FL.
-
+
Hansen House
1820 West Ave.
Miami, FL 33139
(305) 532-5461
-
+
[This is about *engraving* i.e. professional music typesetting, and includes
some good spacing tables]
fi )
mv $(CCDIR)/parser.tab.c $@
-parser.hh: parser.cc
+$(parsheadnew): $(CCDIR)/parser.cc
version.o: $(obs) version.hh
+pl 21:
+ - Move breaking stuff into a separate class Break_algorithm
+ - dependencies for Staff_elem's
+ - scripts
+ - texts
+ - nplets (triplets!)
+
pl 20:
- Rational for time measurement
- updated doco to .pod
-Please refer to the directory Documentation/.
+Please refer to the directory Documentation/, Documentation/README.*
-To generate the pretty-printed docs, do a:
+To generate the pretty-printed docs, do this:
make doc
clef.hh clefitem.hh inputcommands.hh\
getcommand.hh inputmusic.hh timedescription.hh\
inputscore.hh inputstaff.hh identparent.hh\
- inputcommand.hh grouping.hh moment.hh offset.hh
-
+ inputcommand.hh grouping.hh moment.hh offset.hh\
+ staffelem.hh idealspacing.hh break.hh\
+ scriptdef.hh script.hh textdef.hh textitem.hh
mycc= qlp.cc qlpsolve.cc leastsquares.cc\
inputcommands.cc inputmusic.cc \
notehead.cc stem.cc \
rest.cc bar.cc meter.cc keyitem.cc localkeyitem.cc clefitem.cc\
swalker.cc scoreline.cc\
- simplewalker.cc\
+ simplewalker.cc scriptdef.cc script.cc\
texbeam.cc texslur.cc clef.cc key.cc slur.cc beam.cc\
idealspacing.cc grouping.cc identifier.cc\
- lexerinit.cc mylexer.cc\
+ lexerinit.cc mylexer.cc textdef.cc textitem.cc\
+ staffelem.cc wordwrap.cc\
template1.cc template2.cc template3.cc template4.cc\
template5.cc\
version.cc
# version info
MAJVER=0
MINVER=0
-PATCHLEVEL=20
+PATCHLEVEL=21
VERSION=$(MAJVER).$(MINVER).$(PATCHLEVEL)
CXXVER=`$(CXX) --version`
#flower version
-NEEDEFLOWERVER=1.0.16
+NEEDEFLOWERVER=1.0.17
# directories
TOPDIR := $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi)
cad = music { $
\duration { 8}
- 'c4. g8 ['e()'d 'c b]
- [b()c] g c [c e g 'c]
+ \textstyle "italic"
+ 'c4._"f" g8
+ \textstyle "roman"
+ ['e^"accel" ()'d 'c b]
+ [b()'c] g-\fermata c [c_"rubato" e g 'c]
\octave{'}
- e4. e [g ()f e d]
+ e4. e [g ()f_"rit" e d]
\duration{16}
dis4()e4 r8 [c d] [e f g gis]
\duration{4}
- a `f()`e g
- f `d()`cis e
+ a-> `f()`e g
+ f-> `d()`cis e
\duration{8}
- d4 r8 `a [`b cis]
+ d4^\fermata r8 `a [`b cis]
\duration{16}
[d cis d e]
f4()[f e d c] `b4
- \octave{} ['c8 b8] % triplet!
+ \octave{} \plet{2/3} ['d8 'c8 a8] \plet{1/1} % triplet!
g2 [g c e g] ['c e g 'c]\octave{'}
- [e `g c e] g4 %()% BUG!
- [g8.( e g8. )e]
+ [e `g c e] g4^\fermata %()% BUG!
+ [g8.(_"a tempo" e g8. )e]
a4. g8 [f8 e8 d8 c8]
- `g2 d2
+ `g2 d2^"tr"
c4 $}
score {
music { cad }
}
commands { meter 4 4 skip 13:0 }
-}
\ No newline at end of file
+}
\font\musicfnt=musix20
-\font\slurfont=xslhu20
-\def\thefont{\musicfnt}
+\font\slurfont=xslu16
+\def\thefont{\slurfont}
\def\mb#1{{\thefont\char#1}}
\newdimen\inc
\newdimen\here
\def\hruler#1{%
- \wid=#1pt
- \inc=\wid
- \divide\inc by #1
- \divide\wid by 2
- \here=-\wid
- \loop\ifdim\here<\wid\advance\here by\inc
- \hbox to0pt{\kern\here\vrule width0.05pt height 2pt\hss}%
- \repeat%
+ \wid=#1pt
+ \inc=\wid
+ \divide\inc by #1
+ \divide\wid by 2
+ \here=-\wid
+ \loop\ifdim\here<\wid\advance\here by\inc
+ \hbox to0pt{\kern\here\vrule width0.05pt height 2pt\hss}%
+ \repeat%
}
\def\vruler#1{%
- \wid=#1pt
- \inc=\wid
- \divide\inc by #1
- \divide\wid by 2
- \here=-\wid
- \loop\ifdim\here<\wid\advance\here by\inc
- \vbox to0pt{\vskip\here\vrule width2pt height 0.05pt\vss}%
- \repeat%
+ \wid=#1pt
+ \inc=\wid
+ \divide\inc by #1
+ \divide\wid by 2
+ \here=-\wid
+ \loop\ifdim\here<\wid\advance\here by\inc
+ \vbox to0pt{\vskip\here\vrule width2pt height 0.05pt\vss}%
+ \repeat%
}
\def\twhrul{\hbox to 0pt{\hbox{\hruler{20}\vrule
- width0.1pt height 3ptdepth 1pt}}}
+ width0.1pt height 3ptdepth 1pt}}}
\def\twvrul{\hbox{\vbox to 20pt{\vruler{20}\vrule
- width3pt height 0.1pt}}}
+ width3pt height 0.1pt}}}
\def\doitem#1{
- #1 %
- %\twvrul%doesn't work
- \hbox to 50pt{\qquad\twhrul\mb{#1}\hss}\setbox0=\hbox{\mb{#1}} width \the\wd0\ depth \the\dp0 \ height \the\ht0}
+ #1 %
+ %\twvrul%doesn't work
+ \hbox to 50pt{\qquad\twhrul\mb{#1}\hss}\setbox0=\hbox{\mb{#1}} width \the\wd0\ depth \the\dp0 \ height \the\ht0}
\newcount\n
\def\charn{\n=-1
- \loop\ifnum\n<255\advance\n by1
- \doitem{\number\n}\endgraf\repeat}
+ \loop\ifnum\n<255\advance\n by1
+ \doitem{\number\n}\endgraf\repeat}
- \charn
+ \charn
\bye
\ No newline at end of file
MAJVER=1
MINVER=0
-PATCHLEVEL=20
+PATCHLEVEL=21
PACKAGENAME=flower
#PROFILEFLAG=-pg
V val;
};
+/// hungarian: map
template<class K, class V>
struct Assoc {
Array< Assoc_ent_<K,V> > arr;
Accidental(int type, int position);
void print()const;
private:
- void brew_molecole();
+ void brew_molecule();
};
#endif // ACCIDENTAL_HH
String type;
Bar(String type);
- void preprocess();
+
+ Molecule*brew_molecule()const;
};
#endif // BAR_HH
virtual Interval width()const;
Offset center() const;
- Spanner *broken_at(PCol *, PCol *) const;
+ Spanner *do_break_at(PCol *, PCol *) const;
Beam();
void add(Stem*);
- void process();
- void calculate();
+
+
void set_default_dir();
- void preprocess();
- Interval height()const;
+ void do_pre_processing();
+ void do_post_processing();
+
void print() const;
void set_grouping(Rhythmic_grouping def, Rhythmic_grouping current);
void set_stemlens();
~Beam();
+
private:
- Molecule stem_beams(Stem *here, Stem *next, Stem *prev);
+ Molecule stem_beams(Stem *here, Stem *next, Stem *prev)const;
void solve_slope();
- void brew_molecule();
+ Molecule*brew_molecule()const;
};
/** Beam adjusts the stems its owns to make sure that they reach the
beam and that point in the correct direction */
--- /dev/null
+/*
+ break.hh -- part of LilyPond
+
+ (c) 1996 Han-Wen Nienhuys
+*/
+
+#ifndef BREAK_HH
+#define BREAK_HH
+#include "vray.hh"
+#include "proto.hh"
+typedef svec<PCol*> Line_of_cols;
+
+struct Col_configuration {
+ Line_of_cols cols;
+ svec<Real> config;
+ Real energy;
+
+ /****************/
+ void OK()const;
+ void setsol(svec<Real>);
+ Col_configuration() ;
+ void add( PCol*c);
+ void print() const;
+};
+
+struct Break_algorithm {
+ PScore &pscore_;
+ Real linelength;
+
+ /****************/
+
+ Break_algorithm(PScore&);
+ /// check if the spacing/breaking problem is well-stated
+ void problem_OK()const;
+ /// search all pcols which are breakable.
+ svec<PCol *> find_breaks() const;
+
+ /// helper: solve for the columns in #curline#.
+ svec<Real> solve_line(Line_of_cols) const;
+
+
+ /// does curline fit on the paper?
+ bool feasible(Line_of_cols)const;
+
+ virtual svec<Col_configuration> solve()=0;
+};
+
+/// wordwrap type algorithm: move to next line if current is optimal.
+struct Word_wrap : Break_algorithm {
+ virtual svec<Col_configuration> solve();
+ Word_wrap(PScore&);
+};
+#endif // BREAK_HH
+
bool change;
+ /****************/
+
Clef_item();
void read(Clef);
void read(String);
- void preprocess();
+ Molecule* brew_molecule()const;
};
#endif // CLEFITEM_HH
svec<int> generate_beams(svec<int>, int&);
private:
+ void init();
void junk();
void copy(Rhythmic_grouping const&);
};
--- /dev/null
+/*
+ idealspacing.hh -- part of LilyPond
+
+ (c) 1996 Han-Wen Nienhuys
+*/
+
+#ifndef IDEALSPACING_HH
+#define IDEALSPACING_HH
+#include "proto.hh"
+
+/// ideal spacing between two columns
+struct Idealspacing {
+
+ /// the ideal distance
+ Real space;
+
+ /// Hooke's constant: how strong are the "springs" attached to columns
+ Real hooke;
+
+ /// the two columns
+ const PCol *left, *right;
+
+ void print()const;
+ void OK() const ;
+ Idealspacing(const PCol *left,const PCol *right);
+};
+
+
+#endif // IDEALSPACING_HH
+
#include "inputmusic.hh"
#include "notename.hh"
#include "lookup.hh"
+#include "scriptdef.hh"
#define make_id_class(Idclass, Class, accessor) \
struct Idclass : Identifier {\
}\
-
+make_id_class(Script_id, Script_def, script);
make_id_class(Lookup_id, Lookup, lookup);
make_id_class(Symtables_id, Symtables, symtables);
make_id_class(Staff_id, Input_staff, staff);
#include "proto.hh"
#include "string.hh"
+#define IDACCESSOR( Input_staff, staff)\
+ virtual Input_staff * staff(bool = false) { error(#Input_staff); return 0; }
-struct Identifier
-{
+struct Identifier {
void *data;
String name;
Identifier(String n) : name(n) { }
virtual ~Identifier() {}
virtual const char*classname() { return "new Identifier"; }
- void error();
- virtual Input_staff * staff(bool = false) { error(); return 0; }
- virtual Input_music *music(bool = false) { error(); return 0; }
- virtual Music_voice *mvoice(bool = false) { error(); return 0; }
- virtual Symtables *symtables(bool = false) { error(); return 0; }
- virtual Music_general_chord *mchord(bool = false) { error(); return 0; }
- virtual Lookup*lookup(bool = false) { error(); return 0; }
- virtual Notename_tab*notename_tab(bool = false) { error(); return 0; }
+ void error(String);
+ IDACCESSOR(Input_staff, staff)
+ IDACCESSOR(Input_music, music)
+ IDACCESSOR(Music_voice, mvoice)
+ IDACCESSOR(Script_def, script)
+ IDACCESSOR(Symtables, symtables)
+ IDACCESSOR(Music_general_chord, mchord)
+ IDACCESSOR(Lookup,lookup)
+ IDACCESSOR(Notename_tab, notename_tab)
};
#endif // IDENTPARENT_HH
#include "glob.hh"
#include "boxes.hh"
#include "string.hh"
-
+#include "staffelem.hh"
+
+
/// a horizontally fixed size element of the score
-struct Item {
+struct Item : Staff_elem {
/// indirection to the column it is in
PCol * pcol_;
- /// indirection to the pstaff it is in
- PStaff *pstaff_;
-
- /// member: the symbols
- Molecule *output;
-
- ///
- Offset offset_;
- /**
- This is needed, because #output# may still be
- NULL.
- */
/****************/
-
- void translate(Offset);
-
- /// do calculations after determining horizontal spacing
- virtual void postprocess();
-
- /// do calculations before determining horizontal spacing
- virtual void preprocess();
- /**
- This is executed directly after the item is added to the
- PScore
- */
- virtual Interval width() const;
- virtual Interval height() const;
- String TeXstring () const ;
Item();
void print()const;
- virtual ~Item();
- Paperdef *paper() const;
};
/** Item is the datastructure for printables whose width is known
before the spacing is calculated
#include "item.hh"
#include "vray.hh"
+
+///
struct Keyitem : Item {
svec<int> pitch;
svec<int> acc;
int c_position;
+
/****************/
Keyitem(int cposition);
void add(int pitch, int acc);
void read(svec<int> k);
+
void preprocess();
-private:
- void brew_molecole();
+ Molecule* brew_molecule()const;
};
+/**
+ An item which places accidentals at the start of the line
+ */
+
#endif // KEYITEM_HH
/****************/
void set(Notename_tab *n);
- int lookup_keyword(String);
+ int lookup_keyword(String);
void lookup_notename(int &large, int &small, String s);
void LexerError(const char *);
Identifier*lookup_identifier(String s);
#include "glob.hh"
#include "plist.hh"
#include "vray.hh"
-#include "pcol.hh"
-#include "matrix.hh"
+#include "vector.hh"
+#include "interval.hh"
/// helper struct for #Spacing_problem#
struct Colinfo {
const PCol *pcol_;
- bool fixed;
- Real fixpos;
+ const Real* fixpos;
+ Interval width;
+
+ /****************/
Colinfo();
+ void operator=(Colinfo const&);
+ Colinfo(Colinfo const&);
+ ~Colinfo();
+ Colinfo(const PCol*,const Real*);
void print() const;
- Real minright() const { return pcol_->width().right; }
- Real minleft() const { return -pcol_->width().left; }
+ bool fixed() const { return fixpos;}
+ Real fixed_position()const { return *fixpos; }
+ Real minright() const { return width.right; }
+ Real minleft() const { return -width.left; }
};
struct Local_key_item : Item {
svec<Local_acc> accs;
-
- int c0_position;
+ svec<Notehead*> group;
+ int c0_position; // move into walker
/****************/
Local_key_item(int c0position);
- void add(int oct, int pitch, int acc);
-
- void preprocess();
-
-private:
- void brew_molecole();
+ void add(int oct, int pitch, int acc, Notehead*);
+ void do_pre_processing();
+ Molecule* brew_molecule()const;
};
#endif // LOCALKEYITEM_HH
Symbol half_slur_middlepart(Real &dx, int dir);
Symbol big_slur(int dy, Real &dx, int dir);
Symbol text(String style, String text, int align = 1);
-
+ Symbol script(String idx);
Lookup();
struct Meter: Item {
svec<Scalar> args;
+ /****************/
Meter(svec<Scalar> args) ;
- void preprocess();
+ Molecule*brew_molecule() const;
};
#endif // METER_HH
#include "plist.hh"
#include "boxes.hh"
-#include "item.hh"
#include "symbol.hh"
/// a symbol which can be translated, and freely copied
/// a group of #Atom#s
struct Molecule {
- IPointerList<Atom*> ats;
+ IPointerList<Atom*> ats; // change to List<Atom>?
/****************/
/****************/
- void preprocess();
Notehead(int staff_size);
/**
position of top line (5 linestaff: 8)
*/
-
+
void print()const;
static int compare(Notehead*&a, Notehead*&b) ;
-private:
- void brew_molecole();
+ Molecule* brew_molecule()const;
};
/**
takes care of:
void set_default_duration(int *);
void get_default_duration(int *);
void set_default_octave(String);
+void set_plet(int,int);
Staff * get_new_rhythmstaff();
Voice_element * get_note_element(String,int * ,int *);
Voice_element* get_rest_element(String,int *);
Staff * get_new_melodicstaff();
void add_requests( Voice_element*v, svec<Request*>&req);
Request* get_request(char);
-
+void set_text_style(String);
+Script_def* get_scriptdef(char);
+Text_def*get_text(String s);
+Request*get_script_req(int d , Script_def*def);
+Request*get_text_req(int d , Text_def*def);
#endif // PARSECONSTRUCT_HH
instantiate_compare(const PCol &, PCol::compare);
-/// ideal spacing between two columns
-struct Idealspacing {
-
- /// the ideal distance
- Real space;
-
- /// Hooke's constant: how strong are the "springs" attached to columns
- Real hooke;
-
- /// the two columns
- const PCol *left, *right;
-
- void print()const;
- void OK() const ;
- Idealspacing(const PCol *left,const PCol *right);
-};
-
#endif
struct Span_req;
struct Spanner;
struct Staff;
+struct Col_configuration;
struct Staff_column;
struct Stem;
struct Stem_req;
struct Staff_commands_at ;
struct Commands_at ;
struct Time_description;
-
+struct Script_def;
+struct Text_def;
+struct Text_req;
+struct Melodic_req;
#endif // PROTO_HH
#ifndef PSCORE_HH
#define PSCORE_HH
-
+#include "break.hh"
#include "vray.hh"
#include "pcol.hh"
#include "pstaff.hh"
/// after calc_breaking
void postprocess();
- /// search all pcols which are breakable.
- svec< PCol *> find_breaks() const;
-
/// add a line to the broken stuff. Positions given in #config#
- void add_line(svec< PCol *> curline, svec<Real> config);
-
- /// helper: solve for the columns in #curline#.
- svec<Real> solve_line(svec<PCol *> curline) const;
+ void set_breaking(svec< Col_configuration> );
void add(PStaff *);
+
/// add item
void typeset_item(Item *, PCol *,PStaff*,int=1);
/// delete unused columns
void clean_cols();
-
- /// check if the spacing/breaking problem is well-stated
- void problem_OK() const;
-
/// invarinants
void OK()const;
+
PScore(Paperdef*);
void print() const;
- /// does curline fit on the paper?
- bool feasible(svec<PCol *> curline) const;
-
- /// which is first (left, higher)
+ /// which is first (left, higher)
int compare_pcols( PCol*, PCol*)const;
};
/** notes, signs, symbols in a score can be grouped in two ways:
/****************/
Request();
+ virtual ~Request(){}
virtual void print()const ;
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 Beam_req *beam() { return 0 ; }
virtual Slur_req *slur() { return 0 ; }
- virtual Rhythmic_req*rhythmic() { return 0;}
+ virtual Rhythmic_req*rhythmic() { return 0; }
+ virtual Melodic_req *melodic() { return 0; }
virtual Moment duration() const { return 0.0; }
virtual Request* clone() const =0;
};
/**
- Any Voice_element can do a number of requests. A request is done
- to the #Staff# which contains the #Voice_element#. The staff decides
- whether to to honor the request, ignore it, or merge it with other
- requests. Merging of requests is preferably done with other
- requests done by members of the same voicegroups (beams, brackets, stems)
-
- Please refer to the documentation of the Child classes of
- #Request# for explanation of each request type.
-
- The result of a request will be an #Item# or a #Spanner#, which
- will be put on a #PStaff#. Note that the #PStaff# and the original
- #Staff# need not have anything in common. For example, the
- ``double'' piano Staff could interpret commands which juggle
- melodies across the left and right hand, and may put the result in
- two five-line PStaffs (maybe with extra PStaffs to carry the dynamic
- signs and any lyric.
-
- The class #Staff# should be thought as a container for the
- #Voice#s, and an interpreter for #Request#s and #Command#s.
- Different staffs can produce different outputs; a melodious voice
- which is put into a percussion-Staff, will be typeset as the rythm of
- that voice.
-
- After #Staff# made up her mind (Would #Staff# be a smart
- name? How about #struct Susan {}# :-), the resultant items and
- spanners are put on the PScore, and pointers to these items are
- stored in the #Voice_element#. This construction enables the
- beams/stems to look up the balls it has to connect to. */
+see lilygut page
+ */
/// a request with a duration
-struct Rhythmic_req : Request {
+struct Rhythmic_req : virtual Request {
int balltype;
int dots;
-
+ Moment plet_factor;
/****************/
Moment duration() const;
Request*clone() const;
};
-/// Put a note of specified type, height, and with accidental on the staff.
-struct Note_req : Rhythmic_req {
- char name;
+
+struct Melodic_req :virtual Request
+{
+ /// 0 is c
+ int name;
int octave;
int accidental;
bool forceacc;
-
- /****************/
// return height from central c (in halflines)
int height()const;
- Note_req();
+ Melodic_req();
+ Melodic_req*melodic() { return this;}
+ virtual void print() const;
+ Request*clone() const;
+};
+
+/// 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(); }
+
Note_req*note() { return this;}
virtual void print() const;
Request*clone() const;
};
/**
-Staff has to decide if the ball should be hanging left or right. This
-influences the horizontal dimensions of a column, and this is why
-request processing should be done before horizontal spacing.
-
-Other voices' frivolities may cause the need for accidentals, so this
-is also for the Staff to decide. The Staff can decide on positioning
-based on ottava commands and the appropriate clef.
*/
virtual Beam_req * beam() { return this; }
virtual Request*clone()const;
};
-/** Staff will have to combine this with the stem_request, since the
- number of flags that a stem wants to carry will determine the
- number of beams. if #nplet# is set, the staff will try to put an
- appropriate number over the beam
-
+/** if #nplet# is set, the staff will try to put an
+appropriate number over the beam
*/
/// a slur
};
-#if 0
+///Put a script above or below this ``note''
+struct Script_req : Request {
+ int dir;
+ Script_def *scriptdef;
-///Put a lyric above or below (?) this staff.
-struct Lyric_req : Request {
- String text;
+ /****************/
+ Script_req*script() { return this; }
+ virtual void print() const;
+ Request *clone()const;
+ Script_req(int d, Script_def*);
+ ~Script_req();
};
+/** eg upbow, downbow. Why a request? These symbols may conflict with
+slurs and brackets, so this also a request */
-///Put a script above or below this ``note''
-struct Script_req : Request {
- int orientation;
- Symbol sym;
+///Put a text above or below (?) this staff.
+struct Text_req : Request {
+ int dir;
+ Text_def *spec;
+ /****************/
+ Text_req*text() { return this; }
+ virtual void print() const;
+ Request *clone()const;
+ Text_req(int d, Text_def*);
+ ~Text_req();
};
-/**
-eg upbow, downbow. Why a request? These symbols may conflict with slurs and brackets, so this
-also a request
-*/
+#if 0
+
+///Put a lyric above or below (?) this staff.
+struct Lyric_req : Request {
+ String text;
+};
+
///Draw a (Guitar) chord above or below this ``note''
///Start / stop a slur or a bracket.
struct Bracket_req : Span_req {
- int nplet;
+ int nplet; // print a number over the beam.
};
+
/**
Start/stop a bracket at this note. if #nplet# is set, the staff will
try to put an appropriate number over the bracket
*/
-/// helper in the hierarchy
-struct Dynamic {
+struct Subtle_request {
Moment subtime;
};
+
+/// helper in the hierarchy
+struct Dynamic:Subtle_request {
+
+};
/** 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
/// do a dynamic like "fff" or "mp"
struct Absdynamic_req : Request, Dynamic {
- Loudness loudness;
+ Loudness loudness;
+};
+
+struct Grace_req : Subtle_request {
+
+};
+
+struct Grace_turn_req : Grace_turn {
+
+};
+
+struct Grace_note : Melodic_req {
+
+};
+
+struct Grace_notes {
+
};
#endif
#endif
/****************/
- void preprocess();
+
Rest(int dur,int dots);
void print()const;
-private:
- void brew_molecole();
+
+ Molecule* brew_molecule()const;
};
/**
takes care of:
--- /dev/null
+/*
+ script.hh -- part of LilyPond
+
+ (c) 1996 Han-Wen Nienhuys
+*/
+
+#ifndef SCRIPT_HH
+#define SCRIPT_HH
+
+#include "scriptdef.hh"
+#include "item.hh"
+
+struct Script : Item{
+ int dir;
+ int symdir;
+ int pos;
+ int staffsize;
+ Script_def*specs;
+ Stem * stem_;
+ Item * support;
+
+ /****************/
+
+ void set_symdir();
+ void set_default_dir();
+ void set_default_pos();
+
+ Molecule* brew_molecule()const;
+ virtual void do_post_processing();
+ virtual void do_pre_processing();
+ Script(Script_req*, Item*,int,Stem*p=0);
+ virtual Interval width() const;
+};
+
+
+#endif // SCRIPT_HH
+
--- /dev/null
+/*
+ scriptdef.hh -- part of LilyPond
+
+ (c) 1996 Han-Wen Nienhuys
+*/
+
+#ifndef SCRIPTDEF_HH
+#define SCRIPTDEF_HH
+#include "string.hh"
+struct Script_def{
+ int stemdir;
+ int staffdir;
+
+ bool invertsym;
+ String symidx;
+
+ /****************/
+ void print() const;
+ Script_def(String, int, int ,bool);
+};
+
+
+#endif // SCRIPTDEF_HH
+
*/
struct Simple_staff;
+struct Note_info {
+ Rhythmic_req *rq;
+ svec<Script_req*> scripts;
+ Note_info();
+ Note_info(Rhythmic_req*);
+};
/// column of Simple_staff: store one request
struct Simple_column : Staff_column {
- svec<Rhythmic_req *> notes;
+ svec<Note_info> notes;
svec<Slur_req *> slurs;
Stem_req *stem_;
Moment stem_requester_len;
Beam_req *beam_;
Simple_staff* staff_;
-
+ Text_req *text_;
/****************/
Slur_req * find_slur(Voice *);
Clef clef_;
Rhythmic_grouping default_grouping;
Rhythmic_grouping *current_grouping;
-// Real inbar; // whuh?
-
svec<Slur_req*> pending_slur_reqs;
svec<Slur*> pending_slurs;
-
-
-
+
/****************/
virtual void do_TYPESET_command(Command*);
virtual void process_requests();
virtual void reset();
- void do_note(Rhythmic_req*);
+ void do_note(Note_info);
Simple_walker(Simple_staff*);
Simple_column *col();
Simple_staff *staff();
- void do_local_key(Note_req*n);
+ void do_local_key(Note_req*, Notehead*);
int find_slur(const Voice*v);
};
/****************/
Offset center() const;
- void calculate();
- void print()const;
- void preprocess();
+ Slur();
+ void print() const;
+ void do_post_processing();
+ void do_pre_processing();
void add(Notehead*);
void set_default_dir();
- Interval height() const;
- Spanner* broken_at( PCol*, PCol*) const;
+
+ Spanner* do_break_at( PCol*, PCol*) const;
void process();
private:
- void brew_molecule();
+Molecule*brew_molecule()const;
};
#endif // SLUR_HH
#define SPANNER_HH
#include "proto.hh"
-#include "interval.hh"
+#include "staffelem.hh"
/// a symbol which is attached between two columns.
-struct Spanner {
+struct Spanner:Staff_elem {
PCol *left, *right;
- PStaff * pstaff_;
- Molecule *output ;
+
/****************/
-
- String TeXstring () const ;
+
Spanner();
- Paperdef *paper() const;
- virtual ~Spanner();
- virtual Interval height()const=0;
- /**
- PRE:
- processed
- */
- /// do calcs
- virtual void calculate();
- /**
- It is safe to call calculate multiple times on one object
- */
- virtual Interval width()const;
- virtual void process();
- virtual void preprocess();
-
+ virtual Interval width()const;
+ void print()const;
+ Spanner *broken_at(PCol *c1, PCol *c2) const;
+protected:
/// clone a piece of this spanner.
- virtual Spanner *broken_at( PCol *c1, PCol *c2) const=0;
+ virtual Spanner *do_break_at( PCol *c1, PCol *c2) const=0;
/**
PRE
c1 >= start, c2 <= stop
*/
- virtual void print() const;
};
/**
- A spanner is a symbol whose appearance can only be calculated after the breaking problem is solved.
+ A spanner is a symbol whose final appearance can only be calculated
+ after the breaking problem is solved.
Examples
--- /dev/null
+/*
+ staffelem.hh -- part of LilyPond
+
+ (c) 1996 Han-Wen Nienhuys
+*/
+
+#ifndef STAFFELEM_HH
+#define STAFFELEM_HH
+#include "vray.hh"
+#include "proto.hh"
+#include "offset.hh"
+#include "molecule.hh"
+
+struct Staff_elem {
+ enum Status {
+ ORPHAN, // not yet added to pstaff
+ VIRGIN, // added to pstaff
+ PRECALCED, // calcs before spacing done
+ POSTCALCED, // after spacing calcs done
+ OUTPUT, // molecule has been output
+ } status;
+ bool calc_children;
+ svec<Staff_elem*> dependencies;
+
+ /// indirection to the pstaff it is in
+ PStaff *pstaff_;
+
+ /****************/
+
+ String TeXstring () const ;
+ virtual void print() const;
+ virtual Interval width() const;
+ virtual Interval height() const;
+ Paperdef *paper() const;
+ virtual ~Staff_elem();
+ Staff_elem();
+
+ void translate(Offset);
+ void add_processing();
+ void pre_processing();
+ void post_processing();
+ void molecule_processing();
+
+protected:
+ /// generate the molecule
+ virtual Molecule* brew_molecule()const=0;
+ ///executed directly after the item is added to the PScore
+ virtual void do_add_processing();
+ /// do calculations before determining horizontal spacing
+ virtual void do_pre_processing();
+
+ /// do calculations after determining horizontal spacing
+ virtual void do_post_processing();
+
+private:
+ /// member: the symbols
+ Molecule *output; // should scrap, and use temp var?
+
+ ///
+ Offset offset_;
+ /**
+ This is needed, because #output# may still be
+ NULL.
+ */
+};
+
+#endif // STAFFELEM_HH
+
svec<Notehead*> heads;
/****************/
-
+ Stem(int center, Moment duration);
+
/// ensure that this Stem also encompasses the Notehead #n#
void add(Notehead*n);
+
Real hpos()const;
void print() const;
void set_stemend(Real);
void set_default_stemlen();
void set_default_extents();
void set_noteheads();
- void postprocess();
- void preprocess();
- Stem(int center, Moment duration);
+
+
+ void do_pre_processing();
Interval width() const;
-private:
- void brew_molecole();
+ Molecule* brew_molecule() const;
};
/**
takes care of:
--- /dev/null
+/*
+ textdef.hh -- part of LilyPond
+
+ (c) 1996 Han-Wen Nienhuys
+*/
+
+#ifndef TEXTDEF_HH
+#define TEXTDEF_HH
+
+#include "string.hh"
+
+struct Text_def {
+ int align;
+ String text;
+ String style;
+
+ /*****************/
+
+ Text_def();
+ void print()const;
+ Atom create(Paperdef*)const;
+};
+#endif // TEXTDEF_HH
+
--- /dev/null
+/*
+ text.hh -- part of LilyPond
+
+ (c) 1996 Han-Wen Nienhuys
+*/
+
+#ifndef TEXT_ITEM_HH
+#define TEXT_ITEM_HH
+
+#include "textdef.hh"
+#include "item.hh"
+
+struct Text_item : Item{
+ int pos;
+ int staffsize;
+ int dir;
+ Text_def*specs;
+
+ /****************/
+
+ void set_default_pos();
+ Molecule* brew_molecule()const;
+ void do_pre_processing();
+
+ Text_item(Text_req*,int);
+};
+
+
+#endif // TEXT_HH
+
#include "string.hh"
#include "directionalspanner.hh"
+#include "textdef.hh"
/// a spanner which puts texts on top of other spanners.
struct Text_spanner : Spanner {
- int align;
- String text;
- String style;
+ Text_def spec;
+ Offset tpos;
Directional_spanner*support;
/****************/
- virtual void process();
- virtual void preprocess();
- virtual Interval height() const;
- virtual Spanner* broken_at(PCol*,PCol*)const;
+ virtual void do_pre_processing();
+ virtual void do_post_processing();
+ Molecule* brew_molecule()const;
+ virtual Interval height() const ;
+ void print() const;
+ virtual Spanner* do_break_at(PCol*,PCol*)const;
Text_spanner(Directional_spanner*);
};
/**
DFILES=dutch.ini table_sixteen.ini table_twenty.ini\
- english.ini
+ english.ini script.ini
dist:
ln Makefile $(DFILES) $(DDIR)/$(INITDIR)
+%
+% common dutch names for notes. "es" means flat, "is" means sharp
+%
+
+
dutch_names =
notenames {
"ceses" 0 -2 "ces" 0 -1 "c" 0 0 "cis" 0 1 "cisis" 0 2
"beses" 6 -2 "bes" 6 -1 "b" 6 0 "bis" 6 1 "bisis" 6 2
}
+
+notenames { dutch_names }
\ No newline at end of file
--- /dev/null
+
+% name = script {
+% indexstring same_dir_as_stem above_below_staff symbol_can_beinverted }
+%
+
+fermata = script { "fermata" 1 0 1 }
+stopped = script { "stopped" 0 1 0 }
+accent = script { "accent" -1 0 0 }
+staccato = script { "staccato" -1 0 0 }
+staccatissimo = script { "staccatissimo" 1 0 1 }
+portato = script { "portato" -1 0 0 }
+marcato = script { "marcato" -1 0 1 }
+upbow = script { "upbow" 0 1 0 }
+downbow = script { "downbow" 0 1 0 }
+%
+% spacing info for LilyPond. Do not edit this.
+% It has a lot of hard-wired stringconstants
+%
+
table_sixteen=
symboltables {
% index TeXstring, xmin xmax ymin ymax
+ "scripts" = table {
+ "fermata" "\fermata" 0pt 0pt 0pt 11.25pt
+ "-fermata" "\ifermata" 0pt 0pt -11.25pt 0pt
+ "portato" "\portato" 0pt 0pt 0pt 0pt
+ "accent" "\maccent" -1pt 8pt 0pt 0pt
+ "marcato" "\marcato" 0pt 0pt 0pt 11.25pt
+ "-marcato" "\imarcato" 0pt 0pt -11.25pt 0pt
+ "staccato" "\staccato" 0pt 0pt 0pt 5pt
+ "staccatissimo" "\staccatissimo" 0pt 0pt 0pt 7.5pt
+ "istaccatissimo" "\staccatissimo" 0pt 0pt -7.5pt 0pt
+ "upbow" "\upbow" -1pt 6pt 0pt 5pt
+ "downbow" "\downbow" 0pt 5pt 0pt 7.5pt
+ }
"style" = table {
- "roman" "\settext{%}" 0pt 0pt 0pt 0pt
- "italic" "\setitalic{%}" 0pt 0pt 0pt 0pt
+ "roman" "\settext{%}" 0pt 0pt 0pt 8pt
+ "italic" "\setitalic{%}" 0pt 0pt 0pt 8pt
}
"align" = table {
"-1" "\leftalign{%}" 0pt 0pt 0pt 0pt
}
}
+default_table = symboltables { table_sixteen }
\ No newline at end of file
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% spacing info for LilyPond. Do not edit this.
+% It has a lot of hard-wired stringconstants
+%
table_twenty = symboltables {
}
}
+default_table = symboltables { table_twenty }
\ No newline at end of file
%% musix defs
\parindent=0pt
\newdimen\interlinedist
- \newcount\n
- \newdimen\balkhoog
- \newdimen\notewidth
- \newdimen\notewidthhalf
- \newdimen\notewidthdouble
- \newdimen\staffrulethickness
- \newdimen\interstaffrule
-
+ \newcount\n
+ \newdimen\balkhoog
+ \newdimen\notewidth
+ \newdimen\notewidthhalf
+ \newdimen\notewidthdouble
+ \newdimen\staffrulethickness
+ \newdimen\interstaffrule
+\newdimen\balkhalf
\def\musixtwentydefs{
- \font\textfont=cmr10
- \font\slurufont=xslu20
- \font\slurdfont=xsld20
- \font\slurhfont=xslz20
- \font\hslurufont=xslhu20
- \font\hslurdfont=xslhd20
- \font\hslurhfont=xslhz20
- \font\musicfnt=musix20
- \font\italicfont=cmti10
- \balkhoog=20pt
- \notewidth=6pt
- \staffrulethickness=0.4pt
-
- \musixcalc
+ \font\textfont=cmr10
+ \font\meterfont=cmbx12
+ \font\slurufont=xslu20
+ \font\slurdfont=xsld20
+ \font\slurhfont=xslz20
+ \font\hslurufont=xslhu20
+ \font\hslurdfont=xslhd20
+ \font\hslurhfont=xslhz20
+ \font\musicfnt=musix20
+ \font\italicfont=cmti10
+ \balkhoog=20pt
+ \notewidth=6pt
+ \staffrulethickness=0.4pt
+
+ \musixcalc
}
\def\musixsixteendefs{
- \font\textfont=cmr8
- \font\italicfont=cmti8
- \font\slurufont=xslu16
- \font\slurdfont=xsld16
- \font\slurhfont=xslz20 % sigh
- \font\hslurufont=xslhu16
- \font\hslurdfont=xslhd16
- \font\hslurhfont=xslhz20
- \font\musicfnt=musix16
- \balkhoog=16pt
- \staffrulethickness=0.4pt
- \notewidth=5pt
- \musixcalc
+ \font\textfont=cmr8
+ \font\meterfont=cmbx12
+ \font\italicfont=cmti8
+ \font\slurufont=xslu16
+ \font\slurdfont=xsld16
+ \font\slurhfont=xslz20 % sigh
+ \font\hslurufont=xslhu16
+ \font\hslurdfont=xslhd16
+ \font\hslurhfont=xslhz20
+ \font\musicfnt=musix16
+ \balkhoog=16pt
+ \staffrulethickness=0.4pt
+ \notewidth=5pt
+ \musixcalc
}
\def\musixcalc{
- \interstaffrule=\balkhoog
- \advance\interstaffrule by-\staffrulethickness
- \divide\interstaffrule by 4
- \advance\interstaffrule by -\staffrulethickness
- \notewidthhalf=\notewidth
- \notewidthdouble=\notewidth
- \divide \notewidthhalf by 2
- \multiply \notewidthdouble by 2
+ \interstaffrule=\balkhoog
+ \advance\interstaffrule by-\staffrulethickness
+ \divide\interstaffrule by 4
+ \advance\interstaffrule by -\staffrulethickness
+ \notewidthhalf=\notewidth
+ \notewidthdouble=\notewidth
+ \divide \notewidthhalf by 2
+ \multiply \notewidthdouble by 2
+ \balkhalf=\balkhoog
+ \divide \balkhalf by 2
}
\def\maatstreep{\vrule height\balkhoog}
\def\finishbar{\vrule height\balkhoog width 1pt}
-\def\generalmeter#1#2{\vbox to 0pt{\vss\textfont\hbox{#1}\hbox{#2}}}
+\def\generalmeter#1#2{\botalign{\vbox to\balkhalf{\vss \meterfont#1}%
+ \nointerlineskip
+ \vbox to \balkhalf{\vss\meterfont #2}}}
\def\lineseparator{\vbox{\mussepline\vskip -5pt\mussepline}}
\def\beauty{%
- \par\vskip 10pt plus 30pt minus 10pt\par
- \hskip -5pt\lineseparator
- \par\vskip 10pt plus 30pt minus 10pt\par
+ \par\vskip 10pt plus 30pt minus 10pt\par
+ \hskip -5pt\lineseparator
+ \par\vskip 10pt plus 30pt minus 10pt\par
}
\def\interstaffline{%
- \vskip 10pt
+ \vskip 10pt
}
\def\ugly{\nointerlineskip\par
\vskip 40pt\par\vbox{\leftalign{\vrule width30pt height1pt}}\par\vskip 40pt
\def\lines#1#2{%
\vbox{\kern-\interstaffrule
- \n=0\nointerlineskip%
- \loop\ifnum\n<#1\advance\n by1%
- \kern\interstaffrule
- \hrule height \staffrulethickness width#2
- \repeat
- }}
+ \n=0\nointerlineskip%
+ \loop\ifnum\n<#1\advance\n by1%
+ \kern\interstaffrule
+ \hrule height \staffrulethickness width#2
+ \repeat
+ }}
\def\toplines#1{ % why space needed here?
- \vbox to 0pt{\hbox{\kern-\notewidth\lines{#1}{\notewidthdouble}}\vss}}
+ \topalign{\hbox{\kern-\notewidth\lines{#1}{\notewidthdouble}}}}
\def\botlines#1{ % idem ditto
- \vbox to 0pt{\vss\hbox{\kern-\notewidth\lines{#1}{\notewidthdouble}}}}
+ \botalign{\hbox{\kern-\notewidth\lines{#1}{\notewidthdouble}}}}
%
% a staffsymbol with #1 lines, width #2
% bottom at baseline
-\def\linestafsym#1#2{\leftalign{\vbox to 0pt{\vss\lines{#1}{#2}}}}
-
-\def\vcenter#1{\vbox to 0pt{\vss #1\vss}}
-\def\topalign#1{\vbox to 0pt{#1\vss}}
+\def\linestafsym#1#2{\leftalign{\botalign{\lines{#1}{#2}}}}
\def\eigthflag{\topalign{\ueigthflag}}
\def\sixteenthflag{\topalign{\usixteenthflag}}
\def\ldoubledot{\kern-\notewidth\doubledot}
\def\ltripledot{\kern-\notewidth\tripledot}
-
+\mdef\maccent{30}
+\mdef\fermata{80}
+\mdef\ifermata{81}
+\mdef\iaccent{31}
+\mdef\msxmarcato{20}
+\def\marcato{\botalign{\msxmarcato}}
+\mdef\msximarcato{21}
+\def\imarcato{\topalign{\msximarcato}}
+\mdef\staccato{24}
+\mdef\istaccato{25}
+\mdef\staccatissimo{16}
+\mdef\istaccatissimo{17}
+\mdef\spicato{28}
+\mdef\ispicato{29}
+\mdef\upbow{22}
+\mdef\downbow{23}
+\mdef\portato{26}
\def\stem#1#2{\vrule height#2 depth-#1}
\def\placebox#1#2#3{%
- \vbox to 0pt{\vss\hbox{\raise #1\leftalign{\kern #2{}#3}}}%
+ \botalign{\hbox{\raise #1\leftalign{\kern #2{}#3}}}%
}
\def\settext#1{\textfont #1}
\def\setitalic#1{\italicfont #1}
+\def\vcenter#1{\vbox to 0pt{\vss #1\vss}}
+
+\def\topalign#1{\vbox to 0pt{#1\vss}}
+\def\botalign#1{\vbox to 0pt{\vss #1}}
+
\def\centeralign#1{\hbox to 0pt{\hss#1\hss}}
\def\leftalign#1{\hbox to 0pt{#1\hss}}
\duration {4}
{
- \music { c () `bes c}
- \music { 'fis ()'gisis fis }
- \music { d () d dis }
- \music { a () bes eis }
- \music { fis () g gis }
+ \music { c () `bes [c8 c8] }
+ \music { 'fis ()'gisis fis8 fis8 }
+ \music { d () d dis8 dis8 }
+ \music { a () bes eis8 eis8 }
+ \music { fis () g gis8 gis8 }
}
{ c4 'c4 }
\duration { 8}
% 1
- d2( [)d e cis `b] `a4 [`b cis] [cis `b] `b4
- fis2( [)fis g e d] cis4 [d e(] [)e fis d cis]
- `b4 [cis d(] [)d e cis `b] cis2 r2
- r4 fis2 fis4 fis2()[fis e a fis]
- fis4 e4 d4 e4 `b2()[`b `a( d cis]
+ d2( [)d e cis `b]
+ `a4 [`b cis] [cis `b] `b4
+ fis2( [)fis g e d]
+ cis4 [d e(] [)e fis d cis]
+ `b4 [cis d(] [)d e cis `b]
+ cis2 r2^"c\'edez"
+ r4 fis2 fis4
+ fis2^"en mesure" ()[fis e a fis]
+ fis4-- e4-- d4-- e4--
+ `b2()[`b^"un peu retenu" `a( d cis]
% 11
- )`b [`fis `a `b] cis4 `b4 `fis2 r2
- cis4 d4()[d cis d e]
+ )`b [`fis^"en \'elargissant"-- `a-- `b--] cis4-- `b4--
+ `fis2 r2
+ cis4^"1er mouvement" d4^"tr\`es lontain" ()[d cis d e]
\octave { }
- a4 gis2.
- a4 b4()[b a b 'cis] fis4 e4 cis2
- e4 fis4 () [fis e fis gis] cis4 `b4()`b8 r8 r4
+ a4 gis2.
+ a4 b4()[b a b 'cis]
+ fis4 e4 cis2
+ e4 fis4 () [fis e fis gis]
+ cis4 `b4()`b8 r8 r4^"tr\`es soutenu"
- r4 r4 'cis4 'd4 () ['d 'cis 'd 'e]
- a4 gis2. a4 b4()[b a b 'cis]
- fis4 e4 cis2 e4 fis4()[fis e fis gis]
- cis4 `b4()`b8 r8 r4 r1
- r2 r4 r4
+ r4 r4 %2/4 meter
+
+ 'cis4_"ppp" 'd4 () ['d 'cis 'd 'e]
+ a4 gis2.
+ a4 b4()[b a b 'cis]
+ fis4 e4 cis2
+ e4_"pp" fis4()[fis e fis gis]
+ cis4_"mf" `b4()`b8 r8 r4^"un peu plus lent"
+ r1
+ r2 r4 r4%^\fermata
%% cut 'n paste.
\octave { ' }
- d2( [)d e cis `b] `a4 [`b cis] [cis `b] `b4
- fis2( [)fis g e d] cis4 [d e(] [)e fis d cis]
- `b4 [cis d(] [)d e cis `b] cis2 r2
- r4 fis2 fis4 fis2()[fis e a fis]
- fis4 e4 d4 e4 `b2() [`b `a d cis]
- `b [`fis `a `b] cis4 `b4 `fis2 r2
- $}
+ d2^"Reprenez le mouvement"( [)d e cis `b]
+ `a4 [`b cis] [cis `b] `b4
+ fis2( [)fis g e d]
+ cis4 [d e(] [)e fis d cis]
+ `b4 [cis d(] [)d e cis `b]
+ cis2 r2^"c\'edez"
+ r4 fis2 fis4
+ fis2^"en mesure"()[fis e a fis]
+ fis4-- e4-- d4-- e4--
+ `b2() [`b `a-. d-. cis-.]
+ `b-. [`fis^"large" `a `b] cis4 `b4 `fis2 r2
+ r1
+ \duration {8}
+ r2 [c-.( e-. c-. )`a-. ]
+ \plet {2/3}\octave{}
+ [c e a ] \plet{1/1} b4-> () [b c-- e-- a--]
+ b4. b8()g2
+ r1
+ r2
+ [f a f d]
+ \plet {2/3}
+ [f a 'c] \plet{1/1} 'e4-^ () ['e f-> a-> 'c->]
+ e4._"sf" e8()c4 r4
+ r1
+ r4 r4-\fermata
+ \octave { ' }
+ d2( [)d e cis `b]
+ `a4 [`b cis] [cis `b] `b4
+ fis2( [)fis g e d]
+ cis4 [d e(] [)e fis d cis]
+ `b4 [cis d(] [)d e cis `b]
+ cis2 r2^"c\'edez"
+ r4 fis2 fis4
+ fis2()[fis e a fis]
+ fis4-- e4-- d4-- e4--
+ \octave{ }
+ b2()[b a 'd 'cis]
+ b [fis a b ] 'cis4 b4
+ fis2 r2
+ r1-\fermata
+ $}
commands {
key $fis cis $
}
meter 2 4
skip 1:0
meter 4 4
- skip 20:0
+ skip 29:0
+ meter 2 4
+ skip 1:0
+ meter 4 4
+ skip 13:0
}
}
\ No newline at end of file
{
type = t;
}
-void
-Bar::preprocess()
+Molecule*
+Bar::brew_molecule()const
{
Symbol s = paper()->lookup_->bar(type);
- output = new Molecule(Atom(s));
+Molecule* output = new Molecule(Atom(s));
+return output;
+
}
Offset
Beam::center()const
{
- if(!dir)
- ((Beam*)this)->calculate();
+ assert(status >= POSTCALCED);
+ if (calc_children){ // URGGGG!!!
+ Beam*me_p = (Beam*)this;
+ me_p->do_post_processing();
+ }
Real w=width().length()/2;
return Offset(w,
(left_pos + w* slope)*paper()->interline());
Beam::add(Stem*s)
{
stems.bottom().add(s);
+ s->dependencies.add(this);
s->print_flag = false;
}
{
int dirs[2];
dirs[0]=0; dirs[1] =0;
- for (PCursor<Stem*> sc(stems); sc.ok(); sc++) {
- sc->set_default_dir();
- dirs[(sc->dir+1)/2] ++;
+ for (iter_top(stems,i); i.ok(); i++) {
+ i->set_default_dir();
+ dirs[(i->dir+1)/2] ++;
}
dir = (dirs[0] > dirs[1]) ? -1 : 1;
- for (PCursor<Stem*> sc(stems); sc.ok(); sc++) {
- sc->dir = dir;
+ for (iter_top(stems,i); i.ok(); i++) {
+ i->dir = dir;
}
}
Beam::solve_slope()
{
svec<Stem_info> sinfo;
- for (PCursor<Stem* >sc(stems); sc.ok(); sc++) {
- sc->set_default_extents();
- Stem_info i(sc);
- sinfo.add(i);
+ for (iter_top(stems,i); i.ok(); i++) {
+ i->set_default_extents();
+ Stem_info info(i);
+ sinfo.add(info);
}
Real leftx = sinfo[0].x;
Least_squares l;
left_pos += dy;
left_pos *= dir;
slope *= dir;
-
+
+ // URG
+ Real sl = slope*paper()->internote();
+ paper()->lookup_->beam(sl, convert_dimen(20,"pt"));
+ slope = sl /paper()->internote();
}
void
Beam::set_stemlens()
{
- PCursor<Stem*> s(stems);
+ iter_top(stems,s);
Real x0 = s->hpos();
for (; s.ok() ; s++) {
Real x = s->hpos()-x0;
}
}
-void
-Beam::calculate()
-{
- assert(stems.size()>1);
- if (!dir)
- set_default_dir();
-
- solve_slope();
-}
void
-Beam::process()
+Beam::do_post_processing()
{
- calculate();
-
- brew_molecule();
+ solve_slope();
set_stemlens();
}
group = new Rhythmic_grouping(cur);
svec<int> b;
{
- PCursor<Stem*> s(stems);
+ iter_top(stems,s);
svec<int> flags;
for (; s.ok(); s++) {
int f = intlog2(abs(s->flag))-2;
assert(stems.size() == b.sz()/2);
}
- PCursor<Stem*> s(stems);
+ iter_top(stems,s);
for (int i=0; i < b.sz() && s.ok(); i+=2, s++) {
s->beams_left = b[i];
s->beams_right = b[i+1];
// todo.
Spanner *
-Beam::broken_at( PCol *, PCol *) const
+Beam::do_break_at( PCol *, PCol *) const
{
return new Beam(*this);
}
void
-Beam::preprocess()
+Beam::do_pre_processing()
{
left = (*stems.top()) ->pcol_;
right = (*stems.bottom())->pcol_;
-}
+ assert(stems.size()>1);
+ if (!dir)
+ set_default_dir();
-Interval
-Beam::height() const
-{
- return output->extent().y;
}
+
Interval
Beam::width() const
{
beams to go with one stem.
*/
Molecule
-Beam::stem_beams(Stem *here, Stem *next, Stem *prev)
+Beam::stem_beams(Stem *here, Stem *next, Stem *prev)const
{
assert( !next || next->hpos() > here->hpos() );
assert( !prev || prev->hpos() < here->hpos() );
Real stemdx = paper()->rule_thickness();
Real sl = slope*paper()->internote();
paper()->lookup_->beam(sl, convert_dimen(20,"pt"));
- slope = sl /paper()->internote();
+
Molecule leftbeams;
Molecule rightbeams;
}
-void
-Beam::brew_molecule()
+Molecule*
+Beam::brew_molecule() const return out;
{
assert(left->line == right->line);
Real inter=paper()->internote();
- output = new Molecule;
+ out = new Molecule;
Real x0 = stems.top()->hpos();
- for (PCursor<Stem*> i(stems); i.ok(); i++) {
+ for (iter_top(stems,i); i.ok(); i++) {
PCursor<Stem*> p(i-1);
PCursor<Stem*> n(i+1);
Stem * prev = p.ok() ? p.ptr() : 0;
Molecule sb = stem_beams(i, next, prev);
Real x = i->hpos()-x0;
sb.translate(Offset(x, (x * slope + left_pos)* inter));
- output->add(sb);
+ out->add(sb);
}
- output->translate(Offset(x0 - left->hpos,0));
+ out->translate(Offset(x0 - left->hpos,0));
}
void
do calculations for breaking problem
*/
+#include "break.hh"
#include "paper.hh"
#include "linespace.hh"
#include "debug.hh"
#include "scoreline.hh"
#include "pscore.hh"
+
+/*
+ return all breakable columns
+ */
+svec<PCol *>
+Break_algorithm::find_breaks() const
+{
+ svec<PCol *> retval;
+ for (iter_top(pscore_.cols,c); c.ok(); c++)
+ if (c->breakable())
+
+
+ retval.add(c);
+
+ return retval;
+}
+
// construct an appropriate Spacing_problem and solve it.
svec<Real>
-PScore::solve_line(svec< PCol *> curline) const
+Break_algorithm::solve_line(Line_of_cols curline) const
{
Spacing_problem sp;
sp.add_column(curline[0], true, 0.0);
for (int i=1; i< curline.sz()-1; i++)
sp.add_column(curline[i]);
- sp.add_column(curline.last(), true, paper_->linewidth);
+ sp.add_column(curline.last(), true, linelength);
// misschien moeven uit Spacing_problem?
- for (PCursor<Idealspacing *> i(suz); i.ok(); i++) {
+ for (iter_top(pscore_.suz,i); i.ok(); i++) {
sp.add_ideal(i);
}
svec<Real> the_sol=sp.solve();
return the_sol;
}
+Break_algorithm::Break_algorithm(PScore&s)
+ :pscore_(s)
+{
+ linelength = s.paper_->linewidth;
+}
+
bool
-PScore::feasible(svec< PCol *> curline) const
+Break_algorithm::feasible(Line_of_cols curline) const
{
Real l =0;
for (int i=0; i < curline.sz(); i++)
l +=curline[i]->width().length();
- return l < paper_->linewidth;
+ return l < linelength;
}
void
-PScore::problem_OK() const
+Break_algorithm::problem_OK() const
{
- if (!cols.size())
- error("PScore::problem_OK(): Score does not have any columns");
- PCursor<PCol *> start(cols);
- PCursor<PCol *> end (((PScore*)this)->cols.bottom());
+ if (!pscore_.cols.size())
+ error("Score does not have any columns");
+#ifndef NDEBUG
+ iter_top(pscore_.cols,start);
+ PCursor<PCol *> end (pscore_.cols.bottom());
assert(start->breakable());
assert(end->breakable());
+#endif
}
-struct Col_configuration {
- svec< PCol*> line;
- svec<Real> config;
- Real energy;
-
- Col_configuration() {
- energy = INFTY;
- }
- void add( PCol*c) { line.add(c);}
- void setsol(svec<Real> sol) {
- config = sol;
- energy = config.last();
- config.pop();
- }
- void print() const {
-#ifndef NPRINT
- mtor << "energy : " << energy << '\n';
- mtor << "line of " << config.sz() << " cols\n";
-#endif
- }
-};
+/****************/
-/// wordwrap type algorithm
-/* el stupido. This should be done more accurately:
+Col_configuration::Col_configuration()
+{
+ energy = INFTY;
+}
- It would be nice to have a Dynamic Programming type of algorithm
- similar to TeX's
-
- */
+void
+Col_configuration::add( PCol*c)
+{
+ cols.add(c);
+}
void
-PScore::calc_breaking()
+Col_configuration::setsol(svec<Real> sol)
{
- OK();
- problem_OK();
- PCursor<PCol *> curcol(cols);
-
- svec<PCol *> breakpoints(find_breaks());
- assert(breakpoints.sz()>=2);
- for (int i=0 ; i < breakpoints.sz() -1; ) {
- Col_configuration minimum;
- Col_configuration current;
-
- // do another line
- PCol *post = breakpoints[i]->postbreak;
- current.add( post);
- curcol++; // skip the breakable.
- i++;
-
- while (i < breakpoints.sz()) {
-
- // add another measure.
- while (breakpoints[i] != curcol.ptr()){
-
- current.add(curcol);
- curcol++;
- }
- current.add(breakpoints[i]->prebreak );
- if (!feasible(current.line)) {
- if (!minimum.line.sz())
- error("sorry, this measure is too long");
- break;
- }
- current.setsol(solve_line(current.line));
- current.print();
-
- if (current.energy < minimum.energy) {
- minimum = current;
- } else { // we're one col too far.
- i--;
- while (curcol.ptr() != breakpoints[i])
- curcol --;
-
- break;
- }
-
- current.line.last()=breakpoints[i];
- curcol ++;
- i++;
- }
- mtor << "Adding line, next breakpoint " << i << '\n';
- add_line(minimum.line, minimum.config);
- }
+ config = sol;
+ energy = config.last();
+ config.pop();
}
+void
+Col_configuration::print() const
+{
+#ifndef NPRINT
+ mtor << "energy : " << energy << '\n';
+ mtor << "line of " << config.sz() << " cols\n";
+#endif
+}
+void
+Col_configuration::OK()const
+{
+ assert(config.sz() == cols.sz());
+}
+#include "idealspacing.hh"
#include "tstream.hh"
#include "score.hh"
#include "pscore.hh"
void
Score::calc_idealspacing()
{
- PCursor<Score_column*> i(cols_);
+ iter_top(cols_,i);
for (; i.ok(); i++) {
assert(i->used());
- PCursor<Score_column*> j (i+1);
+ PCursor<Score_column*> j(i+1);
if (i->musical) {
assert(j.ok());
for (int n=0; n < i->durations.sz(); n++) {
read(k.clef_type);
}
-void
-Clef_item::preprocess()
+Molecule*
+Clef_item::brew_molecule()const
{
String t = type;
if (change)
t += "_change";
Symbol s = paper()->lookup_->clef(t);
- output = new Molecule(Atom(s));
+ Molecule*output = new Molecule(Atom(s));
output->translate(Offset(0, paper()->interline()/2 * y_off));
+ return output;
}
#include "grouping.hh"
#include "interval.hh"
+void
+Rhythmic_grouping::init()
+{
+ interval_ = 0;
+ children.set_size(0);
+}
+
void
Rhythmic_grouping::OK()const
{
}
return r;
}
-
-Rhythmic_grouping::Rhythmic_grouping(MInterval t, int n)
-{
- if (n == 1 || !n) {
- interval_ = new MInterval(t);
- return;
- }
- Moment dt = t.length()/n;
- MInterval basic = MInterval(t.left, t.left+dt);
- for (int i= 0; i < n; i++)
- children.add(new Rhythmic_grouping( dt*i + basic ));
-}
-
void
Rhythmic_grouping::intersect(MInterval t)
{
children = ch;
}
+
+Rhythmic_grouping::Rhythmic_grouping(MInterval t, int n)
+{
+ init();
+ if (n == 1 || !n) {
+ interval_ = new MInterval(t);
+ return;
+ }
+ Moment dt = t.length()/n;
+ MInterval basic = MInterval(t.left, t.left+dt);
+ for (int i= 0; i < n; i++)
+ children.add(new Rhythmic_grouping( dt*i + basic ));
+}
+
+
Rhythmic_grouping::Rhythmic_grouping(svec<Rhythmic_grouping*> r)
:children(r)
{
Rhythmic_grouping::~Rhythmic_grouping()
{
junk();
+
}
void
Rhythmic_grouping::Rhythmic_grouping(Rhythmic_grouping const&s)
{
+ init();
copy(s);
}
Rhythmic_grouping::junk()
{
delete interval_;
- interval_ = 0;
for (int i=0; i < children.sz(); i++)
delete children[i];
- children.set_size(0);
+ init();
}
void
+#include "idealspacing.hh"
#include "pcol.hh"
#include "pscore.hh"
#include "pstaff.hh"
#include "debug.hh"
void
-Identifier::error()
+Identifier::error(String expect)
{
String e("Wrong identifier type: ");
- ::error(e + classname());
+ e += String(classname()) + "(expected " + expect + ")";
+ ::error(e);
}
#ifndef NPRINT
mtor << "Commands_at {";
tdescription_.print();
- for (PCursor<Input_command *> cc(*this); cc.ok(); cc++)
+ for (iter_top(*this,cc); cc.ok(); cc++)
cc->print();
mtor << "}\n";
#endif
Commands_at::parse(Staff_commands_at*s)
{
s->tdescription_ = tdescription_;
- for (PCursor<Input_command *> cc(*this); cc.ok(); cc++) {
+ for (iter_top(*this,cc); cc.ok(); cc++) {
if (cc->args.sz() && cc->args[0] !="") {
Command c = **cc;
s->add(c);
print();
Staff_commands*nc = new Staff_commands;
- for (PCursor<Commands_at*> i(*this); i.ok(); i++) {
+ for (iter_top(*this,i); i.ok(); i++) {
Staff_commands_at* s= nc->find(i->when());
if (!s){
Input_commands::print() const
{
#ifndef NPRINT
- for (PCursor<Commands_at*> cc(*this); cc.ok() ; cc++) {
+ for (iter_top(*this,cc); cc.ok() ; cc++) {
cc->print();
}
#endif
void
Complex_music::print() const
{
- for (PCursor<Input_music*> i(elts); i.ok(); i++)
+ for (iter_top(elts,i); i.ok(); i++)
i->print();
}
void
Complex_music::concatenate(Complex_music*h)
{
- for (PCursor<Input_music*> i(h->elts); i.ok(); i++)
+ for (iter_top(h->elts,i); i.ok(); i++)
add(i->clone());
}
Complex_music::Complex_music(Complex_music const&s)
{
- for (PCursor<Input_music*> i(s.elts); i.ok(); i++)
+ for (iter_top(s.elts,i); i.ok(); i++)
add(i->clone());
}
{
Moment l = 0.0;
- for (PCursor<Input_music*> i(elts); i.ok(); i++)
+ for (iter_top(elts,i); i.ok(); i++)
l += i->length();
return l;
}
Voice_list l;
Moment here = 0.0;
- for (PCursor<Input_music*> i(elts); i.ok(); i++) {
+ for (iter_top(elts,i); i.ok(); i++) {
Moment len = i->length();
Voice_list k(i->convert());
k.translate_time(here);
l.concatenate(k);
- here +=len;
-
+ here +=len;
}
return l;
}
void
Music_general_chord::translate_time(Moment t)
{
- for (PCursor<Input_music*> i(elts); i.ok(); i++)
+ for (iter_top(elts,i); i.ok(); i++)
i->translate_time(t);
}
{
Moment l =0.0;
- for (PCursor<Input_music*> i(elts); i.ok(); i++)
+ for (iter_top(elts,i); i.ok(); i++)
l = l >? i->length();
return l;
}
Music_general_chord::convert()
{
Voice_list l;
- for (PCursor<Input_music*> i(elts); i.ok(); i++) {
+ for (iter_top(elts,i); i.ok(); i++) {
Voice_list k(i->convert());
l.concatenate(k);
}
void
Voice_list::translate_time(Moment x)
{
- for (PCursor<Voice*> i(*this); i.ok(); i++)
+ for (iter_top(*this,i); i.ok(); i++)
i->start += x;
}
Paperdef* p=new Paperdef(*paper_);
Score *s = new Score(p);
- for (PCursor<Input_staff*> i(staffs_); i.ok(); i++) {
+ for (iter_top(staffs_,i); i.ok(); i++) {
Staff* staf=i->parse(commands_);
s->add(staf);
}
Input_score::print()const
{
mtor << "Input_score {\n";
- for (PCursor<Input_staff*> i(staffs_); i.ok(); i++) {
+ for (iter_top(staffs_,i); i.ok(); i++) {
i->print();
}
mtor << "}\n";
else if (type == "rhythmic")
p = new Rhythmic_staff;
- for (PCursor<Input_music*> i(music_); i.ok(); i++) {
+ for (iter_top(music_,i); i.ok(); i++) {
Voice_list vl = i->convert();
p->add(vl);
}
Input_commands commands;
- for (PCursor<Input_command*> i(score_wide); i.ok(); i++)
+ for (iter_top(score_wide,i); i.ok(); i++)
commands.add(**i);
- for (PCursor<Input_command*> i(commands_); i.ok(); i++)
+ for (iter_top(commands_,i); i.ok(); i++)
commands.add(**i);
p->staff_commands_ = commands.parse();
Input_staff::Input_staff(Input_staff&s)
{
- for (PCursor<Input_command*> i(s.commands_); i.ok(); i++)
+ for (iter_top(s.commands_,i); i.ok(); i++)
commands_.bottom().add(new Input_command(**i));
- for (PCursor<Input_music*> i(s.music_); i.ok(); i++)
+ for (iter_top(s.music_,i); i.ok(); i++)
add(i);
type = s.type;
{
#ifndef NPRINT
mtor << "Input_staff {\n";
- for (PCursor<Input_command*> i(commands_); i.ok(); i++)
+ for (iter_top(commands_,i); i.ok(); i++)
i->print();
- for (PCursor<Input_music*> i(music_); i.ok(); i++)
+ for (iter_top(music_,i); i.ok(); i++)
i->print();
mtor << "}\n";
#endif
-#include "pstaff.hh"
-#include "pscore.hh"
-#include "symbol.hh"
-#include "molecule.hh"
-#include "pcol.hh"
-
-void
-Item::translate(Offset O)
-{
- offset_ += O;
-}
-
-void
-Item::postprocess()
-{
- // default: do nothing
-}
-
-
-void
-Item::preprocess()
-{
- // default: do nothing
-}
-
-String
-Item::TeXstring() const
-{
- Item * me = (Item*) this;
- output->translate(offset_); // ugh?
- me ->offset_ = Offset(0,0); // URRGGH!
- return output->TeXstring();
-}
-
-Interval
-Item::width() const
-{
- Interval i =output->extent().x ;
- if (!i.empty()) // float exception on DEC Alpha
- i+=offset_.x;
- return i;
-}
-
-Interval
-Item::height() const
-{
- Interval i =output->extent().y;
- return i+=offset_.y;
-}
-
-Item::~Item()
-{
- delete output;
-}
+#include "debug.hh"
+#include "item.hh"
Item::Item()
{
pcol_ = 0;
- output = 0;
- pstaff_ = 0;
}
+
void
Item::print() const
{
#ifndef NPRINT
- if (output)
- output->print();
+ mtor << "item " ;
+ Staff_elem::print();
#endif
-}
-Paperdef*
-Item::paper() const
-{
- assert(pstaff_);
- return pstaff_->pscore_->paper_;
}
add(note, acc);
}
}
+
void
Keyitem::add(int p, int a)
{
acc.add(a);
}
-void
-Keyitem::preprocess()
-{
- brew_molecole();
-}
-void
-Keyitem::brew_molecole()
+Molecule*
+Keyitem::brew_molecule()const
{
- output = new Molecule;
+ Molecule*output = new Molecule;
Real inter = paper()->interline()/2;
for (int i =0; i < pitch.sz(); i++) {
Molecule m(paper()->lookup_->fill(Box(
Interval(0, paper()->note_width()),
Interval(0,0))));
- output->add_right(m);
+ output->add_right(m);
+ return output;
}
}
<notes>\| {
}
-<notes>[:space:]+ {
-}
<notes>[%#].*\n {
}
yylval.c = YYText()[0];
return CLOSE_REQUEST_PARENS;
}
+<notes>\"[^\"]*\" {
+ String s (YYText()+1);
+ s = s.left(s.len()-1);
+ yylval.string = new String(s);
+ return STRING;
+}
+<notes>[/.^>_-] {
+ return yylval.c = YYText()[0];
+}
<notes>. {
String s("lexer error: illegal character found: " + String(YYText()));
yyerror(s);
yylval.string = new String (YYText());
}
<quote>\" {
+ mtor << "quoted string\n";
BEGIN(INITIAL);
return STRING;
}
is = new ifstream( s );
if ( ! *is) {
- String e("cant open " + s);
+ String e("can\'t open `" + s+"\'");
error(e);
}
cout << "["<<s<<flush;
#include <math.h>
#include "linespace.hh"
+#include "pcol.hh"
#include "debug.hh"
#include "qlp.hh"
#include "unionfind.hh"
+#include "idealspacing.hh"
const Real COLFUDGE=1e-3;
+
//#define COLFUDGE 1e-3
bool
Spacing_problem::contains(const PCol *w)
connected.connect(l,r);
}
for (int i = 0; i < cols.sz(); i++)
- if (cols[i].fixed)
+ if (cols[i].fixed())
fixed.add(i);
for (int i = 0; i < cols.sz(); i++) {
bool c=false;
// mtor << "checking solution " << v << '\n';
for (int i=0; i < dim; i++) {
- if (cols[i].fixed&& abs(cols[i].fixpos - v(i)) > COLFUDGE) {
+ if (cols[i].fixed()&& abs(cols[i].fixed_position() - v(i)) > COLFUDGE) {
return false;
}
if (!i)
int dim=cols.sz();
Vector initsol(dim);
for (int i=0; i < dim; i++) {
- if (cols[i].fixed) {
- initsol(i)=cols[i].fixpos;
+ if (cols[i].fixed()) {
+ initsol(i)=cols[i].fixed_position();
} else {
Real mindist=cols[i-1].minright()
+cols[i].minleft();
assert(check_constraints(v));
return v;
}
+
// generate the matrices
void
Spacing_problem::make_matrices(Matrix &quad, Vector &lin, Real &c) const
int dim=cols.sz();
for (int j=0; j < dim; j++) {
Colinfo *c=&(cols[j]);
- if (c->fixed) {
- lp.add_fixed_var(j,c->fixpos);
+ if (c->fixed()) {
+ lp.add_fixed_var(j,c->fixed_position());
}
if (j > 0){
Vector c1(dim);
-
c1(j)=1.0 ;
c1(j-1)=-1.0 ;
lp.add_inequality_cons(c1, cols[j-1].minright() +
void
Spacing_problem::add_column(const PCol *col, bool fixed, Real fixpos)
{
- Colinfo c;
- c.fixed=fixed;
- c.fixpos=fixpos;
- assert(col);
- c.pcol_=col;
+ Colinfo c(col,(fixed)? &fixpos : 0);
cols.add(c);
}
}
+/*****************/
+
void
Colinfo::print() const
{
#ifndef NPRINT
mtor << "column { ";
- if (fixed)
- mtor << "fixed at " << fixpos<<", ";
+ if (fixed())
+ mtor << "fixed at " << fixed_position()<<", ";
assert(pcol_);
mtor << "[" << minleft() << ", " << minright() << "]";
mtor <<"}\n";
#endif
}
+Colinfo::Colinfo(Colinfo const&c)
+{
+ fixpos = (c.fixpos)?new Real(*c.fixpos):0;
+ pcol_ = c.pcol_;
+ width = c.width;
+}
+
+Colinfo::Colinfo(const PCol*col_p, const Real*fixed_r_p )
+{
+ fixpos = (fixed_r_p)? new Real(*fixed_r_p) : 0;
+ pcol_ = col_p;
+ width = pcol_->width();
+}
+
+Colinfo::~Colinfo()
+{
+ delete fixpos;
+}
+
Colinfo::Colinfo()
{
- fixed=false;
pcol_=0;
+ fixpos = 0;
+}
+void
+Colinfo::operator=(Colinfo const&c )
+{
+ delete fixpos;
+ fixpos = (c.fixpos)?new Real(*c.fixpos):0;
+ pcol_ = c.pcol_;
+ width = c.width;
}
#include "scalar.hh"
#include "lookup.hh"
#include "paper.hh"
-
+#include "notehead.hh"
Local_key_item::Local_key_item(int i)
{
c0_position = i;
}
void
-Local_key_item::add (int o, int p , int a)
+Local_key_item::add (int o, int p , int a,Notehead*head_p)
{
Local_acc l;
l.octave = o;
l.name = p;
l.acc = a;
accs.add(l);
+ group.add(head_p);
+ dependencies.add(head_p);
}
void
-Local_key_item::preprocess()
+Local_key_item::do_pre_processing()
{
- brew_molecole();
+ accs.sort(Local_acc::compare);
}
-
-void
-Local_key_item::brew_molecole()
+Molecule*
+Local_key_item::brew_molecule()const
{
- accs.sort(Local_acc::compare);
- output = new Molecule;
+ Molecule* output = new Molecule;
Molecule*octmol = 0;
int lastoct = -100;
for (int i = 0; i < accs.sz(); i++) {
output->add(*octmol);
delete octmol;
}
+ return output;
}
int
{
svec<String> a;
- a.add((*symtables_)("style")->lookup(style).tex);
- Symbol s = (*symtables_)("align")->lookup(dir);
- a[0] = substitute_args( text,a);
+ a.add(text);
+ Symbol tsym = (*symtables_)("style")->lookup(style);
+ a[0] = substitute_args(tsym.tex,a);
+ Symbol s = (*symtables_)("align")->lookup(dir);
s.tex = substitute_args(s.tex,a);
+ s.dim.y = tsym.dim.y;
return s;
}
return (*symtables_)("bars")->lookup(s);
}
+Symbol
+Lookup::script(String s)
+{
+ return (*symtables_)("scripts")->lookup(s);
+}
+
Symbol
Lookup::clef(String s)
{
{
}
-void
-Meter::preprocess()
+Molecule*
+Meter::brew_molecule()const
{
Symbol s = paper()->lookup_->meter(args);
- output = new Molecule(Atom(s));
+return new Molecule(Atom(s));
}
-#include "glob.hh"
#include "vray.hh"
#include "interval.hh"
#include "dimen.hh"
Molecule::TeXstring() const
{
String s;
- for(PCursor<Atom*> c(ats); c.ok(); c++)
+ for(iter_top(ats,c); c.ok(); c++)
s+=c->TeXstring();
return s;
}
Molecule::extent() const
{
Box b;
- for(PCursor<Atom*> c(ats); c.ok(); c++)
+ for(iter_top(ats,c); c.ok(); c++)
b.unite(c->extent());
return b;
}
void
Molecule::translate(Offset o)
{
- for (PCursor<Atom*> c(ats); c.ok(); c++)
+ for (iter_top(ats,c); c.ok(); c++)
c->translate(o);
}
void
Molecule::add(const Molecule &m)
{
- for (PCursor<Atom*> c(m.ats); c.ok(); c++) {
+ for (iter_top(m.ats,c); c.ok(); c++) {
add(**c);
}
}
void
Molecule::print() const
{
- for (PCursor<Atom*> c(ats); c.ok(); c++)
+ for (iter_top(ats,c); c.ok(); c++)
c->print();
}
"output", OUTPUT,
"partial", PARTIAL,
"paper", PAPER,
+ "plet", PLET,
"pt", PT,
"rhythmic", RHYTHMIC,
"score", SCORE,
+ "script", SCRIPT,
"skip", SKIP,
"staff", STAFF,
"start", START_T,
"symboltables", SYMBOLTABLES,
"notenames", NOTENAMES,
"texid", TEXID,
+ "textstyle", TEXTSTYLE,
"chord", CHORD,
"multi", MULTI,
"unitspace", UNITSPACE,
#include <ctype.h>
-
+#include "lexer.hh"
#include "string.hh"
#include "real.hh"
#include "debug.hh"
#include "request.hh"
#include "voice.hh"
#include "notename.hh"
+#include "identparent.hh"
#include "vray.hh"
+#include "textdef.hh"
int default_duration = 4, default_dots=0, default_octave=0;
+int default_plet_type = 1, default_plet_dur = 1;
+String textstyle="roman"; // in lexer?
+
+/* triplet is '2/3' */
+void set_plet(int num,int den)
+{
+ assert(num >0&& den>0);
+ default_plet_dur = num;
+ default_plet_type = den;
+}
+
+Text_def*
+get_text(String s) return t;
+{
+ t= new Text_def;
+ t->text= s;
+ t->style = textstyle;
+ return t;
+}
+
+void
+set_text_style(String s)
+{
+ textstyle = s;
+}
void
parse_octave (const char *a, int &j, int &oct)
rq->forceacc = forceacc;
rq->balltype = dur;
rq->dots = dots;
-
+ rq->plet_factor = Moment(default_plet_dur, default_plet_type);
rq->print();
v->add(rq);
Voice_element*v = new Voice_element;
Rest_req * rq = new Rest_req;
-
+ rq->plet_factor = Moment(default_plet_dur, default_plet_type);
rq->balltype = duration[0];
rq->dots = duration[1];
rq->print();
switch (c) {
case '[':
case ']':
- ret = new Beam_req;
+ {
+ Beam_req*b = new Beam_req;
+ if (default_plet_type != 1)
+ b->nplet = default_plet_type;
+ ret = b;
+ }
break;
case ')':
}
req.set_size(0);
}
+
+Script_def*
+get_scriptdef(char c)
+{
+ String s;
+ switch (c) {
+ case '^' : s = "marcato";
+ break;
+ case '+' : s = "stopped";
+ break;
+ case '-' : s = "portato";
+ break;
+ case '|': s = "staccatissimo";
+ break;
+ case 'o' : s = "";
+ break;
+ case '>' : s = "accent";
+ break;
+ case 'v' : s = "";
+ break;
+ case '.' : s = "staccato";
+ break;
+ }
+ return lexer->lookup_identifier(s)->script(1);
+}
+
+Request*
+get_script_req(int d , Script_def*def)
+{
+ return new Script_req(d, def);
+}
+
+
+Request*
+get_text_req(int d , Text_def*def)
+{
+ return new Text_req(d, def);
+}
+
#include "misc.hh"
-
#include "notehead.hh"
#include "dimen.hh"
#include "debug.hh"
#endif
}
-void
-Notehead::preprocess()
-{
- brew_molecole();
-}
int
Notehead::compare(Notehead*&a, Notehead*&b)
return a->position - b->position;
}
-void
-Notehead::brew_molecole()
+Molecule*
+Notehead::brew_molecule() const return out;
{
- assert(pstaff_);
- assert(!output);
-
Paperdef *p = paper();
Real dy = p->internote();
Symbol s = p->lookup_->ball(balltype);
- output = new Molecule(Atom(s));
+ out = new Molecule(Atom(s));
if (dots) {
Symbol d = p->lookup_->dots(dots);
Molecule dm;
dm.add(Atom(d));
if (!(position %2))
dm.translate(Offset(0,dy));
- output->add_right(dm);
+ out->add_right(dm);
}
- output->translate(Offset(x_dir * p->note_width(),0));
+ out->translate(Offset(x_dir * p->note_width(),0));
bool streepjes = (position<-1)||(position > staff_size+1);
if (streepjes) {
int dir = sign(position);
sm.add(Atom(str));
if (position % 2)
sm.translate(Offset(0,-dy* dir));
- output->add(sm);
+ out->add(sm);
}
- output->translate(Offset(0,dy*position));
+ out->translate(Offset(0,dy*position));
}
#include "misc.hh"
#include "lexer.hh"
#include "paper.hh"
-#include "inputstaff.hh"
#include "inputscore.hh"
-#include "inputmusic.hh"
#include "main.hh"
#include "keyword.hh"
#include "inputcommand.hh"
Interval *interval;
Box *box;
Notename_tab *notename_tab;
+ Script_def * script;
+ Text_def * textdef;
}
%token VOICE STAFF SCORE TITLE BAR NOTENAME OUTPUT
%token GEOMETRIC START_T DURATIONCOMMAND OCTAVECOMMAND
%token KEY CLEF VIOLIN BASS MULTI TABLE CHORD VOICES
%token PARTIAL RHYTHMIC MELODIC MUSIC GROUPING
-%token END SYMBOLTABLES TEXID TABLE NOTENAMES
+%token END SYMBOLTABLES TEXID TABLE NOTENAMES SCRIPT TEXTSTYLE PLET
%token <id> IDENTIFIER
%token <string> NEWIDENTIFIER
%type <intvec> int_list
%type <commandvec> score_commands_block score_commands_body
%type <commandvec> staff_commands_block staff_commands_body
-%type <request> post_request pre_request
+%type <request> post_request pre_request
%type <string> clef_id pitchmod
%type <music> music
%type <chord> music_chord music_chord_body
%type <lookup> symtables symtables_body
%type <symbol> symboldef
%type <notename_tab> notename_tab notename_tab_body
+%type <i> script_dir
+%type <script> script_definition script_body mudela_script
+%type <request> script_req textscript_req
+%type <textdef> mudela_text
+
%%
$$ = new M_voice_id(*$1, $3);
delete $1;
}
+ | declarable_identifier '=' script_definition {
+ $$ = new Script_id(*$1, $3);
+ delete $1;
+ }
| declarable_identifier '=' music_chord {
$$ = new M_chord_id(*$1, $3);
delete $1;
post_request:
CLOSE_REQUEST_PARENS { $$ = get_request($1); }
+ | script_req
+ | textscript_req
+ ;
+
+script_definition:
+ SCRIPT '{' script_body '}' { $$ = $3; }
+ ;
+
+script_body:
+ STRING int int int {
+ $$ = new Script_def(*$1,$2, $3,$4);
+ delete $1;
+ }
+ ;
+
+textscript_req:
+ script_dir mudela_text { $$ = get_text_req($1,$2); }
+ ;
+
+mudela_text:
+ STRING { $$ = get_text(*$1); delete $1; }
+ ;
+
+script_req:
+ script_dir mudela_script { $$ = get_script_req($1, $2); }
+ ;
+
+mudela_script:
+ IDENTIFIER { $$ = $1->script(true); }
+ | script_definition { $$ = $1; }
+ | '^' { $$ = get_scriptdef('^'); }
+ | '+' { $$ = get_scriptdef('+'); }
+ | '-' { $$ = get_scriptdef('-'); }
+ | '|' { $$ = get_scriptdef('|'); }
+ | 'o' { $$ = get_scriptdef('o'); }
+ | '>' { $$ = get_scriptdef('>'); }
+ | '.' { $$ = get_scriptdef('.'); }
+ | DOTS {
+ if ($1>1) error("too many staccato reqs");
+ $$ = get_scriptdef('.');
+ }
+ ;
+
+script_dir:
+ '_' { $$ = -1; }
+ |'^' { $$ = 1; }
+ |'-' { $$ = 0; }
;
pre_requests:
voice_command:
- DURATIONCOMMAND '{' duration '}' {
+ PLET '{' INT '/' INT '}' {
+ set_plet($3,$5);
+ }
+ | DURATIONCOMMAND '{' duration '}' {
set_default_duration($3);
}
| OCTAVECOMMAND '{' pitchmod '}' {
set_default_octave(*$3);
delete $3;
}
+ | TEXTSTYLE STRING {
+ set_text_style(*$2);
+ delete $2;
+ }
;
duration: {
Paperdef*
default_paper()
{
- return new Paperdef(lexer->lookup_identifier("default_table")->lookup(true));
+ return new Paperdef(
+ lexer->lookup_identifier("default_table")->lookup(true));
}
{
Interval w;
- for (PCursor<const Item *> ic(its); ic.ok(); ic++)
- w.unite(ic->width());
+ for (iter_top(its,i); i.ok(); i++)
+ w.unite(i->width());
if (w.empty())
w.unite(Interval(0,0));
return w;
}
+
int
PCol::rank() const
{
-// utility functions for PScore
+#include "idealspacing.hh"
#include "debug.hh"
#include "lookup.hh"
#include "spanner.hh"
#include "scoreline.hh"
#include "pscore.hh"
#include "tstream.hh"
+#include "item.hh"
+
+
+Idealspacing*
+PScore::get_spacing(PCol*l, PCol*r)
+{
+ assert(l!=r);
+ for (iter_top(suz,ic); ic.ok(); ic++) {
+ if (ic->left == l && ic->right == r){
+ return ic;
+ }
+ }
+
+ Idealspacing*ip =new Idealspacing(l,r);
+ suz.bottom().add(ip);
+
+ return ip;
+}
void
PScore::clean_cols()
{
- for (PCursor<PCol *> c(cols); c.ok(); )
+ for (iter_top(cols,c); c.ok(); )
if (!c->used()) {
c.del();
} else
c->add(i);
/* first do this, because i->width() may follow the 0-pointer */
- i->preprocess();
-
-
- if (0 && c->daddy && c == c->daddy->prebreak) { // makeshift.
-
- Interval iv (i->width());
- if (!iv.empty()) {
- svec<Item*> col_its (select_items(s, c));
- for (int j =0; j < col_its.sz(); j++)
- col_its[j]->translate(Offset(-iv.length(),0));
- i->translate (Offset(-iv.right, 0));
- }
- }
-
-}
-
-void
-PScore::typeset_spanner(Spanner*sp, PStaff*ps)
-{
- sp->preprocess();
- sp->pstaff_ = ps;
- spanners.bottom().add(sp);
- ps->spans.bottom().add(sp);
- // do not init start/stop fields. These are for broken spans only.
+ i->add_processing();
}
-
void
-PScore::add_line(svec< PCol *> curline, svec<Real> config)
-{
- Line_of_score *p = new Line_of_score(curline,this);
- lines.bottom().add(p);
- for (int i=0; i < curline.sz(); i++){
- PCol *c=(PCol *)curline[i]; // so, this isn't really const.
- c->hpos = config[i];
- }
-}
-
-Idealspacing*
-PScore::get_spacing(PCol*l, PCol*r)
+PScore::typeset_spanner(Spanner*span_p, PStaff*ps)
{
- assert(l!=r);
- for (PCursor<Idealspacing*> ic (suz); ic.ok(); ic++) {
- if (ic->left == l && ic->right == r){
- return ic;
- }
- }
-
- Idealspacing*ip =new Idealspacing(l,r);
- suz.bottom().add(ip);
+ span_p->pstaff_ = ps;
+ spanners.bottom().add(span_p);
+ ps->spans.bottom().add(span_p);
- return ip;
+ // do not init start/stop fields. These are for broken spans only.
+ span_p->add_processing();
}
return ac - bc;
}
-/*
- return all breakable columns
- */
-svec< PCol *>
-PScore::find_breaks() const
-{
- svec< PCol *> retval;
- for (PCursor<PCol *> c(cols); c.ok(); c++)
- if (c->breakable())
- retval.add(c);
-
- return retval;
-}
-
void
PScore::add(PCol *p)
{
int l=1;
ts << "\n "<< paper_->lookup_->texsetting << "%(Tex id)\n";
- for (PCursor<Line_of_score*> lic(lines); lic.ok(); lic++) {
+ for (iter_top(lines,lic); lic.ok(); lic++) {
ts << "% line of score no. " << l++ <<"\n";
ts << lic->TeXstring();
if ((lic+1).ok())
{
svec<Item*> ret;
assert(ps && pc);
- for (PCursor<const Item*> ic(pc->its); ic.ok(); ic++){
- if (ic->pstaff_ == ps)
- ret.add((Item*)(const Item*)ic);
+ for (iter_top(pc->its,i); i.ok(); i++){
+ if (i->pstaff_ == ps)
+ ret.add((Item*)(const Item*)i);
}
return ret;
}
PScore::OK()const
{
#ifdef NDEBUG
- for (PCursor<PCol*> cc(cols); cc.ok(); cc++)
+ for (iter_top(cols,cc); cc.ok(); cc++)
cc->OK();
- for (PCursor<Idealspacing*> ic(suz); ic.ok(); ic++)
- ic->OK();
+ for (iter_top(suz,i); i.ok(); i++)
+ i->OK();
#endif
}
mtor << "PScore { ";
paper_->print();
mtor << "\ncolumns: ";
- for (PCursor<PCol*> cc(cols); cc.ok(); cc++)
+ for (iter_top(cols,cc); cc.ok(); cc++)
cc->print();
mtor << "\nideals: ";
- for (PCursor<Idealspacing*> ic(suz); ic.ok(); ic++)
- ic->print();
+ for (iter_top(suz,i); i.ok(); i++)
+ i->print();
mtor << "}\n";
#endif
}
void
PScore::preprocess()
{
+ for (iter_top(spanners,i); i.ok(); i++) {
+ i->pre_processing();
+ }
+ for (iter_top(its,i); i.ok(); i++){
+ i->pre_processing();
+ }
}
void
PScore::postprocess()
{
- for (PCursor<Spanner*> ic(broken_spans); ic.ok(); ic++) {
- ic->process();
+ for (iter_top(broken_spans,i); i.ok(); i++) { // could chase spans as well.
+ i->post_processing();
}
- for (PCursor<Item*> ic(its); ic.ok(); ic++){
- ic->postprocess();
+ for (iter_top(its,i); i.ok(); i++){
+ i->post_processing();
}
- for (PCursor<Line_of_score*> i(lines); i.ok(); i++)
+
+ for (iter_top(broken_spans,i); i.ok(); i++) {
+ i->molecule_processing();
+ }
+ for (iter_top(its,i); i.ok(); i++){
+ i->molecule_processing();
+ }
+
+ for (iter_top(lines,i); i.ok(); i++)
i->process();
+
}
PCursor<PCol *>
void
PScore::add_broken(Spanner*s)
{
+ assert(s->left->line == s->right->line);
broken_spans.bottom().add(s);
s->left->starters.bottom().add (s);
s->right->stoppers.bottom().add (s);
}
+
+void
+PScore::set_breaking(svec<Col_configuration> breaking)
+{
+ for (int j=0; j < breaking.sz(); j++) {
+ svec<PCol*> &curline(breaking[j].cols);
+ svec<Real> &config(breaking[j].config);
+
+ Line_of_score *p = new Line_of_score(curline,this);
+ lines.bottom().add(p);
+ for (int i=0; i < curline.sz(); i++){
+ curline[i]->hpos = config[i];
+ }
+ }
+}
+
+void
+PScore::calc_breaking()
+{
+ Word_wrap w(*this);
+ set_breaking(w.solve());
+}
#include "request.hh"
#include "misc.hh"
#include "debug.hh"
+#include "scriptdef.hh"
+#include "textdef.hh"
#define VIRTUALCONS(T,R) R *T::clone() const { return new T(*this); } struct T
#define RCONS(T) VIRTUALCONS(T, Request)
RCONS(Rest_req);
+RCONS(Text_req);
RCONS(Rhythmic_req);
RCONS(Stem_req);
+RCONS(Script_req);
RCONS(Note_req);
+RCONS(Melodic_req);
RCONS(Span_req);
RCONS(Slur_req);
RCONS(Beam_req);
elt = 0;
}
-Note_req::Note_req()
+Melodic_req::Melodic_req()
{
name = 0;
octave = 0;
}
int
-Note_req::height() const
+Melodic_req::height() const
{
return name + octave*7;
}
Rhythmic_req::Rhythmic_req()
{
+ plet_factor = 1;
balltype = 1;
dots = 0;
}
int d =dots;
while (d--)
mtor << '.';
- mtor<<"\n";
+
+ mtor<<"xPlet factor"<<plet_factor<<"\n";
}
void
-Note_req::print() const
+Melodic_req::print() const
{
mtor << "note: " << name << " oct: "<< octave;
+}
+
+void
+Note_req::print() const
+{
+ Melodic_req::print();
Rhythmic_req::print();
}
Moment
Rhythmic_req::duration() const {
- return wholes( balltype,dots);
+ return wholes(balltype,dots)*plet_factor;
}
Beam_req::Beam_req()
{
spantype = NOSPAN;
}
+
+Script_req::Script_req(int d , Script_def*def)
+{
+ dir = d;
+ scriptdef = def;
+}
+
+void
+Script_req::print() const
+{
+ mtor << " dir " << dir ;
+ scriptdef->print();
+}
+
+
+Script_req::~Script_req()
+{
+ delete scriptdef;
+}
+
+
+Text_req::Text_req(int d , Text_def*def)
+{
+ dir = d;
+ spec = def;
+}
+
+void
+Text_req::print() const
+{
+ mtor << " dir " << dir ;
+ spec->print();
+}
+
+
+Text_req::~Text_req()
+{
+ delete spec;
+}
+
+
Item::print();
}
-void
-Rest::preprocess()
-{
- brew_molecole();
-}
-
-void
-Rest::brew_molecole()
+Molecule*
+Rest::brew_molecule()const
{
assert(pstaff_);
- assert(!output);
+
Paperdef *p =paper();
Symbol s;
dm.add(Atom(d));
m->add_right(dm);
}
- output = m;
+ return m;
}
/// distribute commands to disciples
pscore_ = new PScore(paper_);
- for (PCursor<Staff*> i(staffs_); i.ok(); i++) {
+ for (iter_top(staffs_,i); i.ok(); i++) {
i->process_commands(last());
i->set_output(pscore_);
i->process();
void
Score::clean_cols()
{
- for (PCursor<Staff * > i(staffs_); i.ok(); i++)
+ for (iter_top(staffs_,i); i.ok(); i++)
i->clean_cols();
- for (PCursor<Score_column*> c(cols_); c.ok(); ) {
+ for (iter_top(cols_,c); c.ok(); ) {
if (!c->pcol_->used()) {
c.del();
} else {
c1->musical = false;
c2->musical = true;
- PCursor<Score_column*> i(cols_);
+ iter_top(cols_,i);
for (; i.ok(); i++) {
assert(i->when != w);
PCursor<Score_column*>
Score::find_col(Moment w,bool mus)
{
- PCursor<Score_column*> i(cols_);
+ iter_top(cols_,i);
for (; i.ok(); i++) {
if (i->when == w && i->musical == mus)
return i;
void
Score::do_pcols()
{
- PCursor<Score_column*> i(cols_);
+ iter_top(cols_,i);
for (; i.ok(); i++) {
pscore_->add(i->pcol_);
}
Score::last() const
{
Moment l = 0;
- for (PCursor<Staff*> i(staffs_); i.ok(); i++) {
+ for (iter_top(staffs_,i); i.ok(); i++) {
l = l>? i->last();
}
return l;
Score::OK() const
{
#ifndef NDEBUG
- for (PCursor<Staff*> i(staffs_); i.ok(); i++) {
+ for (iter_top(staffs_,i); i.ok(); i++) {
i->OK();
assert(i->score_ == this);
}
staffs_.OK();
cols_.OK();
- for (PCursor<Score_column*> cc(cols_); cc.ok() && (cc+1).ok(); cc++) {
+ for (iter_top(cols_,cc); cc.ok() && (cc+1).ok(); cc++) {
assert(cc->when <= (cc+1)->when);
}
#endif
{
#ifndef NPRINT
mtor << "score {\n";
- for (PCursor<Staff*> i(staffs_); i.ok(); i++) {
+ for (iter_top(staffs_,i); i.ok(); i++) {
i->print();
}
- for (PCursor<Score_column*> i(cols_); i.ok(); i++) {
+ for (iter_top(cols_,i); i.ok(); i++) {
i->print();
}
if (pscore_)
Line_of_score::TeXstring() const
{
String s("\\vbox{%<- line of score\n");
- for (PCursor<Line_of_staff*> sc(staffs); sc.ok(); sc++){
+ for (iter_top(staffs,sc); sc.ok(); sc++){
s += sc->TeXstring();
if ((sc+1).ok())
s+= "\\interstaffline\n";
p->line=this;
}
- for (PCursor<PStaff*> sc(pscore_->staffs); sc.ok(); sc++)
+ for (iter_top(pscore_->staffs,sc); sc.ok(); sc++)
staffs.bottom().add(new Line_of_staff(this, sc));
}
/* construct a line with the named columns. Make the line field
void
Line_of_score::process()
{
- for (PCursor<Line_of_staff*> i(staffs); i.ok(); i++)
+ for (iter_top(staffs,i); i.ok(); i++)
i->process();
}
--- /dev/null
+#include "request.hh"
+#include "paper.hh"
+#include "script.hh"
+#include "stem.hh"
+#include "molecule.hh"
+#include "lookup.hh"
+
+Script::Script(Script_req* rq, Item*i , int staflen, Stem*st_p)
+{
+ dependencies.add(st_p);
+ dependencies.add(i);
+
+ staffsize =staflen;
+ specs = rq->scriptdef;
+ support= i;
+ stem_ = st_p;
+ pos = 0;
+ symdir=1;
+ dir =rq->dir;
+}
+
+void
+Script::set_symdir()
+{
+ if (specs->invertsym)
+ symdir = (dir < 0) ? -1:1;
+}
+
+void
+Script::set_default_dir()
+{
+ if (specs->stemdir) {
+ if (!stem_)
+ dir = 1;
+ else
+ dir = stem_->dir * specs->stemdir;
+ }
+}
+
+void
+Script::set_default_pos()
+{
+ assert(dir);
+ Real y;
+ Real inter= paper()->internote();
+
+ int d = specs->staffdir;
+ if (!d) {
+ Interval v= support->height();
+ pos = rint(v[dir]/inter) + dir* 2;
+ } else {
+ y = (d > 0) ? staffsize + 2: -2; // ug
+ y *=inter;
+ Interval v= support->height();
+
+ if (dir > 0) {
+ y = y >? v.max();
+ }else if (dir < 0) {
+ y = y <? v.min();
+ }
+ pos = int(rint(Real(y)/inter));
+ }
+}
+
+Interval
+Script::width() const
+{
+ return paper()->lookup_->script(specs->symidx).dim.x;
+}
+
+void
+Script::do_pre_processing()
+{
+ set_default_dir();
+ set_symdir();
+}
+
+void
+Script::do_post_processing()
+{
+ set_default_pos();
+}
+Molecule*
+Script::brew_molecule() const
+{
+ Paperdef *p =paper();
+
+ Real dy = p->internote();
+ String preidx = (symdir < 0) ?"-" :"";
+ Symbol ss =p->lookup_->script(preidx+specs->symidx);
+ Molecule*out = new Molecule(Atom(ss));
+ out->translate(Offset(0,dy * pos));
+ return
+ out;
+}
--- /dev/null
+#include "debug.hh"
+#include "scriptdef.hh"
+
+Script_def::Script_def(String idx, int stem, int staff ,bool invert)
+{
+ symidx = idx ;
+ stemdir =stem;
+ staffdir = staff;
+ invertsym = invert;
+}
+void
+Script_def::print() const
+{
+ mtor << "idx: " << symidx;
+ mtor << "direction, stem: " << stemdir << " staff : " << staffdir;
+}
s = new Bar(com->args[1]);
} else if (type == "METER") {
s = new Meter(arg);
- } else if (type == "CLEF" ||type == "CURRENTCLEF") {
+ } else if (type == "CLEF" || type == "CURRENTCLEF") {
Clef_item * c = new Clef_item;
s = c;
c->change = (type == "CLEF");
stem_ = 0;
staff_ = rs;
beam_ = 0;
+ text_=0;
}
Simple_staff::Simple_staff()
BREAK: all
TYPESET: bar, meter,
-
+Scalar
*/
Simple_column::process_requests()
{
for (int i = 0 ; i < v_elts.sz(); i ++)
- for (PCursor<Request *> rqc(v_elts[i]->reqs); rqc.ok(); rqc++) {
- Request *rq= rqc;
+ for (iter_top(v_elts[i]->reqs,j); j.ok(); j++) {
+ Request *rq= j;
if (rq->rhythmic()){
- notes.add( rq->rhythmic());
+ notes.add(rq->rhythmic());
+ }
+ if (rq->script()) {
+ notes.last().scripts.add(rq->script());
}
if (rq->stem()) {
stem_ = rq->stem();
stem_requester_len = v_elts[i]->duration;
}
-
+ if (rq->text()) {
+ text_ = rq->text();
+ }
if (rq->beam()) {
beam_ = rq->beam();
}
sc.process();
}
}
-
+Note_info::Note_info()
+{
+ rq =0;
+}
+Note_info::Note_info(Rhythmic_req*r) {
+ rq = r;
+}
/*
UGR
*/
-
+#include "textspanner.hh"
+#include "script.hh"
#include "request.hh"
#include "voice.hh"
#include "clef.hh"
#include "keyitem.hh"
#include "slur.hh"
#include "localkeyitem.hh"
+#include "textitem.hh"
Rhythmic_grouping
parse_grouping(svec<Scalar> a, Moment one_beat)
{
-
svec<int> r;
for (int i= 0 ; i < a.sz(); i++)
r.add(a[i]);
svec<Scalar> args(com->args);
args.del(0);
if (com->args[0] == "GROUPING") {
- default_grouping = parse_grouping(args, col()->tdescription_->one_beat);
+ default_grouping = parse_grouping(args,
+ col()->tdescription_->one_beat);
}else if (com->args[0] == "BAR") {
local_key_.reset(key_);
} else if (com->args[0] == "KEY") {
- if (col()->when()) {
+ if (col()->when() > Moment(0)) {
assert(!oldkey_undo);
oldkey_undo = new svec<int>( key_.oldkey_undo(args));
}
if (processed_key)
return;
else
- com->args[0] = "KEY";
+ com->args[0] = "KEY"; // urgh
if (com->args[0] == "CURRENTCLEF") {
if (processed_clef)
oldkey_undo = 0;
}
processed_key = true;
+
((Keyitem*) i)->read(typesetkey); // ugh
}
}
void
-Simple_walker::do_local_key(Note_req*n)
+Simple_walker::do_local_key(Note_req*n,Notehead* head_p)
{
if ( local_key_.oct(n->octave).acc(n->name) != n->accidental) {
if (!local_key_item_) {
local_key_item_->c0_position = clef_.c0_pos;
}
- local_key_item_->add(n->octave, n->name, n->accidental);
+ local_key_item_->add(n->octave, n->name, n->accidental, head_p);
local_key_.oct(n->octave).set(n->name, n->accidental);
}
}
void
-Simple_walker::do_note(Rhythmic_req*rq)
+Simple_walker::do_note(Note_info n)
{
Simple_column*c = col();
Simple_staff *s = staff();
-
- if (rq->note()) {
- Note_req * req = rq->note() ;
+ Item*rhythmic=0;
+ if (n.rq->note()) {
+ Note_req * req = n.rq->note() ;
const Voice *v = req->elt->voice_;
-
+
Notehead*n = s->get_notehead(req, clef_.c0_pos);
+ rhythmic=n;
stem_->add(n);
if (current_grouping) {
current_grouping->add_child(
- c->tdescription_->whole_in_measure, rq->duration());
+ c->tdescription_->whole_in_measure, req->duration());
}
noteheads.add(n);
int sidx =find_slur(v);
}
if (wantkey)
- do_local_key(req);
+ do_local_key(req,n);
+ }else if (n.rq->rest()) {
+ rhythmic = s->get_rest(n.rq->rest());
+ c->typeset_item(rhythmic);
}
-
- if (rq->rest()) {
- c->typeset_item( s->get_rest(rq->rest()) );
- }
+ for (int i= 0; i < n.scripts.size(); i ++)
+ c->typeset_item(new Script(n.scripts[i], rhythmic, 10, stem_)); // UGR
}
void
{
Simple_column*c = col();
Simple_staff *s = staff();
+
if (c->beam_&& c->beam_->spantype == Span_req::START) {
if (beam_)
error("Too many beams (t = "
beam_ = new Beam;
current_grouping = new Rhythmic_grouping;
}
+
for (int i=0; i < c->slurs.sz(); i++) {
Slur_req*sl = c->slurs[i];
}
}
+ if (c->text_) {
+ c->typeset_item(new Text_item(c->text_, 10)); // UGR
+ }
+
if (c->stem_) {
stem_ = s->get_stem(c->stem_->stem(), c->stem_requester_len);
}
if (c->beam_&& c->beam_->spantype == Span_req::STOP) {
beam_->set_grouping(default_grouping, *current_grouping);
pscore_->typeset_spanner(beam_, s->theline);
+
+ if (c->beam_->nplet) {
+ Text_spanner* t = new Text_spanner(beam_);
+ t->spec.align = 0;
+ t->spec.text = c->beam_->nplet;
+ pscore_->typeset_spanner(t, s->theline);
+ }
+
beam_ = 0;
delete current_grouping;
current_grouping =0;
#include "molecule.hh"
#include "debug.hh"
#include "boxes.hh"
-void
-Slur::calculate()
+
+Slur::Slur()
{
- set_default_dir();
+ dir = 0;
+ open_right=open_left=false;
}
Offset
Slur::center() const
{
- int pos1 = encompass.last()->position;
+ int pos1 = encompass.last()->position;
int pos2 = encompass[0]->position;
int dy = pos1-pos2;
Slur::add(Notehead*n)
{
encompass.add(n);
- dir = 0;
- open_right=open_left=false;
-}
-
-Interval
-Slur::height() const
-{
- return Interval(0,0); // todo
+ dependencies.add(n);
}
void
}
void
-Slur::preprocess()
+Slur::do_pre_processing()
{
right = encompass.last()->pcol_;
left = encompass[0]->pcol_;
}
Spanner*
-Slur::broken_at(PCol*l, PCol*r) const
+Slur::do_break_at(PCol*l, PCol*r) const
{
assert(l->line == r->line);
Slur*ret = new Slur(*this);
+
ret->encompass.set_size(0);
for (int i =0; i < encompass.sz(); i++) {
if (encompass[i]->pcol_->line==l->line)
if (left != l)
ret->open_left = true;
- ret->left = l;
- ret->right = r;
+
return ret;
}
void
-Slur::process()
+Slur::do_post_processing()
{
set_default_dir();
- brew_molecule();
}
-void
-Slur::brew_molecule()
+Molecule*
+Slur::brew_molecule() const
{
- output = new Molecule;
+ Molecule*output = new Molecule;
assert(left->line == right->line);
- int minp=1000, maxp=-1000; // todo
+ int minp=1000, maxp=-1000; // todo
for (int i=0; i<encompass.sz(); i++) {
minp = encompass[i]->position <? minp;
- maxp = encompass[i]->position <? maxp;
- }
+ maxp = encompass[i]->position >? maxp;
+ }
assert(encompass.sz()>0); // todo
- int pos1 = encompass.last()->position;
- int pos2 = encompass[0]->position;
-
- int dy = pos1-pos2;
-
+
+ Notehead *lnote_p =encompass[0];
+ Notehead *rnote_p =encompass.last();
+ int pos1 = lnote_p->position;
+ int pos2 = rnote_p->position;
+
+ int dy = pos2-pos1;
+ Real nw_f = paper()->note_width();
Real w = width().length();
- Real nw = paper()->note_width();
- w -= nw;
- Symbol sl = paper()->lookup_->slur(dy , w, dir);
+ w+= (-lnote_p->x_dir + rnote_p->x_dir)* nw_f ;
+ Real round_w = w; // slur lookup rounds the slurwidth .
+
+ Symbol sl = paper()->lookup_->slur(dy , round_w, dir);
+
+ Real error = w-round_w;
+
Atom a(sl);
- a.translate(Offset(nw,pos2*paper()->internote()));
+ a.translate(Offset((lnote_p->x_dir + 0.5 )*nw_f + error/2,
+ (pos2+2*dir) * paper()->internote()));
output->add(a);
+ return output;
}
-#include "pstaff.hh"
#include "debug.hh"
-#include "pscore.hh"
#include "spanner.hh"
-#include "symbol.hh"
-#include "molecule.hh"
#include "pcol.hh"
-void
-Spanner::calculate()
-{
-}
-String
-Spanner::TeXstring() const
+
+Spanner*
+Spanner::broken_at(PCol*c1, PCol *c2)const
{
+ Spanner *me_p = (Spanner*)this;
+ Spanner *span_p = do_break_at(c1,c2);
+
+ me_p->calc_children = true;
+ me_p->dependencies.add(span_p);
+
+ span_p->calc_children = false; // should handle in ctor
+
+ span_p->left = c1;
+ span_p->right = c2;
- assert(output);
- return output->TeXstring();
+ return span_p;
}
Spanner::Spanner()
{
- pstaff_=0;
left = right = 0;
}
-void
-Spanner::process()
-{
-}
-
-void
-Spanner::preprocess()
-{
-}
Interval
Spanner::width()const
return Interval(0, r-l);
}
-Paperdef*
-Spanner::paper()const
-{
- assert(pstaff_);
- return pstaff_->pscore_->paper_;
-}
void
-Spanner::print()const
+Spanner::print() const
{
#ifndef NPRINT
mtor << "Spanner { ";
- if (output) {
- mtor << "Output ";
- output->print();
- }
-
+ Staff_elem::print();
mtor << "}\n";
#endif
}
-Spanner::~Spanner()
-{
- delete output;
-}
+
void
Staff::add(PointerList<Voice*> &l)
{
- for (PCursor<Voice*> i(l); i.ok(); i++)
+ for (iter_top(l,i); i.ok(); i++)
voices.bottom().add(i);
}
void
Staff::clean_cols()
{
- PCursor<Staff_column *> i(cols);
+ iter_top(cols,i);
for(; i.ok(); ){
if (!i->score_column->used())
i.del();
Score_column* sc = score_->find_col(w,mus);
assert(sc->when == w);
- PCursor<Staff_column *> i(cols);
+ iter_top(cols,i);
for (; i.ok(); i++) {
if (*i->score_column > *sc) // too far
break;
void
Staff::setup_staffcols()
{
- for (PCursor<Voice*> i(voices); i.ok(); i++) {
+ for (iter_top(voices,i); i.ok(); i++) {
Moment now = i->start;
- for (PCursor<Voice_element *> ve(i->elts); ve.ok(); ve++) {
+ for (iter_top(i->elts,ve); ve.ok(); ve++) {
Staff_column *sc=get_col(now,true);
sc->add(ve);
}
}
- for (PCursor<Staff_commands_at*> cc(*staff_commands_); cc.ok(); cc++) {
+ for (iter_top(*staff_commands_,cc); cc.ok(); cc++) {
Staff_column *sc=get_col(cc->tdescription_.when,false);
sc->s_commands = cc;
sc->tdescription_ = new Time_description(cc->tdescription_);
}
- PCursor<Staff_commands_at*> cc(*staff_commands_);
- for (PCursor<Staff_column*> i(cols); i.ok(); i++) {
+ iter_top(*staff_commands_,cc);
+ for (iter_top(cols,i); i.ok(); i++) {
while ((cc+1).ok() && (cc+1)->when() < i->when())
cc++;
Staff::last() const
{
Moment l = 0.0;
- for (PCursor<Voice*> i(voices); i.ok(); i++) {
+ for (iter_top(voices,i); i.ok(); i++) {
l = l >? i->last();
}
return l;
{
#ifndef NPRINT
mtor << "Staff {\n";
- for (PCursor<Voice*> i(voices); i.ok(); i++) {
+ for (iter_top(voices,i); i.ok(); i++) {
i->print();
}
if (staff_commands_)
Staff_commands_at::print() const
{
#ifndef NPRINT
- PCursor<Command*> i (*this);
+ iter_top(*this,i);
mtor << "Commands at: " ;
tdescription_.print();
void
Staff_commands_at::OK()const
{
- PCursor<Command*> i (*this);
+ iter_top(*this,i);
for (; i.ok() && (i+1).ok(); i++)
if (!i->isbreak() && !(i+1)->isbreak())
assert(i->priority >= (i+1)->priority);
bool
Staff_commands_at::is_breakable()
{
- PCursor<Command*> i(*this);
+ iter_top(*this,i);
for (; i.ok(); i++) {
if (i->isbreak())
return true;
Staff_commands_at::add_command_to_break(Command pre, Command mid,Command post)
{
assert(is_breakable());
- PCursor<Command*> c ( *this), f(c), l(c);
+ iter_top(*this,c), f(c), l(c);
while (!c->isbreak())
c++;
if (c.code == INTERPRET)
{ // UGH
+ Command typeset; // kut met peren
+ typeset.code = TYPESET;
+ typeset.args = c.args;
if (c.args[0] == "BAR") {
- Command typeset; // kut met peren
- typeset.code = TYPESET;
- typeset.args = c.args;
typeset.priority = 100;
add(typeset);
} else if (c.args[0] == "KEY") {
- Command typeset;
- typeset.code = TYPESET;
- typeset.args.add("KEY");
typeset.priority = 70;
add(typeset);
} else if (c.args[0] == "CLEF") {
- Command typeset;
- typeset.code = TYPESET;
- typeset.args=c.args;
typeset.priority = 90;
add(typeset);
} else if (c.args[0] == "METER") {
- Command typeset;
- typeset.code = TYPESET;
- typeset.args=c.args;
typeset.priority = 40;
add(typeset);
return;
kc.priority = 80;
add(kc);
}
- }else if (c.args[0] == "METER" && is_breakable()) {
- mid = c;
- pre = c;
- post =c;
- }else
- if( c.args[0] == "KEY" && is_breakable()) {
+ }
+ if (is_breakable()) {
+ if (c.args[0] == "METER") {
+ mid = c;
+ pre = c;
+ post =c;
+ }else if( c.args[0] == "KEY") {
- mid = c;
- pre = c;
- post = c;
- }else if (c.args[0] == "CURRENTKEY" && is_breakable() ){
- post = c;
+ mid = c;
+ pre = c;
+ post = c;
+ }else if (c.args[0] == "CURRENTKEY" ){
+ post = c;
- }else
- if (c.args[0] == "CURRENTCLEF" && is_breakable() ){
- post = c;
+ }else
+ if (c.args[0] == "CURRENTCLEF" ){
+ post = c;
- }else
- if (c.args[0] == "CLEF" && is_breakable()) {
+ }else if (c.args[0] == "CLEF") {
- post = c;
- pre = c;
- mid = c;
+ post = c;
+ pre = c;
+ mid = c;
+ }
}
}
if (encapsulate)
add_command_to_break(pre, mid, post);
else {
- bottom().add(new Command(c));
+ if (c.priority>0)
+ top().insert(new Command(c));
+ else
+ bottom().add(new Command(c));
}
}
Staff_commands::OK() const
{
#ifndef NDEBUG
- for (PCursor<Staff_commands_at*> i(*this); i.ok() && (i+1).ok(); i++) {
+ for (iter_top(*this,i); i.ok() && (i+1).ok(); i++) {
assert(i->tdescription_.when <= (i+1)->tdescription_.when);
i->OK();
}
Staff_commands::print() const
{
#ifndef NPRINT
- for (PCursor<Staff_commands_at*> i(*this); i.ok() ; i++) {
+ for (iter_top(*this,i); i.ok() ; i++) {
i->print();
}
#endif
--- /dev/null
+#include "pscore.hh"
+#include "symbol.hh"
+#include "pstaff.hh"
+#include "molecule.hh"
+#include "staffelem.hh"
+
+String
+Staff_elem::TeXstring() const
+{
+ assert(output && !calc_children);
+ Molecule m(*output);
+ m.translate(offset_); // ugh?
+ return m.TeXstring();
+}
+
+Staff_elem::~Staff_elem()
+{
+ delete output;
+}
+void
+Staff_elem::translate(Offset O)
+{
+ offset_ += O;
+}
+Interval
+Staff_elem::width() const
+{
+ Molecule*m= brew_molecule();
+ Interval r = m->extent().x;
+
+ if (!r.empty()) // float exception on DEC Alpha
+ r+=offset_.x;
+
+ delete m;
+ return r;
+}
+Interval
+Staff_elem::height() const
+{
+ Molecule*m= brew_molecule();
+ Interval r = m->extent().y;
+
+
+ if (!r.empty())
+ r+=offset_.y;
+ delete m;
+
+ return r;
+}
+
+void
+Staff_elem::print()const
+{
+#ifndef NPRINT
+ if (output)
+ output->print();
+#endif
+}
+
+Staff_elem::Staff_elem()
+{
+ calc_children = false;
+ pstaff_=0;
+ offset_ = Offset(0,0);
+ output = 0;
+ status = ORPHAN;
+}
+
+
+Paperdef*
+Staff_elem::paper() const
+{
+ assert(pstaff_);
+ return pstaff_->pscore_->paper_;
+}
+
+void
+Staff_elem::add_processing()
+{
+ if (status >= VIRGIN)
+ return;
+
+ do_add_processing();
+ status = VIRGIN;
+}
+
+void
+Staff_elem::pre_processing()
+{
+ if (status >= PRECALCED )
+ return;
+ for (int i=0; i < dependencies.sz(); i++)
+ if (dependencies[i])
+ dependencies[i]->pre_processing();
+ if (!calc_children)
+ do_pre_processing();
+ status = PRECALCED;
+}
+void
+Staff_elem::post_processing()
+{
+ if (status > POSTCALCED)
+ return;
+ for (int i=0; i < dependencies.sz(); i++)
+ if (dependencies[i])
+ dependencies[i]->post_processing();
+ if (!calc_children)
+ do_post_processing();
+ status=POSTCALCED;
+}
+
+void
+Staff_elem::molecule_processing()
+{
+ if (status >= OUTPUT)
+ return;
+ for (int i=0; i < dependencies.sz(); i++)
+ if (dependencies[i])
+ dependencies[i]->molecule_processing();
+ if (!calc_children)
+ output= brew_molecule();
+ status = OUTPUT;
+}
+
+void
+Staff_elem::do_post_processing()
+{
+}
+
+void
+Staff_elem::do_pre_processing()
+{
+}
+
+void
+Staff_elem::do_add_processing()
+{
+}
brew_molecule(line_of_score_->pscore_->paper_->linewidth);
s+=pstaff_->stafsym->TeXstring();
- PCursor<const PCol *> cc(line_of_score_->cols);
+ iter_top(line_of_score_->cols,cc);
Real lastpos=cc->hpos;
// all items in the current line & staff.
// now output the items.
- for (PCursor<const Item *> ic(cc->its); ic.ok(); ic++) {
- if (ic->pstaff_ == pstaff_)
- s += ic->TeXstring();
+ for (iter_top(cc->its,i); i.ok(); i++) {
+ if (i->pstaff_ == pstaff_)
+ s += i->TeXstring();
}
// spanners.
- for (PCursor<const Spanner *> sc(cc->starters); sc.ok(); sc++)
- if (sc->pstaff_ == pstaff_)
- s += sc->TeXstring();
+ for (iter_top(cc->starters,i); i.ok(); i++)
+ if (i->pstaff_ == pstaff_)
+ s += i->TeXstring();
}
}
s+="\\hss}\\vss}";
PCol *linestart = sc->cols.top();
PCol *linestop = sc->cols.bottom();
- for (PCursor<const Spanner*> sp(pstaff_->spans); sp.ok(); sp++) {
+ for (iter_top(pstaff_->spans,i); i.ok(); i++) {
- PCol *brokenstart = &max(*linestart, *sp->left);
- PCol *brokenstop = &min(*linestop, *sp->right);
+ PCol *brokenstart = &max(*linestart, *i->left);
+ PCol *brokenstop = &min(*linestop, *i->right);
if ( *brokenstart < *brokenstop) {
+ Spanner*span_p =i->broken_at(brokenstart,brokenstop);
line_of_score_->pscore_-> // higghl
- add_broken(sp->broken_at(brokenstart,brokenstop));
+ add_broken(span_p);
}
}
}
Interval
Line_of_staff::height() const
{
- Interval y;
- {
- y = pstaff_->stafsym->extent().y;
- }
- PCursor<const PCol *> cc(line_of_score_->cols);
+ Interval y = pstaff_->stafsym->extent().y;
+ iter_top(line_of_score_->cols,cc);
// all items in the current line & staff.
for (; cc.ok(); cc++) {
- for (PCursor<const Item *> ic(cc->its); ic.ok(); ic++) {
- if (ic->pstaff_ == pstaff_) {
- y.unite(ic->height());
- }
+ for (iter_top(cc->its,i); i.ok(); i++) {
+ if (i->pstaff_ == pstaff_)
+ y.unite(i->height());
+ }
// spanners.
- for (PCursor<const Spanner *> sc(cc->starters); sc.ok(); sc++)
- if (sc->pstaff_ == pstaff_) {
- y.unite(sc->height());
+ for (iter_top(cc->starters,i); i.ok(); i++)
+ if (i->pstaff_ == pstaff_) {
+ y.unite(i->height());
}
- }
}
+
return y;
}
void
Stem::set_stemend(Real se)
{
- assert(!output);
+
// todo: margins
assert((dir > 0 && se >= maxnote) || (se <= minnote && dir <0));
void
Stem::add(Notehead *n)
{
+ assert(status < PRECALCED);
+
if (n->balltype == 1)
return;
int p = n->position;
if ( p> maxnote)
maxnote = p;
heads.add(n);
+ n->dependencies.add(this);
}
Stem::set_noteheads()
{
heads.sort(Notehead::compare);
- int parity=0;
+ int parity=1;
int lastpos = heads[0]->position;
for (int i=1; i < heads.sz(); i ++) {
- if (abs(lastpos- heads[i]->position) == 1) {
+ int dy =abs(lastpos- heads[i]->position);
+
+ if (dy <= 1) {
if (parity)
heads[i]->x_dir = (stem_xoffset>0) ? 1:-1;
parity = !parity;
}
void
-Stem::postprocess()
+Stem::do_pre_processing()
{
if (bot == top)
set_default_extents();
set_noteheads();
- brew_molecole();
}
+
Interval
Stem::width()const
{
return r;
}
-void
-Stem::brew_molecole()
+Molecule*
+Stem::brew_molecule()const return out;
{
assert(pstaff_);
assert(bot!=top);
- assert(!output);
+
Paperdef *p =paper();
Symbol ss =p->lookup_->stem(bot*dy,top*dy);
- output = new Molecule(Atom(ss));
+ out = new Molecule(Atom(ss));
if (print_flag&&abs(flag) > 4){
Symbol fl = p->lookup_->flag(flag);
Molecule m(fl);
if (flag < -4){
- output->add_bottom(m);
+ out->add_bottom(m);
} else if (flag > 4) {
- output->add_top(m);
+ out->add_top(m);
} else
assert(false);
}
- output->translate(Offset(stem_xoffset,0));
-
+ out->translate(Offset(stem_xoffset,0));
}
Real
}
-void
-Stem::preprocess()
-{
- set_default_extents(); // needed for the flags.
-}
{
break_status = BREAK_END - BREAK_PRE;
if (ptr()->s_commands)
- for (PCursor<Command*> i(*ptr()->s_commands); i.ok(); i++) {
+ for (iter_top(*ptr()->s_commands,i); i.ok(); i++) {
process_command(i);
}
-
+#include "idealspacing.hh"
#include "plist.hh"
#include "pcol.hh"
#include "item.hh"
#include "staffline.hh"
-#include "plist.cc"
+#include "plist.tcc"
#define IPLC_instantiate(a) IPL_instantiate(a); PL_instantiate(const a)
#include "stcol.hh"
#include "spanner.hh"
-#include "plist.cc"
+#include "plist.tcc"
IPL_instantiate(Request);
#include "inputcommand.hh"
#include "inputcommands.hh"
#include "molecule.hh"
-#include "plist.cc"
#include "staffcommands.hh"
+
+#include "plist.tcc"
+
IPL_instantiate(Atom);
IPL_instantiate(Command);
IPL_instantiate(Atom);
-#include "list.cc"
-#include "cursor.cc"
+#include "list.tcc"
+#include "cursor.tcc"
L_instantiate(void *);
#include "string.hh"
#include "moment.hh"
#include "real.hh"
-#include "interval.cc"
+
+#include "interval.tcc"
Interval__instantiate(Real);
Interval__instantiate(Rational);
--- /dev/null
+#include "debug.hh"
+#include "lookup.hh"
+#include "paper.hh"
+#include "molecule.hh"
+#include "textdef.hh"
+
+Text_def::Text_def()
+{
+ align = 1; // right
+ style = "roman";
+}
+
+Atom
+Text_def::create(Paperdef*p) const
+{
+ return p->lookup_->text(style, text, -align);
+}
+
+void
+Text_def::print() const
+{
+ mtor << "Text `" << text << "\', style " <<
+ style << "align " <<align<<'\n';
+}
--- /dev/null
+#include "request.hh"
+#include "paper.hh"
+#include "textitem.hh"
+#include "stem.hh"
+#include "molecule.hh"
+#include "lookup.hh"
+
+Text_item::Text_item(Text_req * r, int s)
+{
+ dir = r->dir;
+ if (!dir)
+ dir = -1;
+
+ specs = r->spec;
+ staffsize = s;
+ pos = 0;
+}
+
+void
+Text_item::set_default_pos()
+{
+ pos = (dir > 0) ? staffsize + 2: -4;
+}
+void
+Text_item::do_pre_processing()
+{
+ set_default_pos();
+}
+
+
+Molecule*
+Text_item::brew_molecule() const
+{
+ Molecule* output = new Molecule(specs->create(paper()));
+ if(dir <0)
+ output->translate(Offset(0, -output->extent().y.length() ));
+
+ output->translate(Offset(0, pos * paper()->internote()));
+ return output;
+}
-#include "paper.hh"
#include "molecule.hh"
-#include "lookup.hh"
#include "boxes.hh"
#include "textspanner.hh"
+#include "textdef.hh"
Text_spanner::Text_spanner(Directional_spanner*d)
{
support = d;
- align = 0;
- style = "roman";
+ dependencies.add(d);
}
void
-Text_spanner::process()
+Text_spanner::do_post_processing()
{
- Offset tpos;
-
- switch(align) {
+ switch(spec.align) {
case 0:
tpos = support->center();
break;
break;
}
- Paperdef *pap_p = paper();
- Atom tsym (pap_p->lookup_->text(style, text, -align));
- tsym.translate(tpos);
- output = new Molecule;
- output->add( tsym );
}
+Molecule*
+Text_spanner::brew_molecule() const
+{
+ Atom tsym (spec.create(paper()));
+ tsym.translate(tpos);
+ Molecule*output = new Molecule;
+ output->add( tsym );
+ return output;
+}
+void
+Text_spanner::print() const // todo
+{
+}
void
-Text_spanner::preprocess()
+Text_spanner::do_pre_processing()
{
right = support->right;
left = support->left;
Interval
Text_spanner::height()const
{
- return output->extent().y;
+ return brew_molecule()->extent().y;
}
Spanner*
-Text_spanner::broken_at(PCol*c1, PCol*c2)const
+Text_spanner::do_break_at(PCol*c1, PCol*c2)const
{
- Text_spanner *n=new Text_spanner(*this);
- n->left = c1;
- n->right = c2;
- return n;
+ return new Text_spanner(*this);
}
{
#ifndef NPRINT
mtor << "start: "<< start<<eol;
- for (PCursor<Voice_element*> vec(elts); vec.ok(); vec++)
+ for (iter_top(elts,vec); vec.ok(); vec++)
vec->print();
#endif
}
Voice::last() const
{
Moment l =start;
- for (PCursor<Voice_element*> vec(elts); vec.ok(); vec++)
+ for (iter_top(elts,vec); vec.ok(); vec++)
l += vec->duration;
return l;
}
{
#ifndef NPRINT
mtor << "voice_element { dur :"<< duration <<"\n";
- for (PCursor<Request*> rc(reqs); rc.ok(); rc++) {
+ for (iter_top(reqs,rc); rc.ok(); rc++) {
rc->print();
}
mtor << "}\n";
--- /dev/null
+#include "break.hh"
+#include "pscore.hh"
+#include "debug.hh"
+
+/* el stupido. This should be done more accurately:
+
+ It would be nice to have a Dynamic Programming type of algorithm
+ similar to TeX's
+
+ */
+
+svec<Col_configuration>
+Word_wrap::solve()
+{
+ problem_OK();
+ iter_top(pscore_.cols,curcol);
+ svec<Col_configuration> breaking;
+ svec<PCol *> breakpoints(find_breaks());
+ assert(breakpoints.sz()>=2);
+ for (int i=0 ; i < breakpoints.sz() -1; ) {
+ Col_configuration minimum;
+ Col_configuration current;
+
+ // do another line
+ PCol *post = breakpoints[i]->postbreak;
+ current.add( post);
+ curcol++; // skip the breakable.
+ i++;
+
+ while (i < breakpoints.sz()) {
+
+ // add another measure.
+ while (breakpoints[i] != curcol.ptr()){
+
+ current.add(curcol);
+ curcol++;
+ }
+ current.add(breakpoints[i]->prebreak );
+ if (!feasible(current.cols)) {
+ if (!minimum.cols.sz())
+ error("sorry, this measure is too long");
+ break;
+ }
+ current.setsol(solve_line(current.cols));
+ current.print();
+
+ if (current.energy < minimum.energy) {
+ minimum = current;
+ } else { // we're one col too far.
+ i--;
+ while (curcol.ptr() != breakpoints[i])
+ curcol --;
+
+ break;
+ }
+
+ current.cols.last()=breakpoints[i];
+ curcol ++;
+ i++;
+ }
+ mtor << "Adding cols~, next breakpoint " << i << '\n';
+ breaking.add(minimum);
+ }
+
+ return breaking;
+}
+
+Word_wrap::Word_wrap(PScore&ps)
+ : Break_algorithm(ps)
+{
+}
-%
-% spacing info for LilyPond. Do not edit this.
-% It has a lot of hard-wired stringconstants
-%
+
include "init/dutch.ini"
+include "init/script.ini"
include "init/table_sixteen.ini"
-%
-% common dutch names for notes. "es" means flat, "is" means sharp
-%
-
-default_table = symboltables { table_sixteen }
-notenames { dutch_names }