+2006-05-30 Han-Wen Nienhuys <hanwen@lilypond.org>
+
+ * scm/translation-functions.scm (format-bass-figure): translate
+ digits over 10 to the left
+
+ * scm/define-markup-commands.scm (translate-scaled): new markup.
+
+ * mf/feta-nummer-code.mf (code): overshoot the topright tip of the
+ 7 glyph.
+
+ * ly/engraver-init.ly: add Figured_bass_engraver
+
+ * lily/engraver-group.cc (acknowledge_grobs): use start/stop drul.
+
+ * lily/figured-bass-engraver.cc (clear_spanners): use everywhere.
+
+ * lily/score-engraver.cc (announce_grob): only note START announces.
+
+ * lily/include/engraver-group.hh (Translator_group):
+ acknowledge_hash_table_ is now drul.
+
+ * lily/engraver.cc (announce_end_grob): new method.
+
+ * lily/include/grob-info.hh (class Grob_info): add start_end_ member.
+
+ * lily/translator-dispatch-list.cc (create): take start_end argument.
+
+ * lily/include/translator.hh (TRANSLATOR_DECLARATIONS): change
+ acknowledge_static_array_ to drul
+
+ * lily/include/translator.icc (ADD_END_ACKNOWLEDGER): new macro.
+
+ * scm/define-grob-interfaces.scm
+ (bass-figure-alignment-interface): add bass-figure-alignment-interface
+
+ * scm/define-grobs.scm (all-grob-descriptions): add
+ BassFigureAlignmentPositioning
+
+ * ly/Welcome-to-LilyPond-MacOS.ly: include in LilyPond, so version number
+ stays up to date. Backportme.
+
2006-05-30 Mats Bengtsson <mabe@drongo.s3.kth.se>
* Documentation/user/basic-notation.itely (Bar lines): Document
--- /dev/null
+
+\paper {
+ ragged-right = ##t
+
+}
+\version "2.9.7"
+\header {
+
+
+ texidoc = "Figured bass can also be added to Staff context directly.
+In that case, the figures must be entered with @code{\\figuremode} and be directed
+to an existing @code{Staff} context."
+
+ }
+
+<<
+
+ \new Staff = someUniqueName
+ \relative c'' {
+ c4 c'8 r8 c,4 c'
+ }
+
+ %% send to existing Staff.
+ \context Staff = someUniqueName
+ \figuremode {
+ <4>4 <4>8 s8
+
+ \set Staff.useBassFigureExtenders = ##t
+ <4 6>4 <4 6>
+ }
+>>
= context_->get_parent_context ()
? dynamic_cast<Engraver_group *> (context_->get_parent_context ()->implementation ())
: 0;
+
if (dad_eng)
dad_eng->announce_grob (info);
}
for (vsize j = 0; j < announce_infos_.size (); j++)
{
Grob_info info = announce_infos_[j];
-
+
SCM meta = info.grob ()->internal_get_property (meta_sym);
SCM nm = scm_assoc (name_sym, meta);
if (scm_is_pair (nm))
else
continue;
- SCM acklist = scm_hashq_ref (acknowledge_hash_table_, nm, SCM_BOOL_F);
+ SCM acklist = scm_hashq_ref (acknowledge_hash_table_drul_[info.start_end()],
+ nm, SCM_BOOL_F);
+
Engraver_dispatch_list *dispatch
= Engraver_dispatch_list::unsmob (acklist);
SCM ifaces
= scm_cdr (scm_assoc (ly_symbol2scm ("interfaces"), meta));
acklist = Engraver_dispatch_list::create (get_simple_trans_list (),
- ifaces);
+ ifaces, info.start_end ());
dispatch
= Engraver_dispatch_list::unsmob (acklist);
- scm_hashq_set_x (acknowledge_hash_table_, nm, acklist);
+ scm_hashq_set_x (acknowledge_hash_table_drul_[info.start_end ()], nm, acklist);
}
if (dispatch)
Engraver_group::Engraver_group ()
{
- acknowledge_hash_table_ = SCM_EOL;
- acknowledge_hash_table_ = scm_c_make_hash_table (61);
+ acknowledge_hash_table_drul_[LEFT]
+ = acknowledge_hash_table_drul_[RIGHT]
+ = SCM_EOL;
+
+ acknowledge_hash_table_drul_[LEFT] = scm_c_make_hash_table (61);
+ acknowledge_hash_table_drul_[RIGHT] = scm_c_make_hash_table (61);
}
#include "translator.icc"
void
Engraver_group::derived_mark () const
{
- scm_gc_mark (acknowledge_hash_table_);
+ scm_gc_mark (acknowledge_hash_table_drul_[LEFT]);
+ scm_gc_mark (acknowledge_hash_table_drul_[RIGHT]);
}
get_daddy_engraver ()->announce_grob (inf);
}
+void
+Engraver::announce_end_grob (Grob_info inf)
+{
+ get_daddy_engraver ()->announce_grob (inf);
+}
+
/*
CAUSE is the object (typically a Music object) that
was the reason for making E.
g->announce_grob (i);
}
+
+/*
+ CAUSE is the object (typically a Music object) that
+ was the reason for making E.
+*/
+void
+Engraver::announce_end_grob (Grob *e, SCM cause)
+{
+ if (unsmob_music (cause) || unsmob_grob (cause))
+ e->set_property ("cause", cause);
+
+ Grob_info i (this, e);
+
+ i.start_end_ = STOP;
+ Engraver_group *g = get_daddy_engraver ();
+ if (g)
+ g->announce_grob (i);
+}
+
+
Engraver::Engraver ()
{
}
{
if (!alignment_)
return;
-
- alignment_ = 0;
+
+ if (alignment_)
+ {
+ announce_end_grob (alignment_, SCM_EOL);
+ alignment_ = 0;
+ }
+
if (to_boolean (get_property ("figuredBassCenterContinuations")))
center_repeated_continuations();
- groups_.clear ();
+ for (vsize i = 0; i < groups_.size (); i++)
+ {
+ if (groups_[i].group_)
+ {
+ announce_end_grob (groups_[i].group_ , SCM_EOL);
+ groups_[i].group_ = 0;
+ }
+
+ if (groups_[i].continuation_line_)
+ {
+ announce_end_grob (groups_[i].continuation_line_ , SCM_EOL);
+ groups_[i].continuation_line_ = 0;
+ }
+ }
+
+ /* Check me, groups_.clear () ? */
}
void
if (rest_event_)
{
clear_spanners ();
+ groups_.clear ();
return;
}
&& new_musics_.empty ())
{
clear_spanners ();
+ groups_.clear ();
return;
}
bool use_extenders = to_boolean (get_property ("useBassFigureExtenders"));
if (!use_extenders)
{
- if (to_boolean (get_property ("figuredBassCenterContinuations")))
- center_repeated_continuations ();
-
- alignment_ = 0;
- for (vsize i = 0; i < groups_.size (); i++)
- {
- groups_[i].group_ = 0;
- groups_[i].continuation_line_ = 0;
- }
+ clear_spanners ();
}
if (!continuation_)
- clear_spanners ();
-
+ {
+ clear_spanners ();
+ groups_.clear ();
+ }
+
vsize k = 0;
for (vsize i = 0; i < new_musics_.size (); i++)
{
group.figure_item_->set_property ("transparent", SCM_BOOL_T);
group.continuation_line_->set_bound (RIGHT, group.figure_item_);
}
-
if (groups_[i].group_)
groups_[i].group_->set_bound (RIGHT, muscol);
+
}
}
{
origin_trans_ = t;
grob_ = g;
+ start_end_ = START;
}
Grob_info::Grob_info ()
{
grob_ = 0;
+ start_end_ = START;
origin_trans_ = 0;
}
{
protected:
vector<Grob_info> announce_infos_;
- SCM acknowledge_hash_table_;
+ Drul_array<SCM> acknowledge_hash_table_drul_;
+
public:
VIRTUAL_COPY_CONSTRUCTOR (Translator_group, Engraver_group);
Engraver_group ();
*/
virtual void acknowledge_grob (Grob_info) {}
virtual void announce_grob (Grob_info);
+ virtual void announce_end_grob (Grob_info);
Engraver_group *get_daddy_engraver () const;
public:
Announce element. Default: pass on to daddy. Utility
*/
void announce_grob (Grob *, SCM cause);
+ void announce_end_grob (Grob *, SCM cause);
/**
override other ctor
{
Translator *origin_trans_;
Grob *grob_;
-
+ Direction start_end_;
+
friend class Engraver;
public:
+ Direction start_end () const { return start_end_; }
Grob *grob () const { return grob_; }
Translator *origin_translator () const { return origin_trans_; }
public:
void apply (Grob_info);
SCM static create (SCM trans_list,
- SCM iface_list);
+ SCM iface_list, Direction);
DECLARE_SIMPLE_SMOBS (Engraver_dispatch_list,);
};
NAME (); \
VIRTUAL_COPY_CONSTRUCTOR (Translator, NAME); \
static SCM static_description_; \
- static vector<Acknowledge_information> acknowledge_static_array_; \
+ static Drul_array<vector<Acknowledge_information> > acknowledge_static_array_drul_; \
virtual void fetch_precomputable_methods (Translator_void_method_ptr methods[]); \
virtual SCM static_translator_description () const; \
virtual SCM translator_description () const; \
{ \
return static_get_acknowledger (sym); \
} \
- static Engraver_void_function_engraver_grob_info static_get_acknowledger (SCM sym);
+ virtual Engraver_void_function_engraver_grob_info get_end_acknowledger (SCM sym) \
+ { \
+ return static_get_end_acknowledger (sym); \
+ } \
+ static Engraver_void_function_engraver_grob_info static_get_acknowledger (SCM sym); \
+ static Engraver_void_function_engraver_grob_info static_get_end_acknowledger(SCM); \
+ /* end #define */
+
#define DECLARE_ACKNOWLEDGER(x) public : void acknowledge_ ## x (Grob_info); protected:
+#define DECLARE_END_ACKNOWLEDGER(x) public : void acknowledge_end_ ## x (Grob_info); protected:
enum Translator_precompute_index
{
ADD_GLOBAL_CTOR (_ ## T ## _adder);
#define ADD_TRANSLATOR(classname, desc, grobs, accepted, read, write) \
- vector<Acknowledge_information> classname::acknowledge_static_array_; \
+ Drul_array< vector<Acknowledge_information> > classname::acknowledge_static_array_drul_; \
IMPLEMENT_FETCH_PRECOMPUTABLE_METHODS (classname); \
ADD_THIS_TRANSLATOR (classname); \
Engraver_void_function_engraver_grob_info \
classname::static_get_acknowledger (SCM sym) \
{ \
- return generic_get_acknowledger (sym, &acknowledge_static_array_); \
+ return generic_get_acknowledger (sym, &acknowledge_static_array_drul_[START]); \
+ } \
+ Engraver_void_function_engraver_grob_info \
+ classname::static_get_end_acknowledger (SCM sym) \
+ { \
+ return generic_get_acknowledger (sym, &acknowledge_static_array_drul_[STOP]); \
} \
SCM \
classname::static_translator_description () const \
#define ADD_ACKNOWLEDGER(CLASS, NAME) \
void CLASS ## NAME ## _ack_adder () \
{ \
- add_acknowledger ((Engraver_void_function_engraver_grob_info) & CLASS::acknowledge_ ## NAME, #NAME, &CLASS::acknowledge_static_array_); \
+ add_acknowledger ((Engraver_void_function_engraver_grob_info) & CLASS::acknowledge_ ## NAME, #NAME, &CLASS::acknowledge_static_array_drul_[START]); \
} \
ADD_SCM_INIT_FUNC (CLASS ## NAME ## _ack_adder_initclass, CLASS ## NAME ## _ack_adder);
+#define ADD_END_ACKNOWLEDGER(CLASS, NAME) \
+ void CLASS ## NAME ## _end_ack_adder () \
+ { \
+ add_acknowledger ((Engraver_void_function_engraver_grob_info) & CLASS::acknowledge_end_ ## NAME, #NAME, &CLASS::acknowledge_static_array_drul_[STOP]); \
+ } \
+ ADD_SCM_INIT_FUNC (CLASS ## NAME ## _end_ack_adder_initclass, CLASS ## NAME ## _end_ack_adder);
+
#endif /* TRANSLATOR_ICC */
void
Score_engraver::announce_grob (Grob_info info)
{
- announce_infos_.push_back (info);
- pscore_->root_system ()->typeset_grob (info.grob ());
- elems_.push_back (info.grob ());
+ Engraver_group::announce_grob (info);
+ if (info.start_end () == START)
+ {
+ pscore_->root_system ()->typeset_grob (info.grob ());
+ elems_.push_back (info.grob ());
+ }
}
void
ADD_TRANSLATOR (Stem_engraver,
/* doc */ "Create stems and single-stem tremolos. It also works together with "
"the beam engraver for overriding beaming.",
- /* create */ "Stem StemTremolo",
+ /* create */
+ "Stem "
+ "StemTremolo ",
/* accept */ "tremolo-event",
- /* read */ "tremoloFlags stemLeftBeamCount stemRightBeamCount",
+ /* read */
+ "tremoloFlags "
+ "stemLeftBeamCount "
+ "stemRightBeamCount ",
/* write */ "");
SCM
Engraver_dispatch_list::create (SCM trans_list,
- SCM iface_list)
+ SCM iface_list, Direction start_end)
{
SCM retval = Engraver_dispatch_list ().smobbed_copy ();
Engraver_dispatch_list *list = Engraver_dispatch_list::unsmob (retval);
for (SCM i = iface_list; scm_is_pair (i); i = scm_cdr (i))
{
Engraver_void_function_engraver_grob_info ptr
- = eng->get_acknowledger (scm_car (i));
+ = (start_end == START)
+ ? eng->get_acknowledger (scm_car (i))
+ : eng->get_end_acknowledger (scm_car (i));
+
if (ptr)
{
entry.function_ = ptr;
--- /dev/null
+%{
+Welcome to LilyPond
+===================
+
+Congratulations, LilyPond has been installed successfully.
+
+Now to take it for the first test run.
+
+ 1. Save this file
+
+ 2. Select
+
+ Compile > Typeset file
+
+ from the menu.
+
+ The file is processed, and
+
+ 3. The PDF viewer will pop up. Click one of the noteheads.
+
+
+That's it. For more information, visit http://lilypond.org .
+
+%}
+
+\header{
+ title = "A scale in LilyPond"
+}
+
+\relative {
+ c d e f g a b c
+}
+
+
+\version "2.9.6" % necessary for upgrading to future LilyPond versions.
\consists "Instrument_name_engraver"
\consists "String_number_engraver"
\consists "Axis_group_engraver"
+ \consists "Figured_bass_engraver"
+ \consists "Figured_bass_position_engraver"
\override VerticalAxisGroup #'minimum-Y-extent = #'(-4 . 4)
extraVerticalExtent = ##f
define_pixels (dot_diam);
-code := 31; % , 32
-
-fet_beginchar ("Space", "space");
- set_char_box (0, space#, 0, height#);
-fet_endchar;
-
-
code := 42; % , 43
fet_beginchar ("Plus", "plus");
save tolerance;
save alpha, beta, gamma, delta;
save bow;
+ save x_overshoot;
+
path bow;
- set_char_box (0, 11/15 height# * widen, 0, height#);
+ set_char_box (0, 11/15 height# * widen - thin#, 0, height#);
+ overshoot_x = .75 thin;
message "w:" & decimal w;
message "h:" & decimal h;
alpha = -180;
-if true:
penpos1 (3/2 thick, 180 + alpha);
penpos2 (hair, 180 + alpha - 45);
penpos3 (hair, 180 + alpha + 45);
z2 = z1l + (1/4 sqrt (2) * hair) * dir (alpha - 135);
z3 = z1r + (1/4 sqrt (2) * hair) * dir (alpha - 45);
z4 = z1 + kuulleke * dir (alpha - 90);
-else:
- % does not work
- calc_kuulleke (3/2 thick, -alpha);
-fi;
z1l = (thin, 0);
beta = 55;
penpos5 (thin, 90 + beta);
- z5 = (w, h) + (1/2 sqrt (2) * thin) * dir (-135);
+ z5 = (w, h) + (1/2 sqrt (2) * thin) * dir (-135) + (overshoot_x, 0);
gamma = angle (length (z1r - z1), 2 kuulleke);
delta = 12;
"A bass figure text"
'(implicit))
+(ly:add-interface
+ 'bass-figure-alignment-interface
+ ""
+ '())
(ly:add-interface
'dynamic-interface
rhythmic-grob-interface
bass-figure-interface
font-interface))))))
+
+ (BassFigureAlignment
+ . (
+ (axes . (,Y))
+ (threshold . (2 . 1000))
+ (positioning-done . ,ly:align-interface::calc-positioning-done)
+ (Y-extent . ,ly:axis-group-interface::height)
+ (stacking-dir . -1)
+ (meta . ((class . Spanner)
+ (interfaces . (align-interface
+ bass-figure-alignment-interface
+ axis-group-interface))))))
+
+ (BassFigureAlignmentPositioning
+ . ((Y-offset . ,ly:side-position-interface::y-aligned-side)
+ (side-axis . ,Y)
+ (direction . ,UP)
+ (Y-extent . ,ly:axis-group-interface::height)
+ (axes . (,Y))
+ (staff-padding . 1.0)
+ (padding . 0.5)
+ (meta . ((class . Spanner)
+ (interfaces . (side-position-interface
+ axis-group-interface
+ ))))))
+
(BassFigureBracket
. (
(stencil . ,ly:enclosing-bracket::print)
(interfaces . (axis-group-interface
))))))
- (BassFigureAlignment
- . (
- (axes . (,Y))
- (threshold . (2 . 1000))
- (positioning-done . ,ly:align-interface::calc-positioning-done)
- (Y-extent . ,ly:axis-group-interface::height)
- (stacking-dir . -1)
- (meta . ((class . Spanner)
- (interfaces . (align-interface
- axis-group-interface))))))
(Beam
. (
(- amount) Y))
+(define-markup-command (translate-scaled layout props offset arg) (number-pair? markup?)
+ "Translate @var{arg} by @var{offset}, scaling the offset by the @code{font-size}."
+
+ (let*
+ ((factor (magstep (chain-assoc-get 'font-size props 0)))
+ (scaled (cons (* factor (car offset))
+ (* factor (cdr offset)))))
+
+ (ly:stencil-translate (interpret-markup layout props arg)
+ scaled)))
+
(define-markup-command (raise layout props amount arg) (number? markup?)
"
Raise @var{arg}, by the distance @var{amount}.
(define-public (format-bass-figure figure event context)
(let* ((fig (ly:music-property event 'figure))
(fig-markup (if (number? figure)
- (if (eq? #t (ly:music-property event 'diminished))
- (markup #:slashed-digit figure)
- (markup #:number (number->string figure 10)))
+
+ ;; this is not very elegant, but center-aligning all digits
+ ;; is problematic with other markups, and shows problems
+ ;; in the (lack of) overshoot of feta alphabet glyphs.
+
+ ((if (<= 10 figure)
+ (lambda (y) (make-translate-scaled-markup (cons -0.7 0) y))
+ identity)
+
+ (if (eq? #t (ly:music-property event 'diminished))
+ (markup #:slashed-digit figure)
+ (markup #:number (number->string figure 10))))
#f
))
(alt (ly:music-property event 'alteration))
(alt-markup
(if (number? alt)
(markup
- #:general-align Y DOWN #:fontsize
- (if (not (= alt DOUBLE-SHARP))
- -2 2)
- (alteration->text-accidental-markup alt))
+ #:general-align Y DOWN #:fontsize
+ (if (not (= alt DOUBLE-SHARP))
+ -2 2)
+ (alteration->text-accidental-markup alt))
#f))
(plus-markup (if (eq? #t (ly:music-property event 'augmented))