\font\title = cmbx12 scaled \magstep 4
\font\subtitle = cmr9
-\def\lilyfooter{Lily was here, 1.1.0}
+\def\lilyfooter{Lily was here}
\def\setchar#1#2{\hbox to\charwidth{\hss{#1\char#2}\hss}}
\def\charsperline{6}
\def\charwidth{60pt}
\def\listfont#1#2#3{
- \n=#2
- \advance\n by-1
- \advance\n by-\charsperline
+ \n=#2
+ \advance\n by-1
+ \advance\n by-\charsperline
\loop\ifnum\n<#3
- \advance\n by\charsperline
- \i=0
- {\vbox to\charheight{\vss\centerline{
- {\loop\ifnum\i<\charsperline
- \advance\i by1
- \advance\n by1
+ \advance\n by\charsperline
+ \i=0
+ {\vbox to\charheight{\vss\centerline{
+ {\loop\ifnum\i<\charsperline
+ \advance\i by1
+ \advance\n by1
{\setchar{#1}{\number\n}}
- \repeat}}}}\repeat}
+ \repeat}}}}\repeat}
\centerline{\title FETA}
-\centerline{\subtitle (definately not an abbreviation for Font-En-Tja)}
+\centerline{\subtitle (definitely not an abbreviation for Font-En-Tja)}
\vskip5mm
+
+ - diamond heads (probably really ugly).
+ - cross head.
+ - tweaked harmonic head a bit.
+ - property noteHeadStyle
+
+pl 36.mb2
+ - bf: timeSignatureStyle
+ - Added dynamic fz (forzando) to Lilypond
+ - bf: N.W.Gade, sfz -> fz
+
+pl 36.hwn1
+ - debian fixes.
+ - don't insert extra alignment space for empty stuff.
+ - Align_element derives from Axis_group_element
+ - junk all *{horizontal,vertical}* Score_element derived classes.
+ - G_staff_side_item::padding_f_ now generic property.
+ - some tweaking of beam & stem.
+ - junk pointerlist in Sources
+ - junk Stem::mult_i_, Stem::beam_gap_i_, G_staff_side_item::padding
+ Bar::at_line_start_b_, Key_item::c_position_, Note_head::type_str_,
+ Note_head::staff_size, Stem::xdir_
+
+pl 36.mb1
+ - bf: N.W.Gade
+
+**************
+
pl 35.uu1
- more memory tweaks: don't do Score_element::line_l () when deleting lines.
- more generic properties.
pl 35.jcn1
- some ps fixes
+************
pl 35
pl 34.hwn2
.* BUGS
. * header for PS enteredby = "bla <bla@bar.com>"
+. * Hash_table::remove ().
+. * 1. With "lilypond -f ps": The black notes with ledger lines seem to
+> have extra "blobs" over and to the left of them and all the ledger
+> lines from the staff to the note will have a blob too. For example,
+> with the note "a4" there will be a black note at the ledger line where
+> "c" would be too. However, only the "a4" will have the extra blob.
+
. * ps/lily.ps
. * AFM for BlueSky AFM files.
+. * devise standard for functioning of Vertical_align_element.
+. * fix interstaff slurs & beams.
. * staff size for post/prebreaks
. * .ly files
. * input/star-spangled-banner
}
}
. * midi key.
-. *P.P.S. It can be cool in mudela-book to distinguish in pre,postMudelaExample,
+. * P.P.S. It can be cool in mudela-book to distinguish in pre,postMudelaExample,
whether MudelaExample is epsed or not: ( if this fragment is floating eps, than 1,
otherwise 2). say preMudelaExample[eps]{}, and change it in document body sometimes.
. * fix singleStaffBracket
. * fix height of / collisions with lyrics (chords),
see input/test/vertical-text.ly; input/test/repeat.ly
. * We need feta-din*.mf files for more sizes than 10.
-. * latex bla.tex broken (titles / \lilyfooter stuff?)
+. * latex bla.tex broken (titles / \lilyfooter stuff?
. * fix dynamics decently, ie. use kerning & ligatures.
. * support_l_arr_ empty in staff-margin's G_staff_side_item
. * minVerticalAlign for StaffGroups.
. * make "in-between" engraver (Tie, Extender)
. * make wide_spanner_engraver (line_group_spanne,r staff_symbol)
. * remove Interval dim_ from Dimension_cache and rename the struct.
-. * merge align_element and axis_element_group.
. * do scaled fonts generally
. * The Lilypond accidental symbols are available through the TeX macros,
\textflat, \textsharp and \textnatural defined in the init file
. * junk Script_def
. * include examples in RPM.
. * fix partial measures in meaningful way.
-. * working notehead style.
+
. * add scripts to bars eg. |^"bla"
. * relative mode for mi2mu
. * uniformise recent feta contributions.
about 2.5 whole notes? Is there a mechanism for getting this kind of
length?
-
-
. * fractional chord durs.
. * hang Item on Spanner
. * do --safe for PS output?
. * strip EXEs before installing
. * zip target for binary windows dist (JBR)
. * junking \skip req in lyrics
-. * percussion note heads
. * mi2mu empty staffs.
. * horizontal centering of dynamics
. * $DEPENDENCIES_OUTPUT support
organ you want to be able to give stop indications on the way
through, so the \property Voice.Instrument would be a stop,
and \property GrandStaff.instrument would be PipeOrgan...)
-. * revise the Score_priority_align_engraver concept. It sucks.
. * *.yo: fix pod manpage layout legacy
. * text-items clash with stems/beams
. * --include, -I option for ly2dvi (pass on to lily)
. * specify number of lines
.* INPUTLANGUAGE
+. * \rhythms 4 16 16 16 16; c c c c c -> c4 c16 etc.
. * Language:
. * \type -> \context ?
. * \translator -> ?
--- /dev/null
+basloopje = \notes\relative c{
+ [d,8 a' d f] [a\translator Staff=treble d f d] \translator Staff=bass
+}
+
+
+
+lower = \type Voice=two \notes \relative c{
+ < \basloopje >
+}
+\score {
+ \type PianoStaff <
+\notes \type Staff = treble { c1 }
+
+ \type Staff = bass <
+ \clef bass;
+ \lower
+ >
+ >
+
+ \paper {
+ gourlay_maxmeasures = 4.;
+ indent = 8.\mm;
+ textheight = 295.\mm;
+
+ % no slur damping
+ slur_slope_damping = 100.0;
+ }
+ \midi {
+ \tempo 4 = 54;
+ }
+}
+
- \version "1.0.14";
+\version "1.0.14";
onestaff = \type Staff = foo\notes {
\property Staff.instr = instr
}}
%\score {\stscore}
-\score {\scscore}
+\score {\scscore
+\header { title = "bar scripts"; }
+}
--- /dev/null
+
+\score {
+\notes \relative c {
+\include "noteheadstyle.fly"
+}\header { title = "notehead style"; }
+}
+
+\score {
+\notes \relative c {
+\include "number-staff-lines.fly"
+}\header { title = "number of staff lines"; }
+}
+
+\include "bar-scripts.ly"
+
+\include "font20.ly"
g g g g
}
-toeters = \type StaffGroup = xtoeters <
- \type Staff = toeters <
+toeters = \type Staff = toeters <
\toeter_i
\toeter_ii
- >
>
zager = \type Staff = zager \notes \relative c {
--- /dev/null
+
+c''4 c2 c8 c16 c16 c1
+\property Voice.noteHeadStyle = "diamond"
+c4 c2 c8 c16 c16 c1
+\property Voice.noteHeadStyle = "transparent"
+c4 c2 c8 c16 c16 c1
+\property Voice.noteHeadStyle = "cross"
+c4 c2 c8 c16 c16 c1
+\property Voice.noteHeadStyle = "harmonic"
+c4 c2 c8 c16 c16 c1
-c c c \property Staff . numberOfStaffLines = 3
+c' c c \property Staff . numberOfStaffLines = 3
Molecule*
Abbreviation::do_brew_molecule_p () const
{
- Real interbeam_f = paper_l ()->interbeam_f (stem_l_->mult_i_);
- Real w = 1.5 * lookup_l ()->ball (2).dim_.x ().length ();
+ Beam * b = stem_l_->beam_l_;
+ int mult =0;
+ if (b)
+ {
+ Stem_info i = b->get_stem_info (stem_l_);
+ mult = i.mult_i_;
+ }
+
+ Real interbeam_f = paper_l ()->interbeam_f (mult);
+ Real w = 1.5 * lookup_l ()->notehead (2, "").dim_.x ().length ();
Real space = stem_l_->staff_line_leading_f ();
Real internote_f = space/2;
#include "interval.hh"
#include "direction.hh"
#include "debug.hh"
+#include "hash-table-iter.hh"
struct Align_element_content {
- Score_element * elem_l_;
+ Graphical_element * elem_l_;
int priority_i_;
static int compare (Align_element_content const &h1,
{
return h1.priority_i_ - h2.priority_i_;
}
- Align_element_content (Score_element *elem_l, int p)
+ Align_element_content (Graphical_element *elem_l, int p)
{
priority_i_ = p;
elem_l_ = elem_l;
void
Align_element::add_element (Score_element*el_l)
{
- int p = priority_i_arr_.size ();
+ int p = elem_l_arr_.size ();
add_element_priority (el_l, p);
}
Align_element::add_element_priority (Score_element *el, int p)
{
assert (! contains_b (el));
- elem_l_arr_.push (el);
- priority_i_arr_.push (p);
+ Axis_group_element::add_element (el);
+ priority_i_hash_[el] = p;
add_dependency (el);
}
Align_element::do_substitute_element_pointer (Score_element*o,
Score_element*n)
{
- int i;
- while ((i = elem_l_arr_.find_i (o))>=0)
- if (n)
- elem_l_arr_[i] = n;
- else
- elem_l_arr_.del (i);
-
+ Axis_group_element :: do_substitute_element_pointer (o,n);
if (o == center_l_)
{
center_l_ = n;
}
+ if (priority_i_hash_.elem_b (o))
+ {
+ priority_i_hash_[n] = priority_i_hash_[o];
+ /*
+ Huh? It seems the old pointers are still used. Why?
+ */
+ // priority_i_hash_.remove (o);
+ }
}
void
Align_element::do_post_processing()
{
- if (axis_ == Y_AXIS)
+ if (axis () == Y_AXIS)
do_side_processing ();
}
void
Align_element::do_pre_processing ()
{
- if (axis_ == X_AXIS)
+ if (axis () == X_AXIS)
do_side_processing ();
}
{
sort_elements ();
Array<Interval> dims;
-
+
+ Link_array<Score_element> elems;
for (int i=0; i < elem_l_arr_.size(); i++)
{
- Interval y = elem_l_arr_[i]->extent(axis_) ;
- if (y.empty_b())
- y = Interval (0,0);
-
- dims.push (y);
+ Interval y = elem_l_arr_[i]->extent(axis ());
+ if (!y.empty_b())
+ {
+ dims.push (y);
+ Score_element *e =dynamic_cast<Score_element*>(elem_l_arr_[i]);
+ elems.push (e);
+ }
}
Real where_f=0;
Real center_f = 0.0;
- for (int i=0 ; i < elem_l_arr_.size(); i++)
+ for (int i=0 ; i < elems.size(); i++)
{
Real dy = - stacking_dir_ * dims[i][-stacking_dir_];
if (i)
<? threshold_interval_[BIGGER];
}
-
if (!i && align_dir_ == LEFT)
center_f = where_f;
- else if (align_dir_ == CENTER && elem_l_arr_[i] == center_l_)
+ else if (align_dir_ == CENTER && elems[i] == center_l_)
center_f = where_f;
where_f += stacking_dir_ * dy;
- elem_l_arr_[i]->translate_axis (where_f, axis_);
+ elems[i]->translate_axis (where_f, axis ());
}
+ if (dims.size ())
+ where_f += dims.top ()[stacking_dir_];
if (align_dir_ == RIGHT)
center_f = where_f;
-
+ else if (align_dir_ == CENTER && !center_l_)
+ center_f = where_f / 2;
+
if (center_f)
- for (int i=0 ; i < elem_l_arr_.size(); i++)
- elem_l_arr_[i]->translate_axis (- center_f, axis_);
+ translate_axis ( - center_f, axis ());
+
+ dim_cache_[axis ()].invalidate ();
}
Align_element::Align_element()
{
+ ordered_b_ = true;
threshold_interval_ = Interval (0, Interval::infinity ());
- set_elt_property (transparent_scm_sym, SCM_BOOL_T);
- set_empty (true);
stacking_dir_ = DOWN;
- align_dir_ = LEFT;
- axis_ = X_AXIS;
+ align_dir_ = CENTER;
center_l_ =0;
+ priority_i_hash_.hash_func_ = pointer_hash;
+}
+
+Axis
+Align_element::axis () const
+{
+ return axes_[0];
+}
+
+void
+Align_element::set_axis (Axis a)
+{
+ set_axes (a,a);
}
Align_element::sort_elements ()
{
Array<Align_element_content> content;
- for (int i =0; i < elem_l_arr_.size(); i++)
- content.push (Align_element_content (elem_l_arr_[i], priority_i_arr_[i]));
+ for (int i =0; i < elem_l_arr_.size(); i++)
+ {
+ Score_element * e = dynamic_cast<Score_element*> (elem_l_arr_[i]);
+ assert (priority_i_hash_.elem_b (e));
+ int p = priority_i_hash_[e];
+ content.push (Align_element_content (e, p));
+ }
content.sort (Align_element_content::compare);
elem_l_arr_.clear();
- priority_i_arr_.clear();
+ priority_i_hash_.clear();
for (int i =0; i < content.size(); i++)
{
elem_l_arr_.push (content[i].elem_l_);
- priority_i_arr_.push (content[i].priority_i_);
}
}
Score_element*
Align_element::get_elt_by_priority (int p) const
{
- for (int i=0; i < priority_i_arr_.size (); i++)
+ for (Hash_table_iter<Score_element*, int> i(priority_i_hash_); i.ok (); i++)
{
- if (priority_i_arr_[i] == p)
- return elem_l_arr_[i];
+ if (i.val () == p)
+ return i.key();
}
return 0;
}
+
+int
+Align_element::get_priority (Score_element* e) const
+{
+ if ( priority_i_hash_.elem_b (e))
+ return priority_i_hash_[e];
+ else
+ return elem_l_arr_.find_i (e);
+}
if (prop.isnum_b ())
beam_p->quantisation_ = (Beam::Quantisation)(int)prop;
- // must set minVerticalAlign = = maxVerticalAlign to get sane results
- // see input/test/beam-interstaff.ly
- prop = get_property ("minVerticalAlign", 0);
- if (prop.isnum_b ())
- beam_p->vertical_align_drul_[MIN] = prop;
-
- prop = get_property ("maxVerticalAlign", 0);
- if (prop.isnum_b ())
- beam_p->vertical_align_drul_[MAX] = prop;
-
announce_element (Score_element_info (beam_p, 0));
return beam_p;
}
if (prop.isnum_b ())
beam_p_->quantisation_ = (Beam::Quantisation)(int)prop;
- // must set minVerticalAlign == maxVerticalAlign to get sane results
- // see input/test/beam-interstaff.ly
- prop = get_property ("minVerticalAlign", 0);
- if (prop.isnum_b ())
- beam_p_->vertical_align_drul_[MIN] = prop;
-
- prop = get_property ("maxVerticalAlign", 0);
- if (prop.isnum_b ())
- beam_p_->vertical_align_drul_[MAX] = prop;
-
announce_element (Score_element_info (beam_p_, reqs_drul_[START]));
}
}
/*
[TODO]
- * centre beam symbol
+ * center beam symbol
* less hairy code
* redo grouping
- */
+
+TODO:
+
+The relationship Stem <-> Beam is way too hairy. Let's figure who
+needs what, and what information should be available when.
+
+ */
#include <math.h>
-#include "p-col.hh"
-#include "array.hh"
#include "proto.hh"
#include "dimensions.hh"
#include "beam.hh"
-#include "abbreviation-beam.hh"
#include "misc.hh"
#include "debug.hh"
#include "molecule.hh"
left_y_ = 0;
quantisation_ = NORMAL;
multiple_i_ = 0;
- vertical_align_drul_[MIN] = 0;
- vertical_align_drul_[MAX] = -1;
}
void
Beam::add_stem (Stem*s)
{
+#if 0
+ if (!stems_.size ())
+ {
+ dim_cache_[Y_AXIS].parent_l_ = &s->dim_cache_[Y_AXIS];
+ }
+#endif
stems_.push (s);
s->add_dependency (this);
s->beam_l_ = this;
set_bounds (RIGHT,s);
}
+Stem_info
+Beam::get_stem_info (Stem *s)
+{
+ Stem_info i;
+ for (int i=0; i < sinfo_.size (); i++)
+ {
+ if (sinfo_[i].stem_l_ == s)
+ return sinfo_[i];
+ }
+ assert (false);
+ return i;
+}
+
Molecule*
Beam::do_brew_molecule_p () const
{
// correct if last note (and therefore reference point of beam)
// is on different staff
- Stem_info si = sinfo_.top ();
+ Stem_info si = sinfo_.top ();
mol_p->translate_axis (-si.interstaff_f_ * si.stem_l_->staff_line_leading_f ()/2,
Y_AXIS);
Stem_info si = sinfo_[0];
Real w= (si.stem_l_->note_delta_f () + extent (X_AXIS).length ())/2.0;
- return Offset (w, (left_y_ + w* slope_f_) *
+ return Offset (w, ( w* slope_f_) *
si.stem_l_->staff_line_leading_f ()/2);
}
void
Beam::solve_slope ()
{
- /*
- should use minimum energy formulation (cf linespacing)
- */
assert (sinfo_.size () > 1);
DOUT << "Beam::solve_slope: \n";
for (int i=0; i < stems_.size (); i++)
{
Stem *s = stems_[i];
- s->mult_i_ = multiple_i_;
+
s->set_default_extents ();
if (s->invisible_b ())
continue;
if (s->invisible_b ())
continue;
- Stem_info info (s);
+ Stem_info info (s, multiple_i_);
if (leftx == 0)
leftx = info.x_;
info.x_ -= leftx;
a.translate_axis( - stemdx/2, X_AXIS);
int j = 0;
Real gap_f = 0;
- if (here->beam_gap_i_)
+
+ SCM gap = get_elt_property (beam_gap_scm_sym);
+ if (gap != SCM_BOOL_F)
{
- int nogap = rwholebeams - here->beam_gap_i_;
+ int gap_i = gh_scm2int (gap);
+ int nogap = rwholebeams - gap_i;
+
for (; j < nogap; j++)
{
Molecule b (a);
#include "bezier.hh"
#include "main.hh"
-
-
Bow::Bow ()
{
dy_f_drul_[LEFT] = dy_f_drul_[RIGHT] = 0.0;
dx_f_drul_[LEFT] = dx_f_drul_[RIGHT] = 0.0;
- dash_i_ = 0;
- interstaff_f_ = 0;
- vertical_align_drul_[MIN] = 0;
- vertical_align_drul_[MAX] = -1;
}
Molecule*
Molecule* mol_p = new Molecule;
mol_p->add_molecule (a);
- mol_p->translate_axis (-interstaff_f_, Y_AXIS);
return mol_p;
}
Real y = c[i][Y_AXIS];
iv.unite (Interval (y,y));
}
- iv -= interstaff_f_;
return iv;
}
#include "chord.hh"
#include "warn.hh"
-// doesn't seem common, and we should know about this during purple hit
+// doesn't seem common, and we should know about this during parsing
// #define INVERSION_ADDED_AS_BASE 1
Chord::Chord (Array<Musical_pitch> pitch_arr)
#include "staff-symbol.hh"
#include "note-head.hh"
#include "debug.hh"
+#include "align-element.hh"
Encompass_info::Encompass_info ()
{
if (stem_l->dir_ != dir)
o_.y () += 1.0 * internote * dir;
- if (slur_l->encompass_arr_.size ()
- && stem_l->staff_symbol_l () != slur_l->encompass_arr_[0]->stem_l_->staff_symbol_l ())
+
+ Dimension_cache *common = note->common_group (slur_l, Y_AXIS);
+ Align_element * align = dynamic_cast<Align_element*> (common->element_l ());
+ if (align && align->axis() == Y_AXIS)
{
- if (slur_l->vertical_align_drul_[MIN] !=
- slur_l->vertical_align_drul_[MAX])
- warning (_ ("minVerticalAlign != maxVerticalAlign: interstaff slurs may be broken"));
- interstaff_f_ = slur_l->vertical_align_drul_[MIN];
- /* urg, guess staff order */
- int d = note->head_l_arr_.top ()->position_i_
- - slur_l->encompass_arr_[0]->head_l_arr_[0]->position_i_;
- if (abs (d > 3))
- interstaff_f_ *= sign (d);
- else if (stem_l->chord_start_f () >
- slur_l->encompass_arr_[0]->stem_l_->chord_start_f ())
+ if (align->threshold_interval_[MIN] !=
+ align->threshold_interval_[MAX])
+ warning (_ ("minVerticalAlign != maxVerticalAlign: interstaff beams/slurs may be broken"));
+
+ interstaff_f_ = align->threshold_interval_[MIN];
+
+ Dimension_cache * slur_refpoint = &slur_l->dim_cache_[Y_AXIS];
+ Dimension_cache * note_refpoint = ¬e->dim_cache_[Y_AXIS];
+
+ while (slur_refpoint->parent_l_ != common)
+ slur_refpoint = slur_refpoint->parent_l_;
+ while (note_refpoint->parent_l_ != common)
+ note_refpoint = note_refpoint->parent_l_;
+
+
+ int slur_prio =
+ align->get_priority (dynamic_cast<Score_element*> (slur_refpoint->element_l ()));
+ int stem_prio =
+ align->get_priority (dynamic_cast<Score_element*> (note_refpoint->element_l ()));
+
+ /*
+ our staff is lower -> interstaff_f_ *= -1
+ */
+ // ? Is this OK?
+ if (slur_prio < stem_prio)
interstaff_f_ *= -1;
o_.y () += interstaff_f_;
}
(c) 1997--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
*/
+
#include "interval.hh"
#include "graphical-axis-group.hh"
#include "axis-group-element.hh"
Graphical_axis_group at one time. */
Graphical_axis_group::Graphical_axis_group (Graphical_axis_group const&s)
{
- axes_[0] = s.axes_[0];
- axes_[1] = s.axes_[1];
+ axes_ = s.axes_;
+ ordered_b_ = s.ordered_b_;
}
bool
for (int i = 0; i < 2; i++)
{
Axis a = axes_[i];
+ assert (a>=0);
Dimension_cache * &d = e->dim_cache_[a].parent_l_;
assert (!d || d == &dim_cache_[a]);
d = &dim_cache_[a];
Graphical_axis_group::remove_element (Graphical_element*e)
{
assert (contains_b (e));
- elem_l_arr_.unordered_substitute (e,0);
+ if (ordered_b_)
+ elem_l_arr_.substitute (e,0);
+ else
+ elem_l_arr_.unordered_substitute (e,0);
for (int i=0; i< 2; i++)
{
#endif
}
-Graphical_axis_group::Graphical_axis_group (Axis a1, Axis a2)
+Graphical_axis_group::Graphical_axis_group ()
{
- axes_[0] = a1;
- axes_[1] = a2;
+ ordered_b_ = false;
+ axes_[0] = -1 ;
+ axes_[1] = -1 ;
}
-
+void
+Graphical_axis_group::set_axes (Axis a1, Axis a2)
+{
+ axes_[0] = a1 ;
+ axes_[1] = a2 ;
+}
if (note_p_arr_.size ())
return ;
+ String noteheadstyle = get_property ("noteHeadStyle", 0);
for (int i=0; i < note_req_l_arr_.size (); i++)
{
Note_head *note_p = new Note_head;
// note_p->steps_i_ = note_req_l->pitch_.steps ();
note_p->position_i_ = note_req_l->pitch_.steps ();
- String noteheadstyle = get_property ("noteheadStyle", 0);
- if (noteheadstyle.length_i ())
- note_p->note_head_type_str_ = noteheadstyle;
-
+
+ if (noteheadstyle == "transparent")
+ note_p->set_elt_property (transparent_scm_sym, SCM_BOOL_T);
+ else
+ note_p->set_elt_property (style_scm_sym,
+ gh_str02scm (noteheadstyle.ch_C()));
+
+
Score_element_info itinf (note_p,note_req_l);
announce_element (itinf);
note_p_arr_.push (note_p);
String str () const;
Adobe_font_char_metric ();
-
Box dimensions () const;
};
Adobe_font_metric ();
void read_char_metrics (Data_file &input, int size);
-
Character_metric *get_char (int, bool) const;
};
#ifndef VERTICAL_ALIGN_ITEM_HH
#define VERTICAL_ALIGN_ITEM_HH
-#include "score-element.hh"
+#include "axis-group-element.hh"
#include "interval.hh"
#include "direction.hh"
#include "axes.hh"
+#include "hash-table.hh"
/**
Order elements top to bottom/left to right/right to left etc..
TODO: implement padding.
+
+ document usage of this.
*/
-class Align_element : virtual public Score_element {
- Link_array<Score_element> elem_l_arr_;
- Array<int> priority_i_arr_;
+class Align_element : public virtual Axis_group_element {
+ Hash_table<Score_element*,int> priority_i_hash_;
void sort_elements ();
public:
Interval threshold_interval_ ;
Direction stacking_dir_;
/**
- Which side to align?
- -1: left side, 0: centered (around center_l_ if not nil), 1: right side
+ Which side to align? -1: left side, 0: centered (around
+ center_l_ if not nil, or around center of width), 1: right side
+
+ URG. Unintuitive if stacking_dir_ == -1
*/
Direction align_dir_;
- Axis axis_;
+ Axis axis () const;
Score_element * center_l_;
Align_element ();
+ void set_axis (Axis);
void add_element (Score_element*);
void add_element_priority (Score_element*, int);
bool contains_b (Score_element const*) const;
Score_element *get_elt_by_priority (int) const;
+ int get_priority (Score_element*) const;
protected:
virtual void do_print() const;
virtual void do_substitute_element_pointer (Score_element*,Score_element*);
/// maximum number of beams (for opening-up of beam-spacing)
int multiple_i_;
- /// vertical align distance between staffs
- Drul_array<Real> vertical_align_drul_;
-
Array<Stem_info> sinfo_;
Beam();
void add_stem (Stem*);
+ Stem_info get_stem_info (Stem*);
void set_grouping (Rhythmic_grouping def, Rhythmic_grouping current);
void set_stemlens ();
/**
Base class for anything that looks like a slur.
Anybody with a better name?
+
+ UGH. Fixme. Should junk
+
+ dy_f_drul_ , dx_f_drul_
+
*/
class Bow : public Directional_spanner
{
Bow ();
Offset center () const;
- int dash_i_;
- Real interstaff_f_;
- Drul_array<Real> vertical_align_drul_;
-
protected:
virtual Molecule* do_brew_molecule_p () const;
// virtual Interval do_width () const;
SCM ly_func_o (char const* name);
SCM ly_quote_scm (SCM s);
void ly_display_scm (SCM s);
-
+String ly_scm2string (SCM s);
#include "array.hh"
#include "scalar.hh"
Lookup ();
Lookup (Lookup const&);
-
-
- Molecule special_ball (int, String) const;
Molecule simple_bar (String s, Real w) const;
Molecule accidental (int, bool cautionary) const;
Molecule afm_find (String, bool warn=true) const;
- Molecule ball (int) const;
+ Molecule notehead (int, String) const;
+
Molecule bar (String, Real height) const;
Molecule beam (Real, Real, Real) const;
Molecule clef (String) const;
#define DECLARE_LY_SYMBOL(a) extern SCM a ## _scm_sym
#endif
+DECLARE_LY_SYMBOL(at_line_start);
DECLARE_LY_SYMBOL(beam);
DECLARE_LY_SYMBOL(beam_thickness);
DECLARE_LY_SYMBOL(beam_dir);
+DECLARE_LY_SYMBOL(beam_gap);
DECLARE_LY_SYMBOL(bracket);
DECLARE_LY_SYMBOL(break_helper_only);
DECLARE_LY_SYMBOL(break_priority);
DECLARE_LY_SYMBOL(change);
DECLARE_LY_SYMBOL(damping);
DECLARE_LY_SYMBOL(dashed);
+DECLARE_LY_SYMBOL(extremal);
DECLARE_LY_SYMBOL(dir_forced);
DECLARE_LY_SYMBOL(extender_height);
DECLARE_LY_SYMBOL(filledbox);
DECLARE_LY_SYMBOL(non_default);
DECLARE_LY_SYMBOL(octave_dir);
DECLARE_LY_SYMBOL(output);
+DECLARE_LY_SYMBOL(padding);
DECLARE_LY_SYMBOL(pianobrace);
DECLARE_LY_SYMBOL(placebox);
DECLARE_LY_SYMBOL(rulesym);
DECLARE_LY_SYMBOL(rulethickness);
DECLARE_LY_SYMBOL(staffheight);
+DECLARE_LY_SYMBOL(style);
DECLARE_LY_SYMBOL(text);
DECLARE_LY_SYMBOL(transparent);
DECLARE_LY_SYMBOL(tuplet);
gh_display (s);
gh_newline ();
}
+
+String
+ly_scm2string (SCM s)
+{
+ int len;
+ char * p = gh_scm2newstr (s , &len);
+
+ String r (p);
+ delete p;
+ return r;
+}
}
Molecule
-Lookup::ball (int j) const
+Lookup::notehead (int j, String type) const
{
if (j > 2)
j = 2;
- return afm_find (String ("noteheads-") + to_str (j));
+ return afm_find (String ("noteheads-") + to_str (j) + type);
}
Molecule
{
return fill (Box (Interval(0, 0), Interval (-h/2, h/2)));
}
+ if (str == "scorepostbreak")
+ {
+ return simple_bar ("score", h);
+ }
else if (str == "|")
{
return thin;
String symbolname = "timesig-" + s + to_str (n) + "/" + to_str (d);
Molecule m = afm_find (symbolname, false);
- if (!m.dim_[X_AXIS].empty_b ())
+ if (!m.empty_b())
return m;
// Second guess: s contains the full signature name
m = afm_find ("timesig-"+s, false);
- if (!m.dim_[X_AXIS].empty_b ())
+ if (!m.empty_b ())
return m;
// Resort to default layout with numbers
SCM l = gh_eval_str (("(style-to-cmr \"" + style + "\")").ch_C());
if (l != SCM_BOOL_F)
{
- int len ;
- char * s = gh_scm2newstr(SCM_CDR (l), &len);
- style = String (s) + to_str ((int)font_h);
- delete s;
+ style = ly_scm2string (SCM_CDR(l)) +to_str ((int)font_h);
}
Real w = 0;
}
-Molecule
-Lookup::special_ball (int j, String kind_of_ball) const
-{
- if (j > 2)
- j = 2;
-
- return afm_find (String ("noteheads-") + kind_of_ball);
-}
-
#include "dots.hh"
#include "note-head.hh"
#include "debug.hh"
-#include "paper-def.hh"
#include "lookup.hh"
#include "molecule.hh"
#include "musical-request.hh"
+void
+Note_head::flip_around_stem (Direction d)
+{
+ translate_axis (do_width ().length () * d, X_AXIS);
+}
Note_head::Note_head ()
{
- x_dir_ = CENTER;
position_i_ = 0;
- extremal_i_ = 0;
}
void
return a->position_i_ - b->position_i_;
}
+/**
+ Don't account for ledgerlines in the width.
+ */
Interval
Note_head::do_width () const
{
- Molecule a = lookup_l ()->ball (balltype_i_);
+ Molecule a = lookup_l ()->notehead (balltype_i_, ""); // UGH
Interval i = a.dim_[X_AXIS];
- i+= x_dir_ * i.length ();
return i;
}
Note_head::do_brew_molecule_p() const
{
Molecule*out = 0;
- Paper_def *p = paper_l ();
Real inter_f = staff_line_leading_f ()/2;
int sz = lines_i ()-1;
- // ugh
+
int streepjes_i = abs (position_i_) < sz
? 0
: (abs(position_i_) - sz) /2;
-
- Molecule head;
- if (note_head_type_str_.length_i ()) {
- if (note_head_type_str_ == "normal") // UGH
- note_head_type_str_ = "";
- head = lookup_l()->special_ball (balltype_i_, note_head_type_str_);
+
+ String type;
+ SCM style =get_elt_property (style_scm_sym);
+ if (style != SCM_BOOL_F)
+ {
+ type = ly_scm2string (SCM_CDR(style));
}
- else
- head = lookup_l()->ball (balltype_i_);
- out = new Molecule (Molecule (head));
- out->translate_axis (x_dir_ * head.dim_[X_AXIS].length (), X_AXIS);
-
+ Molecule head (lookup_l()->notehead (balltype_i_, type));
+
+ out = new Molecule (Molecule (head));
if (streepjes_i)
{
Slur * s_p =new Slur;
Scalar prop = get_property ("slurdash", 0);
if (prop.isnum_b ())
- s_p->dash_i_ = prop;
-
- prop = get_property ("minVerticalAlign", 0);
- if (prop.isnum_b ())
- s_p->vertical_align_drul_[MIN] = prop;
-
- prop = get_property ("maxVerticalAlign", 0);
- if (prop.isnum_b ())
- s_p->vertical_align_drul_[MAX] = prop;
+ s_p->set_elt_property (dashed_scm_sym, gh_int2scm(prop));
requests_arr_.push (slur_req_l);
start_slur_l_arr_.push (s_p);
if (d == RIGHT)
{
dx_f_drul_[LEFT] = spanned_drul_[LEFT]->extent (X_AXIS).length ();
-
+
// urg -- check if needed
if (encompass_arr_.size () > 1)
dx_f_drul_[RIGHT] += notewidth_f;
notes.push (info.o_ - left);
}
Encompass_info info (encompass_arr_.top (), dir_, this);
+ Real inter_staff = info.interstaff_f_;
- // urg:
- Slur* urg = (Slur*)this;
- urg->interstaff_f_ = info.interstaff_f_;
-
- d[Y_AXIS] += interstaff_f_;
+ d[Y_AXIS] += inter_staff;
// prebreak
- if (interstaff_f_ && (encompass_arr_.top () != spanned_drul_[RIGHT]))
+ if (inter_staff && (encompass_arr_.top () != spanned_drul_[RIGHT]))
{
Encompass_info info (encompass_arr_[encompass_arr_.size () - 1], dir_, this);
- d[Y_AXIS] -= info.o_[Y_AXIS] - interstaff_f_;
+ d[Y_AXIS] -= info.o_[Y_AXIS] - inter_staff;
}
notes.push (d);
#include "misc.hh"
#include "debug.hh"
+#include "align-element.hh"
#include "stem.hh"
#include "paper-def.hh"
#include "lookup.hh"
{
}
-Stem_info::Stem_info (Stem*s)
+Stem_info::Stem_info (Stem*s, int mult)
{
+ mult_i_ =mult;
stem_l_ = s;
x_ = stem_l_->hpos_f ();
dir_ = stem_l_->dir_;
SCM bd = stem_l_->remove_elt_property (beam_dir_scm_sym);
beam_dir_ = gh_scm2int (SCM_CDR(bd));
-
- mult_i_ = stem_l_->mult_i_;
interstaff_f_ = 0;
Paper_def* paper_l = stem_l_->paper_l ();
idealy_f_ = miny_f_ >? idealy_f_;
// interstaff beam
- Beam* beam_l_ = stem_l_->beam_l_;
- if (beam_l_->sinfo_.size ()
- && stem_l_->staff_symbol_l () != beam_l_->sinfo_[0].stem_l_->staff_symbol_l ())
+ Beam* beam_l = stem_l_->beam_l_;
+ Dimension_cache *common = stem_l_->common_group (beam_l, Y_AXIS);
+ Align_element * align = dynamic_cast<Align_element*> (common->element_l ());
+ if (align && align->axis() == Y_AXIS)
{
- {
- // warning (_ ("invalid dimension cache: guessing staff position"));
- if (beam_l_->vertical_align_drul_[MIN] !=
- beam_l_->vertical_align_drul_[MAX])
- warning (_ ("minVerticalAlign != maxVerticalAlign: interstaff slurs may be broken"));
- interstaff_f_ = beam_l_->vertical_align_drul_[MIN] / internote_f;
- // urg, guess staff order:
- // if our stem ends higher, our staff is probably lower...
- if (idealy_f_ * beam_dir_ > beam_l_->sinfo_[0].idealy_f_ * beam_dir_)
- interstaff_f_ *= -1;
- }
+ if (align->threshold_interval_[MIN] !=
+ align->threshold_interval_[MAX])
+ warning (_ ("minVerticalAlign != maxVerticalAlign: interstaff beams/slurs may be broken"));
+
+ interstaff_f_ = align->threshold_interval_[MIN] / internote_f;
+
+ Dimension_cache * beam_refpoint = &beam_l->dim_cache_[Y_AXIS];
+ Dimension_cache * stem_refpoint = &stem_l_->dim_cache_[Y_AXIS];
+
+ while (beam_refpoint->parent_l_ != common)
+ beam_refpoint = beam_refpoint->parent_l_;
+ while (stem_refpoint->parent_l_ != common)
+ stem_refpoint = stem_refpoint->parent_l_;
+
+
+ int beam_prio =
+ align->get_priority (dynamic_cast<Score_element*> (beam_refpoint->element_l ()));
+ int stem_prio =
+ align->get_priority (dynamic_cast<Score_element*> (stem_refpoint->element_l ()));
+
+ /*
+ our staff is lower -> interstaff_f_ *= -1
+ */
+ if (beam_prio < stem_prio)
+ interstaff_f_ *= -1;
+
idealy_f_ += interstaff_f_ * beam_dir_;
miny_f_ += interstaff_f_ * beam_dir_;
maxy_f_ += interstaff_f_ * beam_dir_;
#include "p-col.hh"
#include "vertical-align-engraver.hh"
-#include "vertical-align-spanner.hh"
-#include "vertical-group-spanner.hh"
+#include "axis-align-spanner.hh"
+#include "axis-group-spanner.hh"
Vertical_align_engraver::Vertical_align_engraver()
{
void
Vertical_align_engraver::do_creation_processing()
{
- valign_p_ =new Vertical_align_spanner;
+ valign_p_ =new Axis_align_spanner;
+ valign_p_->set_axis (Y_AXIS);
+ valign_p_->stacking_dir_ = DOWN;
+
valign_p_->set_bounds(LEFT,get_staff_info().command_pcol_l ());
announce_element (Score_element_info (valign_p_ , 0));
}
{
valign_p_->threshold_interval_[SMALLER] = Real (dist);
}
-
+
+ dist = get_property ("alignmentReference",0);
+ if (dist.length_i () && dist.isnum_b ())
+ {
+ valign_p_->align_dir_ = int (dist);
+ }
valign_p_->set_bounds(RIGHT,get_staff_info().command_pcol_l ());
typeset_element (valign_p_);
valign_p_ =0;
void
Vertical_align_engraver::acknowledge_element (Score_element_info i)
{
- if (i.origin_grav_l_arr_.size() == 1
- && dynamic_cast<Vertical_group_spanner *> (i.elem_l_)
+ if (i.origin_grav_l_arr_.size() == 1 &&
+ dynamic_cast<Axis_group_spanner *> (i.elem_l_)
&& !i.elem_l_->parent_l (Y_AXIS))
{
- assert (!valign_p_->contains_b (i.elem_l_));
-
valign_p_->add_element (i.elem_l_);
}
}
Gourlay = 1.0
Wordwrap = 0.0
-
-papersize = "a4"
-
-\include "paper20.ly"
-
-\paper{
- \paper_twenty
-}
-
-% ugh
-\include "midi.ly"
-
% declarations for standard directions
left = -1
right = 1
major = 0
minor = 3
+
+
+papersize = "a4"
+
+\include "paper20.ly"
+
+\paper{
+ \paper_twenty
+}
+
+% ugh
+\include "midi.ly"
+
\include "dynamic.ly"
\include "property.ly"
\type "Line_group_engraver_group";
\name ChoirStaff;
\consists "Vertical_align_engraver";
+ alignmentReference = \center;
\consists "Staff_group_bar_engraver";
\accepts "Staff";
\accepts "RhythmicStaff";
\consists "Span_bar_engraver";
\consists "Vertical_align_engraver";
\consists "Piano_bar_engraver";
+ alignmentReference = \center;
minVerticalAlign = 1.5*\staffheight;
\accepts "Staff";
\translator{\GrandStaffContext
minVerticalAlign = 3.0*\staffheight;
maxVerticalAlign = 3.0*\staffheight;
+
\name "PianoStaff";
}
StaffGroupContext= \translator {
- \type "Hara_kiri_line_group_engraver";
+% \type "Hara_kiri_line_group_engraver";
% \type "Line_group_engraver_group";
+ \type "Engraver_group_engraver";
\consists "Span_bar_engraver";
\consists "Vertical_align_engraver";
+ alignmentReference = \center;
+
\consists "Staff_group_bar_engraver";
\name StaffGroup;
\accepts "Staff";
};
\translator { \ChordNameContext }
-ScoreContext = \translator {
- \type Score_engraver;
- \name Score;
-
- \consists "Timing_engraver";
-
- \consists "Span_score_bar_engraver";
- \consists "Score_priority_engraver";
-% \consists "Priority_horizontal_align_engraver";
- \consists "Vertical_align_engraver";
-
-
- \accepts "StaffGroup";
- \accepts "Staff";
- \accepts "RhythmicStaff";
- \accepts "Lyrics";
- \accepts "ChordNames";
- \accepts "GrandStaff";
- \accepts "ChoirStaff";
- \accepts "PianoStaff";
-};
-\translator { \ScoreContext }
ScoreWithNumbers = \translator {
\type "Score_engraver";
\consists "Bar_number_engraver";
};
-OrchestralScoreContext= \translator {
+
+ScoreContext = \translator {
\type Score_engraver;
\name Score;
- barScriptPadding = "2.0"; % dimension \pt
- markScriptPadding = "4.0";
- barColumnPriority = "-4";
- markBreakPriority = "-4";
- defaultClef = treble;
\consists "Timing_engraver";
- \consists "Bar_number_engraver";
- \consists "Mark_engraver";
\consists "Span_score_bar_engraver";
\consists "Score_priority_engraver";
-
\consists "Vertical_align_engraver";
+ alignmentReference = \down;
+ defaultClef = treble;
- \accepts "ChoirStaff";
+ \accepts "Staff";
\accepts "StaffGroup";
- \accepts "HaraKiriStaff";
\accepts "RhythmicStaff";
\accepts "Lyrics";
\accepts "ChordNames";
\accepts "GrandStaff";
+ \accepts "ChoirStaff";
\accepts "PianoStaff";
+};
+
+\translator { \ScoreContext }
+
+OrchestralScoreContext= \translator {
+ \ScoreContext
+
+ barScriptPadding = "2.0"; % dimension \pt
+ markScriptPadding = "4.0";
+
+
+ \consists "Bar_number_engraver";
+ \consists "Mark_engraver";
+
+ \accepts "HaraKiriStaff";
};
-%
+i%
% feta-generic.mf -- implement
%
% source file of the Feta (defintively not an abbreviation for Font-En-Tja)
% input feta-schrift;
% input feta-schrift;
% input feta-haak;
- input feta-timesig;
+% input feta-timesig;
fi
\score {
- \type GrandStaff <
+ \type PianoStaff <
\type Staff = treble <
\global
\dux
textheight = 295.\mm;
\translator{ \OrchestralScoreContext }
- \translator{
- \GrandStaffContext
- minVerticalAlign = 3.0*\staffheight;
- maxVerticalAlign = 3.0*\staffheight;
- }
}
\header{
opus = "BWV 847";
\def\placebox#1#2#3{%
\botalign{\hbox{\raise #1\leftalign{\kern #2{}#3}}}}%
-
+%
+%
+% UGH! JUNKME!
+%
\def\fetsixteendefs{%
\font\fetasixteen = feta16
\font\fetanummersixteen = feta-nummer8