diff options
author | Han-Wen Nienhuys <hanwen@xs4all.nl> | 1996-11-28 12:02:01 +0100 |
---|---|---|
committer | Han-Wen Nienhuys <hanwen@xs4all.nl> | 1996-11-28 12:02:01 +0100 |
commit | fc22f69328fd2d5030bb1feff8d0f6da37e8217d (patch) | |
tree | 9e9c59c8c0c104cf4388f728b19f0e9be7b6991d | |
parent | c3fe80ddeb9acfcf5d569fcef1caaef6ef7a01fb (diff) |
release: 0.0.8
-rw-r--r-- | .dstreamrc | 3 | ||||
-rw-r--r-- | Documentation/CodingStyle (renamed from CodingStyle) | 0 | ||||
-rw-r--r-- | Documentation/Makefile | 4 | ||||
-rw-r--r-- | Documentation/algorithms | 98 | ||||
-rw-r--r-- | Makefile | 19 | ||||
-rw-r--r-- | README | 9 | ||||
-rw-r--r-- | Sources.make | 7 | ||||
-rw-r--r-- | TODO | 13 | ||||
-rw-r--r-- | calcideal.cc | 3 | ||||
-rw-r--r-- | flower/Makefile | 4 | ||||
-rw-r--r-- | flower/README | 10 | ||||
-rw-r--r-- | flower/Sources.make | 5 | ||||
-rw-r--r-- | flower/TODO | 7 | ||||
-rw-r--r-- | flower/cursor.cc | 31 | ||||
-rw-r--r-- | flower/cursor.hh | 2 | ||||
-rw-r--r-- | flower/fproto.hh | 38 | ||||
-rw-r--r-- | flower/interval.cc | 18 | ||||
-rw-r--r-- | flower/interval.hh | 58 | ||||
-rw-r--r-- | flower/lgetopt.cc | 2 | ||||
-rw-r--r-- | flower/pcursor.hh | 6 | ||||
-rw-r--r-- | flower/plist.hh | 2 | ||||
-rw-r--r-- | flower/textstr.hh | 4 | ||||
-rw-r--r-- | identifier.cc | 7 | ||||
-rw-r--r-- | identifier.hh | 8 | ||||
-rw-r--r-- | item.cc | 13 | ||||
-rw-r--r-- | item.hh | 19 | ||||
-rw-r--r-- | lexer.hh | 1 | ||||
-rw-r--r-- | lilyponddefs.tex | 26 | ||||
-rw-r--r-- | lookupsyms.cc | 24 | ||||
-rw-r--r-- | lookupsyms.hh | 7 | ||||
-rw-r--r-- | maartje.ly | 2 | ||||
-rw-r--r-- | melodicstaff.cc | 24 | ||||
-rw-r--r-- | misc.cc | 22 | ||||
-rw-r--r-- | misc.hh | 6 | ||||
-rw-r--r-- | notehead.cc | 67 | ||||
-rw-r--r-- | notehead.hh | 38 | ||||
-rw-r--r-- | paper.cc | 23 | ||||
-rw-r--r-- | paper.hh | 4 | ||||
-rw-r--r-- | parser.y | 14 | ||||
-rw-r--r-- | pscore.cc | 18 | ||||
-rw-r--r-- | pscore.hh | 6 | ||||
-rw-r--r-- | request.cc | 3 | ||||
-rw-r--r-- | rhythmstaff.cc | 18 | ||||
-rw-r--r-- | score.cc | 7 | ||||
-rw-r--r-- | simpleprint.cc | 7 | ||||
-rw-r--r-- | spanner.cc | 1 | ||||
-rw-r--r-- | spanner.hh | 5 | ||||
-rw-r--r-- | stem.cc | 15 | ||||
-rw-r--r-- | stem.hh | 21 | ||||
-rw-r--r-- | symbol.ini | 5 | ||||
-rw-r--r-- | table.cc | 12 | ||||
-rw-r--r-- | tex.hh | 1 | ||||
-rw-r--r-- | tstream.cc | 5 | ||||
-rw-r--r-- | voice.hh | 2 |
54 files changed, 646 insertions, 128 deletions
diff --git a/.dstreamrc b/.dstreamrc index 7dcded772c..bb7e1bb71d 100644 --- a/.dstreamrc +++ b/.dstreamrc @@ -18,4 +18,5 @@ Command 1 Score_commands 1 Note_req 1 Rhythmic_req 1 -Rest_req 1
\ No newline at end of file +Rest_req 1 +delete_identifiers 1 diff --git a/CodingStyle b/Documentation/CodingStyle index c5d730c0a6..c5d730c0a6 100644 --- a/CodingStyle +++ b/Documentation/CodingStyle diff --git a/Documentation/Makefile b/Documentation/Makefile new file mode 100644 index 0000000000..da2847045e --- /dev/null +++ b/Documentation/Makefile @@ -0,0 +1,4 @@ + +DOCFILES=CodingStyle algorithms Makefile +dist: + ln $(DOCFILES) $(DDIR)/Documentation/
\ No newline at end of file diff --git a/Documentation/algorithms b/Documentation/algorithms new file mode 100644 index 0000000000..f422332e41 --- /dev/null +++ b/Documentation/algorithms @@ -0,0 +1,98 @@ +Date: Tue, 5 Nov 1996 00:01:32 +0100 +From: Werner Icking <Werner.Icking@gmd.de> +To: hanwen@stack.urc.tue.nl +Cc: dsimons@logicon.com +Subject: Re: font sizes. + +> Date: Mon, 4 Nov 1996 22:37:54 +0100 (MET) +> From: Han-Wen Nienhuys <hanwen@stack.urc.tue.nl> +> > +> >There were different schemes when music was typeset by hand. If I remember +> >right Harder uses another scheme that Gomberg. Both scheme may be used +> +> Who are Harder and Gomberg? Do you have references? + +Both are mentioned in the master thesis by Steinbach & Schofer who +invented M(u)TeX, the grandmother of all M...TeXs. The Musiclibrary +in Bonn has the harder (printed in 1948?) and there are not many books +I liked more to own. + +The master thesis should be available at the CTAN archives under MuTeX +or MTEX maybe subdirectory DIPL (for Diplom). I have the TEX-source +and I may pack it to ftp.gmd.de if you are interested and can't find it +on CTAN. +================================================================ + +[breaking lines] +> +>Incidentally, I use a different approach in PMX, starting with the +>total number of systems for the piece instead of assuming a starting +>physical value for \elemskip. That's equivalent to setting the +>physical length of the whole piece if laid out in one long line. +>Knowing the total amount of scalable and fixed space I compute a +>starting physical value for \elemskip. I use that to get how many +>bars go in the first line. Then I force a line break there, remove +>those bars and their scalable and fixed space from the accounting, and +>start over with the second line, etc. + + +Since you are getting into technical details, I will show mine too: I +think my way is the most elegant algorithm i've seen so far. Some +terminology: I call a vertical group of symbols (notes) which start at +the same time a "column". Each line of a score has notes in it, +grouped in columns. The difference in starting time between those +columns makes it possible to determine ideal distances between those +columns. + +Example: + + time -----> + + col1 col2 col3 col4 + + +voice1 1 1 + +voice2 2 2 2 2 + + +(1 is a whole note, 2 a half note.) + +time_difference (col1 , col2) = 0.5 wholes, +time_difference (col1 , col3) = 1 wholes, +time_difference (col2 , col3) = 0.5 wholes, +etc. + +these differences are translated into ideal distances (these translations +have been the subject of discussion in this thread). + + distance (col1,col2) = 10 pt + distance (col1,col3) = 14.1 pt + distance (col2,col3) = 10 pt + etc. + +as you can see, these distance are conflicting. So instead of +satisfying all those ideals simultaneously, a compromise is sought. + +This is Columbus' egg: LilyPond attaches "springs" to each +column-pair. each spring has an equilibrium-position which is equal to +the above mentioned distance, so + + spring (col1, col2) and spring(col2,col3) try to push column 1 +and 3 away (to a distance of 20pt) from each other, whereas the spring +between col 1 and col 3 tries to pull those two together (to a +distance of 14.1 pt). The net result of this pushing and pulling is an +equilibrium situation (the pushing cancels the pulling), which can be +calculated as the solution of Quadratic program: it is the solution +with minimum potential energy, for you physicists out there. + +This algorithm for doing one line, gives a "badness" parameter for +each line (the potential energy). Now one can use TeX's algorithm for +making paragraphs (using this new version of "badness"): one should +try to minimise the overall badness of a paragraph. LilyPond also uses the +concept of pre- and post-breaks. + +(actually, it is a bit more complicated: each column also has a +minimum distance to other columns, to prevent symbols from running +into symbols of other columns.) + @@ -1,6 +1,8 @@ MAJVER=0 MINVER=0 -PATCHLEVEL=7 +PATCHLEVEL=8 + +TOPDIR := $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi) # # @@ -13,6 +15,7 @@ obs=$(cc:.cc=.o) #dist +.EXPORT_ALL_VARIABLES: DOCDIR=docdir VERSION=$(MAJVER).$(MINVER).$(PATCHLEVEL) @@ -22,9 +25,8 @@ othersrc=lexer.l parser.y SCRIPTS=make_version make_patch genheader IFILES=dimen.tex symbol.ini suzan.ly maartje.ly\ lilyponddefs.tex test.tex .dstreamrc -OFILES=Makefile Sources.make -DOC=COPYING README TODO CodingStyle -DFILES=$(hdr) $(mycc) $(othersrc) $(OFILES) $(IFILES) $(SCRIPTS) $(DOC) +OFILES=Makefile Sources.make COPYING README +DFILES=$(hdr) $(mycc) $(othersrc) $(OFILES) $(IFILES) $(SCRIPTS) #compiling LOADLIBES=-L$(FLOWERDIR) -lflower @@ -83,11 +85,16 @@ version.hh: Makefile make_version lexer.cc: lexer.l $(FLEX) -+ -t $< > $@ -DDIR=$(DNAME) +DDIR=$(TOPDIR)/$(DNAME) +SUBDIRS=Documentation dist: -mkdir $(DDIR) ln $(DFILES) $(DDIR)/ - tar cfz $(DNAME).tar.gz $(DDIR)/ + for a in $(SUBDIRS); \ + do mkdir $(DDIR)/$$a; \ + $(MAKE) -C $$a dist;\ + done + tar cfz $(DNAME).tar.gz $(DNAME)/ rm -rf $(DDIR)/ @@ -56,5 +56,12 @@ stacktrace of the crash. HOW DOES IT WORK -Use The Source, Luke. If you don't know C++, you can try editing +* Use The Source, Luke. If you don't know C++, you can try editing .dstreamrc for copious debugging output. + +* see also the subdir Documentation + +* The source is commented in the DOC++ style. +Check out doc++ at + + http://www.ZIB-Berlin.DE/VisPar/doc++/doc++.html diff --git a/Sources.make b/Sources.make index fcc62df96c..6e860c07d4 100644 --- a/Sources.make +++ b/Sources.make @@ -1,5 +1,5 @@ # -*- Makefile-*- -# sourcefiles to be shipped. Also for depedencies +# sourcefiles to be shipped. Also for dependencies hdr= qlp.hh linespace.hh qlpsolve.hh\ pcol.hh proto.hh pstaff.hh line.hh\ @@ -10,7 +10,8 @@ hdr= qlp.hh linespace.hh qlpsolve.hh\ misc.hh score.hh notename.hh lexer.hh symtable.hh\ symbol.hh main.hh dimen.hh paper.hh lookupsyms.hh\ sccol.hh stcol.hh scommands.hh melodicstaff.hh\ - identifier.hh simplestaff.hh spanner.hh stem.hh + identifier.hh simplestaff.hh spanner.hh stem.hh\ + notehead.hh mycc= qlp.cc qlpsolve.cc \ break.cc linespace.cc molecule.cc line.cc\ @@ -24,6 +25,6 @@ mycc= qlp.cc qlpsolve.cc \ dimen.cc paper.cc lookupsyms.cc scommands.cc\ sccol.cc stcol.cc getcommands.cc simplestaff.cc\ melodicstaff.cc simpleprint.cc stem.cc\ - spanner.cc\ + spanner.cc notehead.cc\ template1.cc template2.cc template3.cc\ version.cc
\ No newline at end of file @@ -1,13 +0,0 @@ - * clefs - - * beam - - * fonttables -> fontdims - - * clear IDENTIFIERs - - * Paperdef -> fontsize . - - * merge Paper, Lookup, Outputfile, and Symtable. - - * all places in the code marked TODO! and ugh/ARGH diff --git a/calcideal.cc b/calcideal.cc index 1dc0e1d385..8099e0e4c7 100644 --- a/calcideal.cc +++ b/calcideal.cc @@ -3,7 +3,6 @@ #include "pscore.hh" #include "staff.hh" #include "paper.hh" -#include "misc.hh" #include "sccol.hh" #include "debug.hh" @@ -50,7 +49,7 @@ Score::calc_idealspacing() if (sc->musical) for (int i=0; i < sc->durations.sz(); i++) { Real d = sc->durations[i]; - Real dist = duration_to_idealspace(d, paper_->whole_width); + Real dist = paper_->duration_to_dist(d); PCol * c2 = find_col(sc->when + d,true)->pcol; connect_nonmus(sc->pcol, c2, dist); c2 = find_col(sc->when + d,false)->pcol; diff --git a/flower/Makefile b/flower/Makefile index e17cbdb0d8..dffea2fb37 100644 --- a/flower/Makefile +++ b/flower/Makefile @@ -1,6 +1,6 @@ MAJVER=1 MINVER=0 -PATCHLEVEL=7 +PATCHLEVEL=8 PACKAGENAME=flower VERSION=$(MAJVER).$(MINVER).$(PATCHLEVEL) @@ -26,7 +26,7 @@ clean: rm -f $(obs) $(staticlib) realclean: clean rm -f depend -DFILES=$(hh) $(cc) $(inl) $(templatecc) Makefile Sources.make TODO +DFILES=$(hh) $(cc) $(inl) $(templatecc) Makefile Sources.make TODO README DDIR=$(DNAME) dist: diff --git a/flower/README b/flower/README new file mode 100644 index 0000000000..d33c68f3df --- /dev/null +++ b/flower/README @@ -0,0 +1,10 @@ +This library contains some general purpose routines which aren't +standardised yet. It was written by: + + Han-Wen Nienhuys <hanwen@stack.nl> + +and + + Jan Nieuwenhuizen <jan@digicash.com> + +It is licensed under the GNU GPL.
\ No newline at end of file diff --git a/flower/Sources.make b/flower/Sources.make index 8016e67323..7f2f6441a1 100644 --- a/flower/Sources.make +++ b/flower/Sources.make @@ -1,7 +1,7 @@ cc=lgetopt.cc string.cc dataf.cc textdb.cc unionfind.cc \ smat.cc matrix.cc choleski.cc vector.cc dstream.cc\ - matdebug.cc + matdebug.cc interval.cc templatecc=cursor.cc list.cc tsmat.cc plist.cc inl=findcurs.inl link.inl list.inl cursor.inl plist.inl @@ -9,5 +9,6 @@ hh=cursor.hh pcursor.hh lgetopt.hh link.hh list.hh dstream.hh \ string.hh stringutil.hh vray.hh textdb.hh textstr.hh assoc.hh\ findcurs.hh unionfind.hh compare.hh handle.hh matrix.hh\ smat.hh vsmat.hh vector.hh real.hh choleski.hh\ - tsmat.hh tvsmat.hh plist.hh associter.hh\ + tsmat.hh tvsmat.hh plist.hh associter.hh fproto.hh\ + interval.hh diff --git a/flower/TODO b/flower/TODO index 4d0774ff7c..ef0ab6bac6 100644 --- a/flower/TODO +++ b/flower/TODO @@ -4,6 +4,8 @@ * efficient copy cons for List + * extend Interval + * change String::pos s[s.pos('%')] == '%' @@ -12,9 +14,10 @@ * use template handle in handle.hh for strings. - * Restricted cursor/list: make sublist from a list, and use rcursor as if list is as big as the sublist. + * Restricted cursor/list: make sublist from a list, and use rcursor +as if list is as big as the sublist. - * move towards gnu? + * move towards gnu or STL? parsestream.h vector.h diff --git a/flower/cursor.cc b/flower/cursor.cc index 2a9f885689..75f607dcaa 100644 --- a/flower/cursor.cc +++ b/flower/cursor.cc @@ -68,27 +68,38 @@ Cursor<T>::operator -( int i ) const return r; } - +/* + warning: can't use Cursor::operator == (Cursor), + since it uses Cursor::operator-(Cursor) + */ template<class T> int -Cursor<T>::operator-(Cursor<T> c) const +Cursor<T>::operator-(Cursor<T> rhs) const { - assert(c.list == list); + assert(rhs.list == list); int dif = 0; - Cursor<T> upward(c); - while (upward.ok() && upward.pointer_ != pointer_) { - upward++; + + // search from *this on further up (positive difference) + Cursor<T> c(*this); + while (c.ok() && c.pointer_ != rhs.pointer_) { + c--; dif++; } - if (upward.ok()) - return dif; + if (c.ok()) + goto gotcha; // so, sue me. + + // search in direction of bottom. (negative diff) dif =0; - while (c.ok()&& c.pointer_ != pointer_) { + c=*this; + while (c.ok() && c.pointer_ !=rhs.pointer_) { dif --; - c--; + c++; } assert(c.ok()); + +gotcha: + assert((*this - dif).pointer_ == c.pointer_); return dif; } diff --git a/flower/cursor.hh b/flower/cursor.hh index 4babf96545..6bd4e1895d 100644 --- a/flower/cursor.hh +++ b/flower/cursor.hh @@ -107,7 +107,7 @@ private: template<class T> inline int cursor_compare(Cursor<T> a,Cursor<T>b) { - return b-a; + return a-b; } template_instantiate_compare(Cursor<T>, cursor_compare, template<class T>); diff --git a/flower/fproto.hh b/flower/fproto.hh new file mode 100644 index 0000000000..5241a13dd0 --- /dev/null +++ b/flower/fproto.hh @@ -0,0 +1,38 @@ +/* + fproto.hh -- typenames in flowerlib + + (c) 1996 Han-Wen Nienhuys +*/ + +#ifndef FPROTO_HH +#define FPROTO_HH + +template<class T> struct svec; +template<class T> struct sstack; +template<class T,class K> struct Assoc; +template<class T> struct List; +template<class T> struct PointerList; +template<class T> struct IPointerList; +template<class T> struct Cursor; +template<class T> struct PCursor; +template<class T> struct Link; +template<class T> struct Handle ; + + +struct Assoc_ent_ ; +struct Assoc ; +struct Assoc_iter ; +struct Choleski_decomposition ; +struct Interval ; +struct long_option_init ; +struct Getopt_long ; +struct Matrix ; +struct StringData ; +struct String_handle ; +struct virtual_smat ; +struct Vector ; +class Text_stream; +class Data_file ; +struct Text_db; +#endif // FPROTO_HH + diff --git a/flower/interval.cc b/flower/interval.cc new file mode 100644 index 0000000000..b307f4c634 --- /dev/null +++ b/flower/interval.cc @@ -0,0 +1,18 @@ +#include <assert.h> +#include "interval.hh" +#include <math.h> + +const Real INFTY = HUGE; + +void +Interval::set_empty() { + min = INFTY; + max = -INFTY; +} + +Real +Interval::length() const { + assert(max >= min); + return max-min; +} + diff --git a/flower/interval.hh b/flower/interval.hh new file mode 100644 index 0000000000..950945ca87 --- /dev/null +++ b/flower/interval.hh @@ -0,0 +1,58 @@ +/* + interval.hh -- part of flowerlib + + (c) 1996 Han-Wen Nienhuys +*/ + +#ifndef INTERVAL_HH +#define INTERVAL_HH + +#include <assert.h> +#include "real.hh" + + +/// 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); + return 0.0; + + } + 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; + } +}; + + +#endif // INTERVAL_HH + + diff --git a/flower/lgetopt.cc b/flower/lgetopt.cc index ac9a12d035..523d54ee5f 100644 --- a/flower/lgetopt.cc +++ b/flower/lgetopt.cc @@ -2,7 +2,7 @@ process command line, GNU style. - this is (Copyleft) 1996, Han-Wen Nienhuys, <hanwen@stack.urc.tue.nl> + this is (Copyleft) 1996, Han-Wen Nienhuys, <hanwen@stack.nl> */ #include <stdio.h> #include <iostream.h> diff --git a/flower/pcursor.hh b/flower/pcursor.hh index 6cc3433e25..5e535300d7 100644 --- a/flower/pcursor.hh +++ b/flower/pcursor.hh @@ -17,7 +17,9 @@ struct PCursor : public Cursor<void *> { PCursor<T> operator -( int no) const { return PCursor<T> (Cursor<void*>::operator-(no)); } - + int operator -(PCursor<T> op) const { + return Cursor<void*>::operator-(op); + } /// make cursor with #no# items further PCursor<T> operator +( int no) const { return PCursor<T> (Cursor<void*>::operator+(no)); @@ -45,7 +47,7 @@ don't create PointerList<void*>'s template<class T> inline int pcursor_compare(PCursor<T> a,PCursor<T>b) { - return cursor_compare(Cursor<void*>(b),Cursor<void*> (a)); + return cursor_compare(Cursor<void*>(a),Cursor<void*> (b)); } #include "compare.hh" diff --git a/flower/plist.hh b/flower/plist.hh index 1bfc2d4ab4..78df40cb17 100644 --- a/flower/plist.hh +++ b/flower/plist.hh @@ -51,7 +51,7 @@ template<class T> void PL_copy(IPointerList<T*> &dst,IPointerList<T*> const&src); -#define PL_instantiate(a) L_instantiate(a *); template class PointerList<a*> +#define PL_instantiate(a) template class PointerList<a*> #define IPL_instantiate(a) PL_instantiate(a); template class IPointerList<a*> #include "plist.inl" diff --git a/flower/textstr.hh b/flower/textstr.hh index 41a979f27f..c64a989c3c 100644 --- a/flower/textstr.hh +++ b/flower/textstr.hh @@ -1,3 +1,6 @@ +#ifndef TEXTSTR_HH +#define TEXTSTR_HH + #include <stdio.h> #include <ctype.h> @@ -112,3 +115,4 @@ class Data_file : private Text_stream exit(1); } }; +#endif diff --git a/identifier.cc b/identifier.cc index 94d48c8d74..5405d5f710 100644 --- a/identifier.cc +++ b/identifier.cc @@ -12,10 +12,15 @@ Identifier::Identifier(String n) Identifier::~Identifier() -{ +{ } Staff_id::~Staff_id() { delete staff(); } + +Voice_id::~Voice_id() +{ + delete voice(); +} diff --git a/identifier.hh b/identifier.hh index 0510f181d1..9cb80386c0 100644 --- a/identifier.hh +++ b/identifier.hh @@ -18,6 +18,7 @@ struct Identifier Identifier(String n) ; virtual ~Identifier(); virtual Staff * staff() { assert(false); } + virtual Voice * voice() { assert(false); } }; struct Staff_id : Identifier { @@ -26,7 +27,10 @@ struct Staff_id : Identifier { ~Staff_id(); }; - - +struct Voice_id : Identifier { + Voice_id(String s, Voice*st):Identifier(s) { data = st; } + virtual Voice * voice() { return (Voice*)data; } + ~Voice_id(); +}; #endif // IDENTIFIER_HH @@ -3,6 +3,19 @@ #include "molecule.hh" #include "pcol.hh" +void +Item::postprocess() +{ + // default: do nothing +} + + +void +Item::preprocess() +{ + // default: do nothing +} + String Item::TeXstring() const { @@ -4,8 +4,6 @@ #include "glob.hh" #include "boxes.hh" #include "string.hh" -#include "tex.hh" - /// a horizontally fixed size element of the score struct Item { @@ -17,7 +15,17 @@ struct Item { */ /****************/ + + /// 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 ; @@ -25,7 +33,12 @@ struct Item { void print()const; virtual ~Item(); }; -/** An item must be part of a Column +/** Item is the datastructure for printables whose width is known + before the spacing is calculated + + NB. This doesn't mean an Item has to initialize the output field before + spacing calculation. + */ @@ -12,4 +12,5 @@ int lookup_keyword(String s); Identifier* lookup_identifier(String s); void add_identifier(Identifier*i); +void delete_identifiers(); #endif diff --git a/lilyponddefs.tex b/lilyponddefs.tex index 45152140cb..41748636de 100644 --- a/lilyponddefs.tex +++ b/lilyponddefs.tex @@ -70,18 +70,26 @@ \vskip 40pt\par\vbox{\hbox to 0pt{\vrule width30pt height1pt\hss}}\par\vskip 40pt } \def\interscoreline{\beauty} -% -% a staffsymbol with #1 lines, width #2 -% bottom at baseline -\def\linestafsym#1#2{\vbox to 0pt{\hbox to 0pt% - {\vbox to 0pt{\vss% - \kern-\interstaffrule + + +\def\lines#1#2{% + \vbox{\kern-\interstaffrule \n=0\nointerlineskip% \loop\ifnum\n<#1\advance\n by1% - \kern\interstaffrule \hrule height \staffrulethickness width#2 + \kern\interstaffrule + \hrule height \staffrulethickness width#2 \repeat - }% -\hss}}} + }} + +\def\toplines#1{ % why space needed here? + \vbox to 0pt{\hbox{\kern-6pt\lines{#1}{12pt}}\vss}} +\def\botlines#1{ % idem ditto + \vbox to 0pt{\vss\hbox{\kern-6pt\lines{#1}{12pt}}}} + +% +% a staffsymbol with #1 lines, width #2 +% bottom at baseline +\def\linestafsym#1#2{\hbox to 0pt{\vbox to 0pt{\vss\lines{#1}{#2}}\hss}} \def\vcenter#1{\vbox to 0pt{\vss #1\vss}} \def\topalign#1{\vbox to 0pt{#1\vss}} diff --git a/lookupsyms.cc b/lookupsyms.cc index 294f2e9af4..e6ad52ca5a 100644 --- a/lookupsyms.cc +++ b/lookupsyms.cc @@ -3,6 +3,7 @@ #include "symtable.hh" #include "dimen.hh" #include "tex.hh" + void Lookup::parse(Text_db&t) { @@ -55,6 +56,29 @@ Lookup::flag(int j) return (*symtables_)("flags")->lookup(j); } +Symbol +Lookup::streepjes(int i) +{ + assert(i); + + int arg; + String idx ; + if (i<0) { + idx = "botlines"; + arg = -i; + }else { + arg = i; + idx = "toplines"; + } + Symbol ret = (*symtables_)("streepjes")->lookup(idx); + + svec<String> a; + a.add(arg); + ret.tex = substitute_args(ret.tex, a); + + return ret; +} + /****************************************************************/ // bare bones. diff --git a/lookupsyms.hh b/lookupsyms.hh index f7ac3858ac..1ec0d04d10 100644 --- a/lookupsyms.hh +++ b/lookupsyms.hh @@ -15,6 +15,13 @@ struct Lookup { Parametric_symbol *linestaff(int n); Parametric_symbol *meter(String); Parametric_symbol *stem(); + Symbol streepjes(int pos); + /** + pos == 3 : 3 lines above staff (extending below note) + + pos == -3: below staff + */ + Symbol ball(int); Symbol flag(int); Symbol rest(int); diff --git a/maartje.ly b/maartje.ly index 50ce2cb577..e12fc345e6 100644 --- a/maartje.ly +++ b/maartje.ly @@ -4,7 +4,7 @@ ritme = rhythmstaff { } melody= melodicstaff { - voice { $ c2.. r8 r4 r8 r16 r32 r32 d8 e8 f8 g8 ''fis1 a8 b8 'c8 c8 `c8 ``c8 c4 c4 c4 c4 $ } + voice { $ ''c2.. r8 r4 r8 r16 r32 r32 d8 e8 f8 g8 ''fis1 a8 b8 'c8 c8 ''c8 ```c8 c4 c4 c4 c4 $ } } score { paper { diff --git a/melodicstaff.cc b/melodicstaff.cc index 83e038652f..2937f45dfe 100644 --- a/melodicstaff.cc +++ b/melodicstaff.cc @@ -1,6 +1,6 @@ #include "melodicstaff.hh" #include "stem.hh" - +#include "notehead.hh" #include "paper.hh" #include "molecule.hh" #include "linestaff.hh" @@ -29,15 +29,18 @@ Melodic_column::typeset_command(Command *com, int breakst) void Melodic_column::typeset_req(Request *rq) { - Item *i =new Item; - Molecule*m=create_req_mol(rq); - + Item *i ; if (rq->note()) { - int h = rq->note()->height(); - Real dy = staff_->paper()->interline()/2; - m->translate(Offset(0,(h-BOTTOM_POSITION)*dy)); + Notehead *n =new Notehead((NO_LINES-1)*2); + n->balltype = rq->rhythmic()->balltype; + n->dots = rq->rhythmic()->dots; + n->position = rq->note()->height() - BOTTOM_POSITION; + i = n; + } else if (rq->rest()) { + i =new Item; + Molecule*m=create_req_mol(rq); + i->output=m; } - i->output = m; typeset_item(i); } @@ -49,10 +52,7 @@ Melodic_column::typeset_stem(Stem_req*rq) int n = the_note->note()->height()-BOTTOM_POSITION; s->minnote =s->maxnote=n; s->flag = rq->stem_number; - s->calculate(); - typeset_item(s); - - s->brew_molecole(); + typeset_item(s); } /* @@ -12,25 +12,3 @@ int intlog2(int d) { return i; } -double log2(double x) { - return log(x) /log(2.0); -} - - -// golden ratio - const Real PHI = (1+sqrt(5))/2; -const double ENGRAVERS_SPACE = PHI; - - - - -Real -duration_to_idealspace(Real d, Real w) -{ - // see Roelofs, p. 57 - return w * pow(ENGRAVERS_SPACE, log2(d)); -} - - - - @@ -1,7 +1,7 @@ #ifndef MISC_HH #define MISC_HH -#include "real.hh" -int intlog2(int d); -Real duration_to_idealspace(Real d,Real w); + + + #endif diff --git a/notehead.cc b/notehead.cc new file mode 100644 index 0000000000..fe026b1036 --- /dev/null +++ b/notehead.cc @@ -0,0 +1,67 @@ +#include "notehead.hh" +#include "dimen.hh" +#include "debug.hh" +#include "pstaff.hh" +#include "pscore.hh" +#include "paper.hh" +#include "lookupsyms.hh" +#include "molecule.hh" + + +Notehead::Notehead(int ss) +{ + staff_size=ss; + position = 0; + balltype = 0; + dots = 0; +} + +void +Notehead::print()const +{ + mtor << "Head "<<balltype<<", position = "<< position << "dots " << dots; + Item::print(); +} + +void +Notehead::preprocess() +{ + brew_molecole(); +} + +void +Notehead::brew_molecole() +{ + assert(pstaff_); + assert(!output); + + Paperdef *p = pstaff_->pscore_->paper_; + + Real dy = p->interline()/2; + Symbol s = p->lookup_->ball(balltype); + + output = 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); + } + bool streepjes = (position<-1)||(position > staff_size+1); + if (streepjes) { + int dir = sgn(position); + int s =(position<-1) ? -((-position)/2): (position-staff_size)/2; + Symbol str = p->lookup_->streepjes(s); + Molecule sm; + sm.add(Atom(str)); + if (position % 2) + sm.translate(Offset(0,-dy* dir)); + output->add(sm); + } + + + output->translate(Offset(0,dy*position)); +} + diff --git a/notehead.hh b/notehead.hh new file mode 100644 index 0000000000..b694e95af8 --- /dev/null +++ b/notehead.hh @@ -0,0 +1,38 @@ +/* + notehead.hh -- part of LilyPond + + (c) 1996 Han-Wen Nienhuys +*/ + +#ifndef NOTEHEAD_HH +#define NOTEHEAD_HH +#include "item.hh" + +/// ball at the end of the stem +struct Notehead : public Item +{ + int position; + int staff_size; + int dots; + int balltype; + + /****************/ + void preprocess(); + + Notehead(int staff_size); + /** + position of top line (5 linestaff: 8) + */ + void print()const; +private: + void brew_molecole(); +}; +/** + takes care of: + + * help lines + * proper placing of dots + + */ +#endif // NOTEHEAD_HH + @@ -1,16 +1,33 @@ +#include <math.h> + #include "paper.hh" #include "debug.hh" #include "lookupsyms.hh" #include "dimen.hh" #include "textdb.hh" +double log2(double x) { + return log(x) /log(2.0); +} + + +// golden ratio +const Real PHI = (1+sqrt(5))/2; + +// see Roelofs, p. 57 +Real +Paperdef::duration_to_dist(Real d) +{ + return whole_width * pow(geometric_, log2(d)); +} + Paperdef::Paperdef() { - linewidth = convert_dimen(15,"cm"); // in cm for now - whole_width= convert_dimen(2,"cm"); lookup_ = new Lookup(); parse(); - + linewidth = convert_dimen(15,"cm"); // in cm for now + whole_width= 6*note_width(); + geometric_ = PHI; } void @@ -8,6 +8,9 @@ struct Paperdef { Real linewidth; /// how much space does a whole note take (ideally?) Real whole_width; + + // ideal = geometric_ ^ log2(duration) + Real geometric_; /****************/ void parse(); @@ -17,5 +20,6 @@ struct Paperdef { Real standard_height()const; Real note_width() const; void print() const; + Real duration_to_dist(Real); }; @@ -37,7 +37,7 @@ %token VOICE STAFF SCORE TITLE RHYTHMSTAFF BAR NOTENAME OUTPUT %token CM IN PT MM PAPER WIDTH METER UNITSPACE SKIP COMMANDS -%token MELODICSTAFF +%token MELODICSTAFF GEOMETRIC START %type <consstr> unit %token <id> IDENTIFIER @@ -76,6 +76,10 @@ declaration: $$ = new Staff_id(*$1, $3); delete $1; // this sux } + | NEWIDENTIFIER '=' voice_block { + $$ = new Voice_id(*$1, $3); + delete $1; + } ; @@ -108,6 +112,7 @@ paper_body: delete $3; } | paper_body UNITSPACE dim { $$->whole_width = $3; } + | paper_body GEOMETRIC REAL { $$->geometric_ = $3; } ; dim: @@ -160,10 +165,14 @@ voice_block: voice_body: - REAL voice_elts_dollar { $$ = $2; $$->start = $1; } + IDENTIFIER { $$ = new Voice(*$1->voice()); } | voice_elts_dollar { $$ = $1; } + | voice_body START REAL { $$->start = $3; } ; + + + voice_elts_dollar: '$' voice_elts '$' { $$ = $2; } ; @@ -219,5 +228,6 @@ parse_file(String s) #endif new_input(s); yyparse(); + delete_identifiers(); *mlog << "\n"; } @@ -50,6 +50,7 @@ PScore::typeset_item(Item *i, PCol *c, PStaff *s, int breakstat) its.bottom().add(i); s->add(i); c->add(i); + i->preprocess(); } void @@ -154,3 +155,20 @@ PScore::print() const #endif } +void +PScore::preprocess() +{ +#if 0 + for (PCursor<Item*> ic(its); ic.ok(); ic++){ + ic->preprocess(); + } +#endif +} + +void +PScore::postprocess() +{ + for (PCursor<Item*> ic(its); ic.ok(); ic++){ + ic->postprocess(); + } +} @@ -33,6 +33,9 @@ struct PScore { /****************************************************************/ svec<Item*> select_items(PStaff*, PCol*); + + /// before calc_breaking + void preprocess(); void calc_breaking(); /** @@ -43,6 +46,9 @@ struct PScore { lines contain the broken lines. */ + /// after calc_breaking + void postprocess(); + /// search all pcols which are breakable. svec<const PCol *> find_breaks() const; diff --git a/request.cc b/request.cc index fd032fcfd8..35a9ae9718 100644 --- a/request.cc +++ b/request.cc @@ -41,13 +41,13 @@ Note_req::height() const return s + octave*7; } -/****************************************************************/ Rhythmic_req::Rhythmic_req(Voice_element*v) :Request(v) { balltype = 1; dots = 0; } + void Rhythmic_req::print() const { @@ -57,6 +57,7 @@ Rhythmic_req::print() const mtor << '.'; mtor<<"\n"; } + void Note_req::print() const { diff --git a/rhythmstaff.cc b/rhythmstaff.cc index 7e2706e02d..98d17d522c 100644 --- a/rhythmstaff.cc +++ b/rhythmstaff.cc @@ -1,4 +1,5 @@ #include "molecule.hh" +#include "notehead.hh" #include "stem.hh" #include "linestaff.hh" #include "rhythmstaff.hh" @@ -28,9 +29,18 @@ Rhythmic_column::typeset_command(Command *com, int breakst) void Rhythmic_column::typeset_req(Request *rq) { - Item *i =new Item; - Molecule*m=create_req_mol(rq); - i->output=m; + Item *i ; + if (rq->note()) { + Notehead *n =new Notehead(1); + n->balltype = rq->rhythmic()->balltype; + n->dots = rq->rhythmic()->dots; + n->position = 0; + i = n; + } else if (rq->rest()) { + i =new Item; + Molecule*m=create_req_mol(rq); + i->output=m; + } typeset_item(i); } @@ -40,9 +50,7 @@ Rhythmic_column::typeset_stem(Stem_req*rq) Stem * s = new Stem(0); s->minnote = s->maxnote = 0; s->flag = rq->stem_number; - s->calculate(); typeset_item(s); - s->brew_molecole(); } /* @@ -13,6 +13,7 @@ Score::set(Paperdef*p) delete paper_; paper_ = p; } + void Score::output(String s) { @@ -29,7 +30,7 @@ Score::output(String s) void Score::process() { - *mlog << "Processing ..."; + *mlog << "Processing ... "; set(commands_->parse(last())); commands_->print(); @@ -53,8 +54,12 @@ Score::process() clean_cols(); OK(); // print(); + + pscore_->preprocess(); *mlog << "Calculating ... "; pscore_->calc_breaking(); + pscore_->postprocess(); + // TODO: calculate vertical structs // TODO: calculate mixed structs. *mlog << "\n"; diff --git a/simpleprint.cc b/simpleprint.cc index b8f02c5798..b069978dce 100644 --- a/simpleprint.cc +++ b/simpleprint.cc @@ -9,12 +9,10 @@ Molecule * Simple_column::create_req_mol(Request *rq) { + assert(rq->rest()); Symbol s; int dots=0; - - if (rq->note()) - s = staff_->paper()->lookup_->ball(rq->note()->balltype); - else if (rq->rest()) + if (rq->rest()) s = staff_->paper()->lookup_->rest(rq->rest()->balltype); if (rq->rhythmic()) @@ -30,6 +28,7 @@ Simple_column::create_req_mol(Request *rq) } return m; } + Molecule * Simple_column::create_command_mol(Command *com) { diff --git a/spanner.cc b/spanner.cc index f9eb65367b..be30c04659 100644 --- a/spanner.cc +++ b/spanner.cc @@ -14,6 +14,7 @@ Spanner::TeXstring() const return strets->eval(w).tex; } +// todo. Spanner * Spanner::broken_at(const PCol *c1, const PCol *c2) const { diff --git a/spanner.hh b/spanner.hh index 542357f7a2..1908d2f013 100644 --- a/spanner.hh +++ b/spanner.hh @@ -13,8 +13,8 @@ struct Spanner { const PCol *left, *right; Parametric_symbol *strets; PStaff * pstaff_; - /// clone a piece of this spanner. - Spanner *broken_at(const PCol *c1, const PCol *c2) const; + /// clone a piece of this spanner. + virtual Spanner *broken_at(const PCol *c1, const PCol *c2) const; /** PRE @@ -23,6 +23,7 @@ struct Spanner { /****************/ String TeXstring () const ; Spanner(); + virtual void process(); }; /** Spanner should know about the items which it should consider: e.g. slurs should be steep enough to "enclose" all those items. This @@ -47,6 +47,13 @@ Stem::calculate() } } +void +Stem::postprocess() +{ + calculate(); + brew_molecole(); +} + Interval Stem::width()const { @@ -60,16 +67,18 @@ void Stem::brew_molecole() { assert(pstaff_); - Paperdef *p = pstaff_->pscore_->paper_; - Parametric_symbol *stem = p->lookup_->stem(); - assert(bot!=top); assert(!output); + Paperdef *p = pstaff_->pscore_->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; + output = new Molecule(Atom(ss)); if (ABS(flag) > 4){ @@ -8,6 +8,7 @@ #define STEM_HH #include "item.hh" +/// the rule attached to the ball struct Stem : public Item { // heads the stem encompasses (positions) int minnote, maxnote; @@ -20,12 +21,24 @@ struct Stem : public Item { // flagtype? 4 none, 8 8th flag, 0 = beam. int flag; - /****************/ - void brew_molecole(); - void calculate(); + + void postprocess(); Stem(int center); void print() const; - Interval width() const; + Interval width() const; +private: + void calculate(); + void brew_molecole(); }; +/** + takes care of: + + \begin{itemize} + \item the rule + \item the flag + \item up/down position. + \end{itemize} + */ + #endif diff --git a/symbol.ini b/symbol.ini index 39553133ec..ea303b04f1 100644 --- a/symbol.ini +++ b/symbol.ini @@ -13,6 +13,11 @@ table balls 4 \quartball 0pt 6pt -2.5pt 2.5pt end +table streepjes + toplines \toplines{%} -6pt 6pt 0pt 0pt + botlines \botlines{%} -6pt 6pt 0pt 0pt +end + table bars empty \emptybar 0pt 0pt 0pt 0pt | \maatstreep 0pt 1pt -12pt 12pt @@ -3,6 +3,7 @@ #include "string.hh" #include "identifier.hh" #include "keyword.hh" +#include "associter.hh" #include "parser.hh" static Keyword_ent the_key_tab[]={ @@ -23,6 +24,7 @@ static Keyword_ent the_key_tab[]={ "skip", SKIP, "commands", COMMANDS, "staff", STAFF, + "geometric", GEOMETRIC, 0,0 } ; @@ -50,3 +52,13 @@ add_identifier(Identifier*i) { the_id_tab[i->name] = i; } + +void +delete_identifiers() +{ + + for (Assoc_iter<String,Identifier*> ai(the_id_tab); ai.ok(); ai++) { + mtor << "deleting: " << ai.key()<<'\n'; + delete ai.val(); + } +} @@ -4,6 +4,7 @@ #include "string.hh" #include "boxes.hh" +/// parameter substitution in TeXstrings String substitute_args(String source, svec<String> args); /** diff --git a/tstream.cc b/tstream.cc index b7c88f1b0b..05e2e9c93e 100644 --- a/tstream.cc +++ b/tstream.cc @@ -32,7 +32,8 @@ Tex_stream::~Tex_stream() // print string. don't forget indent. Tex_stream & Tex_stream::operator<<(String s) -{ +{ + for (const char *cp = s; *cp; cp++) { if (outputting_comment) { *os << *cp; @@ -56,7 +57,7 @@ Tex_stream::operator<<(String s) nest_level--; *os << *cp; assert (nest_level >= 0); - /* FALL THROUGH */ + /* FALTHROUGH */ case '\n': *os << "%\n"; @@ -14,7 +14,7 @@ struct Voice { Real when(const Voice_element*)const; Real last() const; Voice(); - Voice( Voice const&); + Voice(Voice const&); void add(Voice_element*); void print() const; }; |