]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/grob.cc
Merge branch 'lilypond/translation' of ssh://git.sv.gnu.org/srv/git/lilypond into...
[lilypond.git] / lily / grob.cc
index f5c9ebe4ddea19c0034a984744e9c076b5cc4261..5047b35be0c0c337d45bddf338fdc49f7a5f0384 100644 (file)
@@ -1,9 +1,20 @@
 /*
-  grob.cc -- implement Grob
+  This file is part of LilyPond, the GNU music typesetter.
 
-  source file of the GNU LilyPond music typesetter
+  Copyright (C) 1997--2010 Han-Wen Nienhuys <hanwen@xs4all.nl>
 
-  (c) 1997--2007 Han-Wen Nienhuys <hanwen@xs4all.nl>
+  LilyPond is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  LilyPond is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "grob.hh"
@@ -11,6 +22,7 @@
 #include <cstring>
 
 #include "align-interface.hh"
+#include "axis-group-interface.hh"
 #include "input.hh"
 #include "international.hh"
 #include "item.hh"
@@ -19,6 +31,7 @@
 #include "music.hh"
 #include "output-def.hh"
 #include "pointer-group-interface.hh"
+#include "program-option.hh"
 #include "stencil.hh"
 #include "stream-event.hh"
 #include "system.hh"
@@ -110,7 +123,9 @@ Grob::get_print_stencil () const
   if (Stencil *m = unsmob_stencil (stil))
     {
       retval = *m;
-      if (to_boolean (get_property ("transparent")))
+      bool transparent = to_boolean (get_property ("transparent"));
+
+      if (transparent)
        retval = Stencil (m->extent_box (), SCM_EOL);
       else
        {
@@ -142,6 +157,16 @@ Grob::get_print_stencil () const
          retval = Stencil (retval.extent_box (), expr);
        }
 
+      /* process whiteout */
+      /* a grob has to be visible, otherwise the whiteout property has no effect */
+      if (!transparent && to_boolean (get_property ("whiteout")))
+        {
+          /* Call the scheme procedure stencil-whiteout in scm/stencils.scm */
+          /* to add a round-filled-box stencil to the stencil list */
+          retval
+            = *unsmob_stencil (scm_call_1 (ly_lily_module_constant ("stencil-whiteout"),
+                                           retval.smobbed_copy()));
+        }
     }
 
   return retval;
