From: David Nalesnik <david.nalesnik@gmail.com>
Date: Fri, 6 Jan 2017 16:27:25 +0000 (-0600)
Subject: Implement shorten-pair for Hairpin
X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=c473929f7e9d1219a1fbe60ae0922d17c26fdefe;p=lilypond.git

Implement shorten-pair for Hairpin

This property allows the ends of hairpins to be modified
independently.
---

diff --git a/Documentation/changes.tely b/Documentation/changes.tely
index 37e17cae1a..a78d6d3297 100644
--- a/Documentation/changes.tely
+++ b/Documentation/changes.tely
@@ -61,6 +61,20 @@ which scares away people.
 
 @end ignore
 
+@item
+The ends of hairpins may now be fine-tuned using the @code{shorten-pair}
+grob property, which previously only affected text-spanners like
+@code{TupletBracket} and @code{OttavaBracket}.  Positive values offset
+to the right, negative to the left.
+@lilypond[quote,verbatim]
+{ \once \override Hairpin.shorten-pair = #'(2 . 2)
+  c'1~\<
+  c'2~ c'\!
+  \once \override Hairpin.shorten-pair = #'(-2 . -2)
+  c'1~\<
+  c'2~ c'\! }
+@end lilypond
+
 @item
 In fret-diagrams the distance between frets and the distance between strings is
 now independently adjustable.  Available are @code{fret-distance} and
diff --git a/Documentation/notation/expressive.itely b/Documentation/notation/expressive.itely
index 3c249389c2..5f89cc66cf 100644
--- a/Documentation/notation/expressive.itely
+++ b/Documentation/notation/expressive.itely
@@ -454,6 +454,9 @@ items such as text scripts, text spanners, and piano pedal marks.
 @lilypondfile[verbatim,quote,texidoc,doctitle]
 {setting-the-minimum-length-of-hairpins.ly}
 
+@lilypondfile[verbatim,quote,texidoc,doctitle]
+{moving-the-ends-of-hairpins.ly}
+
 @cindex al niente
 @cindex niente, al
 
diff --git a/Documentation/snippets/new/moving-the-ends-of-hairpins.ly b/Documentation/snippets/new/moving-the-ends-of-hairpins.ly
new file mode 100644
index 0000000000..6c8438cddf
--- /dev/null
+++ b/Documentation/snippets/new/moving-the-ends-of-hairpins.ly
@@ -0,0 +1,30 @@
+\version "2.19.55"
+
+\header {
+  lsrtags = "expressive-marks"
+
+  texidoc = "
+The ends of hairpins may be offset by setting the @code{shorten-pair}
+property of the @code{Hairpin} object.  Positive values move endpoints
+to the right, negative to the left.  Unlike the @code{minimum-length}
+property, this property only affects the appearance of the hairpin; it
+does not adjust horizontal spacing (including the position of bounding
+dynamics).  This method is thus suitable for fine-tuning a hairpin
+within its allotted space.
+
+"
+  doctitle = "Moving the ends of hairpins"
+}
+
+{
+  c'1~\<
+  c'2~ c'\!
+  \once \override Hairpin.shorten-pair = #'(2 . 2)
+  c'1~\<
+  c'2~ c'\!
+  \once \override Hairpin.shorten-pair = #'(-2 . -2)
+  c'1~\<
+  c'2~ c'\!
+  c'1~\p-\tweak shorten-pair #'(2 . 0)\<
+  c'2~ c'\ffff
+}
diff --git a/input/regression/hairpin-shorten-pair-circled-tip.ly b/input/regression/hairpin-shorten-pair-circled-tip.ly
new file mode 100644
index 0000000000..63ebfcda24
--- /dev/null
+++ b/input/regression/hairpin-shorten-pair-circled-tip.ly
@@ -0,0 +1,22 @@
+\version "2.19.55"
+
+\header {
+  texidoc = "The @code{shorten-pair} property works with circled-tip
+hairpins.  When two hairpins share a circle, the adjoining ends are
+not moved.
+"
+}
+
+{
+  \override Hairpin.circled-tip = ##t
+  \once \override Hairpin.shorten-pair = #'(-2 . -4)
+  c'1~\<
+  c'2~ c'\!
+  \once \override Hairpin.shorten-pair = #'(0 . -4)
+  c'1~\>
+  c'2~ c'\!
+  \break
+  \override Hairpin.shorten-pair = #'(4 . -8)
+  c'2~\> c'2~\<
+  c'2~ c'2\!
+}
diff --git a/input/regression/hairpin-shorten-pair.ly b/input/regression/hairpin-shorten-pair.ly
new file mode 100644
index 0000000000..55eaaf2300
--- /dev/null
+++ b/input/regression/hairpin-shorten-pair.ly
@@ -0,0 +1,26 @@
+\version "2.19.55"
+
+\header {
+  texidoc = "The ends of hairpins may be offset with the
+@code{shorten-pair} property.  Positive values offset ends to the right,
+negative values to the left.
+"
+}
+
+hairpin = {
+  c'1~\<
+  c'2~ c'\!
+}
+
+{
+  \hairpin
+  \once \override Hairpin.shorten-pair = #'(2 . 2)
+  \hairpin
+  \once \override Hairpin.shorten-pair = #'(-2 . -2)
+  \hairpin
+  \break
+  \alterBroken shorten-pair #'((10 . 0) (-2 . -20)) Hairpin
+  c'1~\<
+  \break
+  c'2~ c'\!
+}
diff --git a/lily/hairpin.cc b/lily/hairpin.cc
index 01d8fd93de..afd94f3ee0 100644
--- a/lily/hairpin.cc
+++ b/lily/hairpin.cc
@@ -157,6 +157,8 @@ Hairpin::print (SCM smob)
   if (circled_tip)
     thick = robust_scm2double (me->get_property ("thickness"), 1.0)
             * Staff_symbol_referencer::line_thickness (me);
