From 30eb1ded55e8d8b17495b96a3741750fe34d3599 Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Wed, 5 Oct 2005 13:05:45 +0000 Subject: [PATCH] * lily/horizontal-bracket.cc (make_bracket): new function. * scm/define-grobs.scm (all-grob-descriptions): new grobs NewBassFigure, BassFigureBracket, BassFigureContinuation, BassFigureLine, BassFigureAlignment * lily/new-figured-bass-engraver.cc (process_music): new file. * lily/figured-bass-continuation.cc: new file. * lily/include/horizontal-bracket.hh (struct Horizontal_bracket): new file. --- ChangeLog | 15 ++ lily/align-interface.cc | 5 + lily/figured-bass-continuation.cc | 138 ++++++++++++ lily/figured-bass-engraver.cc | 4 +- lily/horizontal-bracket.cc | 74 ++++--- lily/include/horizontal-bracket.hh | 19 ++ lily/new-figured-bass-engraver.cc | 332 +++++++++++++++++++++++++++++ lily/parser.yy | 35 +-- ly/engraver-init.ly | 2 +- scm/bass-figure.scm | 25 +++ scm/define-context-properties.scm | 5 + scm/define-grobs.scm | 41 ++++ scm/define-markup-commands.scm | 24 +++ 13 files changed, 670 insertions(+), 49 deletions(-) create mode 100644 lily/figured-bass-continuation.cc create mode 100644 lily/include/horizontal-bracket.hh create mode 100644 lily/new-figured-bass-engraver.cc diff --git a/ChangeLog b/ChangeLog index dd8aca8edb..f0198b7139 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2005-10-05 Han-Wen Nienhuys + + * lily/horizontal-bracket.cc (make_bracket): new function. + + * scm/define-grobs.scm (all-grob-descriptions): new grobs + NewBassFigure, BassFigureBracket, BassFigureContinuation, + BassFigureLine, BassFigureAlignment + + * lily/new-figured-bass-engraver.cc (process_music): new file. + + * lily/figured-bass-continuation.cc: new file. + + * lily/include/horizontal-bracket.hh (struct Horizontal_bracket): + new file. + 2005-10-04 Mats Bengtsson * scripts/lilypond-book.py: Bug fix, put the quote around the diff --git a/lily/align-interface.cc b/lily/align-interface.cc index 5394a0dacb..bedae50c80 100644 --- a/lily/align-interface.cc +++ b/lily/align-interface.cc @@ -159,9 +159,14 @@ Align_interface::align_elements_to_extents (Grob *me, Axis a) if (a == Y_AXIS && me_spanner) { +#if 0 + /* + TODO: messes up for figured bass alignments. + */ if (me_spanner->get_bound (LEFT)->break_status_dir () == CENTER) me->warning (_ ("vertical alignment called before line-breaking. " "Only do cross-staff spanners with PianoStaff.")); +#endif SCM details = me_spanner->get_bound (LEFT)->get_property ("line-break-system-details"); SCM extra_space_handle = scm_assoc (ly_symbol2scm ("alignment-extra-space"), details); diff --git a/lily/figured-bass-continuation.cc b/lily/figured-bass-continuation.cc new file mode 100644 index 0000000000..951807440f --- /dev/null +++ b/lily/figured-bass-continuation.cc @@ -0,0 +1,138 @@ +/* + figured-bass-continuation.cc -- implement Figured_bass_continuation + + source file of the GNU LilyPond music typesetter + + (c) 2005 Han-Wen Nienhuys + +*/ + +#include "line-interface.hh" +#include "lily-guile.hh" +#include "spanner.hh" +#include "output-def.hh" +#include "item.hh" +#include "stencil.hh" +#include "pointer-group-interface.hh" +#include "axis-group-interface.hh" + + +#include "horizontal-bracket.hh" + +struct Figured_bass_bracket +{ + static bool has_interface (Grob*); + +public: + DECLARE_SCHEME_CALLBACK(print, (SCM)); +}; + + +ADD_INTERFACE(Figured_bass_bracket, + "figured-bass-bracket-interface", + "Brackets alongside bass figures.", + + /* props */ + + /* ugh: should make bracket interface. */ + "bracket-flare " + "shorten-pair " + "edge-height " + "padding " + "thickness " + "elements " + ); + +MAKE_SCHEME_CALLBACK (Figured_bass_bracket, print, 1); +SCM +Figured_bass_bracket::print (SCM grob) +{ + Grob *me = unsmob_grob (grob); + extract_grob_set (me, "elements", elements); + if (elements.is_empty ()) + { + me->suicide (); + return SCM_EOL; + } + + Grob *common_x = common_refpoint_of_array (elements, me, X_AXIS); + Interval xext = Axis_group_interface::relative_group_extent (elements, common_x, X_AXIS); + + Stencil left_br = Horizontal_bracket::make_bracket (me, me, elements, + Y_AXIS, LEFT); + Stencil right_br = Horizontal_bracket::make_bracket (me, me, elements, + Y_AXIS, RIGHT); + + xext.widen (robust_scm2double (me->get_property ("padding"), 0.25)); + left_br.translate_axis (xext[LEFT], X_AXIS); + right_br.translate_axis (xext[RIGHT], X_AXIS); + + left_br.add_stencil (right_br); + left_br.translate_axis (-me->relative_coordinate (common_x, X_AXIS), X_AXIS); + return left_br.smobbed_copy (); +} + + +struct Figured_bass_continuation +{ + static bool has_interface (Grob*); + +public: + DECLARE_SCHEME_CALLBACK(print, (SCM)); + DECLARE_SCHEME_CALLBACK(center_on_figures, (SCM, SCM)); +}; + +MAKE_SCHEME_CALLBACK (Figured_bass_continuation, center_on_figures, 2); +SCM +Figured_bass_continuation::center_on_figures (SCM grob, SCM axis) +{ + Spanner *me = dynamic_cast (unsmob_grob (grob)); + (void) axis; + + extract_grob_set (me, "figures", figures); + Grob *common = common_refpoint_of_array (figures, me, Y_AXIS); + + Interval ext = Axis_group_interface::relative_group_extent (figures, common, Y_AXIS); + + return scm_from_double (ext.center () - me->relative_coordinate (common, Y_AXIS)); +} + +MAKE_SCHEME_CALLBACK (Figured_bass_continuation, print, 1); +SCM +Figured_bass_continuation::print (SCM grob) +{ + Spanner *me = dynamic_cast (unsmob_grob (grob)); + + Real thick = + me->get_layout ()->get_dimension (ly_symbol2scm ("linethickness")) + * robust_scm2double (me->get_property ("thickness"), 1); + + Interval spanned; + Direction d = LEFT; + Grob *common = me->get_bound (LEFT)->common_refpoint (me->get_bound (RIGHT), + X_AXIS); + do + { + spanned[d] + = robust_relative_extent (me->get_bound (d), common, X_AXIS)[RIGHT] + - me->relative_coordinate (common, X_AXIS); + } + while (flip (&d) != LEFT); + + Stencil extender + = Line_interface::make_line (thick, + Offset (spanned[LEFT], 0), + Offset (spanned[RIGHT], 0)); + + return extender.smobbed_copy (); +} + +ADD_INTERFACE(Figured_bass_continuation, + "figured-bass-continuation-interface", + "Simple extender line between bounds.", + + /* props */ + "thickness " + "figures " + ); + diff --git a/lily/figured-bass-engraver.cc b/lily/figured-bass-engraver.cc index 628ee2d888..45a3d8f382 100644 --- a/lily/figured-bass-engraver.cc +++ b/lily/figured-bass-engraver.cc @@ -11,6 +11,8 @@ #include "item.hh" #include "context.hh" +#include "translator.icc" + class Figured_bass_engraver : public Engraver { TRANSLATOR_DECLARATIONS (Figured_bass_engraver); @@ -83,8 +85,6 @@ Figured_bass_engraver::process_music () } } -#include "translator.icc" - ADD_TRANSLATOR (Figured_bass_engraver, /* doc */ "Make figured bass numbers.", /* create */ "BassFigure", diff --git a/lily/horizontal-bracket.cc b/lily/horizontal-bracket.cc index 57225c49d4..8c206bb729 100644 --- a/lily/horizontal-bracket.cc +++ b/lily/horizontal-bracket.cc @@ -13,12 +13,7 @@ #include "output-def.hh" #include "staff-symbol-referencer.hh" #include "tuplet-bracket.hh" // ugh. - -struct Horizontal_bracket -{ - DECLARE_SCHEME_CALLBACK (print, (SCM)); - static bool has_interface (Grob *); -}; +#include "horizontal-bracket.hh" // ugh. /* TODO: @@ -27,51 +22,70 @@ struct Horizontal_bracket Support texts on the brackets? */ -MAKE_SCHEME_CALLBACK (Horizontal_bracket, print, 1); -SCM -Horizontal_bracket::print (SCM smob) +Stencil +Horizontal_bracket::make_bracket (Grob *me, Grob *common, + Link_array grobs, Axis a, Direction dir) { - Grob *me = unsmob_grob (smob); - Spanner *sp = dynamic_cast (me); + Axis other = other_axis (a); + + Grob *cx = common_refpoint_of_array (grobs, common, a); - extract_grob_set (me, "columns", gs); - if (!gs.size ()) - { - me->suicide (); - return SCM_EOL; - } - Grob *cx = common_refpoint_of_array (gs, me, X_AXIS); - cx = cx->common_refpoint (sp->get_bound (LEFT), X_AXIS); - cx = cx->common_refpoint (sp->get_bound (RIGHT), X_AXIS); - - Interval ext = gs.top ()->extent (cx, X_AXIS); - ext.unite (gs[0]->extent (cx, X_AXIS)); + Interval ext = grobs.top ()->extent (cx, a); + ext.unite (grobs[0]->extent (cx, a)); Drul_array edge_height = robust_scm2interval (me->get_property ("edge-height"), Interval (1.0, 1.0)); - Drul_array flare = robust_scm2interval (me->get_property ("bracket-flare"), Interval (0, 0)); - Drul_array shorten = robust_scm2interval (me->get_property ("shorten-pair"), Interval (0, 0)); // Make sure that it points in the correct direction: - Real dir = get_grob_direction (me); - scale_drul (&edge_height, -dir); + scale_drul (&edge_height, Real (-dir)); Interval empty; + Offset start; + start[a] = ext.length (); Stencil b - = Tuplet_bracket::make_bracket (me, Y_AXIS, Offset (ext.length (), 0), + = Tuplet_bracket::make_bracket (me, other, start, edge_height, empty, flare, shorten); - b.translate_axis (ext[LEFT] - sp->get_bound (LEFT)->relative_coordinate (cx, X_AXIS), X_AXIS); + b.translate_axis (ext[LEFT], a); + + return b; +} + +MAKE_SCHEME_CALLBACK (Horizontal_bracket, print, 1); +SCM +Horizontal_bracket::print (SCM smob) +{ + Grob *me = unsmob_grob (smob); + Spanner *sp = dynamic_cast (me); + + extract_grob_set (me, "columns", gs); + if (!gs.size ()) + { + me->suicide (); + return SCM_EOL; + } + + Grob *cx = me->common_refpoint (sp->get_bound (LEFT), X_AXIS); + cx = cx->common_refpoint (sp->get_bound (RIGHT), X_AXIS); + + Stencil b = make_bracket (me, cx, gs, X_AXIS, get_grob_direction (me)); + + b.translate_axis (- sp->get_bound (LEFT)->relative_coordinate (cx, X_AXIS), X_AXIS); return b.smobbed_copy (); } ADD_INTERFACE (Horizontal_bracket, "horizontal-bracket-interface", "A horizontal bracket encompassing notes.", - "columns bracket-flare shorten-pair edge-height"); + + /* props */ + "columns " + "bracket-flare " + "shorten-pair " + "edge-height"); diff --git a/lily/include/horizontal-bracket.hh b/lily/include/horizontal-bracket.hh new file mode 100644 index 0000000000..2645f21798 --- /dev/null +++ b/lily/include/horizontal-bracket.hh @@ -0,0 +1,19 @@ +/* + horizontal-bracket.hh -- declare Horizontal_bracket + + source file of the GNU LilyPond music typesetter + + (c) 2005 Han-Wen Nienhuys +*/ + +#ifndef HORIZONTAL_BRACKET_HH +#define HORIZONTAL_BRACKET_HH + +struct Horizontal_bracket +{ + DECLARE_SCHEME_CALLBACK (print, (SCM)); + static Stencil make_bracket (Grob *, Grob *, Link_array, Axis, Direction); + static bool has_interface (Grob *); +}; + +#endif /* HORIZONTAL_BRACKET_HH */ diff --git a/lily/new-figured-bass-engraver.cc b/lily/new-figured-bass-engraver.cc new file mode 100644 index 0000000000..5398e42a20 --- /dev/null +++ b/lily/new-figured-bass-engraver.cc @@ -0,0 +1,332 @@ +/* + new-figured-bass-engraver.cc -- implement New_figured_bass_engraver + + source file of the GNU LilyPond music typesetter + + (c) 2005 Han-Wen Nienhuys + +*/ + +#include "engraver.hh" + +#include "context.hh" +#include "music.hh" +#include "item.hh" +#include "spanner.hh" +#include "axis-group-interface.hh" +#include "align-interface.hh" +#include "pointer-group-interface.hh" +#include "text-interface.hh" + +#include "translator.icc" + +struct Figure_group +{ + Spanner *group_; + Spanner *continuation_line_; + + SCM number_; + SCM alteration_; + + bool is_continuation_; + Item *figure_item_; + Music *current_music_; + + Figure_group () + { + is_continuation_ = false; + continuation_line_ = 0; + number_ = SCM_EOL; + alteration_ = SCM_EOL; + group_ = 0; + current_music_ = 0; + } +}; + +struct New_figured_bass_engraver : public Engraver +{ + TRANSLATOR_DECLARATIONS(New_figured_bass_engraver); + void finalize_spanners(); + void add_brackets (); +protected: + Array groups_; + Spanner *alignment_; + Link_array new_musics_; + bool continuation_; + Moment stop_moment_; + Music *rest_event_; + + virtual bool try_music (Music *); + virtual void finalize (); + virtual void derived_mark () const; + + void start_translation_timestep (); + void stop_translation_timestep (); + void process_music (); +}; + +void +New_figured_bass_engraver::derived_mark () const +{ + for (int i = 0; i < groups_.size (); i++) + { + scm_gc_mark (groups_[i].number_); + scm_gc_mark (groups_[i].alteration_); + } +} + +void +New_figured_bass_engraver::stop_translation_timestep () +{ + if (groups_.is_empty () + || now_mom ().main_part_ < stop_moment_.main_part_) + return ; + + bool found = false; + for (int i = 0; !found && i < groups_.size (); i++) + found = found || groups_[i].current_music_; + + if (!found) + finalize_spanners (); +} + +New_figured_bass_engraver::New_figured_bass_engraver () +{ + alignment_ = 0; + continuation_ = false; + rest_event_ = 0; +} + +void +New_figured_bass_engraver::start_translation_timestep () +{ + if (now_mom ().main_part_ < stop_moment_.main_part_) + return ; + + rest_event_ = 0; + new_musics_.clear (); + for (int i = 0; i < groups_.size (); i++) + { + groups_[i].current_music_ = 0; + groups_[i].is_continuation_ = false; + } + continuation_ = false; +} + +bool +New_figured_bass_engraver::try_music (Music *m) +{ + if (m->is_mus_type ("rest-event")) + { + rest_event_ = m; + return true; + } + else + { + SCM fig = m->get_property ("figure"); + for (int i = 0; i < groups_.size (); i++) + { + if (ly_is_equal (groups_[i].number_, fig)) + { + groups_[i].current_music_ = m; + groups_[i].is_continuation_ = + ly_is_equal (groups_[i].alteration_, + m->get_property ("alteration")); + + continuation_ = true; + return true; + } + } + + new_musics_.push (m); + + stop_moment_ = now_mom () + m->get_length (); + + return true; + } +} +void +New_figured_bass_engraver::finalize_spanners () +{ + if (!alignment_) + return; + + alignment_ = 0; + groups_.clear (); +} + +void +New_figured_bass_engraver::add_brackets () +{ + Link_array encompass; + bool inside = false; + for (int i = 0; i < groups_.size (); i ++) + { + if (!groups_[i].current_music_) + continue; + + if (to_boolean (groups_[i].current_music_->get_property ("bracket-start"))) + { + inside = true; + } + + if (inside && groups_[i].figure_item_) + encompass.push (groups_[i].figure_item_); + + if (to_boolean (groups_[i].current_music_->get_property ("bracket-stop"))) + { + inside = false; + + Item * brack = make_item ("BassFigureBracket", groups_[i].current_music_->self_scm ()); + for (int j = 0; j < encompass.size (); j++) + { + Pointer_group_interface::add_grob (brack, + ly_symbol2scm ("elements"), + encompass[j]); + } + encompass.clear (); + } + } +} + +void +New_figured_bass_engraver::process_music () +{ + if (rest_event_) + { + finalize_spanners (); + return; + } + + if (!continuation_ + && new_musics_.is_empty ()) + { + finalize_spanners (); + return; + } + + Grob *muscol = dynamic_cast (unsmob_grob (get_property ("currentMusicalColumn"))); + if (!continuation_) + { + finalize_spanners (); + alignment_ = make_spanner ("BassFigureAlignment", SCM_EOL); + alignment_->set_bound (LEFT, muscol); + } + + int k = 0; + for (int i = 0; i < new_musics_.size (); i++) + { + while (k < groups_.size() && + groups_[k].current_music_) + k++; + + if (k >= groups_.size ()) + { + Figure_group group; + groups_.push (group); + } + + + groups_[k].current_music_ = new_musics_[i]; + groups_[k].figure_item_ = 0; + k++; + } + + SCM proc = get_property ("newFiguredBassFormatter"); + + alignment_->set_bound (RIGHT, muscol); + if (to_boolean (get_property ("useBassFigureExtenders"))) + for (int i = 0; i < groups_.size(); i++) + { + if (groups_[i].is_continuation_) + { + if (!groups_[i].continuation_line_) + { + Spanner * line = make_spanner ("BassFigureContinuation", SCM_EOL); + Item * item = groups_[i].figure_item_; + groups_[i].continuation_line_ = line; + line->set_bound (LEFT, item); + + /* + Don't add as child. This will cache the wrong + (pre-break) stencil when callbacks are triggered. + */ + line->set_parent (groups_[i].group_, Y_AXIS); + Pointer_group_interface::add_grob (line, ly_symbol2scm ("figures"), item); + + groups_[i].figure_item_ = 0; + } + } + else + groups_[i].continuation_line_ = 0; + } + + for (int i = 0; i < groups_.size(); i++) + { + Figure_group &group = groups_[i]; + + if (group.continuation_line_) + { + group.continuation_line_->set_bound (RIGHT, muscol); + } + else if (group.current_music_) + { + Item *item + = make_item ("NewBassFigure", + group.current_music_->self_scm ()); + SCM fig = group.current_music_->get_property ("figure"); + if (!group.group_) + { + group.group_ = make_spanner ("BassFigureLine", SCM_EOL); + group.group_->set_bound (LEFT, muscol); + Align_interface::add_element (alignment_, + group.group_, + Align_interface::alignment_callback_proc); + } + + + group.number_ = fig; + group.alteration_ = group.current_music_->get_property ("alteration"); + + SCM text = group.current_music_->get_property ("text"); + if (!Text_interface::is_markup (text) + && ly_is_procedure (proc)) + { + text = scm_call_3 (proc, fig, group.current_music_->self_scm (), + context ()->self_scm ()); + } + + item->set_property ("text", text); + + Axis_group_interface::add_element (group.group_, item); + group.figure_item_ = item; + } + + groups_[i].group_->set_bound (RIGHT, muscol); + } + + add_brackets (); +} + +void +New_figured_bass_engraver::finalize () +{ + finalize_spanners (); +} + + +ADD_TRANSLATOR (New_figured_bass_engraver, + /* doc */ + + "Make figured bass numbers.", + /* create */ + "BassFigure BassFigureLine BassFigureAlignment BassFigureBracket", + + /* accept */ + "bass-figure-event rest-event", + + /* read */ + "useBassFigureExtenders", + + /* write */ + ""); diff --git a/lily/parser.yy b/lily/parser.yy index 0b71a7f5db..0f73f67748 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -212,7 +212,9 @@ make_lyric_combine_music (SCM name, Music *music) deleting them. Let's hope that a stack overflow doesnt trigger a move of the parse stack onto the heap. */ +%left PREC_TOP %left ADDLYRICS +%left PREC_BOT %union { Book *book; @@ -477,8 +479,8 @@ parser.yy:352.8-24: warning: symbol `"\\<"' used more than once as a literal str %type assignment_id %type bare_number %type bass_figure -%type bass_number %type br_bass_figure +%type bass_number %type chord_body_elements %type chord_item %type chord_items @@ -2165,14 +2167,10 @@ tremolo_type: bass_number: DIGIT { - $$ = scm_number_to_string (scm_from_int ($1), scm_from_int (10)); - $$ = scm_list_2 (ly_lily_module_constant ("number-markup"), - $$); + $$ = scm_from_int ($1); } | UNSIGNED { - $$ = scm_number_to_string (scm_from_int ($1), scm_from_int (10)); - $$ = scm_list_2 (ly_lily_module_constant ("number-markup"), - $$); + $$ = scm_from_int ($1); } | STRING { $$ = $1; } | full_markup { $$ = $1; } @@ -2194,9 +2192,17 @@ bass_figure: Music *bfr = MY_MAKE_MUSIC ("BassFigureEvent"); $$ = bfr->self_scm (); - bfr->set_property ("figure", $1); + if (scm_is_number ($1)) + bfr->set_property ("figure", $1); + else if (Text_interface::is_markup ($1)) + bfr->set_property ("text", $1); + bfr->unprotect (); } + | bass_figure ']' { + $$ = $1; + unsmob_music ($1)->set_property ("bracket-stop", SCM_BOOL_T); + } | bass_figure bass_mod { Music *m = unsmob_music ($1); if ($2) { @@ -2210,17 +2216,14 @@ bass_figure: } ; + br_bass_figure: - '[' bass_figure { - $$ = $2; - unsmob_music ($$)->set_property ("bracket-start", SCM_BOOL_T); - } - | bass_figure { + bass_figure { $$ = $1; } - | br_bass_figure ']' { - $$ = $1; - unsmob_music ($1)->set_property ("bracket-stop", SCM_BOOL_T); + | '[' bass_figure { + $$ = $2; + unsmob_music ($$)->set_property ("bracket-start", SCM_BOOL_T); } ; diff --git a/ly/engraver-init.ly b/ly/engraver-init.ly index 5e1560cb24..b96ee5eada 100644 --- a/ly/engraver-init.ly +++ b/ly/engraver-init.ly @@ -552,6 +552,7 @@ AncientRemoveEmptyStaffContext = \context { %% bassFigureFormatFunction = #format-bass-figure + newFiguredBassFormatter = #format-new-bass-figure metronomeMarkFormatter = #format-metronome-markup graceSettings = #`( (Voice Stem direction 1) @@ -596,7 +597,6 @@ AncientRemoveEmptyStaffContext = \context { \name FiguredBass \consists "Figured_bass_engraver" - \consists "Rest_swallow_translator" \consists "Note_swallow_translator" \consists "Skip_event_swallow_translator" \consists "Separating_line_group_engraver" diff --git a/scm/bass-figure.scm b/scm/bass-figure.scm index 46d4af7457..5900673cd8 100644 --- a/scm/bass-figure.scm +++ b/scm/bass-figure.scm @@ -11,6 +11,31 @@ "A bass figure, including bracket" '()) + +(define-public (format-new-bass-figure figure event context) + (let* ((fig (ly:music-property event 'figure)) + (fig-markup (markup #:number (number->string figure 10))) + + (alt (ly:music-property event 'alteration)) + (alt-markup + (if (number? alt) + (alteration->text-accidental-markup alt) + #f)) + (alt-dir (ly:context-property context 'figuredBassAlterationDirection)) + + ) + + (if alt-markup + (set! fig-markup + (markup #:put-adjacent fig-markup X + (if (number? alt-dir) + alt-dir + LEFT) + #:raise .33 + #:pad-around 0.5 #:smaller alt-markup ))) + + fig-markup)) + (define-public (format-bass-figure figures context grob) ;; TODO: support slashed numerals here. (define (fig-to-markup fig-music) diff --git a/scm/define-context-properties.scm b/scm/define-context-properties.scm index d357dc92d8..2eaceda23c 100644 --- a/scm/define-context-properties.scm +++ b/scm/define-context-properties.scm @@ -22,6 +22,11 @@ (lambda (x) (apply translator-property-description x)) `( + + ;; TODO FIXME + (useBassFigureExtenders ,boolean? "") + (figuredBassAlterationDirection ,ly:dir? "") + (aDueText ,string? "Text to print at a unisono passage.") (alignBelowContext ,string? "Where to insert newly created context in vertiical alignment.") (alignAboveContext ,string? "Where to insert newly created context in vertiical alignment.") diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm index 575781f335..d5f68bb606 100644 --- a/scm/define-grobs.scm +++ b/scm/define-grobs.scm @@ -204,6 +204,47 @@ bass-figure-interface self-alignment-interface font-interface)))))) + + (NewBassFigure + . ( + (print-function . ,Text_interface::print) + (meta . ((class . Item) + (interfaces . (text-interface + rhythmic-grob-interface + bass-figure-interface + font-interface)))))) + + (BassFigureBracket + . ((print-function . ,Figured_bass_bracket::print) + (edge-height . (0.2 . 0.2)) + (meta . ((class . Item) + (interfaces . (figured-bass-bracket-interface)) )) + )) + (BassFigureContinuation + . ( + (print-function . ,Figured_bass_continuation::print) + (Y-offset-callbacks . (,Figured_bass_continuation::center_on_figures)) + (meta . ((class . Spanner) + (interfaces . (figured-bass-continuation-interface)) + )))) + (BassFigureLine + . ( + (axes . (,Y)) + (Y-extent-callback . ,Axis_group_interface::group_extent_callback) + (meta . ((class . Spanner) + (interfaces . (axis-group-interface + )))))) + + (BassFigureAlignment + . ( + (axes . (,Y)) + (threshold . (2.4 . 1000)) + (Y-extent-callback . ,Axis_group_interface::group_extent_callback) + (stacking-dir . -1) + (meta . ((class . Spanner) + (interfaces . (align-interface + axis-group-interface)))))) + (Beam . ( ;; todo: clean this up a bit: the list is getting diff --git a/scm/define-markup-commands.scm b/scm/define-markup-commands.scm index 748ef92cfb..484a1c3d88 100644 --- a/scm/define-markup-commands.scm +++ b/scm/define-markup-commands.scm @@ -629,6 +629,30 @@ alignment accordingly." (ly:stencil-aligned-to m X dir))) +(def-markup-command (pad-around layout props amount arg) (number? markup?) + + "Add padding @var{amount} all around @var{arg}. " + + (let* + ((m (interpret-markup layout props arg)) + (x (ly:stencil-extent m X)) + (y (ly:stencil-extent m Y))) + + + (ly:make-stencil (ly:stencil-expr m) + (interval-widen x amount) + (interval-widen y amount)) + )) +(def-markup-command (put-adjacent layout props arg1 axis dir arg2) (markup? integer? ly:dir? markup?) + + "Put @var{arg2} next to @var{arg1}, without moving @var{arg1}. " + + (let* ((m1 (interpret-markup layout props arg1)) + (m2 (interpret-markup layout props arg2))) + + (ly:stencil-combine-at-edge m1 axis dir m2 0.0 0.0) + )) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; property ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -- 2.39.5