]> git.donarmstrong.com Git - lilypond.git/commitdiff
(print): new file. Set limits to
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Fri, 23 Jul 2004 14:55:15 +0000 (14:55 +0000)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Fri, 23 Jul 2004 14:55:15 +0000 (14:55 +0000)
ledger line length to avoid clashes.

ChangeLog
lily/ambitus-engraver.cc
lily/ambitus.cc
lily/ledger-line-spanner.cc
scm/define-grobs.scm

index 4bba2c09a1abd2f19bc082e1ebc4ce8301d2f5b8..ec7e0d88b3e8f612823f77fcea6b0b76f5c5155c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2004-07-23  Han-Wen Nienhuys   <hanwen@xs4all.nl>
 
+       * lily/include/pitch-interval.hh (Pitch>): new file.
+
+       * lily/pitch-interval.cc (add_point): new file.
+
        * lily/ledger-line-engraver.cc: new file.
 
        * lily/ledger-line-spanner.cc (print): new file. Set limits to
index bd8fd0104d73b8cbdc938af26c056cd0911ed6b4..9985bf97c9c1f37ce05c95ef721739d80144265f 100644 (file)
@@ -4,6 +4,9 @@
   source file of the GNU LilyPond music typesetter
 
   (c) 2002--2004 Juergen Reuter <reuter@ipd.uka.de>
+  
+  Han-Wen Nienhuys <hanwen@xs4all.nl
+  
 */
 
 #include "engraver.hh"
 #include "pitch.hh"
 #include "pitch-interval.hh"
 #include "protected-scm.hh"
+#include "side-position-interface.hh"
 
 
-
-/*
- * This class implements an engraver for ambitus grobs.
- *
- * TODO: There are quite some conceptional issues left open:
- *
- * - Many publishers put ambitus _before_ the first occurrence of a
- * clef.  Hence, formally the pitches are undefined in this case.  Of
- * course, one could always silently assume that ambitus pitches refer
- * to the first occurrence of a clef.  Or should we, by default, put
- * the ambitus always after the first clef, if any?
- *
- * - Enharmonically equal pitches: Assume piece contains once a "gis",
- * another time an "aes" as highest pitch.  Which one should be
- * selected for the ambitus grob?  The "aes", because it is
- * musically/notationally "higher" than "gis"?  Or "gis", because (if
- * using pure temperament) it has a slightly higher frequency?  Or
- * that pitch that come closer to the key signature?  But there may be
- * key signature changes in the piece...
- *
- * - Multiple voices in single staff: Assume a vocal piece of music,
- * where the soprano voice and the alto voice are put into the same
- * staff (this is generally a bad idea, but unfortunately common
- * practice).  Then, there probably should be two ambitus grobs, one
- * for each voice.  But how can you see which ambitus grob refers to
- * which voice?  Most probably you can guess it from the fact that the
- * ambitus of the alto voice typically lies in a lower range than that
- * of the soprano voice, but this is just a heuristic rather than a
- * generally valid rule.  In the case of only two voices, using stems
- * in the ambitus grob might help, but probably looks quite ugly.
- *
- * - If a piece consists of several loosely coupled sections, should
- * there be multiple ambitus grobs allowed, one for each section?
- * Then there probably should be some "\ambitus" event added to
- * mudela, stating where an ambitus grob should be placed.  This
- * ambitus grob should then represent the ambitus in the range of time
- * between this "\ambitus" event and the next one (or the end of the
- * piece, if there is no more such event).  To be compliant with the
- * current implementation, we might implicitly assume an "\ambitus"
- * event at the beginning of the piece, but then the question where
- * to put this first ambitus grob (before/after the clef?) becomes
- * even more urgent.
- *
- * - Incipits of transcribed music may need special treatment for
- * ambitus, since, for readability, the ambitus most probably should
- * not refer to the ancient clefs of the incipit, but rather to the
- * clefs used in the transcribed parts.
- */
 class Ambitus_engraver : public Engraver
 {
 public:
@@ -133,8 +89,10 @@ Ambitus_engraver::stop_translation_timestep ()
          heads_[d] = make_item ("AmbitusNoteHead", SCM_EOL);
          accidentals_[d] = make_item ("AmbitusAccidental", SCM_EOL);
          heads_[d]->set_property ("accidental-grob", accidentals_[d]->self_scm ());
+         Side_position_interface::add_support (accidentals_[d], heads_[d]);
        }
       while (flip (&d) != DOWN);
+      ambitus_->set_parent (heads_[DOWN], X_AXIS);
       is_typeset_ = true;
     }
 }
