[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
LilyPond-indents-to-small.png
Description: PNG image
LilyPond-indents-automatically-adjusted.png
Description: PNG image
- Proposal: Automatically adjusting indents for instrument names,
Johannes Feulner <=