}
return *this;
}
+
+ Real linear_combination (Real x) const {
+ return ((1.0 - x) * Real (elem (LEFT)) + (x + 1.0) * Real (elem(RIGHT))) * 0.5;
+ }
String str() const;
void print () const;
bool elem_b (T r);
}
allup = \notes{
- \property Voice.verticalDirection = \up
- \property Voice.slurVerticalDirection = \up
- \property Voice.tieVerticalDirection = \up
- \property Voice.dynamicDirection = \up
+ \stemUp
+ \slurUp
+ \tieUp
+ \property Voice.DynamicLineSpanner \push #'direction = #1
\autoBeamOff
}
+
alldown = \notes{
- \property Voice.verticalDirection = \down
- \property Voice.slurVerticalDirection = \down
- \property Voice.tieVerticalDirection = \down
- \property Voice.dynamicDirection = \down
+ \stemDown
+ \slurDown
+ \tieDown
+ \property Voice.DynamicLineSpanner \push #'direction = #-1
\autoBeamOff
}
-
/*
auto-beam-engraver.cc -- implement Auto_beam_engraver
(c) 1999--2000 Jan Nieuwenhuizen <janneke@gnu.org>
*/
+
#include "beaming.hh"
#include "musical-request.hh"
#include "beam.hh"
#include "item.hh"
#include "spanner.hh"
+/*
+ TODO: figure what to do in grace?
+ */
class Auto_beam_engraver : public Engraver
{
public:
Beaming_info_list*finished_grouping_p_;
};
-
-
-
ADD_THIS_TRANSLATOR (Auto_beam_engraver);
-
-/*
- TODO: remove all references to Timing_engraver; should read properties.
-
- */
Auto_beam_engraver::Auto_beam_engraver ()
{
stem_l_arr_p_ = 0;
grouping_p_ = 0;
}
-
bool
Auto_beam_engraver::do_try_music (Music*)
{
int num = *unsmob_moment (get_property("measureLength")) / one_beat;
int den = one_beat.den_i ();
-
String time_str = String ("time") + to_str (num) + "_" + to_str (den);
return;
if (begin_mom)
- r = unsmob_moment (get_property ("measurePosition"))->mod_rat (begin_mom);
+ r = unsmob_moment (get_property ("measurePosition"))->mod_rat (begin_mom);
if (!stem_l_arr_p_ && (!begin_mom || !r))
begin_beam ();
}
}
}
}
-
column->set_elt_property ("stretch-distance",
gh_cons (gh_double2scm (-dists[0]),
gh_double2scm (stretch_distance)));
-
-
}
#include "group-interface.hh"
/**
- Treat a group of elements as a union. This sets the parent of any S
- added to ELT_L_ to ELT_L_.
- Properties:
*/
struct Axis_group_interface
{
#include "lily-guile.hh"
#include "molecule.hh"
-/**
- elt_properties:
- pitches: list of musical-pitch
- inversion(optional): musical-pitch
- bass(optional): musical-pitch
- */
+
class Chord_name
{
public:
#include "lily-guile.hh"
#include "lily-proto.hh"
-/**
- As Vertical_group_spanner, but keep track of interesting items. If
- we don't contain any interesting items after linebreaking, then
- gracefully commit suicide. Objective: don't disgrace Lily by
- typesetting empty lines in orchestral scores.
- properties:
-
- items-worth-living -- list of interesting items. If empty in a particular system,
- clear this line
-
-
- todo: naming
-*/
class Hara_kiri_group_spanner
{
public:
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.
-
-
- Element properties
-
- visibility-lambda -- a function that takes the break
- direction and returns a (transparent, empty) cons
-
- breakable -- boolean indicating if this is a breakable item (clef,
- barline, key sig, etc.)
-
- */
+*/
class Item : public Score_element
{
Drul_array<Item*> broken_to_drul_;
#include "lily-guile.hh"
#include "lily-proto.hh"
-/**
-
- Properties:
-
-
- */
struct Key_item
{
static int calculate_position(Score_element*,SCM pair) ;
#include "column-x-positions.hh"
#include "spanner.hh"
-/**
- The columns of a score that form one line. The toplevel element.
- Any element has a Line_of_score as both X and Y reference
- point. The Paper_score contains one element of this type. Control
- enters the Score_element dependency calculation from this single
- Line_of_score object.
-
-
- properties:
-
- all-elements -- list of all score elements in this line. Needed
- for protecting elements from GC.
-
- columns -- list of all paper columns
-
- */
class Line_of_score : public Spanner
{
public:
-/*
- Move rests in note-columns so that they do not collide.
-
- properties:
-
- read-only
-
- maximum-rest-count -- kill off rests so we don't more than this
- number left.
-
- minimum-distance -- minimum distance between notes and rests.
-
- read/write
-
- elements -- list of elts (both rests and notes) participating in the
- collision.
-
-
- sets in elements:
-
- rest-collision -- pointer to self.
-
-
-
-
-*/
-
-class Rest_collision // interface
+class Rest_collision
{
public:
static void add_column (Score_element*me,Score_element*);
PRECALCED, // calcs before spacing done
POSTCALCING, // busy calculating. This is used to trap cyclic deps.
POSTCALCED, // after spacing calcs done
- BREWING,
- BREWED,
};
typedef void (Score_element::*Score_element_method_pointer) (void);
-/**
+/*
Basic output object.
-
- Element Properties:
-
- transparent -- boolean: if true, do not print anything black.
-
- dependencies -- list of score-element pointers that indicate who to
- compute first.
-
- interfaces -- list of symbols indicating the interfaces supported
- by this object.
-
- extra-offset -- pair of reals (a cons) forcing an extra offset
- before outputting
-
- glyph -- afm character name to output.
-
*/
class Score_element {
/**
bool has_interface (SCM intf);
void set_interface (SCM intf);
-
- DECLARE_SCHEME_CALLBACK(brew_molecule, (SCM ));
virtual void handle_broken_dependencies ();
virtual void handle_prebroken_dependencies ();
#include "lily-proto.hh"
-/** Calc dimensions for the Separating_group_spanner; this has to be
- an item to get dependencies correct. It can't be an element_group
- since these usually are in a different X_group
-
- Properties:
-
-
- elements -- list of items.
-
- no-spacing-rods -- read from elements: boolean that makes Separation_item ignore
- this item
-
+/**
*/
struct Separation_item
{
#include "spanner.hh"
#include "item.hh"
-/**
- Position victim object (ELT_L_) next to other objects (the support).
+/*
+ TODO: move out unrelated callbacks.
- side-support -- list of score elements
-
- direction-source -- in case side-relative-direction is set, where
- to get the direction
-
- TODO: move out unrelated callbacks.
-
- TODO: reduce number of methods.
+ TODO: reduce number of methods.
*/
struct Side_position
{
#include "lily-proto.hh"
#include "rod.hh"
-/**
-*/
class Slur
{
public:
#include "lily-guile.hh"
#include "stem-info.hh"
-/**the rule attached to the ball.
- takes care of:
-
- \begin{itemize}
- \item the rule
- \item the flag
- \item up/down position.
- \end{itemize}
-
- should move beam_{left, right} into Beam
-
- TODO.
-
- Stem size depends on flag.
-
- elt properties:
-
- beam_dir: direction of the beam (int)
-
- dir_force: is direction explicitely specified? (bool)
-
- /// how many abbrev beam don't reach stem?
- int beam_gap_i_;
-
- */
class Stem
{
public:
DECLARE_SCHEME_CALLBACK(brew_molecule, (SCM ));
- /// log of the duration. Eg. 4 -> 16th note -> 2 flags
static int flag_i (Score_element*) ;
static int beam_count (Score_element*,Direction) ;
static void set_beaming (Score_element*,int, Direction d);
- /**
- don't print flag when in beam.
- our beam, for aligning abbrev flags
- */
static Score_element * beam_l (Score_element*);
static Score_element * first_head (Score_element*) ;
static Drul_array<Score_element*> extremal_heads (Score_element*);
static Score_element * support_head (Score_element*) ;
-
- /// ensure that this Stem also encompasses the Notehead #n#
static void add_head (Score_element*me, Score_element*n);
static Stem_info calc_stem_info (Score_element *) ;
static Real chord_start_f (Score_element *) ;
static int get_center_distance(Score_element *,Direction) ;
static int heads_i (Score_element *) ;
static bool invisible_b(Score_element *) ;
-
- /// heads that the stem encompasses (positions)
static Interval head_positions(Score_element *) ;
static Real get_default_stem_end_position (Score_element*me) ;
static void position_noteheads(Score_element*);
#include "lily-guile.hh"
-/** supportable plet: triplets, eentweetjes, ottava, etc.
+/*
TODO: quantise, we don't want to collide with staff lines.
(or should we be above staff?)
todo: handle breaking elegantly.
-properties:
-
- beams -- list of beam ptrs.
-
- columns -- list of note-columns.
-
*/
-
class Tuplet_spanner
{
public:
return 0;
}
+SCM
+ly_input_p (SCM x)
+{
+ return unsmob_input (x) ? SCM_BOOL_T : SCM_BOOL_F ;
+}
+
static
void start_input_smobs()
{
= scm_make_smob_type_mfpe ("input", 0,
mark_smob, free_smob,
print_smob, 0);
+ scm_make_gsubr ("ly-input-location?", 1, 0, 0, (Scheme_function_unknown)ly_input_p);
+
}
SCM
Input dummy_input_global;
+
return ;
SCM cs = get_property ("repeatCommands");
-
+
String s = "";
- bool start = false;
+ bool start = false;
bool end = false;
+ bool volta_found = false;
while (gh_pair_p (cs))
{
SCM command = gh_car (cs);
start = true;
else if (command == ly_symbol2scm ("end-repeat"))
end = true;
+ else if (gh_pair_p (command) && gh_car (command) == ly_symbol2scm ("volta"))
+ volta_found = true;
cs = gh_cdr (cs);
}
else if (end)
s = ":|";
- if (s != "")
+ /*
+ TODO: line breaks might be allowed if we set whichBar to "".
+ */
+ if (s != "" || (volta_found && !gh_string_p (get_property ("whichBar"))))
{
daddy_trans_l_->set_property ("whichBar", ly_str02scm(s.ch_C()));
}
Molecule m (create_molecule (mol));
/*
- This is almost the same as setting molecule-callback to #f, but
- this retains the dimensions of this element, which means that you
- can erase elements individually. */
+ transparent retains dimensions of element.
+ */
if (to_boolean (get_elt_property ("transparent")))
m = Molecule (m.extent_box (), SCM_EOL);
-MAKE_SCHEME_CALLBACK(Score_element,brew_molecule,1)
-
-/*
- ugh.
- */
-SCM
-Score_element::brew_molecule (SCM smob)
-{
- Score_element * sc = unsmob_element (smob);
- SCM glyph = sc->get_elt_property ("glyph");
- if (gh_string_p (glyph))
- {
- return sc->lookup_l ()->afm_find (String (ly_scm2string (glyph))).create_scheme ();
- }
- else
- {
- return SCM_EOL;
- }
-}
-
Line_of_score *
Score_element::line_l() const
}
else
{
- Real lambda = (0.5 - gh_scm2double (align) / 2.0);
- return gh_double2scm (- (lambda * ext[LEFT] + (1 - lambda) * ext[RIGHT]));
+ return gh_double2scm (- ext.linear_combination (gh_scm2double (align)));
}
}
else if (unsmob_element (align))
curve_.control_[2][X_AXIS] -= da[1] * u * pct;
}
- Real area = enclosed_area_f ();
+ // Real area = enclosed_area_f ();
}
return to_dir (me->get_elt_property ("default-neutral-direction"));
}
-/*
- ugh. A is used for different purposes. This functionality should be
- moved into scheme at some point to get rid of the silly
- conversions. (but lets wait till we have namespaces in SCM)
- */
Real
Stem::get_default_stem_end_position (Score_element*me)
{
bool grace_b = to_boolean (me->get_elt_property ("grace"));
- String type_str = grace_b ? "grace-" : "";
SCM s;
Array<Real> a;
Real st = head_positions(me)[dir] + dir * length_f;
bool no_extend_b = to_boolean (me->get_elt_property ("no-stem-extend"));
- if (!grace_b && !no_extend_b && dir * st < 0)
+ if (!grace_b && !no_extend_b && dir * st < 0) // junkme?
st = 0.0;
return st;
}
/*
- FIXME: wrong name
+ Number of hooks on the flag, ie. the log of the duration.
*/
int
Stem::flag_i (Score_element*me)
Real x_gap_f = gh_scm2double (me->get_elt_property ("x-gap"));
- Score_element* commonx = me->common_refpoint (me->get_bound (LEFT), X_AXIS);
- commonx = me->common_refpoint (me->get_bound (RIGHT), X_AXIS);
-
Score_element* l = me->get_bound (LEFT);
Score_element* r = me->get_bound (RIGHT);
+ Score_element* commonx = me->common_refpoint (l, X_AXIS);
+ commonx = me->common_refpoint (r, X_AXIS);
+
Real left_x;
+
+ /*
+ this is a kludge: the tie has to be long enough to be
+ visible, but should not go through key sigs.
+
+ (please fixme)
+ */
+ Real lambda = 0.5;
+
if (Note_head::has_interface (me->get_bound (LEFT)))
left_x = l->extent (l, X_AXIS)[RIGHT] + x_gap_f;
else
- left_x = l->extent (l, X_AXIS).length () / 2;
+ left_x = l->extent (l, X_AXIS).linear_combination (lambda);
+
Real width;
if (Note_head::has_interface (me->get_bound (LEFT))
- l->extent (commonx, X_AXIS)[RIGHT]
- 2 * x_gap_f;
else
- width =
- - l->extent (l, X_AXIS).length () / 2
+ width =
+ - l->extent (commonx, X_AXIS).linear_combination (lambda)
+ r->extent (commonx, X_AXIS)[LEFT]
- - l->relative_coordinate (commonx, X_AXIS)
- 2 * x_gap_f;
}
/*
Avoid colliding of the horizontal part with stafflines.
+
- should do me for slurs as well.
+ TODO: redo this, heuristic is half-baken, and ties often look ugly
+ as a result.
+ TODO: doesn't work when on staff with even number of lines.
*/
Array<Real> horizontal (b.solve_derivative (Offset (1,0)));
if (horizontal.size ())
if (fabs (y) <= Staff_symbol_referencer::staff_radius (me)
&& fabs (diff) < clear)
{
- newy = ry - 0.5 * staff_space * sign (diff) ;
+ Real y1 = ry + clear;
+ Real y2 = ry - clear;
+
+ newy = (fabs (y1 - y) < fabs (y2 - y)) ? y1 : y2;
+
+ // newy = ry - 0.5 * staff_space * sign (diff) ;
+
+ /*
+ we don't want horizontal ties
+ */
+ if (fabs (newy - b.control_[0][Y_AXIS]) < 1e-2)
+ {
+ newy = newy + dir * staff_space;
+ }
}
Real y0 = b.control_ [0][Y_AXIS];
- go to alternative if we're a volta
+ - make a :| if there are no alternatives
+
- do something intelligent when we're fully unfolding (fixcomment)
*/
ly_str02scm (repstr.ch_C()), SCM_UNDEFINED));
}
}
- else if (done_count_ < repmus->repeats_i_ && !repmus->volta_fold_b_)
+ else if (repmus->volta_fold_b_)
+ {
+ add_repeat_command (ly_symbol2scm ("end-repeat"));
+ }
+ else if (done_count_ < repmus->repeats_i_)
{
current_iter_p_ = get_iterator_p (repmus->body ());
do_main_b_ = true;
end_volta_span_p_ =0;
}
}
+
+/*
+ TODO: should attach volta to paper-column if no bar is found.
+ */
\name ChoirStaff;
alignmentReference = \center;
\consists "System_start_delimiter_engraver";
- systemStartDelimiterGlyph = #'bracket
+ SystemStartDelimiter \push #'glyph = #'bracket
\accepts "Staff";
\accepts "RhythmicStaff";
\consists "Stem_engraver";
\consists "Beam_engraver";
\consists "Slur_engraver";
-
+
\consists "Auto_beam_engraver";
\consists "Align_note_column_engraver";
\consists "Span_bar_engraver";
\consists "Span_arpeggio_engraver";
\consists "System_start_delimiter_engraver";
- systemStartDelimiterGlyph = #'brace
+ SystemStartDelimiter \push #'glyph = #'brace
\consists "Property_engraver";
Generic_property_list = #generic-grand-staff-properties
\consists "Span_bar_engraver";
\consists "Span_arpeggio_engraver";
\consists "Output_property_engraver";
- systemStartDelimiterGlyph = #'bracket
+ SystemStartDelimiter \push #'glyph = #'bracket
+
\consists "System_start_delimiter_engraver";
\accepts "Staff";
\accepts "RhythmicStaff";
alignmentReference = \down;
defaultClef = #"treble"
defaultBarType = #"|"
- systemStartDelimiterGlyph = #'bar-line
+
explicitClefVisibility = #all-visible
explicitKeySignatureVisibility = #all-visible
))
(Clef . (
- (molecule-callback . ,Score_element::brew_molecule)
+ (molecule-callback . ,Clef::brew_molecule)
(before-line-breaking-callback . ,Clef::before_line_breaking)
(breakable . #t)
(break-align-symbol . Clef_item)
(InstrumentName . (
(breakable . #t)
- (Y-offset-callbacks . (,Side_position::centered_on_parent))
+ (Y-offset-callbacks . (,Side_position::centered_on_parent
+ ,Side_position::aligned_on_self))
+ (self-alignment-Y . 0)
(molecule-callback . ,Text_item::brew_molecule)
(break-align-symbol . Instrument_name)
(visibility-lambda . ,begin-of-line-visible)
(LineOfScore . (
(axes . (0 1))
- (meta . ,(element-description "LineOfScore" axis-group-interface))
+ (meta . ,(element-description "LineOfScore" line-of-score-interface axis-group-interface))
))
(LyricExtender . (
(arch-height . 1.5)
(arch-angle . 50.0)
(arch-thick . 0.25)
+ (glyph . bar-line)
(arch-width . 1.5)
(bracket-thick . 0.25)
(bracket-width . 2.0)
+ (Y-extent-callback . #f)
(meta . ,(element-description "SystemStartDelimiter" system-start-delimiter ))
))
(Tie . (
(molecule-callback . ,Tie::brew_molecule)
(spacing-procedure . ,Tie::set_spacing_rods)
- (staffline-clearance . 0.24)
+ (staffline-clearance . 0.35)
(details . ((ratio . 0.333) (height-limit . 1.0)))
(thickness . 1.2)
(x-gap . 0.2)
)
(define (self-evaluating? x)
- (or (number? x) (string? x) (procedure? x))
+ (or (number? x) (string? x) (procedure? x) (boolean? x))
)
-(define (type-name predicate)
- (cond
- ((eq? predicate dir?) "direction")
- ((eq? predicate ly-element?) "graphic element")
- ((eq? predicate pair?) "pair")
- ((eq? predicate integer?) "integer")
- ((eq? predicate list?) "list")
- ((eq? predicate symbol?) "symbol")
- ((eq? predicate string?) "string")
- ((eq? predicate boolean?) "string")
- ((eq? predicate number?) "number")
- ((eq? predicate char?) "char")
- ((eq? predicate input-port?) "input port")
- ((eq? predicate output-port?) "output port")
- ((eq? predicate vector?) "vector")
- ((eq? predicate procedure?) "procedure")
- (else "(unknown)")
- ))
(define (htmlfy x)
(let*
(name (cdr (assoc 'name meta)))
(ifaces (cdr (assoc 'interface-descriptions meta)))
(ifacedoc (map (lambda (x) (document-interface x description))
- ifaces))
+ (reverse ifaces)))
(outname (string-append name ".html"))
(out (open-output-file outname))
)
(use-modules (ice-9 regex))
+(define (number-pair? x)
+ (and (pair? x) (number? (car x)) (number? (cdr x))))
+
+(define (type-name predicate)
+ (cond
+ ((eq? predicate dir?) "direction")
+ ((eq? predicate number-pair?) "pair of numbers")
+ ((eq? predicate ly-input-location?) "input location")
+ ((eq? predicate ly-element?) "graphic element")
+ ((eq? predicate pair?) "pair")
+ ((eq? predicate integer?) "integer")
+ ((eq? predicate list?) "list")
+ ((eq? predicate symbol?) "symbol")
+ ((eq? predicate string?) "string")
+ ((eq? predicate boolean?) "boolean")
+ ((eq? predicate moment?) "moment")
+ ((eq? predicate number?) "number")
+ ((eq? predicate char?) "char")
+ ((eq? predicate input-port?) "input port")
+ ((eq? predicate output-port?) "output port")
+ ((eq? predicate vector?) "vector")
+ ((eq? predicate procedure?) "procedure")
+ (else "unknown type")
+ ))
+
+
;; The regex module may not be available, or may be broken.
(define use-regex
(let ((os (string-downcase (vector-ref (uname) 0))))