@@ -166,7 +124,7 @@ Ambitus_engraver::finalize ()
       do
        {
          Pitch p = pitch_interval_[d];
-         heads_[d]->set_property ("position",
+         heads_[d]->set_property ("staff-position",
                                   scm_from_int (start_c0_ +
                                                 p.steps ()));
 
index 34b017d9e1472a3d95c65f846fabcf0834338ac8..44953bd4ca113197b8919719a20e8a3c4efe2d7d 100644 (file)
 #include "font-interface.hh"
 #include "output-def.hh"
 #include "lookup.hh"
-
-/*
-  UGH UGH UGH
-
-  This does 3 things at one:
-
-  - acc positioning
-  - drawing accidentals
-  - drawing note heads
-
-  It confuses interpretation & formatting.
-
-  UGH.
-  --hwn.
- */
-
-/*
- * TODO: note-head collision handling
- *
- * TODO: accidentals collision handling
- *
- * TODO: alternative representation: adding the ambitus as text script
- * to the instrument name (e.g. "Soprano (c^1 - f^2)").
- *
- * FIXME: Accidentals are too close at the note heads (it seems that
- * the extent of the ledger lines is ignored).
- *
- * TODO: If (depending on breakAlignOrder) ambitus is put behind
- * key-signature, then do not repeat accidentals that already appear
- * in the key signature.
- *
- * FIXME: A staff containing more than a single context will result in
- * multiple ambitus grobs per staff.  This is basically ok, but there is
- * currently no proper collision handling for this case.
- *
- * TODO: make ignore_octave and force_accidental of function
- * number_accidentals accessible via grob properties.
- */
-
-/**
-  Given a pitch and a key_signature, decide what accidentals to show.
-  Possible return values:
-  0: do not show any accidental
-  1: show pitch->alteration_ only
-  2: show pitch->get_alteration, preceded by a natural sign
-
-  UGH: code duplication! See accidental-engraver.
- */
-static int
-number_accidentals (SCM key_signature, Pitch *pitch,
-                   bool ignore_octave_b, bool force_accidental)
-{
-  int notename = pitch->get_notename ();
-  int octave = pitch->get_octave ();
-  int alteration = pitch->get_alteration ();
-
-  if (force_accidental) // ignore key signature
-    return 1;
-
-  
-#if DEBUG_AMBITUS
-  scm_display (key_signature, scm_current_output_port ());
-#endif
-
-  SCM prev;
-  if (ignore_octave_b)
-    prev = ly_assoc_cdr (scm_int2num (notename), key_signature);
-  else
-    prev = scm_assoc (scm_cons (scm_int2num (octave), scm_int2num (notename)),
-                    key_signature);
-
-  /* should really be true unless prev == SCM_BOOL_F */
-  if (ly_c_pair_p (prev) && ly_c_pair_p (ly_cdr (prev)))
-    {
-      prev = scm_cons (ly_car (prev), ly_cadr (prev));
-    }
-
-  /* If an accidental was not found */
-  if (prev == SCM_BOOL_F)
-    prev = scm_assoc (scm_int2num (notename), key_signature);
-
-  SCM prev_acc = (prev == SCM_BOOL_F) ? scm_int2num (0) : ly_cdr (prev);
-  int sig_alteration = ly_c_number_p (prev_acc) ? ly_scm2int (prev_acc) : 0;
-
-  if (alteration == sig_alteration) // no accidental at all needed
-    return 0;
-
-  if ((alteration == 0) && (sig_alteration != 0)) // need ordinary natural
-    return 2;
-
-  if (sig_alteration == 0) // use pitch's alteration
-    return 1;
-
-  return 2;
-}
-
-
-
-void
-add_accidentals (Item *me, Stencil *head, int num_acc,
-                Pitch *pitch, String accidentals_style, Real yoffs)
-{
-  if (!num_acc)
-    return;
-  if (pitch->get_alteration ())
-    {
-      Stencil accidental (Font_interface::get_default_font (me)->
-                          find_by_name (String ("accidentals-") +
-                                        accidentals_style +
-                                        to_string (pitch->get_alteration ())));
-      accidental.translate_axis (yoffs, Y_AXIS);
-      head->add_at_edge (X_AXIS,  LEFT, accidental, 0.1, 0);
-    }
-  if (num_acc == 2)
-    {
-      Stencil natural (Font_interface::get_default_font (me)->
-                       find_by_name (String ("accidentals-") +
-                                     accidentals_style +
-                                     to_string ("0")));
-      natural.translate_axis (yoffs, Y_AXIS);
-      head->add_at_edge (X_AXIS,  LEFT, natural, 0.1, 0);
-    }
-}
+#include "group-interface.hh"
 
 MAKE_SCHEME_CALLBACK (Ambitus,print,1);
 SCM
@@ -149,87 +24,46 @@ Ambitus::print (SCM smob)
   Item *me = (Item*) unsmob_grob (smob);
   Stencil stencil;
 
-  SCM scm_note_head_style = me->get_property ("note-head-style");
-  String note_head_style;
-  if (ly_c_symbol_p (scm_note_head_style))
-    {
-      String note_head_style =
-       ly_symbol2string (scm_note_head_style);
-    }
-  else
-    {
-      note_head_style = String ("noteheads-2");
-    }
-  if (Font_interface::get_default_font (me)->find_by_name (note_head_style).is_empty ())
-    {
-      String message = "Ambitus: no such note head: `" + note_head_style + "'";
-      me->warning (_ (message.to_str0 ()));
-      return SCM_EOL;
-    }
-
-  /*
-    FIXME: Use positions. 
-   */
-  int p_min, p_max;
-  Slice posns = get_positions(me);
-  
-  p_min = posns[LEFT];
-  p_max = posns[RIGHT];
-
-  // create heads
-  Stencil head_min =
-    Font_interface::get_default_font (me)->find_by_name (note_head_style);
-  head_min.translate_axis (0.5*p_min, Y_AXIS);
-  Stencil head_max =
-    Font_interface::get_default_font (me)->find_by_name (note_head_style);
-  head_max.translate_axis (0.5*p_max, Y_AXIS);
-
   // join heads
-  if (to_boolean (me->get_property ("join-heads")) &&
-      ((p_max - p_min) >= 3))
+  Link_array<Grob> heads (Pointer_group_interface__extract_grobs (me, (Grob*)0, "note-heads"));
+  if (to_boolean (me->get_property ("join-heads"))
+      && heads.size() > 1)
     {
-      Real linethickness = me->get_paper ()->get_dimension (ly_symbol2scm ("linethickness"));
-      Real blotdiameter = me->get_paper ()->get_dimension (ly_symbol2scm ("blotdiameter"));
-      Interval x_extent = 0.5 * Interval (-linethickness, +linethickness);
-      Interval y_extent = 0.5 * Interval (p_min + 1.35, p_max - 1.35);
-      Box line_box (x_extent, y_extent);
-      Stencil line = Lookup::round_filled_box (line_box, blotdiameter);
-      line.translate_axis (0.5 * head_min.extent (X_AXIS).length (), X_AXIS);
-      stencil.add_stencil (line);
+      Grob *common
+       = common_refpoint_of_array (heads.slice (0,2), me, Y_AXIS);
+
+      Grob *minh = heads[0];
+      Grob *maxh = heads[1];
+      
+      if (minh->relative_coordinate (common, Y_AXIS) >
+         maxh->relative_coordinate (common, Y_AXIS))
+       {
+         maxh = heads[0];
+         minh = heads[0];
+       }
+
+      Real pad = 1.35;
+      Real pmax = maxh->relative_coordinate (common, Y_AXIS) - pad;
+      Real pmin = minh->relative_coordinate (common, Y_AXIS) + pad;
+      
+      if (pmin < pmax)
+       {
+         Real linethickness = me->get_paper ()->get_dimension (ly_symbol2scm ("linethickness"));
+         Real blotdiameter = me->get_paper ()->get_dimension (ly_symbol2scm ("blotdiameter"));
+         Interval x_extent = 0.5 * Interval (-linethickness, +linethickness);
+         Interval y_extent = 0.5 * Interval (pmin, pmax);
+         Box line_box (x_extent, y_extent);
+
+         Stencil line = Lookup::round_filled_box (line_box, blotdiameter);
+         line.translate_axis (- me-> relative_coordinate (common, Y_AXIS),
+                                  Y_AXIS);
+         return line.smobbed_copy ();
+       }
     }
 
-  
-  // add accidentals
-  SCM key_signature = me->get_property ("key-signature");
-  SCM scm_accidentals_style = me->get_property ("accidentals-style");
-  String accidentals_style;
-  if (ly_c_symbol_p (scm_accidentals_style))
-    {
-      accidentals_style =
-       ly_symbol2string (scm_accidentals_style);
-    }
-  else
-    {
-      accidentals_style = String ("");
-    }
-  
-  int num_acc;
-  Pitch *pitch_min = unsmob_pitch (me->get_property ("pitch-min"));
-  Pitch *pitch_max = unsmob_pitch (me->get_property ("pitch-max"));
-  num_acc = number_accidentals (key_signature, pitch_min, true, false);
-  add_accidentals (me, &head_min, num_acc, pitch_min,
-                  accidentals_style, 0.5 * p_min);
-  num_acc = number_accidentals (key_signature, pitch_max, true, false);
-  add_accidentals (me, &head_max, num_acc, pitch_max,
-                  accidentals_style, 0.5 * p_max);
-
-  // add heads
-  stencil.add_stencil (head_min);
-  stencil.add_stencil (head_max);
-
-  return stencil.smobbed_copy ();
+  return SCM_EOL;
 }
 
 ADD_INTERFACE (Ambitus, "ambitus-interface",
-  "An object that represents the pitch range of a voice.",
-  "c0-position pitch-min pitch-max accidentals note-head-style accidentals-style join-heads");
+  "The line between note heads for a pitch range.",
+  "note-heads join-heads");
index 6bc1b830c69e7eb4bc30fac66e573ee06040cca0..ca54f00089789ea7f73543a06f68fbeff47a255d 100644 (file)
@@ -107,9 +107,8 @@ Ledger_line_spanner::print (SCM smob)
 {
   Spanner *me = dynamic_cast<Spanner*> (unsmob_grob (smob));
   Link_array<Grob> heads (Pointer_group_interface__extract_grobs (me, (Grob*)0, "note-heads"));
-  Link_array<Grob> ambituses (Pointer_group_interface__extract_grobs (me, (Grob*)0, "ambituses"));
 
-  if (heads.is_empty () && ambituses.is_empty ())
+  if (heads.is_empty ())
     return SCM_EOL;
     
   Stencil ledgers;
@@ -121,7 +120,6 @@ Ledger_line_spanner::print (SCM smob)
     {
       Axis a = Axis (i);
       common[a] = common_refpoint_of_array (heads, me, a);
-      common[a] = common_refpoint_of_array (ambituses, common[a], a);
       for (int i = heads.size (); i--; )
        if (Grob * g = unsmob_grob (me->get_property ("accidental-grob")))
          common[a] = common[a]->common_refpoint (g, a);
@@ -237,30 +235,7 @@ Ledger_line_spanner::print (SCM smob)
        }
     }
 