+  Drul_array<Real> shorten = robust_scm2interval (me->get_property ("shorten-pair"),
+                                                  Interval (0, 0));
 
   for (LEFT_and_RIGHT (d))
     {
@@ -220,7 +222,10 @@ Hairpin::print (SCM smob)
                         Handle back-to-back hairpins with a circle in the middle
                       */
                       if (circled_tip && (grow_dir != d))
-                        x_points[d] = e.center () + d * (rad - thick / 2.0);
+                        {
+                          x_points[d] = e.center () + d * (rad - thick / 2.0);
+                          shorten[d] = 0.0;
+                        }
                       /*
                         If we're hung on a paper column, that means we're not
                         adjacent to a text-dynamic, and we may move closer. We
@@ -248,6 +253,8 @@ Hairpin::print (SCM smob)
                 }
             }
         }
+
+        x_points[d] -= shorten[d] * d;
     }
 
   Real width = x_points[RIGHT] - x_points[LEFT];
@@ -336,4 +343,5 @@ ADD_INTERFACE (Hairpin,
                "bound-padding "
                "grow-direction "
                "height "
+               "shorten-pair "
               );
diff --git a/scm/define-grob-properties.scm b/scm/define-grob-properties.scm
index 3f7a94d9c2..34450a9d23 100644
--- a/scm/define-grob-properties.scm
+++ b/scm/define-grob-properties.scm
@@ -883,9 +883,10 @@ of the staff-position at which each clef places C:
 If the list contains a single element it applies for all clefs.
 A single number in place of a pair sets accidentals within the octave
 ending at that staff-position.")
-     (shorten-pair ,number-pair? "The lengths to shorten a
-text-spanner on both sides, for example a pedal bracket.  Positive
-values shorten the text-spanner, while negative values lengthen it.")
+     (shorten-pair ,number-pair? "The lengths to shorten on both sides
+a hairpin or text-spanner such as a pedal bracket.  Positive values
+shorten the hairpin or text-spanner, while negative values lengthen
+it.")
      (shortest-duration-space ,number? "Start with this multiple of
 @code{spacing-increment} space for the shortest duration.  See also
 @rinternals{spacing-spanner-interface}.")