]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/custos.cc
Run `make grand-replace'.
[lilypond.git] / lily / custos.cc
index 5fc7266b18023bc998dc3b8c04ac7d04fff8f454..5ef96c58683261633e54fd949fa8e98b87c34738 100644 (file)
 
   source file of the GNU LilyPond music typesetter
 
(C) 2000, 2002 Juergen Reuter <reuter@ipd.uka.de>
 (c) 2000--2008 Juergen Reuter <reuter@ipd.uka.de>
 */
 
 /* TODO:
 
- - merge create_ledger_line () and Note_head::create_ledger_line ()
-
- - rewrite create_ledger_line () to support short and thin ledger lines
-
- - do not show if a clef change immediately follows in the next line
-
- - decide: do or do not print custos if the next line starts with a rest
+- do not show if a clef change immediately follows in the next line
 
+- decide: do or do not print custos if the next line starts with a rest
 */
 
+#include <cstdio>
+#include <cmath> // rint
+using namespace std;
 
-#include <stdio.h>
-#include "direction.hh"
-#include "staff-symbol-referencer.hh"
 #include "custos.hh"
-#include "molecule.hh"
-#include "debug.hh"
-#include "note-head.hh"
-#include "item.hh"
+#include "direction.hh"
 #include "font-interface.hh"
-#include "math.h" // rint
-
-/*
-   This function is a patched and hopefully much more understandable
-   rewrite of Note_head::ledger_line ().  It still has some
-   bugs/limitations:
- *
- (1) The term thick/2 probably should be thick*2 (probably a bug,
-   see the code below).
- *
- (2) The minimal width of the resulting ledger line equals the width
-   of the noteheads-ledgerending symbol (a limitation):
- *
- (---- left ledger ending
-     ----) right ledger ending
- (---) resulting ledger line (just ok)
- *
-   If x_extent ("xwid" in Note_head) is less than the width of the
-   ledger ending, the width of the total ledger line is even *greater*
-   than the width of a ledger ending (I would call this a bug).  In
-   the below code, the condition "if (x_extent.length () >
-   slice_x_extent.length ())" avoids outputting the left ending in such
-   cases (rather a silly workaround, but better than nothing).
- *
- (---- left ledger ending
-     ----)   right ledger ending
- (-)   desired ledger line
-     ------- resulting ledger line (too long)
-     ----)   resulting ledger line with additional "if" (still too long)
- *
-   The algorithm works properly only for a desired ledger line width
-   greater than the width of the ledger ending:
- *
- (----    left ledger ending
-        ----) right ledger ending
- (------) desired ledger line
- (------) resulting ledger line (ok)
- *
- * (3) The thickness of the ledger line is fixed (limitation).
- */
-Molecule
-Custos::create_ledger_line (Interval x_extent, Grob *me) 
-{
-  Molecule line;
-  Molecule slice = Font_interface::get_default_font (me)->find_by_name ("noteheads-ledgerending");
-  Interval slice_x_extent = slice.extent (X_AXIS);
-  Interval slice_y_extent = slice.extent (Y_AXIS);
-
-  // Create left ending of ledger line.
-  Molecule left_ending = slice;
-  left_ending.translate_axis (x_extent[LEFT] - slice_x_extent[LEFT], X_AXIS);
-  if (x_extent.length () > slice_x_extent.length ())
-    line.add_molecule (left_ending);
-
-  // Create right ending of ledger line.
-  Molecule right_ending = slice;
-  right_ending.translate_axis (x_extent[RIGHT] - slice_x_extent[RIGHT],
-                              X_AXIS);
-  line.add_molecule (right_ending);
-
-  // Fill out space between left and right ending of ledger line by
-  // lining up a series of slices in a row between them.
-  Molecule fill_out_slice = left_ending;
-  Real thick = slice_y_extent.length ();
-  Real delta_x = slice_x_extent.length () - thick;
-  Real xpos = x_extent [LEFT] + 2*delta_x + thick/2; // TODO: check: thick*2?
-  while (xpos <= x_extent[RIGHT])
-    {
-      fill_out_slice.translate_axis (delta_x, X_AXIS);
-      line.add_molecule (fill_out_slice);
-      xpos += delta_x;
-    }
-
-  return line;
-}
-
-void
-Custos::add_streepjes (Grob* me,
-                  int pos,
-                  int interspaces,
-                  Molecule* custos_p_)
-{
-  // TODO: This is (almost) duplicated code (see
-  // Note_head::brew_molecule).  Junk me.
-  Real inter_f = Staff_symbol_referencer::staff_space (me)/2;
-  int streepjes_i = abs (pos) < interspaces
-    ? 0
-    : (abs (pos) - interspaces) /2;
-  if (streepjes_i) 
-    {
-      Direction dir = (Direction)sign (pos);
-      Molecule ledger_line (create_ledger_line (custos_p_->extent (X_AXIS),
-                                               me));
-      ledger_line.set_empty (true);
-      Real offs = (Staff_symbol_referencer::on_staffline (me))
-       ? 0.0
-       : -dir * inter_f;
-      for (int i = 0; i < streepjes_i; i++)
-       {
-         Molecule streep (ledger_line);
-         streep.translate_axis (-dir * inter_f * i * 2 + offs,
-                                Y_AXIS);
-         custos_p_->add_molecule (streep);
-       }
-    }
-}
+#include "international.hh"
+#include "item.hh"
+#include "note-head.hh"
+#include "staff-symbol-referencer.hh"
+#include "warn.hh"
 
-MAKE_SCHEME_CALLBACK (Custos,brew_molecule,1);
+MAKE_SCHEME_CALLBACK (Custos, print, 1);
 SCM
-Custos::brew_molecule (SCM smob)
+Custos::print (SCM smob)
 {
   Item *me = (Item *)unsmob_grob (smob);
-  SCM scm_style = me->get_grob_property ("style");
 
-  if (gh_symbol_p (scm_style))
+  SCM scm_style = me->get_property ("style");
+  string style;
+  if (scm_is_symbol (scm_style))
+    style = ly_symbol2string (scm_style);
+  else
+    style = "mensural";
+
+  /*
+   * Shall we use a common custos font character regardless if on
+   * staffline or not, or shall we use individual font characters
+   * for both cases?
+   */
+  bool adjust = true;
+
+  int neutral_pos = robust_scm2int (me->get_property ("neutral-position"), 0);
+  Direction neutral_direction
+    = to_dir (me->get_property ("neutral-direction"));
+
+  int pos = Staff_symbol_referencer::get_rounded_position (me);
+  int sz = Staff_symbol_referencer::line_count (me) - 1;
+
+  string font_char = "custodes." + style + ".";
+  if (pos < neutral_pos)
+    font_char += "u";
+  else if (pos > neutral_pos)
+    font_char += "d";
+  else if (neutral_direction == UP)
+    font_char += "u";
+  else if (neutral_direction == DOWN)
+    font_char += "d";
+  else // auto direction; not yet supported -> use "d"
+    font_char += "d";
+
+  if (adjust)
+    font_char += (((pos ^ sz) & 0x1) == 0) ? "1" : "0";
+  else
+    font_char += "2";
+
+  Stencil stencil
+    = Font_interface::get_default_font (me)->find_by_name (font_char);
+  if (stencil.is_empty ())
     {
-      String style = ly_scm2string (scm_symbol_to_string (scm_style));
-
-      /*
-       DOCME:
-       
-       Why would we want it differently? What's the meaning of adjust ?
-       */
-      bool adjust =
-       to_boolean (me->get_grob_property ("adjust-if-on-staffline"));
-
-      String idx = "custodes-" + style + "-";
-
-      int neutral_pos;
-      SCM ntr_pos = me->get_grob_property ("neutral-position");
-      if (gh_number_p (ntr_pos))
-       neutral_pos = gh_scm2int (ntr_pos);
-      else
-       neutral_pos = 0;
-
-      Direction neutral_direction =
-       to_dir (me->get_grob_property ("neutral-direction"));
-
-      int pos = (int)rint (Staff_symbol_referencer::position_f (me));
-      int sz = Staff_symbol_referencer::line_count (me)-1;
-
-      if (pos < neutral_pos)
-       idx += "u";
-      else if (pos > neutral_pos)
-       idx += "d";
-      else if (neutral_direction == UP)
-       idx += "u";
-      else if (neutral_direction == DOWN)
-       idx += "d";
-      else // auto direction; not yet supported -> use "d"
-       idx += "d";
-
-      if (adjust)
-        {
-         idx += (((pos ^ sz) & 0x1) == 0) ? "1" : "0";
-       }
-      else
-        {
-         idx += "2";
-       }
-
-      Molecule molecule
-       = Font_interface::get_default_font (me)->find_by_name (idx);
-      if (molecule.empty_b ())
-        {
-         String message = "no such custos: `" + idx + "'";
-         warning (_ (message.ch_C ()));
-         return SCM_EOL;
-       }
-      else
-        {
-         add_streepjes (me, (int)pos, sz, &molecule);
-         return  molecule.smobbed_copy ();
-       }
+      me->warning (_f ("custos `%s' not found", font_char));
+      return SCM_EOL;
     }
-  else
-    return SCM_EOL;
-}
 
-bool
-Custos::has_interface (Grob*m)
-{
-  return m && m->has_interface (ly_symbol2scm ("custos-interface"));
+  return stencil.smobbed_copy ();
 }
 
+ADD_INTERFACE (Custos,
+              "A custos object.  @code{style} can have four valid values:"
+              " @code{mensural}, @code{vaticana}, @code{medicaea}, and"
+              " @code{hufnagel}.  @code{mensural} is the default style.",
 
-ADD_INTERFACE (Custos, "custos-interface",
-  "A custos is a staff context symbol that appears at the end of a
-  staff line with monophonic musical contents (i.e. with a single
-  voice).  It anticipates the pitch of the first note of the following
-  line and thus helps the player or singer to manage line breaks
-  during performance, thus enhancing readability of a score.
-
-  Custodes were frequently used in music notation until the 16th
-  century.  There were different appearences for different notation
-  styles.  Nowadays, they have survived only in special forms of
-  musical notation such as via the editio vaticana dating back to the
-  beginning of the 20th century.
-
-[TODO: add to glossary]",
-  "style adjust-if-on-staffline neutral-position");
+              /* properties */
+              "style "
+              "neutral-position "
+              "neutral-direction "
+              );