+pl 13.hwn2
+ - paper/score column cleanups. Junk Score_column type
+
+pl 13.hwn1
+ - Bezier_bow/Bezier cleanups
+ - bf: rest under beam.
+
+pl 13.jcn2
+ - untangled Chord_name (item) and Chord (list-of-pitches)
+
+pl 13.jcn1
+ - bezier-bow fix
+
+***********
pl 12.hwn1
- polynomial.hh
- bf: generic properties
- use smobs for font metric tables/hashes.
- nl.po bf
+************
pl 11.jcn3
- small beam fixes (interstaff knees still broken)
PACKAGE_NAME=LilyPond
MAJOR_VERSION=1
MINOR_VERSION=3
-PATCH_LEVEL=13
+PATCH_LEVEL=14
MY_PATCH_LEVEL=
# use the above to send patches: MY_PATCH_LEVEL is always empty for a
{
coefs_[i-1] = coefs_[i] * i;
}
+ coefs_.pop ();
}
Polynomial
return dest;
}
-const Real FUDGE = 1e-8;
+static Real const FUDGE = 1e-8;
void
Polynomial::clean()
--- /dev/null
+\version "1.3.5";
+
+\score{
+ \notes{
+ c( d e )c |
+ \slurdotted
+ c( d e )c |
+ \slurnormal
+ c( d e )c |
+ \property Voice.slurDash = 3
+ c( d e )c |
+ \slurnormal
+ c( d e )c |
+ }
+ \paper{
+ indent = 0.0\pt;
+ %for broken!
+ % linewidth= 30.\mm;
+ castingalgorithm = \Wordwrap;
+ }
+}
+
+
}
-Bezier_bow::Bezier_bow (Paper_def* paper_l)
+Bezier_bow::Bezier_bow (Paper_def* paper_l,
+ Array<Offset> points, Direction dir)
{
paper_l_ = paper_l;
+ dir_ = dir;
+ encompass_ = points;
+ to_canonic_form ();
+
+ calc_default (0.0);
+ if (fit_factor () > 1.0)
+ {
+ calc_tangent_controls ();
+ blow_fit ();
+ }
}
void
Bezier_bow::blow_fit ()
{
- Real x1 = encompass_[0][X_AXIS];
- Real x2 = encompass_.top ()[X_AXIS];
-
- Real factor = 1.0;
- for (int i=1; i < encompass_.size ()-1; i++)
- {
- if (encompass_[i][X_AXIS] > x1 && encompass_[i][X_AXIS] < x2)
- {
- Real y = curve_.get_other_coordinate (X_AXIS, encompass_[i][X_AXIS]);
- if (y>0)
- {
- Real f = encompass_[i][Y_AXIS] / y;
- factor = factor >? f;
- }
- }
- }
-
- curve_.control_[1][Y_AXIS] *= factor;
- curve_.control_[2][Y_AXIS] *= factor;
- return_.control_[1][Y_AXIS] *= factor;
- return_.control_[2][Y_AXIS] *= factor;
+ Real f = fit_factor ();
+
+ curve_.control_[1][Y_AXIS] *= f;
+ curve_.control_[2][Y_AXIS] *= f;
curve_.check_sanity ();
}
-Real
-Bezier_bow::calc_f (Real height)
-{
- transform ();
- calc_default (height);
- Real dy = check_fit_f ();
- calc_return (0, 0);
- transform_back ();
- return dy;
-}
-
-void
-Bezier_bow::calc ()
-{
- transform ();
- calc_controls ();
- transform_back ();
-}
-
-
-
-/*
- [TODO]
- * see if it works
- * document in Documentation/fonts.tex
- */
-
-/*
- Clipping
- This function tries to address two issues:
- * the tangents of the slur should always point inwards
- in the actual slur, i.e. *after rotating back*.
- * slurs shouldn't be too high
- let's try : h <= 1.2 b && h <= 3 staffheight?
- We could calculate the tangent of the bezier curve from
- both ends going inward, and clip the slur at the point
- where the tangent (after rotation) points up (or inward
- with a certain maximum angle).
-
- However, we assume that real clipping is not the best
- answer. We expect that moving the outer control point up
- if the slur becomes too high will result in a nicer slur
- after recalculation.
-
- Knowing that the tangent is the line through the first
- two control points, we'll clip (move the outer control
- point upwards) too if the tangent points outwards.
- */
-
-bool
-Bezier_bow::calc_clipping ()
+Bezier
+Bezier_bow::get_curve ()const
{
- Real clip_height = paper_l_->get_var ("slur_clip_height");
- Real clip_ratio = paper_l_->get_var ("slur_clip_ratio");
- Real clip_angle = paper_l_->get_var ("slur_clip_angle");
-
- Real b = curve_.control_[3][X_AXIS] - curve_.control_[0][X_AXIS];
- Real clip_h = clip_ratio * b <? clip_height;
- Real begin_h = curve_.control_[1][Y_AXIS] - curve_.control_[0][Y_AXIS];
- Real end_h = curve_.control_[2][Y_AXIS] - curve_.control_[3][Y_AXIS];
- Real begin_dy = 0 >? begin_h - clip_h;
- Real end_dy = 0 >? end_h - clip_h;
-
- Real pi = M_PI;
- Real begin_alpha = (curve_.control_[1] - curve_.control_[0]).arg () + dir_ * alpha_;
- Real end_alpha = pi - (curve_.control_[2] - curve_.control_[3]).arg () - dir_ * alpha_;
-
- Real max_alpha = clip_angle / 90 * pi / 2;
- if ((begin_dy < 0) && (end_dy < 0)
- && (begin_alpha < max_alpha) && (end_alpha < max_alpha))
- return false;
- transform_back ();
-
- bool again = true;
-
- if ((begin_dy > 0) || (end_dy > 0))
- {
- Real dy = (begin_dy + end_dy) / 4;
- dy *= cos (alpha_);
- encompass_[0][Y_AXIS] += dir_ * dy;
- encompass_.top ()[Y_AXIS] += dir_ * dy;
- }
- else
+ Bezier rv = curve_;
+ if (dir_ == DOWN)
{
- //ugh
- Real c = 0.4;
- if (begin_alpha >= max_alpha)
- begin_dy = 0 >? c * begin_alpha / max_alpha * begin_h;
- if (end_alpha >= max_alpha)
- end_dy = 0 >? c * end_alpha / max_alpha * end_h;
-
- encompass_[0][Y_AXIS] += dir_ * begin_dy;
- encompass_.top ()[Y_AXIS] += dir_ * end_dy;
-
- Offset delta = encompass_.top () - encompass_[0];
- alpha_ = delta.arg ();
+ rv.flip (Y_AXIS);
}
- transform ();
-
- return again;
+ rv.rotate (alpha_);
+ rv.translate (origin_);
+ return rv;
}
-void
-Bezier_bow::calc_controls ()
-{
- for (int i = 0; i < 3; i++)
- {
-
- if (i && !calc_clipping ())
- return;
-
- /*
- why do we always recalc from 0?
- shouldn't calc_f () be used (too), rather than blow_fit () (only)?
- */
- calc_default (0);
- curve_.check_sanity ();
- if (check_fit_f () > 0)
- {
- calc_tangent_controls ();
- blow_fit ();
- }
- else
- {
- calc_return (0, 0);
- return;
- }
- }
-}
-
-void
-Bezier_bow::calc_return (Real begin_alpha, Real end_alpha)
-{
- Real thick = paper_l_->get_var ("slur_thickness");
-
- return_.control_[0] = curve_.control_[3];
- return_.control_[3] = curve_.control_[0];
-
- return_.control_[1] = curve_.control_[2] - thick * complex_exp (Offset (0, 90 + end_alpha));
- return_.control_[2] = curve_.control_[1] - thick * complex_exp (Offset (0, 90 - begin_alpha));
-}
+static Real const FUDGE = 1e-8;
/*
-This function calculates 2 center control points, based on
+ This function calculates 2 center control points,
+ based on lines through c_0 --> left disturbing
+ and c_3--> right disturbing encompass points.
- See Documentation/fonts.tex
+ See Documentation/fonts.tex
*/
void
Bezier_bow::calc_tangent_controls ()
Direction d = LEFT;
do
{
- maxtan[d] *= rc_correct;
- angles[d] = atan (-d * maxtan[d]);
+ maxtan[d] *= -d * rc_correct;
+ angles[d] = atan (maxtan[d]);
}
while (flip(&d) != LEFT);
Real rc3 = 0.0;
- // if we have two disturbing points, have line through those...
- if (disturb[LEFT][Y_AXIS] != disturb[RIGHT][Y_AXIS])
+ /*
+ if we have two disturbing points, have line through those...
+ in order to get a sane line, make sure points are reasonably far apart
+ X distance must be reasonably(!) big (division)
+ */
+ if (abs (disturb[LEFT][X_AXIS] - disturb[RIGHT][X_AXIS]) > FUDGE)
rc3 = (disturb[RIGHT][Y_AXIS] - disturb[LEFT][Y_AXIS]) / (disturb[RIGHT][X_AXIS] - disturb[LEFT][X_AXIS]);
else
- rc3 = tan ((angles[RIGHT] - angles[LEFT]) / 2);
+ rc3 = tan ((angles[LEFT] - angles[RIGHT]) / 2);
// ugh: be less steep
curve_.check_sanity();
-
- calc_return (angles[LEFT], angles[RIGHT]);
}
/*
The maximum amount that the encompass points stick out above the bezier curve.
*/
Real
-Bezier_bow::check_fit_f () const
+Bezier_bow::fit_factor () const
{
- Real dy = 0;
Real x1 = encompass_[0][X_AXIS];
Real x2 = encompass_.top ()[X_AXIS];
- for (int i = 1; i < encompass_.size () - 1; i++)
+
+ Real factor = 1.0;
+ for (int i=1; i < encompass_.size ()-1; i++)
{
- Real x = encompass_[i][X_AXIS];
- if (x1< x&& x < x2)
- dy = dy >? (encompass_[i][Y_AXIS] - curve_.get_other_coordinate (X_AXIS, x));
+ if (encompass_[i][X_AXIS] > x1 && encompass_[i][X_AXIS] < x2)
+ {
+ Real y = curve_.get_other_coordinate (X_AXIS, encompass_[i][X_AXIS]);
+ if (y>0)
+ {
+ Real f = encompass_[i][Y_AXIS] / y;
+ factor = factor >? f;
+ }
+ }
}
- return dy;
-}
-void
-Bezier_bow::set (Array<Offset> points, Direction dir)
-{
- dir_ = dir;
- encompass_ = points;
+ return factor;
}
+
+
+
void
-Bezier_bow::transform ()
+Bezier_bow::to_canonic_form ()
{
origin_ = encompass_[0];
translate (encompass_,-origin_);
alpha_ = delta.arg ();
rotate (encompass_, -alpha_);
-
- if (dir_ == DOWN)
- flipy (encompass_);
-}
-
-void
-Bezier_bow::transform_back ()
-{
if (dir_ == DOWN)
{
- curve_.flip (Y_AXIS);
- return_.flip (Y_AXIS);
flipy (encompass_);
}
-
- curve_.rotate (alpha_);
- curve_.translate (origin_);
-
- return_.rotate (alpha_);
- return_.translate (origin_);
-
- rotate (encompass_,alpha_);
- translate (encompass_,origin_);
}
+
+
/*
See Documentation/fonts.tex
*/
Array<Real>
Bezier::solve_derivative (Offset deriv)const
{
- Polynomial xp[2];
+ Polynomial xp=polynomial (X_AXIS);
+ Polynomial yp=polynomial (Y_AXIS);
+ xp.differentiate ();
+ yp.differentiate ();
+
+ Polynomial combine = xp * deriv[Y_AXIS] - yp * deriv [X_AXIS];
- xp[X_AXIS] = polynomial (X_AXIS);
- xp[Y_AXIS] = polynomial (Y_AXIS);
- Polynomial combine = xp[X_AXIS] * deriv[Y_AXIS] - xp[Y_AXIS] * deriv [X_AXIS];
return filter_solutions (combine.solve ());
}
assert (!isnan (control_[i].length ())
&& !isinf (control_[i].length ()));
}
+
+void
+Bezier::reverse ()
+{
+ Bezier b2;
+ for (int i =0; i < CONTROL_COUNT; i++)
+ b2.control_[CONTROL_COUNT-i-1] = control_[i];
+ *this = b2;
+}
Bow::do_brew_molecule_p () const
{
Real thick = paper_l ()->get_var ("slur_thickness");
- Array<Offset> c = get_controls ();
+ Bezier one = get_curve ();
Molecule a;
-
SCM d = get_elt_property ("dashed");
if (d == SCM_UNDEFINED)
- a = lookup_l ()->slur (c, thick);
+ a = lookup_l ()->slur (one, get_direction () * thick, thick);
else
- a = lookup_l ()->dashed_slur (c, thick, gh_scm2int (d));
-
+ a = lookup_l ()->dashed_slur (one, thick, gh_scm2int (d));
+
return new Molecule (a);
}
return Offset (dx / 2, dy);
}
-/*
- Ugh. Control points are too crude measures.
- */
+
Interval
-Bow::dim_callback (Dimension_cache const* c)
+Bow::curve_extent (Axis a) const
{
- Interval iv;
- Bow * b = dynamic_cast<Bow*> (c->element_l ());
- Array<Offset> p (b->get_controls());
- for (int i=0; i < p.size (); i++)
- {
- Real y = p[i][Y_AXIS];
- iv.unite (Interval (y,y));
- }
- return iv;
+ return get_curve ().extent (a);
}
-Interval
-Bow::curve_extent (Axis a) const
+Bezier
+Bow::get_curve () const
{
- Bezier_bow b (paper_l ());
- b.set (get_encompass_offset_arr (), get_direction ());
- b.calc ();
- return b.curve_.extent (a);
+
+
+
+ Bezier_bow b (paper_l (),
+ get_encompass_offset_arr (), get_direction ());
+
+ return b.get_curve ();
}
-Array<Offset>
-Bow::get_controls () const
+#if 0
+
+/*
+ TODO: FIXME.
+ */
+
+/*
+ Clipping
+
+ This function tries to address two issues:
+ * the tangents of the slur should always point inwards
+ in the actual slur, i.e. *after rotating back*.
+
+ * slurs shouldn't be too high
+ let's try : h <= 1.2 b && h <= 3 staffheight?
+
+ We could calculate the tangent of the bezier curve from
+ both ends going inward, and clip the slur at the point
+ where the tangent (after rotation) points up (or inward
+ with a certain maximum angle).
+
+ However, we assume that real clipping is not the best
+ answer. We expect that moving the outer control point up
+ if the slur becomes too high will result in a nicer slur
+ after recalculation.
+
+ Knowing that the tangent is the line through the first
+ two control points, we'll clip (move the outer control
+ point upwards) too if the tangent points outwards.
+ */
+
+bool
+Bezier_bow::calc_clipping ()
{
- Bezier_bow b (paper_l ());
- b.set (get_encompass_offset_arr (), get_direction ());
- b.calc ();
- Array<Offset> controls;
- for (int i = 0; i < 4; i++)
- controls.push (b.curve_.control_[i]);
- for (int i = 0; i < 4; i++)
- controls.push (b.return_.control_[i]);
- return controls;
+ Real clip_height = paper_l_->get_var ("slur_clip_height");
+ Real clip_ratio = paper_l_->get_var ("slur_clip_ratio");
+ Real clip_angle = paper_l_->get_var ("slur_clip_angle");
+
+ Real b = curve_.control_[3][X_AXIS] - curve_.control_[0][X_AXIS];
+ Real clip_h = clip_ratio * b <? clip_height;
+ Real begin_h = curve_.control_[1][Y_AXIS] - curve_.control_[0][Y_AXIS];
+ Real end_h = curve_.control_[2][Y_AXIS] - curve_.control_[3][Y_AXIS];
+ Real begin_dy = 0 >? begin_h - clip_h;
+ Real end_dy = 0 >? end_h - clip_h;
+
+ Real pi = M_PI;
+ Real begin_alpha = (curve_.control_[1] - curve_.control_[0]).arg () + dir_ * alpha_;
+ Real end_alpha = pi - (curve_.control_[2] - curve_.control_[3]).arg () - dir_ * alpha_;
+
+ Real max_alpha = clip_angle / 90 * pi / 2;
+ if ((begin_dy < 0) && (end_dy < 0)
+ && (begin_alpha < max_alpha) && (end_alpha < max_alpha))
+ return false;
+
+ transform_back ();
+
+ if ((begin_dy > 0) || (end_dy > 0))
+ {
+ Real dy = (begin_dy + end_dy) / 4;
+ dy *= cos (alpha_);
+ encompass_[0][Y_AXIS] += dir_ * dy;
+ encompass_.top ()[Y_AXIS] += dir_ * dy;
+ }
+ else
+ {
+ //ugh
+ Real c = 0.4;
+ if (begin_alpha >= max_alpha)
+ begin_dy = 0 >? c * begin_alpha / max_alpha * begin_h;
+ if (end_alpha >= max_alpha)
+ end_dy = 0 >? c * end_alpha / max_alpha * end_h;
+
+ encompass_[0][Y_AXIS] += dir_ * begin_dy;
+ encompass_.top ()[Y_AXIS] += dir_ * end_dy;
+
+ Offset delta = encompass_.top () - encompass_[0];
+ alpha_ = delta.arg ();
+ }
+
+ to_canonic_form ();
+
+ return true;
}
+#endif
+
+
Array<Offset>
Bow::get_encompass_offset_arr () const
Array<Offset> offset_arr;
offset_arr.push (Offset (dx_f_drul_[LEFT], dy_f_drul_[LEFT]));
offset_arr.push (Offset (spanner_length () + dx_f_drul_[RIGHT],
- dy_f_drul_[RIGHT]));
+ dy_f_drul_[RIGHT]));
return offset_arr;
}
(c) 1996, 1997--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
*/
-#include "score-column.hh"
+#include "paper-column.hh"
#include "break-algorithm.hh"
#include "paper-def.hh"
#include "debug.hh"
*/
#include "chord-name-engraver.hh"
-#include "chord.hh"
+#include "chord-name.hh"
#include "musical-request.hh"
#include "paper-def.hh"
#include "lookup.hh"
Chord_name_engraver::Chord_name_engraver ()
{
- chord_p_ = 0;
+ chord_name_p_ = 0;
tonic_req_ = 0;
inversion_req_ = 0;
bass_req_ = 0;
void
Chord_name_engraver::do_process_requests ()
{
- if (chord_p_)
+ if (chord_name_p_)
return;
if (!pitch_arr_.size ())
return;
if (gh_boolean_p (chord_inversion))
find_inversion_b = gh_scm2bool (chord_inversion);
- chord_p_ = new Chord (to_chord (pitch_arr_, tonic_req_, inversion_req_, bass_req_, find_inversion_b));
+ chord_name_p_ = new Chord_name (to_chord (pitch_arr_, tonic_req_, inversion_req_, bass_req_, find_inversion_b));
- announce_element (Score_element_info (chord_p_, 0));
+ announce_element (Score_element_info (chord_name_p_, 0));
}
void
Chord_name_engraver::do_pre_move_processing ()
{
- if (chord_p_)
+ if (chord_name_p_)
{
- typeset_element (chord_p_);
+ typeset_element (chord_name_p_);
}
pitch_arr_.clear ();
- chord_p_ = 0;
+ chord_name_p_ = 0;
tonic_req_ = 0;
inversion_req_ = 0;
bass_req_ = 0;
--- /dev/null
+/*
+ chord-name.cc -- implement Chord_name
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 1999 Jan Nieuwenhuizen <janneke@gnu.org>
+*/
+
+#include "chord-name.hh"
+#include "musical-request.hh"
+#include "warn.hh"
+#include "debug.hh"
+#include "molecule.hh"
+#include "paper-def.hh"
+#include "lookup.hh"
+
+SCM
+pitch2scm (Musical_pitch p)
+{
+ return gh_cons (gh_int2scm (p.notename_i_), gh_int2scm (p.accidental_i_));
+}
+
+Chord_name::Chord_name (Chord const& c)
+{
+ chord_ = c;
+}
+
+/*
+ word is roman text or styled text:
+ "text"
+ ("style" . "text")
+ */
+Molecule
+Chord_name::ly_word2molecule (SCM scm) const
+{
+ String style;
+ if (gh_pair_p (scm))
+ {
+ style = ly_scm2string (gh_car (scm));
+ scm = gh_cdr (scm);
+ }
+ String text = ly_scm2string (scm);
+ return lookup_l ()->text (style, text, paper_l ());
+}
+
+/*
+ scm is word or list of words:
+ word
+ (word word)
+ */
+Molecule
+Chord_name::ly_text2molecule (SCM scm) const
+{
+ Molecule mol;
+ if (gh_list_p (scm))
+ {
+ while (gh_cdr (scm) != SCM_EOL)
+ {
+ mol.add_at_edge (X_AXIS, RIGHT,
+ ly_word2molecule (gh_car (scm)), 0);
+ scm = gh_cdr (scm);
+ }
+ scm = gh_car (scm);
+ }
+ mol.add_at_edge (X_AXIS, RIGHT,
+ ly_word2molecule (scm), 0);
+ return mol;
+}
+
+Molecule
+Chord_name::pitch2molecule (Musical_pitch p) const
+{
+ SCM name = scm_eval (gh_list (ly_symbol2scm ("user-pitch-name"), ly_quote_scm (pitch2scm (p)), SCM_UNDEFINED));
+
+ if (name != SCM_UNSPECIFIED)
+ {
+ return ly_text2molecule (name);
+ }
+
+ Molecule mol = lookup_l ()->text ("", p.str ().left_str (1).upper_str (), paper_l ());
+
+ /*
+ We want the smaller size, even if we're big ourselves.
+ */
+ if (p.accidental_i_)
+ mol.add_at_edge (X_AXIS, RIGHT,
+
+ paper_l ()->lookup_l (-2)->afm_find (String ("accidentals-") + to_str (p.accidental_i_)), 0.0);
+ return mol;
+}
+
+Musical_pitch
+diff_pitch (Musical_pitch tonic, Musical_pitch p)
+{
+ Musical_pitch diff (p.notename_i_ - tonic.notename_i_,
+ p.accidental_i_ - tonic.accidental_i_,
+ p.octave_i_ - tonic.octave_i_);
+
+ while (diff.notename_i_ >= 7)
+ {
+ diff.notename_i_ -= 7;
+ diff.octave_i_ ++;
+ }
+ while (diff.notename_i_ < 0)
+ {
+ diff.notename_i_ += 7;
+ diff.octave_i_ --;
+ }
+
+ diff.accidental_i_ -= (tonic.semitone_pitch () + diff.semitone_pitch ())
+ - p.semitone_pitch ();
+
+ return diff;
+}
+
+bool
+Chord_name::user_chord_name (Array<Musical_pitch> pitch_arr, Chord_mol* name_p) const
+{
+ SCM chord = SCM_EOL;
+ Array<Musical_pitch> chord_type = pitch_arr;
+ Chord::rebuild_transpose (&chord_type, diff_pitch (pitch_arr[0], Musical_pitch (0)), false);
+
+ for (int i= chord_type.size (); i--; )
+ chord = gh_cons (pitch2scm (chord_type[i]), chord);
+
+ SCM name = scm_eval (gh_list (ly_symbol2scm ("user-chord-name"), ly_quote_scm (chord), SCM_UNDEFINED));
+ if (gh_pair_p (name))
+ {
+ name_p->modifier_mol = ly_text2molecule (gh_car (name));
+ name_p->addition_mol = ly_text2molecule (gh_cdr (name));
+ return true;
+ }
+ return false;
+}
+
+void
+Chord_name::banter (Array<Musical_pitch> pitch_arr, Chord_mol* name_p) const
+{
+ Array<Musical_pitch> add_arr;
+ Array<Musical_pitch> sub_arr;
+ Chord::find_additions_and_subtractions (pitch_arr, &add_arr, &sub_arr);
+
+ Array<Musical_pitch> scale;
+ for (int i=0; i < 7; i++)
+ scale.push (Musical_pitch (i));
+
+ Musical_pitch tonic = pitch_arr[0];
+ chord_.rebuild_transpose (&scale, tonic, true);
+
+ /*
+ Does chord include this step? -1 if flat
+ */
+ int has[16];
+ for (int i=0; i<16; i++)
+ has[i] = 0;
+
+ String mod_str;
+ String add_str;
+ String sep_str;
+ for (int i = 0; i < add_arr.size (); i++)
+ {
+ Musical_pitch p = add_arr[i];
+ int step = Chord::step_i (tonic, p);
+ int accidental = p.accidental_i_ - scale[(step - 1) % 7].accidental_i_;
+ if ((step < 16) && (has[step] != -1))
+ has[step] = accidental == -1 ? -1 : 1;
+ // only from guile table ?
+ if ((step == 3) && (accidental == -1))
+ {
+ mod_str = "m";
+ }
+ else if (accidental
+ || (!(step % 2)
+ || ((i == add_arr.size () - 1) && (step > 5))))
+ {
+ add_str += sep_str;
+ sep_str = "/";
+ if ((step == 7) && (accidental == 1))
+ {
+ add_str += "maj7";
+ }
+ else
+ {
+ add_str += to_str (step);
+ if (accidental)
+ add_str += accidental < 0 ? "-" : "+";
+ }
+ }
+ }
+
+ for (int i = 0; i < sub_arr.size (); i++)
+ {
+ Musical_pitch p = sub_arr[i];
+ int step = Chord::step_i (tonic, p);
+ /*
+ if additions include 2 or 4, assume sus2/4 and don't display 'no3'
+ */
+ if (!((step == 3) && (has[2] || has[4])))
+ {
+ add_str += sep_str + "no" + to_str (step);
+ sep_str = "/";
+ }
+ }
+
+ if (mod_str.length_i ())
+ name_p->modifier_mol.add_at_edge (X_AXIS, RIGHT,
+ lookup_l ()->text ("roman", mod_str, paper_l ()), 0);
+ if (add_str.length_i ())
+ {
+ if (!name_p->addition_mol.empty_b ())
+ add_str = "/" + add_str;
+ name_p->addition_mol.add_at_edge (X_AXIS, RIGHT,
+ lookup_l ()->text ("script", add_str, paper_l ()), 0);
+ }
+}
+
+Molecule*
+Chord_name::do_brew_molecule_p () const
+{
+ Musical_pitch tonic = chord_.pitch_arr_[0];
+
+ Chord_mol name;
+ name.tonic_mol = pitch2molecule (tonic);
+
+ /*
+ if user has explicitely listed chord name, use that
+
+ TODO
+ urg
+ maybe we should check all sub-lists of pitches, not
+ just full list and base triad?
+ */
+ if (!user_chord_name (chord_.pitch_arr_, &name))
+ {
+ /*
+ else, check if user has listed base triad
+ use user base name and add banter for remaining part
+ */
+ if ((chord_.pitch_arr_.size () > 2)
+ && user_chord_name (chord_.pitch_arr_.slice (0, 3), &name))
+ {
+ Array<Musical_pitch> base = Chord::base_arr (tonic);
+ base.concat (chord_.pitch_arr_.slice (3, chord_.pitch_arr_.size ()));
+ banter (base, &name);
+ }
+ /*
+ else, use pure banter
+ */
+ else
+ {
+ banter (chord_.pitch_arr_, &name);
+ }
+ }
+
+ if (chord_.inversion_b_)
+ {
+ name.inversion_mol = lookup_l ()->text ("", "/", paper_l ());
+ // zucht const&
+ Molecule mol = pitch2molecule (chord_.inversion_pitch_);
+ name.inversion_mol.add_at_edge (X_AXIS, RIGHT, mol, 0);
+ }
+
+ if (chord_.bass_b_)
+ {
+ name.bass_mol = lookup_l ()->text ("", "/", paper_l ());
+ Molecule mol = pitch2molecule (chord_.bass_pitch_);
+ name.bass_mol.add_at_edge (X_AXIS, RIGHT, mol, 0);
+ }
+
+ // urg, howto get a good superscript_y?
+ Real super_y = lookup_l ()->text ("", "x", paper_l ()).dim_.y ().length ()/2;
+ if (!name.addition_mol.empty_b ())
+ name.addition_mol.translate (Offset (0, super_y));
+
+ Molecule* mol_p = new Molecule;
+ mol_p->add_at_edge (X_AXIS, RIGHT, name.tonic_mol, 0);
+ // huh?
+ if (!name.modifier_mol.empty_b ())
+ mol_p->add_at_edge (X_AXIS, RIGHT, name.modifier_mol, 0);
+ if (!name.addition_mol.empty_b ())
+ mol_p->add_at_edge (X_AXIS, RIGHT, name.addition_mol, 0);
+ if (!name.inversion_mol.empty_b ())
+ mol_p->add_at_edge (X_AXIS, RIGHT, name.inversion_mol, 0);
+ if (!name.bass_mol.empty_b ())
+ mol_p->add_at_edge (X_AXIS, RIGHT, name.bass_mol, 0);
+ return mol_p;
+}
#include "paper-def.hh"
#include "lookup.hh"
-SCM
-pitch2scm (Musical_pitch p)
-{
- return gh_cons (gh_int2scm (p.notename_i_), gh_int2scm (p.accidental_i_));
-}
/*
construct from parser output
return Chord (pitch_arr, inversion_p, bass_p);
}
+Chord::Chord ()
+{
+ inversion_b_ = false;
+ bass_b_ = false;
+}
+
Chord::Chord (Array<Musical_pitch> pitch_arr, Musical_pitch* inversion_p, Musical_pitch* bass_p)
{
pitch_arr_ = pitch_arr;
- inversion_p_ = inversion_p;
- bass_p_ = bass_p;
+ inversion_b_ = false;
+ bass_b_ = false;
+ if (inversion_p)
+ {
+ inversion_pitch_ = *inversion_p;
+ inversion_b_ = true;
+ delete inversion_p;
+ }
+ if (bass_p)
+ {
+ bass_pitch_ = *bass_p;
+ bass_b_ = true;
+ delete bass_p;
+ }
}
-
+
Chord::Chord (Chord const& chord)
- : Item (chord)
{
pitch_arr_ = chord.pitch_arr_;
- inversion_p_ = chord.inversion_p_ ? new Musical_pitch (*chord.inversion_p_) : 0;
- bass_p_ = chord.bass_p_ ? new Musical_pitch (*chord.bass_p_) : 0;
-}
-
-Chord::~Chord ()
-{
- delete inversion_p_;
- delete bass_p_;
+ inversion_b_ = chord.inversion_b_;
+ inversion_pitch_ = chord.inversion_pitch_;
+ bass_b_ = chord.bass_b_;
+ bass_pitch_ = chord.bass_pitch_;
}
+
Array<Musical_pitch>
Chord::base_arr (Musical_pitch p)
Chord::to_pitch_arr () const
{
Array<Musical_pitch> pitch_arr = pitch_arr_;
- if (inversion_p_)
+ if (inversion_b_)
{
int i = 0;
for (; i < pitch_arr.size (); i++)
{
- if ((pitch_arr[i].notename_i_ == inversion_p_->notename_i_)
- && (pitch_arr[i].accidental_i_ == inversion_p_->accidental_i_))
+ if ((pitch_arr[i].notename_i_ == inversion_pitch_.notename_i_)
+ && (pitch_arr[i].accidental_i_ == inversion_pitch_.accidental_i_))
break;
}
if (i == pitch_arr.size ())
{
warning (_f ("invalid inversion pitch: not part of chord: %s",
- inversion_p_->str ()));
+ inversion_pitch_.str ()));
}
else
rebuild_with_bass (&pitch_arr, i);
}
- if (bass_p_)
+ if (bass_b_)
{
- pitch_arr.insert (*bass_p_, 0);
+ pitch_arr.insert (bass_pitch_, 0);
rebuild_with_bass (&pitch_arr, 0);
}
return pitch_arr;
}
void
-Chord::find_additions_and_subtractions (Array<Musical_pitch> pitch_arr, Array<Musical_pitch>* add_arr_p, Array<Musical_pitch>* sub_arr_p) const
+Chord::find_additions_and_subtractions (Array<Musical_pitch> pitch_arr, Array<Musical_pitch>* add_arr_p, Array<Musical_pitch>* sub_arr_p)
{
Musical_pitch tonic = pitch_arr[0];
/*
}
-/*
- word is roman text or styled text:
- "text"
- ("style" . "text")
- */
-Molecule
-Chord::ly_word2molecule (SCM scm) const
-{
- String style;
- if (gh_pair_p (scm))
- {
- style = ly_scm2string (gh_car (scm));
- scm = gh_cdr (scm);
- }
- String text = ly_scm2string (scm);
- return lookup_l ()->text (style, text, paper_l ());
-}
-
-/*
- scm is word or list of words:
- word
- (word word)
- */
-Molecule
-Chord::ly_text2molecule (SCM scm) const
-{
- Molecule mol;
- if (gh_list_p (scm))
- {
- while (gh_cdr (scm) != SCM_EOL)
- {
- mol.add_at_edge (X_AXIS, RIGHT,
- ly_word2molecule (gh_car (scm)), 0);
- scm = gh_cdr (scm);
- }
- scm = gh_car (scm);
- }
- mol.add_at_edge (X_AXIS, RIGHT,
- ly_word2molecule (scm), 0);
- return mol;
-}
-
-Molecule
-Chord::pitch2molecule (Musical_pitch p) const
-{
- SCM name = scm_eval (gh_list (ly_symbol2scm ("user-pitch-name"), ly_quote_scm (pitch2scm (p)), SCM_UNDEFINED));
-
- if (name != SCM_UNSPECIFIED)
- {
- return ly_text2molecule (name);
- }
-
- Molecule mol = lookup_l ()->text ("", p.str ().left_str (1).upper_str (), paper_l ());
-
- /*
- We want the smaller size, even if we're big ourselves.
- */
- if (p.accidental_i_)
- mol.add_at_edge (X_AXIS, RIGHT,
-
- paper_l ()->lookup_l (-2)->afm_find (String ("accidentals-") + to_str (p.accidental_i_)), 0.0);
- return mol;
-}
-
-Musical_pitch
-diff_pitch (Musical_pitch tonic, Musical_pitch p)
-{
- Musical_pitch diff (p.notename_i_ - tonic.notename_i_,
- p.accidental_i_ - tonic.accidental_i_,
- p.octave_i_ - tonic.octave_i_);
-
- while (diff.notename_i_ >= 7)
- {
- diff.notename_i_ -= 7;
- diff.octave_i_ ++;
- }
- while (diff.notename_i_ < 0)
- {
- diff.notename_i_ += 7;
- diff.octave_i_ --;
- }
-
- diff.accidental_i_ -= (tonic.semitone_pitch () + diff.semitone_pitch ())
- - p.semitone_pitch ();
-
- return diff;
-}
-
-bool
-Chord::user_chord_name (Array<Musical_pitch> pitch_arr, Chord_name* name_p) const
-{
- SCM chord = SCM_EOL;
- Array<Musical_pitch> chord_type = pitch_arr;
- rebuild_transpose (&chord_type, diff_pitch (pitch_arr[0], Musical_pitch (0)), false);
-
- for (int i= chord_type.size (); i--; )
- chord = gh_cons (pitch2scm (chord_type[i]), chord);
-
- SCM name = scm_eval (gh_list (ly_symbol2scm ("user-chord-name"), ly_quote_scm (chord), SCM_UNDEFINED));
- if (gh_pair_p (name))
- {
- name_p->modifier_mol = ly_text2molecule (gh_car (name));
- name_p->addition_mol = ly_text2molecule (gh_cdr (name));
- return true;
- }
- return false;
-}
-
-void
-Chord::banter (Array<Musical_pitch> pitch_arr, Chord_name* name_p) const
-{
- Array<Musical_pitch> add_arr;
- Array<Musical_pitch> sub_arr;
- find_additions_and_subtractions (pitch_arr, &add_arr, &sub_arr);
-
- Array<Musical_pitch> scale;
- for (int i=0; i < 7; i++)
- scale.push (Musical_pitch (i));
-
- Musical_pitch tonic = pitch_arr[0];
- rebuild_transpose (&scale, tonic, true);
-
- /*
- Does chord include this step? -1 if flat
- */
- int has[16];
- for (int i=0; i<16; i++)
- has[i] = 0;
-
- String mod_str;
- String add_str;
- String sep_str;
- for (int i = 0; i < add_arr.size (); i++)
- {
- Musical_pitch p = add_arr[i];
- int step = step_i (tonic, p);
- int accidental = p.accidental_i_ - scale[(step - 1) % 7].accidental_i_;
- if ((step < 16) && (has[step] != -1))
- has[step] = accidental == -1 ? -1 : 1;
- // only from guile table ?
- if ((step == 3) && (accidental == -1))
- {
- mod_str = "m";
- }
- else if (accidental
- || (!(step % 2)
- || ((i == add_arr.size () - 1) && (step > 5))))
- {
- add_str += sep_str;
- sep_str = "/";
- if ((step == 7) && (accidental == 1))
- {
- add_str += "maj7";
- }
- else
- {
- add_str += to_str (step);
- if (accidental)
- add_str += accidental < 0 ? "-" : "+";
- }
- }
- }
-
- for (int i = 0; i < sub_arr.size (); i++)
- {
- Musical_pitch p = sub_arr[i];
- int step = step_i (tonic, p);
- /*
- if additions include 2 or 4, assume sus2/4 and don't display 'no3'
- */
- if (!((step == 3) && (has[2] || has[4])))
- {
- add_str += sep_str + "no" + to_str (step);
- sep_str = "/";
- }
- }
-
- if (mod_str.length_i ())
- name_p->modifier_mol.add_at_edge (X_AXIS, RIGHT,
- lookup_l ()->text ("roman", mod_str, paper_l ()), 0);
- if (add_str.length_i ())
- {
- if (!name_p->addition_mol.empty_b ())
- add_str = "/" + add_str;
- name_p->addition_mol.add_at_edge (X_AXIS, RIGHT,
- lookup_l ()->text ("script", add_str, paper_l ()), 0);
- }
-}
-
/*
This routine tries to guess tonic in a possibly inversed chord, ie
<e g c'> should produce: C.
pitch_arr_p->insert (bass, 0);
}
-Molecule*
-Chord::do_brew_molecule_p () const
-{
- Musical_pitch tonic = pitch_arr_[0];
-
- Chord_name name;
- name.tonic_mol = pitch2molecule (tonic);
-
- /*
- if user has explicitely listed chord name, use that
-
- TODO
- urg
- maybe we should check all sub-lists of pitches, not
- just full list and base triad?
- */
- if (!user_chord_name (pitch_arr_, &name))
- {
- /*
- else, check if user has listed base triad
- use user base name and add banter for remaining part
- */
- if ((pitch_arr_.size () > 2)
- && user_chord_name (pitch_arr_.slice (0, 3), &name))
- {
- Array<Musical_pitch> base = base_arr (tonic);
- base.concat (pitch_arr_.slice (3, pitch_arr_.size ()));
- banter (base, &name);
- }
- /*
- else, use pure banter
- */
- else
- {
- banter (pitch_arr_, &name);
- }
- }
-
- if (inversion_p_)
- {
- name.inversion_mol = lookup_l ()->text ("", "/", paper_l ());
- // zucht const&
- Molecule mol = pitch2molecule (*inversion_p_);
- name.inversion_mol.add_at_edge (X_AXIS, RIGHT, mol, 0);
- }
-
- if (bass_p_)
- {
- name.bass_mol = lookup_l ()->text ("", "/", paper_l ());
- Molecule mol = pitch2molecule (*bass_p_);
- name.bass_mol.add_at_edge (X_AXIS, RIGHT, mol, 0);
- }
-
- // urg, howto get a good superscript_y?
- Real super_y = lookup_l ()->text ("", "x", paper_l ()).dim_.y ().length ()/2;
- if (!name.addition_mol.empty_b ())
- name.addition_mol.translate (Offset (0, super_y));
-
- Molecule* mol_p = new Molecule;
- mol_p->add_at_edge (X_AXIS, RIGHT, name.tonic_mol, 0);
- // huh?
- if (!name.modifier_mol.empty_b ())
- mol_p->add_at_edge (X_AXIS, RIGHT, name.modifier_mol, 0);
- if (!name.addition_mol.empty_b ())
- mol_p->add_at_edge (X_AXIS, RIGHT, name.addition_mol, 0);
- if (!name.inversion_mol.empty_b ())
- mol_p->add_at_edge (X_AXIS, RIGHT, name.inversion_mol, 0);
- if (!name.bass_mol.empty_b ())
- mol_p->add_at_edge (X_AXIS, RIGHT, name.bass_mol, 0);
- return mol_p;
-}
-
-void
-Chord::do_print () const
-{
-#ifndef NPRINT
- //DEBUG_OUT << "chord = " ...
-#endif
-}
#include "dimensions.hh"
#include "paper-def.hh"
#include "debug.hh"
-#include "score-column.hh"
+#include "paper-column.hh"
#include "atom.hh"
Crescendo::Crescendo ()
Drul_array<bool> broken;
Direction d = LEFT;
do {
- Score_column* s = dynamic_cast<Score_column*>(spanned_drul_[d]); // UGH
+ Paper_column* s = dynamic_cast<Paper_column*>(spanned_drul_[d]); // UGH
broken[d] = (!s->musical_b ());
} while (flip (&d) != LEFT);
#include "musical-request.hh"
#include "lookup.hh"
#include "paper-def.hh"
-#include "score-column.hh"
+#include "paper-column.hh"
#include "staff-symbol.hh"
#include "note-column.hh"
#include "text-item.hh"
#include "musical-request.hh"
#include "extender-engraver.hh"
#include "extender-spanner.hh"
-#include "score-column.hh"
+#include "paper-column.hh"
#include "text-item.hh"
#include "extender-engraver.hh"
#include "musical-request.hh"
#include "hyphen-engraver.hh"
#include "hyphen-spanner.hh"
-#include "score-column.hh"
+#include "paper-column.hh"
#include "text-item.hh"
#include "extender-engraver.hh"
/**
- Implement bow specific bezier curve
- */
+ Implement bow specific bezier curve. Calculate bezier curve for bow
+ from bow paratime_signatures. */
class Bezier_bow
{
-public:
- Bezier_bow (Paper_def* paper_l);
+ Bezier curve_;
+ Array<Offset> encompass_;
- /**
- Calculate bezier curve for bow from bow paratime_signatures.
- */
void blow_fit ();
- void calc ();
- Real calc_f (Real height);
- void calc_bezier ();
- bool calc_clipping ();
- void calc_controls ();
- void check_sanity () const;
void calc_default (Real h);
- void calc_return (Real begin_alpha, Real end_alpha);
+ void to_canonic_form ();
void calc_tangent_controls ();
- bool check_fit_b () const;
- Real check_fit_f () const;
- void set (Array<Offset> points, Direction dir);
- void transform ();
- void transform_back ();
+ Real fit_factor () const;
- Array<Offset> encompass_;
Paper_def* paper_l_;
Direction dir_;
Real alpha_;
Offset origin_;
-
-
- Bezier curve_;
- Bezier return_;
+public:
+ Bezier_bow (Paper_def* paper_l, Array<Offset> points, Direction dir);
+ Bezier get_curve () const;
};
Polynomial polynomial (Axis)const;
Offset curve_point (Real t) const;
+ void reverse ();
+
static const int CONTROL_COUNT = 4;
Offset control_[CONTROL_COUNT];
};
protected:
virtual Molecule* do_brew_molecule_p () const;
- Array<Offset> get_controls () const;
+
virtual Array<Offset> get_encompass_offset_arr () const;
- static Interval dim_callback (Dimension_cache const*);
- Interval curve_extent (Axis) const;
+ Interval curve_extent (Axis) const;
+ Bezier get_curve () const;
+
Drul_array<Real> dy_f_drul_;
Drul_array<Real> dx_f_drul_;
};
private:
Array<Musical_pitch> pitch_arr_;
- Chord* chord_p_;
+ Chord_name* chord_name_p_;
Tonic_req* tonic_req_;
Inversion_req* inversion_req_;
Bass_req* bass_req_;
--- /dev/null
+/*
+ chord-name.hh -- declare Chord_name
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 1999 Jan Nieuwenhuizen <janneke@gnu.org>
+*/
+
+#ifndef CHORD_NAME_HH
+#define CHORD_NAME_HH
+
+#include "chord.hh"
+#include "item.hh"
+#include "molecule.hh"
+
+class Chord_mol
+{
+public:
+ Molecule tonic_mol;
+ Molecule modifier_mol;
+ Molecule addition_mol;
+ Molecule inversion_mol;
+ Molecule bass_mol;
+};
+
+class Chord_name : public Item
+{
+public:
+ VIRTUAL_COPY_CONS (Score_element);
+ Molecule ly_word2molecule (SCM scm) const;
+ Molecule ly_text2molecule (SCM scm) const;
+ Molecule pitch2molecule (Musical_pitch p) const;
+ bool user_chord_name (Array<Musical_pitch> pitch_arr, Chord_mol* name_p) const;
+ void banter (Array<Musical_pitch> pitch_arr, Chord_mol* name_p) const;
+
+ Chord_name (Chord const& c);
+ Chord chord_;
+
+protected:
+ virtual Molecule* do_brew_molecule_p () const;
+};
+
+#endif // CHORD_NAME_HH
#include "array.hh"
#include "musical-pitch.hh"
#include "lily-proto.hh"
-#include "item.hh"
-#include "molecule.hh"
-
-class Chord_name
-{
-public:
- Molecule tonic_mol;
- Molecule modifier_mol;
- Molecule addition_mol;
- Molecule inversion_mol;
- Molecule bass_mol;
-};
-
-class Chord : public Item
+class Chord
{
public:
- VIRTUAL_COPY_CONS (Score_element);
static Array<Musical_pitch> base_arr (Musical_pitch p);
+ static void find_additions_and_subtractions(Array<Musical_pitch> pitch_arr, Array<Musical_pitch>* add_arr_p, Array<Musical_pitch>* sub_arr_p);
static int find_tonic_i (Array<Musical_pitch> const*);
static int find_pitch_i (Array<Musical_pitch> const*, Musical_pitch p);
static int find_notename_i (Array<Musical_pitch> const*, Musical_pitch p);
static void rebuild_with_bass (Array<Musical_pitch>*, int bass_i);
static int step_i (Musical_pitch tonic, Musical_pitch p);
+
+ Chord ();
Chord (Array<Musical_pitch> pitch_arr, Musical_pitch* inversion_p, Musical_pitch* bass_p);
Chord (Chord const&);
- virtual ~Chord ();
-
Array<Musical_pitch> to_pitch_arr () const;
- void find_additions_and_subtractions(Array<Musical_pitch> pitch_arr, Array<Musical_pitch>* add_arr_p, Array<Musical_pitch>* sub_arr_p) const;
-
- Molecule ly_word2molecule (SCM scm) const;
- Molecule ly_text2molecule (SCM scm) const;
- Molecule pitch2molecule (Musical_pitch p) const;
- bool user_chord_name (Array<Musical_pitch> pitch_arr, Chord_name* name_p) const;
- void banter (Array<Musical_pitch> pitch_arr, Chord_name* name_p) const;
-
Array<Musical_pitch> pitch_arr_;
- Musical_pitch* inversion_p_;
- Musical_pitch* bass_p_;
-
-protected:
- virtual Molecule* do_brew_molecule_p () const;
- virtual void do_print () const;
+ bool inversion_b_;
+ Musical_pitch inversion_pitch_;
+ bool bass_b_;
+ Musical_pitch bass_pitch_;
};
Chord to_chord (Musical_pitch tonic, Array<Musical_pitch>* add_arr_p, Array<Musical_pitch>* sub_arr_p, Musical_pitch* inversion_p, Musical_pitch* bass_p);
struct Beam_engraver;
struct Beaming_info;
struct Beaming_info_list;
+struct Bezier;
+struct Bezier_bow;
struct Blank_req;
struct Bow;
struct Box;
struct Change_iterator;
struct Change_translator;
struct Chord;
+struct Chord_name;
struct Chord_name_engraver;
struct Chord_tremolo;
struct Chord_tremolo_engraver;
Molecule afm_find (String, bool warn=true) const;
Molecule bar (String, Real height, Paper_def*) const;
Molecule beam (Real, Real, Real) const;
- Molecule dashed_slur (Array<Offset> controls, Real thick, Real dash) const;
+ Molecule dashed_slur (Bezier, Real thick, Real dash) const;
Molecule ledger_line (Interval) const;
Molecule fill (Box b) const;
Molecule filledbox (Box b) const;
Molecule tuplet_bracket (Real dy, Real dx, Real gap, Real thick,Real height, Direction dir) const;
Molecule accordion (SCM arg, Real interline_f) const;
- Molecule slur (Array<Offset> controls, Real thick) const;
+ Molecule slur (Bezier controls, Real cthick, Real thick) const;
Molecule text (String style, String text, Paper_def*) const;
Molecule staff_brace (Real dy, int) const;
Molecule staff_bracket (Real height, Paper_def* paper_l) const;
DECLARE_SMOBS;
};
+
IMPLEMENT_ARITHMETIC_OPERATOR (Moment, / );
IMPLEMENT_ARITHMETIC_OPERATOR (Moment, + );
IMPLEMENT_ARITHMETIC_OPERATOR (Moment, * );
VIRTUAL_COPY_CONS(Score_element);
Drul_array<Array<Column_rod> > minimal_dists_arr_drul_;
Drul_array<Array<Column_spring> > spring_arr_drul_;
- void preprocess ();
+
/// set a minimum distance
void add_rod (Paper_column * to, Real distance);
void add_spring (Paper_column * to, Real dist, Real strength);
virtual Paper_column * column_l () const;
+ virtual Line_of_score *line_l () const;
+
+
/// if lines are broken then this column is in #line#
Line_of_score *line_l_;
- virtual Line_of_score *line_l () const;
/// which one (left =0)
int rank_i() const;
- bool breakpoint_b() const;
- void add_item (Item *i);
+ Paper_column (Moment when);
+ Moment when_mom ()const;
- Paper_column();
+ bool musical_b () const;
void set_rank (int);
-
- void OK() const;
virtual void do_print() const;
private:
Link_array<Score_element> elem_p_arr_;
- Score_column* command_column_l_;
- Score_column* musical_column_l_;
+ Paper_column* command_column_l_;
+ Paper_column* musical_column_l_;
- void set_columns (Score_column*,Score_column*);
+ void set_columns (Paper_column*,Paper_column*);
void typeset_all();
public:
Spacing_spanner ();
VIRTUAL_COPY_CONS(Score_element);
- Array<Spring> do_measure (Link_array<Score_column>) const;
+ Array<Spring> do_measure (Link_array<Paper_column>) const;
protected:
virtual Array<Spring> get_springs () const;
- Real stem_dir_correction (Score_column*,Score_column*) const;
- Real default_bar_spacing (Score_column*,Score_column*,Moment) const;
- Real note_spacing (Score_column*,Score_column*,Moment) const;
+ Real stem_dir_correction (Paper_column*,Paper_column*) const;
+ Real default_bar_spacing (Paper_column*,Paper_column*,Moment) const;
+ Real note_spacing (Paper_column*,Paper_column*,Moment) const;
};
#endif /* SPACING_SPANNER_HH */
JUNKME.
*/
struct Staff_info {
- Score_column *musical_l_;
- Score_column *command_l_;
+ Paper_column *musical_l_;
+ Paper_column *command_l_;
Paper_column * command_pcol_l();
Paper_column * musical_pcol_l();
return broken_to_drul_[LEFT] || broken_to_drul_[RIGHT];
}
+#if 0
int
Item::left_right_compare(Item const *l, Item const *r)
{
Paper_column* p2 = r->column_l ();
return p1->rank_i () - p2->rank_i ();
}
+#endif
Paper_column *
Item::column_l () const
#include "debug.hh"
#include "dimensions.hh"
+#include "bezier.hh"
#include "paper-def.hh"
#include "string-convert.hh"
#include "file-path.hh"
#include "atom.hh"
#include "lily-guile.hh"
+SCM
+ly_offset2scm (Offset o)
+{
+ return gh_list (gh_double2scm (o[X_AXIS]), gh_double2scm(o[Y_AXIS]),
+ SCM_UNDEFINED);
+}
Lookup::Lookup ()
{
return m;
}
-SCM
-offset2scm (Offset o)
-{
- return gh_list (gh_double2scm (o[X_AXIS]), gh_double2scm(o[Y_AXIS]),
- SCM_UNDEFINED);
-}
+
+/*
+ FIXME.
+ */
Molecule
-Lookup::dashed_slur (Array<Offset> controls, Real thick, Real dash) const
+Lookup::dashed_slur (Bezier b, Real thick, Real dash) const
{
- assert (controls.size () == 8);
- Offset d = controls[3] - controls[0];
-
- Real dx = d[X_AXIS];
- Real dy = d[Y_AXIS];
-
- Molecule m;
-
-
- m.dim_[X_AXIS] = Interval (0, dx);
- m.dim_[Y_AXIS] = Interval (0 <? dy, 0 >? dy);
-
- SCM sc[4];
- for (int i=0; i< 4; i++)
+ SCM l = SCM_EOL;
+ for (int i= 4; i -- ;)
{
- sc[i] = offset2scm (controls[i]);
+ l = gh_cons (ly_offset2scm (b.control_[i]), l);
}
- Atom at
- (gh_list (ly_symbol2scm ("dashed-slur"),
- gh_double2scm (thick),
- gh_double2scm (dash),
- ly_quote_scm (array_to_list (sc, 4)),
- SCM_UNDEFINED));
-
-
+ Atom at (gh_list (ly_symbol2scm ("dashed-slur"),
+ gh_double2scm (thick),
+ gh_double2scm (dash),
+ ly_quote_scm (l),
+ SCM_UNDEFINED));
+ Molecule m;
m.add_atom (&at);
return m;
}
Make a smooth curve along the points
*/
Molecule
-Lookup::slur (Array<Offset> controls, Real linethick) const
+Lookup::slur (Bezier curve, Real curvethick, Real linethick) const
{
- Offset delta_off = controls[3]- controls[0];
- Molecule m;
-
- SCM scontrols [8];
- int indices[] = {5,6,7,4,1,2,3,0};
+ Real alpha = (curve.control_[3] - curve.control_[0]).arg ();
+ Bezier back = curve;
- for (int i= 0; i < 8; i++)
- scontrols[i] = offset2scm (controls[indices[i]]);
+ back.reverse ();
+ back.control_[1] += curvethick * complex_exp (Offset (0, alpha + M_PI/2));
+ back.control_[2] += curvethick * complex_exp (Offset (0, alpha + M_PI/2));
+ SCM scontrols[8];
+ for (int i=4; i--;)
+ scontrols[ i ] = ly_offset2scm (back.control_[i]);
+ for (int i=4 ; i--;)
+ scontrols[i+4] = ly_offset2scm (curve.control_[i]);
+ /*
+ Need the weird order b.o. the way PS want its arguments
+ */
+ int indices[]= {5, 6, 7, 4, 1, 2, 3, 0};
+ SCM list = SCM_EOL;
+ for (int i= 8; i--; )
+ {
+ list = gh_cons (scontrols[indices[i]], list);
+ }
+
+
Atom at (gh_list (ly_symbol2scm ("bezier-sandwich"),
- ly_quote_scm (array_to_list (scontrols, 8)),
+ ly_quote_scm (list),
gh_double2scm (linethick),
SCM_UNDEFINED));
- m.dim_[X_AXIS] = Interval (0, delta_off[X_AXIS]);
- m.dim_[Y_AXIS] = Interval (0 <? delta_off[Y_AXIS], 0 >? delta_off[Y_AXIS]);
+ Molecule m;
+ m.dim_[X_AXIS] = curve.extent (X_AXIS);
+ m.dim_[Y_AXIS] = curve.extent (Y_AXIS);
m.add_atom (&at);
return m;
}
#include "musical-request.hh"
#include "multi-measure-rest.hh"
#include "multi-measure-rest-engraver.hh"
-#include "score-column.hh"
+#include "paper-column.hh"
#include "engraver-group-engraver.hh"
#include "timing-translator.hh"
#include "bar.hh"
Simultaneous_music*v = new Request_chord;
v->set_spot (here_input ());
+ /*
+ UARGAUGRAGRUAUGRUINAGRAUGIRNA
+
+ ugh
+ */
Chord chord = to_chord (tonic, add_arr_p, sub_arr_p, inversion_p, bass_p);
Tonic_req* t = new Tonic_req;
(what? should be done --jcn)
scary too?: height is calculated during post_processing
*/
- Real dy = 0;
- Real y = 0;
+ Real beam_dy = 0;
+ Real beam_y = 0;
+
SCM s = b->get_elt_property ("height");
if (s != SCM_UNDEFINED)
- dy = gh_scm2double (s);
- s = b->get_elt_property ("y-position");
+ beam_dy = gh_scm2double (s);
+
+ s = b->get_elt_property ("y-position");
if (s != SCM_UNDEFINED)
- y = gh_scm2double (s);
+ beam_y = gh_scm2double (s);
Real x0 = b->first_visible_stem ()->hpos_f ();
- Real dydx = b->last_visible_stem ()->hpos_f () - x0;
+ Real dydx = beam_dy/(b->last_visible_stem ()->hpos_f () - x0);
Direction d = stem_l ()->get_direction ();
- Real beamy = (stem_l ()->hpos_f () - x0) * dydx + y;
+ Real beamy = (stem_l ()->hpos_f () - x0) * dydx + beam_y;
s = get_elt_property ("rests");
Score_element * se = unsmob_element (gh_car (s));
(c) 1997--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
*/
-
+#include "moment.hh"
#include "paper-column.hh"
#include "paper-score.hh"
#include "debug.hh"
#endif
}
-bool
-Paper_column::breakpoint_b() const
-{
- return !line_l_;
-}
-
-Paper_column::Paper_column()
-{
- set_axes (X_AXIS, X_AXIS);
-
- line_l_=0;
- rank_i_ = -1;
-}
-
Line_of_score*
Paper_column::line_l() const
{
return (Paper_column*)(this);
}
-/*
- ugh. JUNKME
- */
-void
-Paper_column::preprocess ()
+
+
+
+Paper_column::Paper_column (Moment w)
+{
+ set_elt_property ("when", (new Moment (w))->smobify_self ());
+ set_axes (X_AXIS, X_AXIS);
+
+ line_l_=0;
+ rank_i_ = -1;
+}
+
+Moment
+Paper_column::when_mom () const
{
- /*
- JUNKME
- */
- minimal_dists_arr_drul_[LEFT].sort (Column_rod::compare);
- minimal_dists_arr_drul_[RIGHT].sort (Column_rod::compare);
- spring_arr_drul_[LEFT].sort (Column_spring::compare);
- spring_arr_drul_[RIGHT].sort (Column_spring::compare);
+ SCM m = get_elt_property ("when");
+ Moment s (0);
+ if (SMOB_IS_TYPE_B(Moment, m))
+ {
+ s = *SMOB_TO_TYPE (Moment,m);
+ }
+ return s;
+}
+
+bool
+Paper_column::musical_b () const
+{
+ SCM m = get_elt_property ("shortest-starter");
+ Moment s (0);
+ if (SMOB_IS_TYPE_B(Moment, m))
+ {
+ s = *SMOB_TO_TYPE (Moment,m);
+ }
+ return s != Moment(0);
}
/*
- score-column.cc -- implement Score_column
+ score-column.cc -- implement Paper_column
source file of the GNU LilyPond music typesetter
(c) 1997--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
*/
-
-#include "debug.hh"
-#include "paper-column.hh"
-#include "score-column.hh"
-#include "command-request.hh"
-
-Score_column::Score_column (Moment w)
-{
- when_ = w;
-}
-
-void
-Score_column::do_print() const
-{
-#ifndef NPRINT
- DEBUG_OUT << " at " << when_ << '\n';
- DEBUG_OUT << "Shortest playing: " << shortest_playing_mom_ << " shortest starter: " << shortest_starter_mom_;
- Paper_column::do_print();
-#endif
-}
-
-
-bool
-Score_column::musical_b () const
-{
- return shortest_starter_mom_ != Moment(0);
-}
void * mp = (void*) gh_cdr(ses);
Score_element * s = (Score_element*) mp;
- assert (s->self_scm_ == ses);
+ if (s->self_scm_ != ses)
+ {
+ programming_error ("SMOB marking gone awry");
+ return SCM_EOL;
+ }
return s->element_property_alist_;
}
#include "score-engraver.hh"
#include "paper-score.hh"
#include "musical-request.hh"
-#include "score-column.hh"
+#include "paper-column.hh"
#include "command-request.hh"
#include "paper-def.hh"
Score_engraver::prepare (Moment w)
{
Global_translator::prepare (w);
- set_columns (new Score_column (w), new Score_column (w));
+ set_columns (new Paper_column (w), new Paper_column (w));
command_column_l_->set_elt_property ("breakable", SCM_BOOL_T);
post_move_processing();
}
void
-Score_engraver::set_columns (Score_column *new_command_l,
- Score_column *new_musical_l)
+Score_engraver::set_columns (Paper_column *new_command_l,
+ Paper_column *new_musical_l)
{
if (command_column_l_ && command_column_l_->linked_b())
{
}
-static int
-Note_column_compare (Note_column *const&n1 , Note_column* const&n2)
-{
- return Item::left_right_compare (n1, n2);
-}
-
-
Offset
Slur::encompass_offset (Note_column const* col) const
{
void
Slur::do_post_processing ()
{
- Link_array<Note_column> encompass_arr =
+ Link_array<Note_column> encompass_arr =
Group_interface__extract_elements (this, (Note_column*)0, "note-columns");
- encompass_arr.sort (Note_column_compare);
+
if (!get_direction ())
set_direction (get_default_dir ());
*/
#include "musical-request.hh"
-#include "score-column.hh"
+#include "paper-column.hh"
#include "spacing-engraver.hh"
#include "spacing-spanner.hh"
shortest_playing = shortest_playing <? starter;
- Score_column * sc
- = dynamic_cast<Score_column*> (get_staff_info ().musical_pcol_l ());
+ Paper_column * sc
+ = dynamic_cast<Paper_column*> (get_staff_info ().musical_pcol_l ());
- sc->shortest_playing_mom_ = shortest_playing;
- sc->shortest_starter_mom_ = starter;
+ sc->set_elt_property ("shortest-playing", (new Moment (shortest_playing))->smobify_self ());
+
+ sc->set_elt_property ("shortest-starter", (new Moment (starter))->smobify_self ());
}
void
*/
#include "spacing-spanner.hh"
-#include "score-column.hh"
+#include "paper-column.hh"
#include "dimensions.hh"
#include "paper-def.hh"
#include "warn.hh"
*/
Array<Spring>
-Spacing_spanner::do_measure (Link_array<Score_column> cols) const
+Spacing_spanner::do_measure (Link_array<Paper_column> cols) const
{
- for (int i =0 ; i < cols.size (); i++)
- {
- cols[i]->preprocess ();
- cols[i]->print ();
- }
-
Moment shortest;
shortest.set_infinite (1);
for (int i =0 ; i < cols.size (); i++)
{
if (cols[i]->musical_b ())
{
- shortest = shortest <? cols[i]->shortest_starter_mom_;
+ SCM st = cols[i]->get_elt_property ("shortest-starter");
+
+ shortest = shortest <? (*SMOB_TO_TYPE(Moment, st));
}
}
for (int j=0; j < 4; j++)
{
- Score_column * lc = dynamic_cast<Score_column*> (combinations[j][0]);
- Score_column *rc = dynamic_cast<Score_column*> (combinations[j][1]);
+ Paper_column * lc = dynamic_cast<Paper_column*> (combinations[j][0]);
+ Paper_column *rc = dynamic_cast<Paper_column*> (combinations[j][1]);
if (!lc || !rc)
continue;
Do something if breakable column has no spacing hints set.
*/
Real
-Spacing_spanner::default_bar_spacing (Score_column *lc, Score_column *rc,
+Spacing_spanner::default_bar_spacing (Paper_column *lc, Paper_column *rc,
Moment shortest) const
{
Real symbol_distance = lc->extent (X_AXIS)[RIGHT] ;
Real
-Spacing_spanner::note_spacing (Score_column *lc, Score_column *rc, Moment shortest) const
+Spacing_spanner::note_spacing (Paper_column *lc, Paper_column *rc, Moment shortest) const
{
- Moment shortest_playing_len = lc->shortest_playing_mom_;
+ Moment shortest_playing_len = 0;
+ SCM s = lc->get_elt_property ("shortest-playing");
+ if (SMOB_IS_TYPE_B(Moment, s))
+ shortest_playing_len = *SMOB_TO_TYPE (Moment, s);
+
+
if (! shortest_playing_len)
{
programming_error ("Can't find a ruling note at " + lc->when_mom ().str ());
This routine reads the DIR_LIST property of both its L and R arguments.
*/
Real
-Spacing_spanner::stem_dir_correction (Score_column*l, Score_column*r) const
+Spacing_spanner::stem_dir_correction (Paper_column*l, Paper_column*r) const
{
SCM dl = l->get_elt_property ("dir-list");
SCM dr = r->get_elt_property ("dir-list");
Array<Spring> springs;
SCM last_col = pscore_l_->line_l_->get_elt_property ("columns");
- Link_array<Score_column> measure;
+ Link_array<Paper_column> measure;
for (SCM s = last_col; gh_pair_p (s); s = gh_cdr (s))
{
Score_element * elt = unsmob_element (gh_car (s));
- Score_column* sc = dynamic_cast<Score_column*> (elt);
+ Paper_column* sc = dynamic_cast<Paper_column*> (elt);
measure.push (sc);
if (sc->breakable_b ())
{
#include "paper-score.hh"
#include "molecule.hh"
#include "paper-outputter.hh"
-#include "score-column.hh"
+#include "paper-column.hh"
#include "line-of-score.hh"
#include "break-align-item.hh"
Real
Spanner::get_broken_left_end_align () const
{
- Score_column *sc = dynamic_cast<Score_column*> (spanned_drul_[LEFT]->column_l());
+ Paper_column *sc = dynamic_cast<Paper_column*> (spanned_drul_[LEFT]->column_l());
// Relevant only if left span point is first column in line
if(sc != NULL &&
/*
We used to do a full search for the Break_align_item.
- But that doesn't make a difference, since the Score_column
+ But that doesn't make a difference, since the Paper_column
is likely to contain only a Break_align_item.
*/
return sc->extent (X_AXIS)[RIGHT];
#include "proto.hh"
#include "staff-info.hh"
-#include "score-column.hh"
+#include "paper-column.hh"
Staff_info::Staff_info()
{
/**
set stem directions for hinting the optical spacing correction.
- Modifies DIR_LIST property of the Stem's Score_column
+ Modifies DIR_LIST property of the Stem's Paper_column
TODO: more advanced: supply height of noteheads as well, for more advanced spacing possibilities
*/
#include "string.hh"
#include "moment.hh"
#include "real.hh"
-
#include "interval.tcc"
-
#include "compare.hh"
Rational