]> git.donarmstrong.com Git - lilypond.git/commitdiff
rewrite balloon-text support. This is now a separate grob, with its
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Sun, 5 Nov 2006 22:05:55 +0000 (23:05 +0100)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Sun, 5 Nov 2006 22:05:55 +0000 (23:05 +0100)
victim as the parent. This involves adding
Balloon_engraver, AnnotateOutputEvent, annotate-output-event,
\balloonText, \balloonGrobText, and modifying Balloon_interface::print.

12 files changed:
Documentation/topdocs/NEWS.tely
Documentation/user/advanced-notation.itely
THANKS
input/regression/balloon.ly
lily/balloon-engraver.cc [new file with mode: 0644]
lily/balloon.cc
ly/music-functions-init.ly
scm/define-event-classes.scm
scm/define-grobs.scm
scm/define-music-properties.scm
scm/define-music-types.scm
scm/output-lib.scm

index c8ee8888d594526ce74a543ee0c07ec5cfb3ef6b..8343acd721125a447e24d2d44febda6296c14db0 100644 (file)
@@ -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" }
+  <c-\balloonText #'(-2 . -2) \markup { \simple #"hoi" }  >8
+}
+@end lilypond
 
 @item Slurs now avoid clefs and key changes.
  
index 1604f37544cd6400792337764a97bdb0c2112ea4..b327f8aec1f93e56c711d8200c65efdbdf995ed2 100644 (file)
@@ -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" }
+  <c-\balloonText #'(-2 . -2) \markup { Hello }  >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 5519d5bb0eb09779ecfeb388d2fddb2ed1b9e20a..c2eeb461e19774b3e4a36747d8def8134ea74e38 100644 (file)
--- 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
index 8f1ab2b8e9aace3796e1dae716cfcf87ad1e5d56..548dae058feb91391d84c558248d364301928bcf 100644 (file)
@@ -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" }
+    <c-\balloonText #'(-2 . -2) \markup { \simple #"hoi" }  >8
   }
 }
diff --git a/lily/balloon-engraver.cc b/lily/balloon-engraver.cc
new file mode 100644 (file)
index 0000000..374d691
--- /dev/null
@@ -0,0 +1,88 @@
+/* 
+  balloon-engraver.cc -- implement Balloon_engraver
+  
+  source file of the GNU LilyPond music typesetter
+  
+  (c) 2006 Han-Wen Nienhuys <hanwen@lilypond.org>
+  
+*/
+
+#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<Stream_event *> 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*/ ""
+              );
index 560a2f667586ec4ca0eb2fd51067f9a0bb98d8b4..03477d9ba4c80536fcb14efbf1959ab2b3f8777b 100644 (file)
@@ -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 "
+              );
 
index 35cf74296e27b2449533d4d4c1803630b7d786ca..1dda0e187ad0ce979fbc4e7b7e66c8c1354fd15a 100644 (file)
@@ -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?)
index 951c0e7641777ac36846ad6642bfc7b7dbc8ed03..e7d59622d4fec6af82016cdbe0d3c73cd4364f07 100644 (file)
     (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))
index 3ad6b22bff125b113e77982f4eac300a2ae2340d..3c1988c9c8c027cf52bf50040da70610eb3856a7 100644 (file)
                                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)
     (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)
index 09f2a14b96b8650903e2e8f7460799ca80617ccf..b9901d5d86793efc0478a40a62b9a15b1e6090bb 100644 (file)
@@ -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?
index fde38a1804d9867bbb460a4d0e82f441bc90de09..99036e4ed49f9c0fea41f5e0878a51bad20a3187 100644 (file)
@@ -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.  
index 0087169af5f6eefe0ce879e856d013ee50a10744..d918290d218fc1e3f016f98373a3ef845b18123e 100644 (file)
@@ -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