@@ -426,10 +451,7 @@ Grob::extent (Grob *refp, Axis a) const
 Interval
 Grob::pure_height (Grob *refp, int start, int end)
 {
-  SCM proc = get_property_data (ly_symbol2scm ("Y-extent"));
-  SCM iv_scm = call_pure_function (proc,
-                                  scm_list_1 (self_scm ()),
-                                  start, end);
+  SCM iv_scm = get_pure_property ("Y-extent", start, end);
   Interval iv = robust_scm2interval (iv_scm, Interval (0, 0));
   Real offset = pure_relative_y_coordinate (refp, start, end);
 
@@ -533,6 +555,9 @@ Grob::fixup_refpoint ()
 void
 Grob::warning (string s) const
 {
+  if (get_program_option ("warning-as-error"))
+    error (s);
+
   SCM cause = self_scm ();
   while (Grob *g = unsmob_grob (cause))
     cause = g->get_property ("cause");
@@ -559,6 +584,9 @@ Grob::name () const
 void
 Grob::programming_error (string s) const
 {
+  if (get_program_option ("warning-as-error"))
+    error (s);
+
   SCM cause = self_scm ();
   while (Grob *g = unsmob_grob (cause))
     cause = g->get_property ("cause");
@@ -569,7 +597,7 @@ Grob::programming_error (string s) const
   if (Music *m = unsmob_music (cause))
     m->origin ()->message (s);
   else if (Stream_event *ev = unsmob_stream_event (cause))
-    ev->origin ()->warning (s);
+    ev->origin ()->message (s);
   else
     ::message (s);
 }
@@ -578,40 +606,40 @@ Grob::programming_error (string s) const
 ADD_INTERFACE (Grob,
               "A grob represents a piece of music notation.\n"
               "\n"
-              "All grobs have an X and Y@tie{}position on the page.  These "
-              "X and Y@tie{}positions are stored in a relative format, thus "
-              "they can easily be combined by stacking them, hanging one "
-              "grob to the side of another, or coupling them into grouping "
-              "objects.\n"
+              "All grobs have an X and Y@tie{}position on the page.  These"
+              " X and Y@tie{}positions are stored in a relative format, thus"
+              " they can easily be combined by stacking them, hanging one"
+              " grob to the side of another, or coupling them into grouping"
+              " objects.\n"
               "\n"
-              "Each grob has a reference point (a.k.a.@: parent): The "
-              "position of a grob is stored relative to that reference "
-              "point.  For example, the X@tie{}reference point of a staccato "
-              "dot usually is the note head that it applies to.  When the "
-              "note head is moved, the staccato dot moves along "
-              "automatically.\n"
+              "Each grob has a reference point (a.k.a.@: parent): The"
+              " position of a grob is stored relative to that reference"
+              " point.  For example, the X@tie{}reference point of a staccato"
+              " dot usually is the note head that it applies to.  When the"
+              " note head is moved, the staccato dot moves along"
+              " automatically.\n"
               "\n"
-              "A grob is often associated with a symbol, but some grobs do "
-              "not print any symbols.  They take care of grouping objects. "
-              "For example, there is a separate grob that stacks staves "
-              "vertically.  The @ref{NoteCollision} object is also an "
-              "abstract grob: It only moves around chords, but doesn't print "
-              "anything.\n"
+              "A grob is often associated with a symbol, but some grobs do"
+              " not print any symbols.  They take care of grouping objects."
+              " For example, there is a separate grob that stacks staves"
+              " vertically.  The @ref{NoteCollision} object is also an"
+              " abstract grob: It only moves around chords, but doesn't print"
+              " anything.\n"
               "\n"
-              "Grobs have properties (Scheme variables) that can be read and "
-              "set.  Two types of them exist: immutable and mutable.  "
-              "Immutable variables define the default style and behavior.  "
-              "They are shared between many objects.  They can be changed "
-              "using @code{\\override} and @code{\\revert}.  Mutable "
-              "properties are variables that are specific to one grob.  "
-              "Typically, lists of other objects, or results from "
-              "computations are stored in mutable properties.  In "
-              "particular, every call to @code{set-grob-property} (or its "
-              "C++ equivalent) sets a mutable property.\n"
+              "Grobs have properties (Scheme variables) that can be read and"
+              " set.  Two types of them exist: immutable and mutable."
+              "  Immutable variables define the default style and behavior."
+              "  They are shared between many objects.  They can be changed"
+              " using @code{\\override} and @code{\\revert}.  Mutable"
+              " properties are variables that are specific to one grob."
+              "  Typically, lists of other objects, or results from"
+              " computations are stored in mutable properties.  In"
+              " particular, every call to @code{ly:grob-set-property!}"
+              " (or its C++ equivalent) sets a mutable property.\n"
               "\n"
-              "The properties @code{after-line-breaking} and "
-              "@code{before-line-breaking} are dummies that are not "
-              "user-serviceable.",
+              "The properties @code{after-line-breaking} and"
+              " @code{before-line-breaking} are dummies that are not"
+              " user-serviceable.",
 
               /* properties */
               "X-extent "
@@ -643,6 +671,7 @@ ADD_INTERFACE (Grob,
               "staff-symbol "
               "stencil "
               "transparent "
+              "whiteout "
               );
 
 /****************************************************************
@@ -703,7 +732,6 @@ Grob::stencil_width (SCM smob)
 }
 
 
-
 Grob *
 common_refpoint_of_list (SCM elist, Grob *common, Axis a)
 {
@@ -722,14 +750,11 @@ common_refpoint_of_list (SCM elist, Grob *common, Axis a)
 Grob *
 common_refpoint_of_array (vector<Grob*> const &arr, Grob *common, Axis a)
 {
-  for (vsize i = arr.size (); i--;)
-    if (Grob *s = arr[i])
-      {
-       if (common)
-         common = common->common_refpoint (s, a);
-       else
-         common = s;
-      }
+  for (vsize i = 0; i < arr.size (); i++)
+    if (common)
+      common = common->common_refpoint (arr[i], a);
+    else
+      common = arr[i];
 
   return common;
 }
@@ -744,3 +769,18 @@ robust_relative_extent (Grob *me, Grob *refpoint, Axis a)
   return ext;
 }
 
+// Checks whether there is a vertical alignment in the chain of
+// parents between this and commony.
+bool
+Grob::check_cross_staff (Grob *commony)
+{
+  if (Align_interface::has_interface (commony))
+    return true;
+
+  for (Grob *g = this; g && g != commony; g = g->get_parent (Y_AXIS))
+    if (Align_interface::has_interface (g))
+      return true;
+
+  return false;
+}
+