lilypond-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Proposal: Automatically adjusting indents for instrument names


From: Johannes Feulner
Subject: Proposal: Automatically adjusting indents for instrument names
Date: Sat, 13 Feb 2021 14:18:42 +0100
User-agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:78.0) Gecko/20100101 Thunderbird/78.7.1

Hi there,

for programatically produced scores I've found it to be a nuisance that indents for somewhat longer instrument names had to be tuned by hand. And I guess LilyPond beginners will wonder why in the face of so much perfection longer instrument names simply get cut off.

I 'd like to propose the enhancement below to LilyPond. It will increase the indent and short-indent of a score to fit all of its instrument names and instrument short names.

Example input:

   \version "2.23.1"
   \new Staff \with {
      instrumentName = #"Viol con il più grande degli amori"
      shortInstrumentName = #"Vla. con i. p. g. d. a." }
      { c''2 a'2 \break | f'1 }

See attached pictures of current and desired behaviour.

I'd be happy to get feedback to refine the implementation below, changing score.cc, system.cc and system.hh.

Cheers,

Johannes

-------------------------------------------------------------------------------------

diff --git a/lily/score.cc b/lily/score.cc
index 140db0e..3f2b6e9 100644
--- a/lily/score.cc
+++ b/lily/score.cc
@@ -32,6 +32,7 @@
 #include "paper-book.hh"
 #include "paper-score.hh"
 #include "warn.hh"
+#include "system.hh" // <SCORIO JF20210212/>

 Input *
 Score::origin () const
@@ -99,6 +100,37 @@ Score::Score (Score const &s)
     ly_module_copy (header_, s.header_);
 }

+// <SCORIO JF20210212>
+/*
+  Set indent and short-indent to cover the width of
+  of the longest instrument name and the longest instrument short name resp.
+  but only in case they are longer than indent or short-indent resp.
+  Otherwise, do not change the values of indent or short-indent.
+*/
+void
+sc_adjust_indents(SCM context, Output_def *def, Real scale) {
+
+       Global_context *g = unsmob<Global_context> (context);
+       LY_ASSERT_SMOB (Global_context, context, 1);
+       SCM output = g->get_output ();
+
+       if (Paper_score *od = unsmob<Paper_score> (output)) {
+               Interval instrumentNamesWidth = od->root_system()->scGetInstrumentNamesWidth ();
+               Real padding = 1.5 * scale;
+
+               Real indent = def->get_dimension (ly_symbol2scm ("indent"));
+               Real long_width = instrumentNamesWidth[LEFT];
+               def->set_variable(ly_symbol2scm( "indent"),
+                       scm_from_double (std::max (indent, long_width + padding)));
+
+               Real short_indent = def->get_dimension (ly_symbol2scm ("short-indent"));
+               Real short_width = instrumentNamesWidth[RIGHT];
+               def->set_variable (ly_symbol2scm ("short-indent"),
+                       scm_from_double (std::max (short_indent, short_width + padding)));
+       }
+}
+// </SCORIO JF20210212>
+
 /*
   Format score, return list of Music_output objects.

@@ -139,6 +171,8 @@ Score::book_rendering (Output_def *layoutbook,
         {
           SCM s = ly_format_output (context);

+          sc_adjust_indents(context, def, scale); // <SCORIO JF20210212/>
+
           outputs = scm_cons (s, outputs);
         }

-------------------------------------------------------------------------------------

diff --git a/lily/system.cc b/lily/system.cc
index 804811d..7a67f57 100644
--- a/lily/system.cc
+++ b/lily/system.cc
@@ -1004,6 +1004,49 @@ get_maybe_spaceable_staves (SCM smob, int filter)
   return ret;
 }

+// <SCORIO JF20210212>
+Interval
+System::scGetInstrumentNamesWidth() {
+
+       // Return interval [long_name_width, short_name_width] containing
+       // the width of the longest instrument name and the longest instrument short name resp.
+       // If a name is not present, 0 will be returned as its width.
+       // For meaningful output this function should only be called after
+       // grobs have been created in this system.
+
+       Real long_name_width = 0;
+       Real short_name_width = 0;
+       for (vsize i = 0; i < all_elements_->size (); i++) {
+               Grob *grob = all_elements_->grob( i);
+               SCM meta =  get_property (grob, "meta");
+               SCM name = scm_assq_ref (meta, ly_symbol2scm("name"));
+               if (scm_is_symbol (name)) {
+                       std::string grobType = ly_symbol2string (name);
+                       if (0 == grobType.compare ("InstrumentName")) {
+                               SCM func = scm_variable_ref (scm_c_lookup ("grob-interpret-markup"));
+
+                               SCM long_name = get_property (grob, "long-text");
+                               if (!scm_is_null(long_name)) {
+                                       SCM long_stil = scm_call_2 (func, grob->self_scm (), long_name); +                                       auto *const ls = LY_ASSERT_SMOB (const Stencil, long_stil, 1); +                                       Interval long_extent = ls->extent (X_AXIS); +                                       long_name_width = std::max (long_name_width, long_extent.length ());
+                               }
+
+                               SCM short_name = get_property (grob, "text");
+                               if (!scm_is_null(short_name)) {
+                                       SCM short_stil = scm_call_2 (func, grob->self_scm (), short_name); +                                       auto *const ss = LY_ASSERT_SMOB (const Stencil, short_stil, 1); +                                       Interval short_extent = ss->extent (X_AXIS); +                                       short_name_width = std::max( short_name_width, short_extent.length ());
+                               }
+                       }
+               }
+       }
+       return Interval (long_name_width, short_name_width);
+}
+// </SCORIO JF20210212>
+
 MAKE_SCHEME_CALLBACK (System, get_staves, 1)
 SCM
 System::get_staves (SCM smob)

-------------------------------------------------------------------------------------

diff --git a/lily/include/system.hh b/lily/include/system.hh
index 072722b..4e2f5ea 100644
--- a/lily/include/system.hh
+++ b/lily/include/system.hh
@@ -122,6 +122,8 @@ public:
   Interval pure_refpoint_extent (vsize start, vsize end);
   void collect_labels (Grob const *, SCM *);

+  Interval scGetInstrumentNamesWidth(); // <SCORIO JF20210212/>
+
 protected:
   void derived_mark () const override;
   System *clone () const override { return new System (*this); }

--

Johannes Feulner
Tel: +49 721 33500158  johannes.feulner@scorio.com

scorio GmbH  Bonhoefferweg 3   76327 Pfinztal
Geschäftsführer Johannes Feulner
Sitz der Gesellschaft Karlsruhe
Amtsgericht Mannheim HRB 713486

Attachment: LilyPond-indents-to-small.png
Description: PNG image

Attachment: LilyPond-indents-automatically-adjusted.png
Description: PNG image


reply via email to

[Prev in Thread] Current Thread [Next in Thread]