From: Han-Wen Nienhuys Date: Sun, 5 Nov 2006 22:05:55 +0000 (+0100) Subject: rewrite balloon-text support. This is now a separate grob, with its X-Git-Tag: release/2.10.0-2~32^2~12 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=b53ca26b6a62e30c75b758d17bcdab530cba1e2b;p=lilypond.git rewrite balloon-text support. This is now a separate grob, with its victim as the parent. This involves adding Balloon_engraver, AnnotateOutputEvent, annotate-output-event, \balloonText, \balloonGrobText, and modifying Balloon_interface::print. --- diff --git a/Documentation/topdocs/NEWS.tely b/Documentation/topdocs/NEWS.tely index c8ee8888d5..8343acd721 100644 --- a/Documentation/topdocs/NEWS.tely +++ b/Documentation/topdocs/NEWS.tely @@ -65,6 +65,17 @@ which scares away people. * only show user-visible changes. @end ignore +@item Balloon texts can be entered more ergonomically, and are no +longer clipped from the output. + +@lilypond[fragment,ragged-right,relative=1] +\new Voice \with {\consists "Balloon_engraver" } +{ + \balloonGrobText #'Stem #'(3 . 4) \markup { "I'm a Stem" } + 8 +} +@end lilypond + @item Slurs now avoid clefs and key changes. diff --git a/Documentation/user/advanced-notation.itely b/Documentation/user/advanced-notation.itely index 1604f37544..b327f8aec1 100644 --- a/Documentation/user/advanced-notation.itely +++ b/Documentation/user/advanced-notation.itely @@ -2061,17 +2061,18 @@ balloon. The primary purpose of this feature is to explain notation. The following example demonstrates its use. @lilypond[quote,verbatim,fragment,ragged-right,relative=2] -\applyOutput #'Voice - #(add-balloon-text 'NoteHead "heads, or tails?" - '(1 . -3)) - c8 +\new Voice \with { \consists "Balloon_engraver" } +{ + \balloonGrobText #'Stem #'(3 . 4) \markup { "I'm a Stem" } + 8 +} @end lilypond @noindent -The function @code{add-balloon-text} takes the name of a grob, the -label to print, and the position where to put the label relative to -the object. In the above example, the text ``heads or tails?'' ends -3 spaces below and 1 space to the right of the marked head. +There are two music functions, @code{balloonText} and +@code{balloonGrobText}. The latter takes the name of the grob to +adorn, while the former may be used as an articulation on a note. +The other arguments are the offset and the text of the label. @cindex balloon @cindex notation, explaining diff --git a/THANKS b/THANKS index 5519d5bb0e..c2eeb461e1 100644 --- a/THANKS +++ b/THANKS @@ -76,6 +76,7 @@ Keith Packard Kieren MacMillan Lee T. Wilkirson Lieke van der Meer +Manuzhai Mark Dewey Marcus Macauley Markus Schneider diff --git a/input/regression/balloon.ly b/input/regression/balloon.ly index 8f1ab2b8e9..548dae058f 100644 --- a/input/regression/balloon.ly +++ b/input/regression/balloon.ly @@ -1,31 +1,18 @@ \header { + texidoc = "With balloon texts, objects in the output can be marked, with lines and explanatory text added." + } -\version "2.9.6" +\version "2.9.28" \layout{ ragged-right = ##t } +\new Voice \with {\consists "Balloon_engraver" } { - \relative c' { - - %% by hand: - \once\override Stem #'stencil = #ly:balloon-interface::print - \once\override Stem #'original-stencil = #ly:stem::print - \once\override Stem #'balloon-text = #"I'm a stem" - \once\override Stem #'balloon-text-offset = #'(3 . 4) - \once\override Stem #'balloon-text-props - = #'((font-family . roman)) - - - %% use predefd function. - \applyOutput #'Voice #(add-balloon-text - 'NoteHead "heads, or tails?" - '(0 . -3)) - - - c8 + \balloonGrobText #'Stem #'(3 . 4) \markup { "I'm a Stem" } + 8 } } diff --git a/lily/balloon-engraver.cc b/lily/balloon-engraver.cc new file mode 100644 index 0000000000..374d6913d8 --- /dev/null +++ b/lily/balloon-engraver.cc @@ -0,0 +1,88 @@ +/* + balloon-engraver.cc -- implement Balloon_engraver + + source file of the GNU LilyPond music typesetter + + (c) 2006 Han-Wen Nienhuys + +*/ + +#include "engraver.hh" + + +#include "stream-event.hh" +#include "item.hh" + +#include "translator.icc" + +class Balloon_engraver : public Engraver +{ + TRANSLATOR_DECLARATIONS(Balloon_engraver); + + DECLARE_TRANSLATOR_LISTENER(annotate_output); + DECLARE_ACKNOWLEDGER(grob); + vector events_; + + void stop_translation_timestep (); + + void balloonify (Grob *, Stream_event *); +}; + +IMPLEMENT_TRANSLATOR_LISTENER (Balloon_engraver, annotate_output); +void +Balloon_engraver::listen_annotate_output (Stream_event *ev) +{ + events_.push_back (ev); +} + +void +Balloon_engraver::stop_translation_timestep () +{ + events_.clear (); +} + +Balloon_engraver::Balloon_engraver () +{ +} + +void +Balloon_engraver::balloonify (Grob *g, Stream_event *event) +{ + Grob * b = make_item ("BalloonTextItem", event->self_scm ()); + b->set_property ("text", event->get_property ("text")); + b->set_parent (g, Y_AXIS); + b->set_parent (g, X_AXIS); +} + +void +Balloon_engraver::acknowledge_grob (Grob_info info) +{ + Stream_event *cause = info.event_cause (); + + SCM arts = cause ? cause->get_property ("articulations") : SCM_EOL; + for (SCM s = arts; scm_is_pair (s); s = scm_cdr (s)) + { + Stream_event *e = unsmob_stream_event (scm_car (s)); + if (e->in_event_class ("annotate-output-event")) + { + balloonify (info.grob (), e); + } + } + + for (vsize i = 0; i < events_.size (); i++) + { + if (info.grob ()->name () == ly_symbol2string (events_[i]->get_property ("symbol"))) + balloonify (info.grob (), events_[i]); + } +} + + + +ADD_ACKNOWLEDGER(Balloon_engraver,grob); + +ADD_TRANSLATOR(Balloon_engraver, + "Create balloon texts", + "BalloonTextItem ", + /*read*/ "", + /*write*/ "" + ); diff --git a/lily/balloon.cc b/lily/balloon.cc index 560a2f6675..03477d9ba4 100644 --- a/lily/balloon.cc +++ b/lily/balloon.cc @@ -28,42 +28,33 @@ Balloon_interface::print (SCM smob) { Grob *me = unsmob_grob (smob); - SCM stil = me->get_property ("original-stencil"); - if (!unsmob_stencil (stil)) - return stil; + Grob *p = me->get_parent (X_AXIS); + + Offset off(me->relative_coordinate (p, X_AXIS), + me->relative_coordinate (p, Y_AXIS)); - SCM scm_off = me->get_property ("balloon-text-offset"); + Box b (p->extent (p, X_AXIS), + p->extent (p, Y_AXIS)); - if (!is_number_pair (scm_off)) - return stil; - - Offset off = ly_scm2offset (scm_off); - Stencil *s = unsmob_stencil (stil); - Box orig_extent = s->extent_box (); - Box box_extent = orig_extent; - - Real w = robust_scm2double (me->get_property ("balloon-padding"), .1); - box_extent.widen (w, w); + Real padding = robust_scm2double (me->get_property ("padding"), .1); + b.widen (padding, padding); // FIXME - Stencil fr = Lookup::frame (box_extent, 0.1, 0.05); - - fr.add_stencil (*s); + Stencil fr = Lookup::frame (b, 0.1, 0.05); - SCM bt = me->get_property ("balloon-text"); + SCM bt = me->get_property ("text"); SCM chain = Font_interface::text_font_alist_chain (me); - chain = scm_cons (me->get_property ("balloon-text-props"), chain); - SCM text = Text_interface::interpret_markup (me->layout ()->self_scm (), + SCM stencil = Text_interface::interpret_markup (me->layout ()->self_scm (), chain, bt); - Stencil *text_stil = unsmob_stencil (text); + Stencil *text_stil = unsmob_stencil (stencil); Offset z1; for (int i = X_AXIS; i < NO_AXES; i++) { Axis a ((Axis)i); - z1[a] = box_extent [a].linear_combination (sign (off[a])); + z1[a] = b[a].linear_combination (sign (off[a])); text_stil->align_to (a, -sign (off[a])); } @@ -74,7 +65,7 @@ Balloon_interface::print (SCM smob) text_stil->translate (z2); fr.add_stencil (*text_stil); - fr = Stencil (orig_extent, fr.expr ()); + fr.translate (-off); return fr.smobbed_copy (); } @@ -82,9 +73,7 @@ ADD_INTERFACE (Balloon_interface, "text-balloon-interface", "A collection of routines to put text balloons around an object.", /* properties */ - "balloon-padding " - "balloon-text-props " - "balloon-text-offset " - "balloon-text " - "original-stencil "); + "padding " + "text " + ); diff --git a/ly/music-functions-init.ly b/ly/music-functions-init.ly index 35cf74296e..1dda0e187a 100644 --- a/ly/music-functions-init.ly +++ b/ly/music-functions-init.ly @@ -98,6 +98,24 @@ applyContext = 'origin location 'procedure proc)) + +balloonText = +#(define-music-function (parser location offset text) (number-pair? markup?) + + (make-music 'AnnotateOutputEvent + 'X-offset (car offset) + 'Y-offset (cdr offset) + 'text text)) + +balloonGrobText = +#(define-music-function (parser location grob-name offset text) (symbol? number-pair? markup?) + + (make-music 'AnnotateOutputEvent + 'symbol grob-name + 'X-offset (car offset) + 'Y-offset (cdr offset) + 'text text)) + bar = #(define-music-function (parser location type) (string?) diff --git a/scm/define-event-classes.scm b/scm/define-event-classes.scm index 951c0e7641..e7d59622d4 100644 --- a/scm/define-event-classes.scm +++ b/scm/define-event-classes.scm @@ -13,17 +13,19 @@ (StreamEvent . (RemoveContext ChangeParent Override Revert UnsetProperty SetProperty music-event OldMusicEvent CreateContext Prepare - OneTimeStep Finish)) - (music-event . (arpeggio-event breathing-event extender-event span-event + OneTimeStep Finish)) + (music-event . (annotate-output-event + arpeggio-event breathing-event extender-event span-event rhythmic-event dynamic-event break-event percent-event key-change-event string-number-event stroke-finger-event tie-event part-combine-event beam-forbid-event script-event tremolo-event bend-after-event fingering-event glissando-event harmonic-event hyphen-event laissez-vibrer-event mark-event - multi-measure-text-event note-grouping-event + multi-measure-text-event note-grouping-event pes-or-flexa-event repeat-tie-event spacing-section-event layout-instruction-event)) - (layout-instruction-event . (apply-output-event)) + + (layout-instruction-event . (apply-output-event )) (script-event . (articulation-event text-script-event)) (part-combine-event . (solo-one-event solo-two-event unisono-event)) (break-event . (line-break-event page-break-event page-turn-event)) diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm index 3ad6b22bff..3c1988c9c8 100644 --- a/scm/define-grobs.scm +++ b/scm/define-grobs.scm @@ -144,6 +144,14 @@ side-position-interface font-interface)))))) + (BalloonTextItem + . ((stencil . ,ly:balloon-interface::print) + (text . ,(grob::calc-property-by-copy 'text)) + (X-offset . ,(grob::calc-property-by-copy 'X-offset)) + (Y-offset . ,(grob::calc-property-by-copy 'Y-offset)) + (meta . ((class . Item) + (interfaces . (text-interface + font-interface)))))) (BarLine . ( (break-align-symbol . staff-bar) @@ -920,7 +928,7 @@ (LyricText . ( (stencil . ,lyric-text::print) - (text . ,lyric-text::calc-text) + (text . ,(grob::calc-property-by-copy 'text)) (X-offset . ,ly:self-alignment-interface::aligned-on-x-parent) (self-alignment-X . 0) (word-space . 0.6) diff --git a/scm/define-music-properties.scm b/scm/define-music-properties.scm index 09f2a14b96..b9901d5d86 100644 --- a/scm/define-music-properties.scm +++ b/scm/define-music-properties.scm @@ -16,6 +16,9 @@ (map (lambda (x) (apply music-property-description x)) `( + (X-offset ,number? "Offset of resulting grob; only used for balloon texts.") + (Y-offset ,number? "Offset of resulting grob; only used for balloon texts. ") + (alteration ,number? "alteration for figured bass") (absolute-octave ,integer? diff --git a/scm/define-music-types.scm b/scm/define-music-types.scm index fde38a1804..99036e4ed4 100644 --- a/scm/define-music-types.scm +++ b/scm/define-music-types.scm @@ -30,12 +30,19 @@ Syntax: @var{note}@code{\\x}, where x is one of \\ppp, \\pp, \\p, \\mp, \\mf, \\f, \\ff, \\fff.") (types . (general-music event dynamic-event absolute-dynamic-event)) )) + + (AnnotateOutputEvent + . ((description . "Print an annotation of an output element.") + (types . (general-music event annotate-output-event)) + )) + (ApplyContext . ( (description . "Call the argument with the current context during interpreting phase") (types . (general-music apply-context)) (iterator-ctor . ,ly:apply-context-iterator::constructor) )) + (ApplyOutputEvent . ( (description . " @@ -95,6 +102,7 @@ is an articulation (such as @code{-.}, @code{->}, @code{\\tenuto}, (types . (general-music event rhythmic-event bass-figure-event)) )) + (BeamEvent . ( (description . "Starts or stops a beam. diff --git a/scm/output-lib.scm b/scm/output-lib.scm index 0087169af5..d918290d21 100644 --- a/scm/output-lib.scm +++ b/scm/output-lib.scm @@ -458,8 +458,8 @@ centered, X==1 is at the right, X == -1 is at the left." (make-tied-lyric-markup text) text)))) -(define-public (lyric-text::calc-text grob) - (ly:event-property (event-cause grob) 'text)) +(define-public ((grob::calc-property-by-copy prop) grob) + (ly:event-property (event-cause grob) prop)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; fret boards