-DOCFILES=commands CodingStyle algorithms Makefile breaking
+DOCFILES=commands CodingStyle algorithms Makefile breaking\
+ slurfont pointers
dist:
ln $(DOCFILES) $(DDIR)/Documentation/
\ No newline at end of file
--- /dev/null
+This describes the ownership of certain classes in LilyPond. +
+signifies a "list of". (This is not complete)
+
+Score:
+ Paperdef
+ Staff+
+ Score_commands
+ Score_columns+
+ PScore
+
+Staff:
+ Voice
+ Staff_column+
+ Command+
+
+
+Voice:
+ Voice_element
+
+Voice_element:
+ Request+
+
+
+PScore:
+ PStaff+
+ PCol+
+ Idealspacing+
+ Item+
+ Spanner+
+ Spanner+ (broken)
+
--- /dev/null
+How are slur fonts organised?
+
+xhslu20: see xslhu20
+
+xslhu20: half slurs, pointing up
+ right
+ width in steps of 12pt (12pt-96pt)
+ height in 16 steps
+ left
+ idem
+
+xslhd20: half slurs, pointing down, idem
+
+xslu20: whole slurs, ascending
+ pointing up
+ height (dy) in 8 steps
+ width in 16 steps of 4pt (8 pt - 64pt)
+ pointing down
+ height (dy) in 8 steps
+ width in steps of 4pt (8 pt - 64pt)
+
+xsld20: whole slurs, descending
+ pointing up
+ height (dy) in 8 steps
+ width in steps of 4pt (8 pt - 60pt)
+ pointing down
+ height (dy) in 8 steps
+ width in steps of 4pt (8 pt - 60pt)
+
+
+xslhz: middlepieces for half-slurs
+ pointing up
+ width in 100 steps of 4 pt (4 pt to 400pt)
+ pointing down
+ idem
+
+xslz: horizontal slurs
+ pointing up
+ width in 54 steps of 4pt
+ pointing down
+ idem
+
+xtie: same as xslhz.
$(CXX) -o $@ $^ $(LOADLIBES)
clean:
+ $(MAKE) -C objects clean
rm -f $(exe) *.o $(DOCDIR)/* core
distclean: clean
This is a beta version of LilyPond (a music typesetter). Please send
your helpful comments and patches to me,
- hanwen@stack.urc.tue.nl
+ hanwen@stack.nl
LilyPond is updated very frequently, the latest version is always available at:
notehead.hh leastsquares.hh beam.hh rest.hh\
swalker.hh bar.hh meter.hh accidental.hh\
key.hh keyitem.hh localkeyitem.hh simplewalker.hh\
- clef.hh clefitem.hh
+ clef.hh clefitem.hh slur.hh
mycc= qlp.cc qlpsolve.cc \
break.cc linespace.cc molecule.cc staffline.cc\
texbeam.cc rest.cc swalker.cc scoreline.cc\
simplewalker.cc bar.cc meter.cc accidental.cc\
key.cc keyitem.cc localkeyitem.cc\
- clef.cc clefitem.cc\
- template1.cc template2.cc template3.cc\
+ clef.cc clefitem.cc texslur.cc slur.cc\
+ template1.cc template2.cc template3.cc template4.cc\
version.cc
# version info
MAJVER=0
MINVER=0
-PATCHLEVEL=10
+PATCHLEVEL=11
VERSION=$(MAJVER).$(MINVER).$(PATCHLEVEL)
# directories
\font\musicfnt=musix20
-\def\mb#1{{\musicfnt\musicfnt\char#1}}
+%\def\mb#1{{\musicfnt\musicfnt\char#1}}
+\font\slurfont=xslhz20
+\def\mb#1{{\musicfnt\slurfont\char#1}}
\newdimen\wid
\newdimen\inc
\newdimen\here
\hbox to0pt{\kern\here\vrule width0.05pt height 2pt\hss}%
\repeat%
}
+
\def\vruler#1{%
\wid=#1pt
\inc=\wid
MAJVER=1
MINVER=0
-PATCHLEVEL=11
+PATCHLEVEL=12
PACKAGENAME=flower
VERSION=$(MAJVER).$(MINVER).$(PATCHLEVEL)
sum += y(j) * L(i,j);
y(i) = (rhs(i) - sum)/L(i,i);
}
- for (int i=0; i < n; i++) {
- assert(D(i));
+ for (int i=0; i < n; i++)
y(i) /= D(i);
- }
// backward subst
- Vector x(n);
+ Vector &x(rhs); // using input as return val.
for (int i=n-1; i >= 0; i--) {
Real sum(0.0);
for (int j=i+1; j < n; j++)
return invm;
}
-
-
-
-
#include <assert.h>
template<class T>
-Cursor<T>
-Cursor<T>::operator ++( int )
+ void
+Cursor<T>::backspace()
{
- Cursor<T> r = *this;
- assert( pointer_ );
- pointer_ = pointer_->next();
- return r;
+ Cursor<T> c(*this);
+ c--;
+ list_.remove( *this );
+}
+
+template<class T>
+ void
+Cursor<T>::del()
+{
+ Cursor<T> c(*this);
+ c++;
+ list_.remove( *this );
+ *this = c;
}
+
+
template<class T>
Cursor<T>
Cursor<T>::operator -=( int j )
return *this;
}
-template<class T>
-Cursor<T>
-Cursor<T>::operator --( int )
-{
- Cursor<T> r = *this;
- assert( pointer_ );
- pointer_ = pointer_->previous();
- return r;
-}
-
template<class T>
Cursor<T>
Cursor<T>::operator +( int i ) const
list_.insert( th, *this );
}
-template<class T>
-inline void
-Cursor<T>::backspace()
-{
- Cursor<T> c(*this);
- c--;
- list_.remove( *this );
-}
-
-template<class T>
-inline void
-Cursor<T>::del()
-{
- Cursor<T> c(*this);
- c++;
- list_.remove( *this );
- *this = c;
-}
-
template<class T>
inline const List<T>&
Cursor<T>::list() const
return ( pointer_ != 0 );
}
+
+template<class T>
+inline Cursor<T>
+Cursor<T>::operator ++( int )
+{
+ Cursor<T> r (*this);
+ assert( pointer_ );
+ pointer_ = pointer_->next();
+ return r;
+}
+
+template<class T>
+inline Cursor<T>
+Cursor<T>::operator --( int )
+{
+ Cursor<T> r (*this);
+ assert( pointer_ );
+ pointer_ = pointer_->previous();
+ return r;
+}
+
#endif
struct Matrix ;
struct StringData ;
struct String_handle ;
+struct String;
struct virtual_smat ;
struct Vector ;
class Text_stream;
#include <assert.h>
-#include "interval.hh"
#include <math.h>
+#include "interval.hh"
+#include "string.hh"
+
const Real INFTY = HUGE;
assert(max >= min);
return max-min;
}
+void
+Interval::unite(Interval h)
+{
+ if (h.min<min)
+ min = h.min;
+ if (h.max>max)
+ max = h.max;
+}
+void
+Interval::intersect(Interval h)
+{
+ min = MAX(h.min, min);
+ max = MIN(h.max, max);
+}
+Interval
+intersect(Interval x, Interval const &y)
+{
+ x.intersect(y);
+ return x;
+}
+
+
+Interval::operator String() const
+{
+ if (empty())
+ return "[empty]";
+ String s("[");
+
+ return s + min + "," + max +"]";
+}
#define INTERVAL_HH
#include <assert.h>
+#include "fproto.hh"
#include "real.hh"
return 0.0;
}
- void unite(Interval h) {
- if (h.min<min)
- min = h.min;
- if (h.max>max)
- max = h.max;
- }
+ void unite(Interval h) ;
+ void intersect(Interval h);
+
Real length() const;
void set_empty() ;
- bool empty() { return min > max; }
+ bool empty() const { return min > max; }
Interval() {
set_empty();
}
max +=r;
return *this;
}
+
+ operator String() const;
};
+Interval intersection(Interval, Interval const&);
+
#endif // INTERVAL_HH
return sqrt(r);
}
-//inline
-Real
-Matrix::operator()(int i,int j) const
-{
- assert(i >= 0 && j >= 0);
- assert(i < rows() && j < cols());
- return dat->elem(i,j);
-}
-
-//inline
-Real &
-Matrix::operator()(int i, int j)
-{
- assert(i >= 0 && j >= 0);
- assert(i < rows() && j < cols());
- return dat->elem(i,j);
-}
-
void
Matrix::fill(Real r)
{
void unit() { set_diag(1.0); }
void operator+=(const Matrix&m);
- void operator-=(const Matrix&m);
+ void operator-=(const Matrix&m);
void operator*=(Real a);
void operator/=(Real a) { (*this) *= 1/a; }
void operator=(const Matrix&m);
/// access an element
- Real operator()(int i,int j) const;
+ Real operator()(int i,int j) const { return dat->elem(i,j); }
/// access an element
- Real &operator()(int i, int j);
+ Real &operator()(int i, int j) { return dat->elem(i,j); }
/// Matrix multiply with vec (from right)
Vector operator *(const Vector &v) const;
#ifndef BOXES_HH
#define BOXES_HH
-#include "textdb.hh"
+#include "fproto.hh"
#include "real.hh"
-#include "vray.hh"
+#include "interval.hh"
+
/// 2d vector
struct Offset {
}
};
-/// a Real interval
-struct Interval {
- Real min, max;
-
- void translate(Real t) {
- min += t;
- max += t;
- }
- Real operator[](int j) {
- if (j==-1)
- return min;
- else if (j==1)
- return max;
- else
- assert(false);
-
- }
- void unite(Interval h) {
- if (h.min<min)
- min = h.min;
- if (h.max>max)
- max = h.max;
- }
- Real length() const;
- void set_empty() ;
- bool empty() { return min > max; }
- Interval() {
- set_empty();
- }
- Interval(Real m, Real M) {
- min =m;
- max = M;
- }
- Interval &operator += (Real r) {
- min += r;
- max +=r;
- return *this;
- }
-};
-
/// a 4-tuple of #Real#s
struct Box {
x.unite(b.x);
y.unite(b.y);
}
- Box(svec<Real> );
+ Box(svec<Real> &);
Box();
Box(Interval ix, Interval iy);
};
#define KEYITEM_HH
#include "item.hh"
-
+#include "vray.hh"
struct Keyitem : Item {
svec<int> pitch;
svec<int> acc;
#ifndef LOCALKEYITEM_HH
#define LOCALKEYITEM_HH
#include "item.hh"
+#include "vray.hh"
struct Local_acc {
int name , acc, octave;
#define LOOKUPSYMS_HH
#include "symbol.hh"
-
+#include "fproto.hh"
struct Lookup {
Symtables *symtables_;
/****************/
-
+ Real internote();
void parse (Text_db&t);
Parametric_symbol *linestaff(int n);
- Parametric_symbol *meter(String);
- Parametric_symbol *stem();
Symbol beam_element(int,int,Real=0);
/// round slope to closest TeXslope
pos == -3: below staff
*/
+ Symbol meter(svec<String>);
+ Symbol stem(Real y1_pos, Real y2_pos);
Symbol rule_symbol(Real height, Real width);
Symbol accidental(int);
Symbol ball(int);
Symbol clef(String);
Symbol bar(String);
Symbol dots(int);
+ Symbol slur(int dy, Real &dx, int dir);
+ Symbol half_slur(int dy, Real &dx, int dir, int xpart);
+ Symbol half_slur_middlepart(Real &dx, int dir);
+ Symbol big_slur(int dy, Real &dx, int dir);
+
+
+
Lookup();
~Lookup();
};
#ifndef METER_HH
#define METER_HH
#include "item.hh"
+#include "vray.hh"
struct Meter: Item {
svec<String> args;
Paperdef();
~Paperdef();
Real interline()const;
+ Real internote()const;
Real rule_thickness()const;
Real standard_height()const;
Real note_width() const;
PointerList<const Item*> its;
PointerList<const Spanner*> stoppers, starters;
- /// Can this be broken? true eg. for bars.
- bool breakable()const;
-
- /// does this column have items, does it have spacings attached?
- bool used;
/// prebreak is put before end of line.
PCol *prebreak;
PCol *postbreak;
/** \See{prebreak}
*/
+
PCol *daddy;
- /*
- if this column is pre or postbreak, then this field points to the parent.
- */
+ /** if this column is pre or postbreak, then this field points to
+ the parent. */
+
/// if lines are broken then this column is in #line#
const Line_of_score *line;
/// if lines are broken then this column x-coord #hpos#
Real hpos;
-
- /****************************************************************/
+ PScore * pscore_;
+
+ /****************/
+ /// does this column have items, does it have spacings attached?
+ bool used() const;
+
void add(Item *i);
+
+ /// Can this be broken? true eg. for bars.
+ bool breakable()const;
Interval width() const;
~PCol();
struct Local_key_item;
struct Clef;
struct Clef_item;
-
+struct Slur;
#endif // PROTO_HH
/// crescs etc; no particular order
IPointerList<Spanner *> spanners;
- /****************************************************************/
+ /// broken spanners
+ IPointerList<Spanner*> broken_spans;
+ /****************/
+
+ void add_broken(Spanner*);
+
svec<Item*> select_items(PStaff*, PCol*);
/// before calc_breaking
*/
/// return argument as a cursor.
- PCursor<PCol *> find_col(PCol *);
+ PCursor<PCol *> find_col(const PCol *)const;
/// delete unused columns
void clean_cols();
/// does curline fit on the paper?
bool feasible(svec<const PCol *> curline) const;
+
+ /// which is first (left, higher)
+ int compare_pcols(const PCol*, const PCol*)const;
};
/** notes, signs, symbols in a score can be grouped in two ways:
horizontally (staffwise), and vertically (columns). #PScore#
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 Real duration() const { return 0.0; }
virtual Request* clone() const =0;
/// a slur
struct Slur_req : Span_req {
virtual Request*clone()const;
+ virtual Slur_req*slur() { return this; }
};
#ifndef SCCOL_HH
#define SCCOL_HH
#include "pcol.hh"
+#include "vray.hh"
struct Score_column {
/// indirection to column
PCol * pcol_;
+
/// length of notes/rests in this column
svec<Real> durations;
#endif // SCCOL_HH
+
+
+
// need to store height of each staff.
IPointerList<Line_of_staff*> staffs;
- const PScore * score; // needed to generate staffs
+ PScore * pscore_; // needed to generate staffs
/****************/
- Line_of_score(svec<const PCol *> sv, const PScore *);
+ Line_of_score(svec<const PCol *> sv, PScore *);
String TeXstring() const;
};
#endif
+
struct Simple_column : Staff_column {
svec<Rhythmic_req *> notes;
+ svec<Slur_req *> slurs;
Stem_req *stem_;
Beam_req *beam_;
Simple_staff* staff_;
/****************/
-
+ Slur_req * find_slur(Voice *);
void typeset_item(Item *, int=1);
-
void typeset_item_directional(Item *, int dir, int=1);
Molecule *create_command_mol(Command *com);
bool processed_key;
bool processed_clef;
Clef clef_;
-
+ 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_notes();
+ void do_note(Rhythmic_req*);
Simple_walker(Simple_staff*);
Simple_column *col();
Simple_staff *staff();
void do_local_key(Note_req*n);
+ int find_slur(const Voice*v);
};
--- /dev/null
+/*
+ slur.hh -- part of LilyPond
+
+ (c) 1996 Han-Wen Nienhuys
+*/
+
+#ifndef SLUR_HH
+#define SLUR_HH
+
+#include "spanner.hh"
+#include "fproto.hh"
+#include "vray.hh"
+
+struct Slur : Spanner {
+
+ svec<Notehead*> encompass;
+ int dir;
+
+ bool open_left,open_right;
+
+ /****************/
+
+ void print()const;
+ void preprocess();
+ void add(Notehead*);
+ void set_default_dir();
+ Interval height() const;
+ Spanner* broken_at(const PCol*, const PCol*) const;
+ void process();
+private:
+ void brew_molecule();
+};
+
+#endif // SLUR_HH
+
+
/// one broken line of staff.
struct Line_of_staff {
- IPointerList<Spanner *> brokenspans;
- Line_of_score const * scor;
+
+ Line_of_score * line_of_score_;
const PStaff *pstaff_;
/****************/
String TeXstring() const;
Line_of_staff(Line_of_score*, PStaff *);
Interval height() const;
+
};
#endif
struct Voice_element {
Real duration;
const Voicegroup *group;
- const Voice *voice;
+ const Voice *voice_;
IPointerList<Request*> reqs;
PointerList<const Item *> granted_items;
%%
%% include file for LilyPond
+
\def\mdef#1#2{\def#1{{\musicfnt\char#2}}}
%% musix defs
\newdimen\interstaffrule
\def\musixtwentydefs{
+ \font\slurufont=xslu20
+ \font\slurdfont=xsld20
+ \font\slurhfont=xslz20
+ \font\hslurufont=xslhu20
+ \font\hslurdfont=xslhd20
+ \font\hslurhfont=xslhz20
\font\musicfnt=musix20
\balkhoog=20pt
\staffrulethickness=0.4pt
\musixtwentydefs
\musixcalc
+\def\slurcharh#1{{\slurhfont\char#1}}
+\def\slurcharu#1{{\slurufont\char#1}}
+\def\slurchard#1{{\slurdfont\char#1}}
+\def\hslurcharh#1{{\hslurhfont\char#1}}
+\def\hslurcharu#1{{\hslurufont\char#1}}
+\def\hslurchard#1{{\hslurdfont\char#1}}
\mdef\quartball{'007}
\mdef\halfball{'010}
ritme = rhythmstaff {
- voice { $ c2 r32 r32 r16 r8 r4 c2 c2 c2 c2 c2
- c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 $ }
+ voice { $ c2 c2
+ %[c8( )'a8 c8 c8]
+ c2 c2
+
+ [fis16 'dis16( fis16 'dis16 ][fis16) 'dis16 fis16 'dis16]
+ c2 r32 r32 r16 r8 r4 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 $ }
}
melody=
melodicstaff {
-
- voice { $ fis 'dis 'fis 'gisis $ }
- voice { $ 'eses $ start 0.75}
- voice { $ 'cis $ start 0.75}
- voice { $ f $ start 0.75}
- voice { $ gis $ start 0.75}
+ voice { $ c () `bes $ start 0.5 }
+ voice { $
+ %[fis16 'dis16 fis16 'dis16 fis16 'dis16 fis16 'dis16]
+ c2
+ 'fis ()'gisis $ }
+
+
+ voice { $ d () d $ start 0.5 }
+ voice { $ a () bes $ start 0.5 }
+ voice { $ fis () g $ start 0.5 }
voice { $
''c2.. r8 r4 r8 r16 r32 r32
- [d8 e8 f8 g8] [d8 e8 f8 g8]
+ [d8 e8 'f8 g8] [d8 e8 f8 g8]
''fis1
a8 b8 'c8 'd8 ''c8 ```c8 c4 c4 c4 c4
\duration 16 `b16 `a16 `g16 `f16 \duration 4
% staff { melody }
commands {
meter 4 4
-
key $ fis cis gis $
skip 2:0
key $ $
meter 2 4
-
skip 19:0
}
}
dist:
- ln Makefile $(DDIR)/objects/
\ No newline at end of file
+ ln Makefile $(DDIR)/objects/
+
+clean:
+ rm -f *.o
slope *= dir;
{
- Real inter =paper()->interline()/2;
+ Real inter =paper()->internote();
Real unitslope = slope*inter;
// set beamslope, for setting stems correctly
void
Beam::brew_molecule()
{
- Real inter=paper()->interline()/2;
+ assert(left->line == right->line);
+ Real inter=paper()->internote();
Real sl = slope*inter;
Real w = width().length() + paper()->rule_thickness();
Symbol s = paper()->lookup_->beam(sl,w);
#include "boxes.hh"
#include "const.hh"
+#include "vray.hh"
-void
-Interval::set_empty() {
- min = INFTY;
- max = -INFTY;
-}
-Real
-Interval::length() const {
- return max-min;
-}
-Box::Box(svec<Real> s)
+Box::Box(svec<Real> &s)
{
assert(s.sz() == 4);
x.min = s[0];
void
Score::connect_nonmus(PCol* c1, PCol *c2, Real d)
{
- if (c2->used && c1->used) {
+ if (c2->used() && c1->used()) {
do_connect(c1,c2,d);
// alert! this is broken!
Key::read(svec<String> s)
{
svec<int> newkey;
-
+ for (int j = 0; j < 7; j++)
+ accidentals[j] = 0;
+
for (int i=0; i < s.sz(); i++) {
int large, small;
lookup_notename(large, small, s[i]);
for (int i =0; i < pitch.sz(); i++) {
Symbol s= paper()->lookup_->accidental(acc[i]);
Atom a(s);
- a.translate(Offset(0,c_position + pitch[i] * inter));
+ a.translate(Offset(0,(c_position + pitch[i]) * inter));
Molecule m(a);
output->add_right(m);
}
#include "dimen.hh"
#include "tex.hh"
+Real
+Lookup::internote()
+{
+ return ball(4).dim.y.length()/2;
+}
+
void
Lookup::parse(Text_db&t)
{
{
return (*symtables_)("rests")->lookup(String(j));
}
+
Symbol
Lookup::accidental(int j)
{
return (*symtables_)("clefs")->lookup(s);
}
- Symbol
+Symbol
Lookup::dots(int j)
{
if (j>3)
assert(i);
int arg;
- String idx ;
- if (i<0) {
+ String idx;
+
+ if (i < 0) {
idx = "botlines";
arg = -i;
- }else {
+ } else {
arg = i;
idx = "toplines";
}
/****************************************************************/
-struct Meter_sym:Parametric_symbol {
-
- Meter_sym(Symtables*s) : Parametric_symbol(s){ }
- Symbol eval(svec<String> a) const{
- Symbol s;
- s.dim.x = Interval( convert_dimen(0,"pt"),
- convert_dimen(10,"pt"));
- s.dim.y = Interval(0, convert_dimen(20,"pt") ); // todo
- String src = (*symtables_)("param")->lookup("meter").tex;
- s.tex = substitute_args(src,a);
- return s;
- }
-};
-/****************************************************************/
-
-struct Stem_sym:Parametric_symbol {
- Stem_sym(Symtables*s) : Parametric_symbol(s) { }
- Symbol eval(svec<String> a) const {
- Real y1 = a[0].fvalue();
- Real y2 = a[1].fvalue();
- assert(y1 <= y2);
- Symbol s;
- s.dim.x = Interval(0,0);
- s.dim.y = Interval(y1,y2);
+Symbol
+Lookup::meter(svec<String> a)
+{
+ Symbol s;
+ s.dim.x = Interval( convert_dimen(0,"pt"),
+ convert_dimen(10,"pt"));
+ s.dim.y = Interval(0, convert_dimen(20,"pt") ); // todo
+ String src = (*symtables_)("param")->lookup("meter").tex;
+ s.tex = substitute_args(src,a);
+ return s;
+}
- String src = (*symtables_)("param")->lookup("stem").tex;
- s.tex = substitute_args(src,a);
- return s;
- }
-};
-Parametric_symbol *
-Lookup::meter(String )
+Symbol
+Lookup::stem(Real y1,Real y2)
{
- return new Meter_sym(symtables_);
+ assert(y1 <= y2);
+ Symbol s;
+
+ s.dim.x = Interval(0,0);
+ s.dim.y = Interval(y1,y2);
+
+ svec<String> a;
+ a.add(print_dimen(y1));
+ a.add(print_dimen(y2));
+
+ String src = (*symtables_)("param")->lookup("stem").tex;
+ s.tex = substitute_args(src,a);
+ return s;
}
+
Parametric_symbol *
Lookup::linestaff(int n)
{
return new Linestaf_symbol(n,symtables_);
}
-Parametric_symbol*
-Lookup::stem()
-{
- return new Stem_sym(symtables_);
-}
cout <<
"LilyPond, a music typesetter.\n"
"Copyright (C) 1996 by\n"
- " Han-Wen Nienhuys <hanwen@stack.urc.tue.nl>\n"
+ " Han-Wen Nienhuys <hanwen@stack.nl>\n"
"\n"
" This program is free software; you can redistribute it and/or\n"
"modify it under the terms of the GNU General Public License version 2\n"
Melodic_staff::get_TYPESET_item(Command*com)
{
if (com->args[0] == "KEY") {
- return new Keyitem(NO_LINES); // urgh.
+ return new Keyitem(NO_LINES); // urgh. depends on clef.
} else
return Simple_staff::get_TYPESET_item(com);
}
:args(a)
{
}
+
void
Meter::preprocess()
-{
- Parametric_symbol *p = paper()->lookup_->meter("general");
- Symbol s = p->eval(args);
- delete p;
+{
+ Symbol s = paper()->lookup_->meter(args);
output = new Molecule(Atom(s));
}
#include "glob.hh"
+#include "vray.hh"
+#include "interval.hh"
#include "dimen.hh"
#include "string.hh"
#include "molecule.hh"
return substitute_args(s, a);
}
+/****************/
String
Molecule::TeXstring() const
Paperdef *p = paper();
- Real dy = p->interline()/2;
+ Real dy = p->internote();
Symbol s = p->lookup_->ball(balltype);
output = new Molecule(Atom(s));
{
return lookup_->ball(4).dim.y.length();
}
+
+Real
+Paperdef::internote() const
+{
+ return lookup_->internote();
+}
Real
Paperdef::note_width()const
{
#include "pcol.hh"
+#include "pscore.hh"
#include "pstaff.hh"
#include "debug.hh"
void
PCol::print() const
{
- #ifndef NPRINT
+#ifndef NPRINT
mtor << "PCol {";
+ if (pscore_) { // ugh
+ PCursor<PCol*> me=pscore_->find_col(this);
+ PCursor<PCol*> bot(pscore_->cols.top());
+ if (me.ok()) {
+ mtor << "rank: " << me - bot << '\n';
+ }
+ }
mtor << "# symbols: " << its.size() ;
if (breakable()){
- mtor << "pre,post: ";
+ mtor << "\npre,post: ";
prebreak->print();
postbreak->print();
+ } else if (daddy) {
+ mtor<<'\n' << ((this == daddy->prebreak) ? "prebreak" : "postbreak");
}
mtor << "extent: " << width().min << ", " << width().max << "\n";
mtor << "}\n";
- #endif
+#endif
}
int
-PCol::compare(const PCol &, const PCol &)
+PCol::compare(const PCol &c1, const PCol &c2)
{
- assert(false);
- return 0 ;
+ return c1.pscore_->compare_pcols(&c1,&c2);
}
void
assert(prebreak&&postbreak);
assert(prebreak->daddy == this);
assert(postbreak->daddy == this);
- }
-
+ }
}
void
prebreak = new PCol(this);
postbreak = new PCol(this);
- used = true;
+ prebreak->pscore_ = pscore_;
+ postbreak->pscore_ = pscore_;
+
+
}
bool
prebreak=0;
postbreak=0;
line=0;
- used = false;
+
+ pscore_ = 0;
}
PCol::~PCol()
{
its.bottom().add(i);
i->pcol_ = this;
- used = true;
+
+}
+
+bool
+PCol::used()const
+{
+ return breakable() || its.size();
}
PScore::clean_cols()
{
for (PCursor<PCol *> c(cols); c.ok(); )
- if (!c->used) {
+ if (!c->used()) {
c.del();
} else
c++;
sp->pstaff_ = ps;
spanners.bottom().add(sp);
ps->spans.bottom().add(sp);
- sp->left->starters.bottom().add(sp);
- sp->right->stoppers.bottom().add(sp);
+ // do not init start/stop fields. These are for broken spans only.
}
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];
+ c->hpos = config[i];
}
}
}
+int
+PScore::compare_pcols(const PCol*a, const PCol*b)const
+{
+ PCursor<PCol*> ac(find_col(a));
+ PCursor<PCol*> bc(find_col(b));
+ assert(ac.ok() && bc.ok());
+ return ac - bc;
+}
+
/*
return all breakable columns
*/
void
PScore::add(PCol *p)
{
+ p->pscore_ = this;
+ if (p->breakable()){
+ p->prebreak->pscore_ = this;
+ p->postbreak->pscore_ = this;
+ }
cols.bottom().add(p);
}
void
PScore::postprocess()
{
- for (PCursor<Spanner*> ic(spanners); ic.ok(); ic++) {
+ for (PCursor<Spanner*> ic(broken_spans); ic.ok(); ic++) {
ic->process();
}
for (PCursor<Item*> ic(its); ic.ok(); ic++){
ic->postprocess();
}
}
+
+PCursor<PCol *>
+PScore::find_col(const PCol *c)const
+{
+ PCursor<PCol*> cc(cols);
+ for (; cc.ok(); cc++)
+ if (cc.ptr() == c || cc->prebreak == c || cc->postbreak == c)
+ return cc;
+ return cc;
+}
+
+void
+PScore::add_broken(Spanner*s)
+{
+ broken_spans.bottom().add(s);
+ s->left->starters.bottom().add (s);
+ s->right->stoppers.bottom().add (s);
+}
bool
Score_column::used() {
- return pcol_->used;
+ return pcol_->used();
}
void
Command*c = new Command(w);
c->priority = -10000;
pc.add(c);
- pc ++;
+ pc++;
}
return pc;
Score_commands::insert_between(Command victim, PCursor<Command*> firstc,
PCursor<Command*> last)
{
- assert(last->when==firstc->when);
PCursor<Command*> c(firstc+1);
- assert(last.ok());
+ assert(last->when==firstc->when&&firstc < last&&last.ok());
+
while (c < last) {
if (c->priority <= victim.priority) {
c.insert(new Command(victim));
sc->clean_cols();
for (PCursor<Score_column*> c(cols_); c.ok(); ) {
- if (!c->pcol_->used) {
+ if (!c->pcol_->used()) {
mtor << "removing : ";
c->print();
c.del();
Line_of_score::Line_of_score(svec<const PCol *> sv,
- const PScore *ps)
+ PScore *ps)
{
- score = ps;
+ pscore_ = ps;
for (int i=0; i< sv.sz(); i++) {
PCol *p=(PCol *) sv[i];
cols.bottom().add(p);
p->line=this;
}
- for (PCursor<PStaff*> sc(score->staffs); sc.ok(); sc++)
+ for (PCursor<PStaff*> sc(pscore_->staffs); sc.ok(); sc++)
staffs.bottom().add(new Line_of_staff(this, sc));
}
/* construct a line with the named columns. Make the line field
if (rq->beam()) {
beam_ = rq->beam();
}
+ if (rq->slur()) {
+ slurs.add(rq->slur());
+ }
}
}
#include "keyitem.hh"
#include "clefitem.hh"
#include "keyitem.hh"
+#include "slur.hh"
#include "localkeyitem.hh"
void
}
void
-Simple_walker::do_notes()
+Simple_walker::do_note(Rhythmic_req*rq)
{
Simple_column*c = col();
Simple_staff *s = staff();
- for (int i = 0; i < c->notes.sz(); i ++) {
- Rhythmic_req*rq = c->notes[i];
- if (rq->note()) {
- Note_req * req = rq->note() ;
- Notehead*n = s->get_notehead(req, clef_.c0_pos);
- stem_->add(n);
- noteheads.add(n);
-
- if (wantkey)
- do_local_key(req);
- }
+
+ if (rq->note()) {
+ Note_req * req = rq->note() ;
+ const Voice *v = req->elt->voice_;
- if (rq->rest()) {
- c->typeset_item( s->get_rest(rq->rest()) );
+ Notehead*n = s->get_notehead(req, clef_.c0_pos);
+ stem_->add(n);
+ noteheads.add(n);
+ int sidx =find_slur(v);
+ if (sidx >= 0) {
+ pending_slurs[sidx]->add(n);
}
- }
+
+ if (wantkey)
+ do_local_key(req);
+ }
+
+ if (rq->rest()) {
+ c->typeset_item( s->get_rest(rq->rest()) );
+ }
}
void
error("Too many beams");
beam_ = new Beam;
}
+ for (int i=0; i < c->slurs.sz(); i++) {
+ Slur_req*sl = c->slurs[i];
+
+ if (sl->spantype == Span_req::START) {
+ if (find_slur(sl->elt->voice_ )>=0)
+ error("Too many slurs in voice");
+ pending_slur_reqs.add(sl);
+ pending_slurs.add(new Slur);
+ }
+ }
if (c->stem_) {
stem_ = s->get_stem(c->stem_->stem());
}
- do_notes();
-
+ for (int i = 0; i < c->notes.sz(); i ++) {
+ do_note(c->notes[i]);
+ }
+
if (beam_) {
beam_->add(stem_);
}
c->typeset_item(noteheads[i]);
}
noteheads.set_size(0);
-
+
if (local_key_item_) {
c->typeset_item_directional(local_key_item_, -1);
local_key_item_ = 0;
if (stem_) {
stem_ = 0;
}
+ for (int i=0; i < c->slurs.sz(); i++) {
+ Slur_req*sl = c->slurs[i];
+
+ if (sl->spantype == Span_req::STOP) {
+ int idx = find_slur(sl->elt->voice_);
+ if (idx < 0)
+ error("can't find slur to end");
+
+ pscore_->typeset_spanner(pending_slurs[idx],
+ s->theline);
+ pending_slurs.del(idx);
+ pending_slur_reqs.del(idx);
+ }
+ }
+
}
Simple_walker::Simple_walker(Simple_staff*s)
processed_clef =false;
processed_key = false;
}
+
+int
+Simple_walker::find_slur(const Voice *v)
+{
+ for (int i=0; i < pending_slur_reqs.sz(); i++) {
+ if (pending_slur_reqs[i]->elt->voice_ == v)
+ return i;
+ }
+ return -1;
+}
+
+
--- /dev/null
+#include "slur.hh"
+#include "lookup.hh"
+#include "paper.hh"
+#include "notehead.hh"
+#include "pcol.hh"
+#include "molecule.hh"
+#include "debug.hh"
+#include "boxes.hh"
+
+void
+Slur::add(Notehead*n)
+{
+ encompass.add(n);
+ dir = 0;
+ open_right=open_left=false;
+}
+
+Interval
+Slur::height() const
+{
+ return Interval(0,0); // todo
+}
+
+void
+Slur::set_default_dir()
+{
+ int sumpos=0;
+ for (int i=0; i < encompass.sz(); i ++) {
+ sumpos += encompass[i]->position;
+ }
+
+ /* should consult stems */
+ Real meanpos = sumpos/Real(encompass.sz());
+ if (meanpos < 5) // todo
+ dir = -1;
+ else
+ dir = 1;
+}
+
+void
+Slur::print()const
+{
+ mtor << "Slur.\n";
+}
+
+void
+Slur::preprocess()
+{
+ right = encompass.last()->pcol_;
+ left = encompass[0]->pcol_;
+}
+
+Spanner*
+Slur::broken_at(const PCol*l, const 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)
+ ret->encompass.add(encompass[i]);
+ }
+ if (right != r)
+ ret->open_right = true;
+ if (left != l)
+ ret->open_left = true;
+
+ ret->left = l;
+ ret->right = r;
+ return ret;
+}
+
+void
+Slur::process()
+{
+ set_default_dir();
+ brew_molecule();
+}
+
+void
+Slur::brew_molecule()
+{
+ output = new Molecule;
+ assert(left->line == right->line);
+ int minp=1000, maxp=-1000; // todo
+ for (int i=0; i<encompass.sz(); i++) {
+ minp = MIN(encompass[i]->position, minp);
+ maxp = MAX(encompass[i]->position, maxp);
+ }
+
+ assert(encompass.sz()>0); // todo
+ int pos1 = encompass.last()->position;
+ int pos2 = encompass[0]->position;
+
+ int dy = pos1-pos2;
+
+ Real w = width().length();
+ Real nw = paper()->note_width();
+ w -= nw;
+ Symbol sl = paper()->lookup_->slur(dy , w, dir);
+ Atom a(sl);
+ a.translate(Offset(nw,pos2*paper()->internote()));
+ output->add(a);
+}
+
Interval
Spanner::width()const
{
- return Interval(0,right->hpos - left->hpos);
+ Real r =right->hpos,
+ l= left->hpos;
+ assert(r>=l);
+
+ return Interval(0, r-l);
}
Paperdef*
// the staff itself: eg lines, accolades
s += "\\hbox{";
{
- Symbol sym = pstaff_->get_stafsym(scor->score->paper_->linewidth);
+ Symbol sym = pstaff_->get_stafsym(line_of_score_->pscore_-> // ugh
+ paper_->linewidth);
s+=sym.tex;
- PCursor<const PCol *> cc(scor->cols);
+ PCursor<const PCol *> cc(line_of_score_->cols);
Real lastpos=cc->hpos;
// all items in the current line & staff.
Line_of_staff::Line_of_staff(Line_of_score * sc, PStaff*st)
{
- scor=sc;
+ line_of_score_=sc;
pstaff_=st;
-#if 0
+
+
const PCol *linestart = sc->cols.top();
const PCol *linestop = sc->cols.bottom();
+
for (PCursor<const Spanner*> sp(pstaff_->spans); sp.ok(); sp++) {
const PCol *brokenstart = &MAX(*linestart, *sp->left);
const PCol *brokenstop = &MIN(*linestop, *sp->right);
-// if (*brokenstop < *brokenstart)
- brokenspans.bottom().add(sp->broken_at(0,0));
- }
-#endif
- for (PCursor<const Spanner*> sp(pstaff_->spans); sp.ok(); sp++) {
-
- brokenspans.bottom().add(sp->broken_at(0,0));
+ if ( *brokenstart < *brokenstop) {
+ line_of_score_->pscore_-> // higghl
+ add_broken(sp->broken_at(brokenstart,brokenstop));
+ }
}
}
{
Interval y;
{
- Symbol s = pstaff_->stafsym->eval(scor->score->paper_->linewidth);
+ Symbol s = pstaff_->stafsym->eval(line_of_score_->pscore_->
+ paper_->linewidth);
y = s.dim.y;
}
- PCursor<const PCol *> cc(scor->cols);
+ PCursor<const PCol *> cc(line_of_score_->cols);
// all items in the current line & staff.
for (; cc.ok(); cc++) {
void
Stem::set_stemend(Real se)
{
+ assert(!output);
// todo: margins
assert((dir > 0 && se >= maxnote) || (se <= minnote && dir <0));
assert(!output);
Paperdef *p =paper();
- Parametric_symbol *stem = p->lookup_->stem();
-
- Real dy = p->interline()/2;
- String y1 =print_dimen( dy * bot);
- String y2 = print_dimen(dy * top);
- Symbol ss =stem->eval(y1,y2);
- delete stem;
+
+ Real dy = p->internote();
+ Symbol ss =p->lookup_->stem(bot*dy,top*dy);
+
output = new Molecule(Atom(ss));
#include "symbol.hh"
+#include "vray.hh"
+#include "textdb.hh"
Symbol::Symbol()
: dim(Interval(0,0),Interval(0,0))
#include "misc.hh"
+#include "textdb.hh"
#include "dimen.hh"
#include "debug.hh"
#include "real.hh"
if (elt_query(s))
return (*this)[s];
else {
- error( "Unknown symbol " +s+'\n');
+ error( "Unknown symbol `" +s+"'\n");
}
+ Symbol sy; // unreachable
+ return sy;
}
Symtable*
Symtables::read(Text_db &symini)
{
while (!symini.eof()) {
- Text_record r( symini++);
+ Text_record r(symini++);
if (r[0] == "end" )
return;
assert (r[0] == "table");
(*this)[tabnam] = sp;
}
}
-
-
-
#include "scoreline.hh"
#include "staffline.hh"
-#include "list.cc"
+
#include "plist.cc"
-#include "cursor.cc"
+
#define IPLC_instantiate(a) IPL_instantiate(a); PL_instantiate(const a)
#include "stcol.hh"
#include "spanner.hh"
-#include "list.cc"
#include "plist.cc"
-#include "cursor.cc"
+
IPL_instantiate(Score_column);
IPL_instantiate(Staff_column);
#include "request.hh"
#include "command.hh"
#include "molecule.hh"
-#include "list.cc"
#include "plist.cc"
-#include "cursor.cc"
+
IPL_instantiate(Atom);
IPL_instantiate(Command);
IPL_instantiate(Request);
-L_instantiate(void*);
+
--- /dev/null
+#include "list.cc"
+#include "cursor.cc"
+
+L_instantiate(void *);
#include "tex.hh"
#include "symbol.hh"
#include "const.hh"
+#include "vray.hh"
String
vstrut(Real h)
--- /dev/null
+#include "lookup.hh"
+#include "molecule.hh"
+#include <math.h>
+#include "dimen.hh"
+#include "debug.hh"
+
+static
+char direction_char(int y_sign)
+{
+ char c;
+ switch(y_sign){
+ case -1:
+ c = 'd';
+ break;
+ case 0:
+ c = 'h';
+ break;
+ case 1:
+ c = 'u';
+ break;
+ default:
+ assert(false);
+ }
+ return c;
+}
+
+Symbol
+Lookup::half_slur_middlepart(Real &dx, int dir)
+{
+ if (dx >= convert_dimen(400,"pt")) // todo
+ error ("halfslur too large");
+ int widx = int(floor(dx / 4.0));
+ dx = widx * 4.0;
+ widx --;
+
+ Symbol s;
+
+ s.dim.y = Interval(MIN(0,0), MAX(0,0));
+ s.dim.x = Interval(0,dx);
+
+ String f = String("\\hslurchar");
+ f += direction_char(0);
+
+ int idx = widx;
+ if (dir < 0)
+ idx += 128;
+
+
+ f+=String( "{" ) + idx + "}";
+ s.tex = f;
+ Atom a(s);
+ a.translate(Offset(dx/2,0));
+ s.tex = a.TeXstring();
+
+ return s;
+}
+Symbol
+Lookup::half_slur(int dy, Real &dx, int dir, int xpart)
+{
+ if (!xpart)
+ return half_slur_middlepart(dx, dir);
+
+ int widx;
+
+ if (dx >= convert_dimen(96,"pt"))
+ dx = convert_dimen(96,"pt");
+
+ widx = int(rint(dx/12.0));
+ dx = widx*12.0;
+ widx --;
+
+ Symbol s;
+ s.dim.x = Interval(0,dx);
+ s.dim.y = Interval(MIN(0,dy), MAX(0,dy));
+
+
+ String f = String("\\hslurchar");
+
+ f+= direction_char(dir);
+
+ int hidx = dy;
+ if (hidx <0)
+ hidx = -hidx;
+ hidx --;
+ int idx =-1;
+
+
+ idx = widx * 16 + hidx;
+ if (xpart < 0)
+ idx += 128;
+
+ f+=String( "{" ) + idx + "}";
+
+
+ s.tex = f;
+
+ return s;
+}
+
+Symbol
+Lookup::slur (int dy , Real &dx, int dir)
+{ // ugh. assuming pt here.
+ assert(dx >=0);
+ int y_sign = sgn(dy);
+
+ bool large = dy > 16;
+
+ if (y_sign) {
+ large |= dx>= convert_dimen(4*16, "pt");
+ } else
+ large |= dx>= convert_dimen(4*54, "pt");
+
+ if (large) {
+ return big_slur(dy, dx, dir);
+ }
+
+ int widx = int(floor(dx/4.0)); // slurs better too small..
+ dx = 4.0 * widx;
+ widx--;
+ int hidx = dy;
+ if (hidx <0)
+ hidx = -hidx;
+ hidx --;
+ if (hidx > 16)
+ error("slur to steep");
+
+
+ Symbol s;
+ s.dim.x = Interval(0,dx);
+ s.dim.y = Interval(MIN(0,dy), MAX(0,dy));
+
+ String f = String("\\slurchar") + direction_char(y_sign);
+
+ int idx=-1;
+ if (y_sign) {
+ idx = hidx * 16 + widx;
+ if (dir < 0)
+ idx += 128;
+ } else {
+ if (dx >= convert_dimen(4*54, "pt"))
+ error("slur too wide");
+ idx = widx;
+ if (dir > 0)
+ idx += 54;
+ }
+
+ f+=String( "{" ) + idx + "}";
+ s.tex = f;
+
+ Atom a(s);
+ a.translate(Offset(dx/2,0));
+ s.dim = a.extent();
+ s.tex = a.TeXstring();
+ return s;
+}
+
+Symbol
+Lookup::big_slur(int dy , Real &dx, int dir)
+{
+ assert(dx >= convert_dimen(24,"pt"));
+
+ Real slur_extra =ABS(dy) /2.0 + 2;
+ int l_dy = Real (dy)/2 + slur_extra*dir;
+ int r_dy = dy - l_dy;
+
+ Real left_wid = dx/4.0;
+ Real right_wid = left_wid;
+
+ Atom l = half_slur(l_dy, left_wid, dir, -1);
+ Atom r = half_slur(r_dy, right_wid, dir, 1);
+ Real mid_wid = dx - left_wid - right_wid;
+ Atom m = half_slur(0, mid_wid, dir, 0);
+
+ Molecule mol;
+ mol.add(l);
+ Atom a(m);
+ a.translate(Offset(0,slur_extra * internote()));
+ mol.add_right(m);
+ mol.add_right(r);
+ mol.translate(Offset(l_dy * internote(), 0));
+ Symbol s;
+ s.tex = mol.TeXstring();
+ s.dim = mol.extent();
+ return s;
+}
+
+
void
Voice::add(Voice_element*v)
{
+ v->voice_ = this;
elts.bottom().add(v);
}
void
Voice::print() const
{
- #ifndef NPRINT
-
+#ifndef NPRINT
mtor << "start: "<< start<<eol;
for (PCursor<Voice_element*> vec(elts); vec.ok(); vec++)
vec->print();
Voice_element::Voice_element()
{
- voice = 0;
+ voice_ = 0;
group = 0;
duration = 0.0;
}
Voice_element::Voice_element(Voice_element const&src)
{
duration=src.duration;
- voice=src.voice;
+ voice_=src.voice_;
IPointerList__copy(Request*, reqs, src.reqs, clone());
group=src.group;
assert(!granted_items.size() && !granted_spanners.size());
-void warning(String s)
+void
+warning(String s)
{
WARN << s;
}
-void error(String s)
+void
+error(String s)
{
- cerr << "\n" << s << "\nexiting..\n";
+ cerr << "\nerror: " << s << "\n";
exit(1);
}
4 \quartball 0pt 6pt -2.5pt 2.5pt
end
+table slur
+ whole \slurchar%{%} 0pt 0pt 0pt 0pt
+ half \hslurchar%{%} 0pt 0pt 0pt 0pt
+end
table accidentals
-2 \flatflat 0pt 10.2pt -2.5pt 7.5pt
-1 \flat 0pt 6pt -2.5pt 7.5pt