-  /* create  ledgers for ambitus.
 
-  TODO: split off separate function
-
-  */      
-  for (int i = ambituses.size (); i--; )
-    {
-      Item *a = dynamic_cast<Item*> (ambituses[i]);
-      Interval x_ext = ambituses[i]->extent (common[X_AXIS], X_AXIS);
-      x_ext.widen (length_fraction * x_ext.length ());
-      
-      Slice ps (Ambitus::get_positions (a));
-      Direction d = DOWN; 
-      do
-       {
-         if (abs (ps[d]) > interspaces + 1)
-           ledgers.add_stencil (brew_ledger_lines (staff, ps[d], interspaces,
-                                                   halfspace,
-                                                   ledgerlinethickness,
-                                                   x_ext, 0.0));
-       }
-      while (flip (&d) != DOWN);
-    }
-      
   ledgers.translate_axis (-me->relative_coordinate (common[X_AXIS], X_AXIS),
                          X_AXIS);
   
index 373e46dbbdd6b757e14975a24a089c64f2dde259..00b9e655df0e7eb20c85e5654081674152d906b0 100644 (file)
        (breakable . #t)
        (break-align-symbol . ambitus)
        (print-function . ,Ambitus::print)
-       (font-family . music)
-       (note-head-style . "noteheads-2")
-       (break-visibility . ,begin-of-line-visible)
        (join-heads . #t)
+       (break-visibility . ,begin-of-line-visible)
        (space-alist . (
                       (clef . (extra-space . 0.0))
                       (key-signature . (extra-space . 0.0))
                       ))
        (meta . ((interfaces . (ambitus-interface staff-symbol-referencer-interface break-aligned-interface item-interface  font-interface))))
        ))
+    (AmbitusAccidental
+     . (
+       (print-function . ,Accidental_interface::print)
+       (font-family . music)
+       (X-offset-callbacks . (,Side_position_interface::aligned_side))
+       (direction . -1) 
+       (cautionary-style . parentheses)
+       (after-line-breaking-callback . ,Accidental_interface::after_line_breaking)             (meta . ((interfaces . (item-interface accidental-interface font-interface))))
+       ))
     (AmbitusNoteHead
      . (
+       (duration-log . 2)
        (style . default)
        (breakable . #t)
        (print-function . ,Note_head::print)
        (break-align-symbol . ambitus)
+        (break-visibility . ,begin-of-line-visible)
        (glyph-name-procedure . ,find-notehead-symbol)
        (X-extent-callback . ,Note_head::extent)
        (Y-extent-callback . ,Note_head::extent)