]> git.donarmstrong.com Git - lilypond.git/commitdiff
Issue 4022: Allow specifying different alignment for grob and its parent
authorJanek Warchoł <lemniskata.bernoullego@gmail.com>
Sun, 20 Jul 2014 18:07:16 +0000 (20:07 +0200)
committerJanek Warchoł <lemniskata.bernoullego@gmail.com>
Sat, 9 Aug 2014 19:22:28 +0000 (21:22 +0200)
This gives users more possibilities for grob positioning - for example,
they can align left edge of a grob on center of its parent, etc.

Also fix Issue 4054.

input/regression/parent-alignment-synchronized-with-self-alignment.ly [new file with mode: 0644]
input/regression/self-alignment-and-parent-alignment.ly [new file with mode: 0644]
lily/self-alignment-interface.cc
scm/define-grob-properties.scm
scm/define-grobs.scm

diff --git a/input/regression/parent-alignment-synchronized-with-self-alignment.ly b/input/regression/parent-alignment-synchronized-with-self-alignment.ly
new file mode 100644 (file)
index 0000000..50d21d8
--- /dev/null
@@ -0,0 +1,36 @@
+\version "2.19.11"
+
+\header {
+  texidoc = "When @code{parent-alignment-X} property is unset,
+the value of @code{self-alignment-X} will be used as the factor
+for parent alignment.  This happens e.g. for LyricTexts."
+}
+
+{
+  \time 4/2
+  % use breve noteheads because their refpoints aren't on their
+  % left edges - this may help catching subtle bugs.
+  \override NoteHead.style = #'altdefault
+  <>^"alignments “synchronized”:"
+  f'\breve f' f'
+  <>^"parent-alignment set to ##f:"
+  f' f' f'
+}
+\addlyrics {
+  \override LyricSpace.minimum-distance = 5
+
+  \override LyricText.self-alignment-X = #LEFT
+  left
+  \override LyricText.self-alignment-X = #CENTER
+  center
+  \override LyricText.self-alignment-X = #RIGHT
+  right
+
+  \override LyricText.parent-alignment-X = ##f
+  \override LyricText.self-alignment-X = #LEFT
+  left
+  \override LyricText.self-alignment-X = #CENTER
+  center
+  \override LyricText.self-alignment-X = #RIGHT
+  right
+}
diff --git a/input/regression/self-alignment-and-parent-alignment.ly b/input/regression/self-alignment-and-parent-alignment.ly
new file mode 100644 (file)
index 0000000..9f26287
--- /dev/null
@@ -0,0 +1,49 @@
+\version "2.19.11"
+
+\header {
+  texidoc = "Grobs using @code{ly:self-alignment-interface::aligned-on-x-parent}
+and @code{ly:self-alignment-interface::aligned-on-y-parent}
+callbacks support separate alignments for self and parent."
+}
+
+{ f'1 f' f' }
+\addlyrics {
+  \override LyricSpace.minimum-distance = 5
+  \override LyricText.self-alignment-X = #LEFT
+  \override LyricText.parent-alignment-X = #LEFT
+  left-left
+  \override LyricText.self-alignment-X = #LEFT
+  \override LyricText.parent-alignment-X = #CENTER
+  left-center
+  \override LyricText.self-alignment-X = #LEFT
+  \override LyricText.parent-alignment-X = #RIGHT
+  left-right
+}
+
+{ f'1 f' f' }
+\addlyrics {
+  \override LyricSpace.minimum-distance = 5
+  \override LyricText.self-alignment-X = #CENTER
+  \override LyricText.parent-alignment-X = #LEFT
+  center-left
+  \override LyricText.self-alignment-X = #CENTER
+  \override LyricText.parent-alignment-X = #CENTER
+  center-center
+  \override LyricText.self-alignment-X = #CENTER
+  \override LyricText.parent-alignment-X = #RIGHT
+  center-right
+}
+
+{ f'1 f' f' }
+\addlyrics {
+  \override LyricSpace.minimum-distance = 5
+  \override LyricText.self-alignment-X = #RIGHT
+  \override LyricText.parent-alignment-X = #LEFT
+  right-left
+  \override LyricText.self-alignment-X = #RIGHT
+  \override LyricText.parent-alignment-X = #CENTER
+  right-center
+  \override LyricText.self-alignment-X = #RIGHT
+  \override LyricText.parent-alignment-X = #RIGHT
+  right-right
+}
index 27800679701299f0ec4f33eef5eee748a44ca3c9..9c73b6c7d8cf8cd6bf458b9648964150a28378b4 100644 (file)
@@ -122,30 +122,38 @@ Self_alignment_interface::aligned_on_parent (Grob *me, Axis a)
         he = him->extent (him, a);
     }
 
-  SCM sym = (a == X_AXIS) ? ly_symbol2scm ("self-alignment-X")
-            : ly_symbol2scm ("self-alignment-Y");
-  SCM align_prop (me->internal_get_property (sym));
+  SCM self_align = (a == X_AXIS)
+          ? me->internal_get_property (ly_symbol2scm ("self-alignment-X"))
+          : me->internal_get_property (ly_symbol2scm ("self-alignment-Y"));
 
-  if (!scm_is_number (align_prop))
-    return scm_from_int (0);
+  SCM par_align = (a == X_AXIS)
+          ? me->internal_get_property (ly_symbol2scm ("parent-alignment-X"))
+          : me->internal_get_property (ly_symbol2scm ("parent-alignment-Y"));
 
-  Real x = 0.0;
-  Real align = scm_to_double (align_prop);
+  if (par_align == SCM_EOL)
+      par_align = self_align;
 
+  Real x = 0.0;
   Interval ext (me->extent (me, a));
 
-  // Empty extent doesn't mean an error - we simply don't align such grobs.
-  // However, empty extent and non-empty stencil would be suspicious.
-  if (!ext.is_empty ())
-    x -= ext.linear_combination (align);
-  else if (me->get_stencil ())
-    warning (me->name () + " has empty extent and non-empty stencil.");
+  if (scm_is_number (self_align))
+    {
+      // Empty extent doesn't mean an error - we simply don't align such grobs.
+      // However, empty extent and non-empty stencil would be suspicious.
+      if (!ext.is_empty ())
+        x -= ext.linear_combination (scm_to_double (self_align));
+      else if (me->get_stencil ())
+        warning (me->name () + " has empty extent and non-empty stencil.");
+    }
 
-  // See comment above.
-  if (!he.is_empty ())
-    x += he.linear_combination (align);
-  else if (him->get_stencil ())
-    warning (him->name () + " has empty extent and non-empty stencil.");
+  if (scm_is_number (par_align))
+    {
+      // See comment above.
+      if (!he.is_empty ())
+        x += he.linear_combination (scm_to_double (par_align));
+      else if (him->get_stencil ())
+        warning (him->name () + " has empty extent and non-empty stencil.");
+    }
 
   return scm_from_double (x);
 }
@@ -173,6 +181,8 @@ ADD_INTERFACE (Self_alignment_interface,
                "@end table\n",
 
                /* properties */
+               "parent-alignment-X "
+               "parent-alignment-Y "
                "self-alignment-X "
                "self-alignment-Y "
                "X-align-on-main-noteheads "
index 05cff648d4bdcc06ca1d8fad9cf79d93b1f636ac..35f0074a88de07538712e29d39c651af28445cb2 100644 (file)
@@ -756,6 +756,15 @@ at a column with a negative penalty.")
      (page-turn-permission ,symbol? "Instructs the page breaker on
 whether to put a page turn at this column.  Can be @code{force} or
 @code{allow}.")
+     (parent-alignment-X ,number? "Specify on which point
+of the parent the object is aligned. The value @w{@code{-1}} means
+aligned on parent's left edge, @code{0}@tie{}on@tie{}center, and
+@code{1}@tie{}right edge, in X@tie{}direction.  Other numerical
+values may also be specified - the unit is half the parent's width.
+If unset, the value from @code{self-alignment-X} property will be
+used.")
+     (parent-alignment-Y ,number? "Like @code{parent-alignment-X}
+but for the Y@tie{}axis.")
      (parenthesized ,boolean? "Parenthesize this grob.")
      (positions ,number-pair? "Pair of staff coordinates
 @code{(@var{left} . @var{right})}, where both @var{left} and
@@ -817,7 +826,7 @@ influenced by changes to
      (self-alignment-X ,number? "Specify alignment of an object.  The
 value @w{@code{-1}} means left aligned, @code{0}@tie{}centered, and
 @code{1}@tie{}right-aligned in X@tie{}direction.  Other numerical
-values may also be specified.")
+values may also be specified - the unit is half the object width.")
      (self-alignment-Y ,number? "Like @code{self-alignment-X} but for
 the Y@tie{}axis.")
      (sharp-positions ,list? "Sharps in key signatures are placed
index 73588907e738c1f402346b5190f0141e74efe5c2..ce418e8cf8f9e650e1d5ea1f6bb191e4412f0bd4 100644 (file)
         (extra-spacing-height . (0.2 . -0.2))
         (font-series . medium)
         (font-size . 1.0)
+        (parent-alignment-X . ())
         (self-alignment-X . ,CENTER)
         (stencil . ,lyric-text::print)
         (text . ,(grob::calc-property-by-copy 'text))