]> git.donarmstrong.com Git - lilypond.git/commitdiff
Merge branch 'master' of /home/jcharles/GIT/Lily/. into translation
authorJean-Charles Malahieude <lilyfan@orange.fr>
Sat, 30 Apr 2016 08:06:01 +0000 (10:06 +0200)
committerJean-Charles Malahieude <lilyfan@orange.fr>
Sat, 30 Apr 2016 08:06:01 +0000 (10:06 +0200)
12 files changed:
Documentation/contributor/source-code.itexi
Documentation/included/compile.itexi
Documentation/notation/input.itely
Documentation/web/news-front.itexi
Documentation/web/news.itexi
Documentation/web/server/lilypond.org.htaccess
VERSION
lily/ledger-line-spanner.cc
ly/Welcome-to-LilyPond-MacOS.ly
ly/Welcome_to_LilyPond.ly
po/lilypond.pot
scm/framework-ps.scm

index b961a82cf6c65897090fd5736731974ac19096b4..9541fe963a775bcabe1ef4ed841cd6cf9e800bc5 100644 (file)
@@ -2288,11 +2288,32 @@ end up in master after all, defeating the purpose of the system.  The
 proper fix usually involves rewriting the staging branch and is best
 left to core developers after discussion on the developer list.
 
+Before pushing to staging it is a good practice to check whether
+staging is ahead of master, and if so, wait until master has caught up
+with staging before pushing.  This simplifies things if changes to
+staging have to be backed out for some reason.  To check whether
+master has caught up with staging you can look at the git web interface
+on savannah, or do:
+
+@example
+git fetch
+gitk
+@end example
+
+and check that @code{origin/master} is at the same commit as
+@code{origin/staging}.  Another option is to see if any commits are
+listed when you do:
+
+@example
+git fetch
+git log origin/master..origin/staging
+@end example
+
 @subsubheading If your work is in a patch file
 
 Assuming that your patch is in a file called
-@file{0001-my-patch.patch}, and you are currently on git master,
-do:
+@file{0001-my-patch.patch} (see @ref{Patches}), and you are currently
+on git master, do:
 
 @example
 git checkout staging
@@ -2310,20 +2331,26 @@ commit ahead of @code{origin/staging}.}
 
 @subsubheading If your work is in a branch
 
-If you are working on branches and your work in is
+If you are working on branches and your work is in
 @code{my_branch_name}, then do:
 
 @example
-git checkout staging
-git pull -r
-git merge my_branch_name
+git checkout my_branch_name
+git pull -r origin staging
+@end example
+
+This will rebase your branch on @code{origin/staging}.  At this point
+git will let you know if there are any conflicts.  If so, resolve them
+before continuing:
+
+@example
 gitk
-git push origin staging
+git push origin HEAD:staging
 @end example
 
 @warning{Do not skip the @command{gitk} step; a quick 5-second
 check of the visual history can save a great deal of frustration
-later on.  You should see that @code{staging} is only ahead of
+later on.  You should see that @code{my_branch_name} is only ahead of
 @code{origin/staging} by the commits from your branch.}
 
 
index 896fa0cb3c31c10137310542ce534aa40c6ff728..76bd48cd2f747821a5487f4ccb73a4c9f90775d9 100644 (file)
@@ -412,7 +412,7 @@ sudo apt-get build-dep lilypond
 Download and install additional @q{build} tools required for compiling;
 
 @example
-sudo apt-get install autoconf fonts-texgyre texlive-land-cyrillic
+sudo apt-get install autoconf fonts-texgyre texlive-lang-cyrillic
 @end example
 
 @item
index da9b1347a260688f95f3acbd0001336ba45f12f0..67506114b8a8e34b616a8f1009e44a40d7595e78 100644 (file)
@@ -1890,7 +1890,7 @@ tocAct =
   \markuplist \table-of-contents
   \tocAct \markup { Atto Primo }
   \tocItem \markup { Coro. Viva il nostro Alcide }
-  \tocItem \markup { Cesare. Presti omai l'Egizzia terra }
+  \tocItem \markup { Cesare. Presti omai l'Egizia terra }
   \tocAct \markup { Atto Secondo }
   \tocItem \markup { Sinfonia }
   \tocItem \markup { Cleopatra. V'adoro, pupille, saette d'Amore }
@@ -2285,8 +2285,8 @@ music = \relative c'' {
 
 Multiple @code{\removeWithTag} filters may be applied to a single
 music expression to remove several differently named tagged
-sections.  Alternatively, you can use a single
-@code{\removeWithTag} with a list of tags.
+sections.  Alternatively, you can use a single @code{\removeWithTag}
+with a list of tags.
 
 @lilypond[verbatim,quote]
 music = \relative c'' {
@@ -2304,41 +2304,74 @@ music = \relative c'' {
 }
 @end lilypond
 
-Two or more @code{\keepWithTag} filters applied to a single music
-expression will cause @emph{all} tagged sections to be removed, as
-the first filter will remove all tagged sections except the one
-named, and the second filter will remove even that tagged section.
-Usually you would rather want to use a single @code{\keepWithTag}
-command with a list of multiple tags: this will only remove tagged
-sections not given in @emph{any} of the tags.
+Using two or more @code{\keepWithTag} filters on a single music
+expression will cause @emph{all} of the tagged sections to be removed.
+The first filter will remove all except the one named and any subsequent
+filters will remove the rest.  Using one @code{\keepWithTag} command
+with a list of multiple tags will only remove tagged sections that are
+not specified in that list.
+
+@lilypond[verbatim,quote]
+music = \relative c'' {
+  \tag #'violinI { a4 a a a }
+  \tag #'violinII { b4 b b b }
+  \tag #'viola { c4 c c c }
+  \tag #'cello { d4 d d d }
+}
+
+\new Staff {
+  \keepWithTag #'(violinI violinII)
+  \music
+}
+@end lilypond
+
+@noindent
+will print @code{\tag}s @var{violinI} and @var{violinII} but not
+@var{viola} or @var{cello}.
 
 @cindex tag groups
 @funindex \tagGroup
-While @code{\keepWithTag} is convenient when dealing with
-@emph{one} set of alternatives, the removal of music tagged with
-@emph{unrelated} tags is problematic when using tags for more than
-one purpose.  For that reason, @q{tag groups} of related tags can
-be declared:
+
+While @code{\keepWithTag} is convenient when dealing with @emph{one} set
+of alternatives, the removal of music tagged with @emph{unrelated} tags
+is problematic when using them for more than one purpose.  In that case
+@q{groups} of tags can be declared:
 
 @example
 \tagGroup #'(violinI violinII viola cello)
 @end example
 
-declares the respective tags as belonging to one tag group.
+@noindent
+Now the all the different tags belong to a single @q{tag group}.  Note
+that individual tags cannot be members of more than one
+@emph{tag group}.
 
 @example
 \keepWithTag #'violinI @dots{}
 @end example
 
-will then only be concerned with tags from @code{violinI}'s tag
-group: any element of the included music that is tagged with one
-or more of tags from this set but @emph{not} with @code{violinI}
-will get removed.
+@noindent
+will now only show music tagged from @code{violinI}'s tag group and any
+music tagged with one of the @emph{other} tags will removed.
+
+@lilypond[verbatim,quote]
+music = \relative {
+  \tagGroup #'(violinI violinII viola cello)
+  \tag #'violinI { c''4^"violinI" c c c }
+  \tag #'violinII { a2 a }
+  \tag #'viola { e8 e e2. }
+  \tag #'cello { d'2 d4 d }
+  R1^"untagged"
+}
 
-To any @code{\keepWithTag} command, only tags from the tag groups
-of the tags given in the command are visible.
+\new Voice {
+  \keepWithTag #'violinI
+  \music
+}
+@end lilypond
 
-Tags cannot be members of more than one tag group.
+When using the @code{\keepWithTag} command, only tags from the tag
+groups of the tags given in the command are visible.
 
 @funindex \pushToTag
 @funindex \appendToTag
@@ -2352,15 +2385,15 @@ construct has @code{elements}, but sequential and simultaneous music are
 safe bets:
 
 @lilypond[verbatim,quote]
-test = { \tag #'here { \tag #'here <<c''>> } }
+music = { \tag #'here { \tag #'here <<c''>> } }
 
 {
   \pushToTag #'here c'
   \pushToTag #'here e'
-  \pushToTag #'here g' \test
+  \pushToTag #'here g' \music
   \appendToTag #'here c'
   \appendToTag #'here e'
-  \appendToTag #'here g' \test
+  \appendToTag #'here g' \music
 }
 @end lilypond
 
@@ -2452,7 +2485,7 @@ instruction containing non-ASCII characters, must be encoded in
 UTF-8.  The easiest way to enter such text is by using a
 Unicode-aware editor and saving the file with UTF-8 encoding.  Most
 popular modern editors have UTF-8 support, for example, vim, Emacs,
-jEdit, and GEdit do.  All MS Windows systems later than NT use
+jEdit, and Gedit do.  All MS Windows systems later than NT use
 Unicode as their native character encoding, so even Notepad can
 edit and save a file in UTF-8 format.  A more functional
 alternative for Windows is BabelPad.
@@ -2469,9 +2502,10 @@ will be generated.
 Here is an example showing Cyrillic, Hebrew and Portuguese
 text:
 
+@c NOTE: No verbatim in the following example as the code does not
+@c display correctly in PDF Font settings for Cyrillic and Hebrew
+
 @lilypond[quote]
-%c No verbatim here as the code does not display correctly in PDF
-% Font settings for Cyrillic and Hebrew
 % Linux Libertine fonts contain Cyrillic and Hebrew glyphs.
 \paper {
   #(define fonts
@@ -2666,7 +2700,7 @@ generated.
 Notation Reference:
 @ref{The layout block}.
 
-Application Usage
+Application Usage:
 @rprogram{Command-line usage}.
 
 
@@ -2839,7 +2873,7 @@ When combined with the @file{articulate} script the following,
 additional musical notation can be output to MIDI;
 
 @itemize
-@item Appogiaturas.  These are made to take half the value of the note
+@item Appoggiaturas.  These are made to take half the value of the note
 following (without taking dots into account).  For example;
 
 @example
@@ -3532,10 +3566,10 @@ Installed Files:
 @warning{The @file{articulate} script may shorten chords, which might
 not be appropriate for some types of instrument, such as organ music.
 Notes that do not have any articulations attached to them may also be
-shortened; so to compensate for this, restrict the use of the
-@code{\articulate} function to shorter segments of music or modify the
+shortened; so to allow for this, restrict the use of the
+@code{\articulate} function to shorter segments of music, or modify the
 values of the variables defined in the @file{articulate} script to
-compentate for the note-shortening behavior.}
+compensate for the note-shortening behavior.}
 
 
 
@@ -3584,15 +3618,16 @@ lilypond file.ly >display.txt
 @funindex \void
 Note that Lilypond does not just display the music expression, but
 also interprets it (since @code{\displayLilyMusic} returns it in
-addition to displaying it).  This is convenient since you can just
-insert @code{\displayLilyMusic} into existing music in order to get
-information about it.  If you don't actually want Lilypond to
-interpret the displayed music as well as display it, use @code{\void}
-in order to have it ignored:
+addition to displaying it).  Just insert @code{\displayLilyMusic} into
+the existing music in order to get information about it.
+
+To interpret and display a music section in the console but, at the same
+time, remove it from the output file use the @code{\void} command.
 
 @example
 @{
   \void \displayLilyMusic \transpose c a, @{ c4 e g a bes @}
+  c1
 @}
 @end example
 
index dcba99ed2e5a36704c290220377080df6823efbb..ccd09c884faa01fc7fb8ab7cfb678391f397bee0 100644 (file)
@@ -9,10 +9,10 @@
 @c used for news about the upcoming release; see CG 10.2
 
 @newsItem
-@subheading LilyPond 2.19.39 released  @emph{March 27, 2016}
+@subheading LilyPond 2.19.40 released  @emph{April 17, 2016}
 
 We are happy to announce the release of LilyPond
-2.19.39.  This release includes a number of enhancements, and contains some
+2.19.40.  This release includes a number of enhancements, and contains some
 work in progress.  You will have access to the very latest features, but
 some may be incomplete, and you may encounter bugs and crashes.  If you
 require a stable version of Lilypond, we recommend using the 2.18
@@ -35,23 +35,19 @@ updated manuals.  We recommend all users to upgrade to this version.
 
 
 @newsItem
-@subheading LilyPond production named BEST EDITION 2014  @emph{March 11, 2014}
-
-We are thrilled that the edition of the songs of Oskar
-Fried (1871-1941), published recently by our fellow contributors Urs Liska
-and Janek Warchoł [1], received the "Musikeditionspreis BEST EDITION
-2014" of the German Music Publishers' Association [2].  The ceremony
-took place at the Frankfurt Musikmesse.
-
-We congratulate Janek and Urs for gaining such public recognition of
-typographical and editorial excellence of their work.  We are also delighted
-to inform you that they intend to make their work available under a Free
-license as soon as the publisher expenses are covered.  Please support this
-initiative by buying the printed volume through the publisher [3].
-
-[1] @uref{http://lilypondblog.org/category/fried-songs}@*
-[2] @uref{http://www.best-edition.de}@*
-[3] @uref{http://www.sound-rel.de}@*
+@subheading Two LilyPond projects in Google Summer of Code 2016  @emph{April 23, 2016}
+
+We are happy to see two students, Nathan Chou and Jeffery Shivers, working on
+LilyPond as participants in the Google Summer of Code this year.  We hope they
+produce great results and stay in the developer community afterwards.
+
+Nathan will tackle an annoying limitation, namely the unability of spanners
+to cross voices.  His work will make a class of ugly workarounds obsolete.
+Jeffery will bring the ScholarLY package[1] to production quality and add a
+LaTeX package to it, making it possible to create beautiful critical reports
+from data encoded directly in the LilyPond score.
+
+[1] @uref{https://github.com/openlilylib/scholarly}@*
 
 @newsEnd
 
index 2a029b6f52cde7f5848f92f9343bbbbdc1c2898b..dabfc79144f1179b44477a125ce126f2c0235a1f 100644 (file)
@@ -26,6 +26,18 @@ NOTE:
   * don't duplicate entries from news-front.itexi
 @end ignore
 
+@newsItem
+@subheading LilyPond 2.19.39 released  @emph{March 27, 2016}
+
+We are happy to announce the release of LilyPond
+2.19.39.  This release includes a number of enhancements, and contains some
+work in progress.  You will have access to the very latest features, but
+some may be incomplete, and you may encounter bugs and crashes.  If you
+require a stable version of Lilypond, we recommend using the 2.18
+version.
+
+@newsEnd
+
 @newsItem
 @subheading LilyPond 2.19.38 released  @emph{March 13, 2016}
 
@@ -447,6 +459,28 @@ a stable version of Lilypond, we recommend using the 2.18 version.
 
 @newsEnd
 
+@newsItem
+@subheading LilyPond production named BEST EDITION 2014  @emph{March 11, 2014}
+
+We are thrilled that the edition of the songs of Oskar
+Fried (1871-1941), published recently by our fellow contributors Urs Liska
+and Janek Warchoł [1], received the "Musikeditionspreis BEST EDITION
+2014" of the German Music Publishers' Association [2].  The ceremony
+took place at the Frankfurt Musikmesse.
+
+We congratulate Janek and Urs for gaining such public recognition of
+typographical and editorial excellence of their work.  We are also delighted
+to inform you that they intend to make their work available under a Free
+license as soon as the publisher expenses are covered.  Please support this
+initiative by buying the printed volume through the publisher [3].
+
+[1] @uref{http://lilypondblog.org/category/fried-songs}@*
+[2] @uref{http://www.best-edition.de}@*
+[3] @uref{http://www.sound-rel.de}@*
+
+@newsEnd
+
+
 @newsItem
 @subheading LilyPond 2.19.3 released  @emph{March 2, 2014}
 
index 29d90284118dd52942e03bcb5d46b69c0ee219b9..9060d0709a207f6b810c251b1781405e5757f437 100644 (file)
@@ -49,9 +49,12 @@ RedirectMatch ^/stable    /doc/stable
 # the new website has a dedicated page for development.
 #RedirectMatch ^/development    /doc/development
 
-#old# default doc dir
-RedirectMatch ^/doc/*$ /doc/v2.18
-# make attempt at `latest' symlink avoid ^v catch-all doc fix rule below
+# Main doc URL redirects
+RedirectMatch ^/doc/?$ /manuals
+RedirectMatch ^/doc/stable/?$ /manuals
+RedirectMatch ^/doc/development/?$ /development
+
+# Allow to use deep links to latest stable or development docs
 RedirectMatch ^/doc//*latest/*(.*)$ /doc/v2.19/$1
 RedirectMatch ^/doc//*development/*(.*)$ /doc/v2.19/$1
 RedirectMatch ^/doc//*stable/*(.*)$ /doc/v2.18/$1
diff --git a/VERSION b/VERSION
index 4f515550c29f1497fe828f2ac28539e468f73375..b71387ae8bb5995f9d2a4006d7ddd607a4930687 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1,7 +1,7 @@
 PACKAGE_NAME=LilyPond
 MAJOR_VERSION=2
 MINOR_VERSION=19
-PATCH_LEVEL=40
+PATCH_LEVEL=41
 MY_PATCH_LEVEL=
 VERSION_STABLE=2.18.2
-VERSION_DEVEL=2.19.39
+VERSION_DEVEL=2.19.40
index b0e8fee3c2321b8e7f078a7946048714deca168a..42d32b496af7bb5ec7a15f1b52cdbc4ea84959c8 100644 (file)
@@ -140,16 +140,33 @@ Ledger_line_spanner::set_spacing_rods (SCM smob)
   return SCM_UNSPECIFIED;
 }
 
-struct Ledger_request
+struct Head_data
 {
-  Interval ledger_extent_;
-  Interval head_extent_;
   int position_;
-  Ledger_request ()
+  vector<Real> ledger_positions_;
+  Interval head_extent_;
+  Interval ledger_extent_;
+  Interval accidental_extent_;
+  Head_data ()
   {
-    ledger_extent_.set_empty ();
     head_extent_.set_empty ();
-    position_ = 0;
+    ledger_extent_.set_empty ();
+    accidental_extent_.set_empty ();
+  }
+};
+
+struct Ledger_request
+{
+  Interval max_ledger_extent_;
+  Interval max_head_extent_;
+  int max_position_;
+  vector <Head_data> heads_;
+  map <Real, Interval> ledger_extents_;
+  Ledger_request ()
+  {
+    max_ledger_extent_.set_empty ();
+    max_head_extent_.set_empty ();
+    max_position_ = 0;
   }
 };
 
@@ -165,12 +182,12 @@ Ledger_line_spanner::print (SCM smob)
 {
   Spanner *me = unsmob<Spanner> (smob);
 
+  // Generate ledger requests from note head properties, etc.
   extract_grob_set (me, "note-heads", heads);
 
   if (heads.empty ())
     return SCM_EOL;
 
-  // find size of note heads.
   Grob *staff = Staff_symbol_referencer::get_staff_symbol (me);
   if (!staff)
     return SCM_EOL;
@@ -183,17 +200,11 @@ Ledger_line_spanner::print (SCM smob)
   Real length_fraction
     = robust_scm2double (me->get_property ("length-fraction"), 0.25);
 
-  Stencil ledgers;
-
-  Grob *common[NO_AXES];
-
-  for (int i = X_AXIS; i < NO_AXES; i++)
+  Grob *common_x = common_refpoint_of_array (heads, me, X_AXIS);
+  for (vsize i = heads.size (); i--;)
     {
-      Axis a = Axis (i);
-      common[a] = common_refpoint_of_array (heads, me, a);
-      for (vsize i = heads.size (); i--;)
-        if (Grob *g = unsmob<Grob> (me->get_object ("accidental-grob")))
-          common[a] = common[a]->common_refpoint (g, a);
+      if (Grob *g = unsmob<Grob> (heads[i]->get_object ("accidental-grob")))
+        common_x = common_x->common_refpoint (g, X_AXIS);
     }
 
   Ledger_requests reqs;
@@ -202,23 +213,43 @@ Ledger_line_spanner::print (SCM smob)
       Item *h = dynamic_cast<Item *> (heads[i]);
 
       int pos = Staff_symbol_referencer::get_rounded_position (h);
-      if (pos && !staff_extent.contains (pos))
+      vector<Real> ledger_positions =
+        Staff_symbol::ledger_positions (staff, pos);
+
+      // We work with all notes that produce ledgers and any notes that
+      // fall outside the staff that do not produce ledgers, such as
+      // notes in the first space just beyond the staff.
+      if (ledger_positions.size () != 0 || !staff_extent.contains (pos))
         {
-          Interval head_extent = h->extent (common[X_AXIS], X_AXIS);
+          Interval head_extent = h->extent (common_x, X_AXIS);
           Interval ledger_extent = head_extent;
           ledger_extent.widen (length_fraction * head_extent.length ());
 
-          Direction vdir = Direction (sign (pos));
+          Direction vdir = Direction (sign (pos != 0 ? pos : 1));
           int rank = h->get_column ()->get_rank ();
 
-          reqs[rank][vdir].ledger_extent_.unite (ledger_extent);
-          reqs[rank][vdir].head_extent_.unite (head_extent);
-          reqs[rank][vdir].position_
-            = vdir * max (vdir * reqs[rank][vdir].position_, vdir * pos);
+          reqs[rank][vdir].max_ledger_extent_.unite (ledger_extent);
+          reqs[rank][vdir].max_head_extent_.unite (head_extent);
+          reqs[rank][vdir].max_position_
+            = vdir * max (vdir * reqs[rank][vdir].max_position_,
+                          vdir * pos);
+          Head_data hd;
+          hd.position_ = pos;
+          hd.ledger_positions_ = ledger_positions;
+          hd.ledger_extent_ = ledger_extent;
+          hd.head_extent_ = head_extent;
+          if (Grob *g = unsmob<Grob> (h->get_object ("accidental-grob")))
+            hd.accidental_extent_ = g->extent (common_x, X_AXIS);
+          reqs[rank][vdir].heads_.push_back(hd);
         }
     }
 
-  // determine maximum size for non-colliding ledger.
+  if (reqs.size () == 0)
+    return SCM_EOL;
+
+  // Iterate through ledger requests and when ledger lines will be
+  // too close together horizontally, shorten max_ledger_extent to
+  // produce more space between them.
   Real gap = robust_scm2double (me->get_property ("gap"), 0.1);
   Ledger_requests::iterator last (reqs.end ());
   for (Ledger_requests::iterator i (reqs.begin ());
@@ -229,81 +260,111 @@ Ledger_line_spanner::print (SCM smob)
 
       for (DOWN_and_UP (d))
         {
-          if (!staff_extent.contains (last->second[d].position_)
-              && !staff_extent.contains (i->second[d].position_))
+          // Some rank--> vdir--> reqs will be 'empty' because notes
+          // will not be above AND below the staff for a given rank.
+          if (!staff_extent.contains (last->second[d].max_position_)
+              && !staff_extent.contains (i->second[d].max_position_))
             {
+              // Midpoint between the furthest bounds of the two heads.
               Real center
-                = (last->second[d].head_extent_[RIGHT]
-                   + i->second[d].head_extent_[LEFT]) / 2;
+                = (last->second[d].max_head_extent_[RIGHT]
+                   + i->second[d].max_head_extent_[LEFT]) / 2;
+
+              // Do both reqs have notes further than the first space
+              // beyond the staff?
+              // (due tilt of quarter note-heads)
+              /* FIXME */
+              bool both
+                = (!staff_extent.contains (last->second[d].max_position_
+                                           - sign (last->second[d].max_position_))
+                   && !staff_extent.contains (i->second[d].max_position_
+                                              - sign (i->second[d].max_position_)));
 
               for (LEFT_and_RIGHT (which))
                 {
                   Ledger_request &lr = ((which == LEFT) ? * last : *i).second[d];
 
-                  // due tilt of quarter note-heads
-                  /* FIXME */
-                  bool both
-                    = (!staff_extent.contains (last->second[d].position_
-                                               - sign (last->second[d].position_))
-                       && !staff_extent.contains (i->second[d].position_
-                                                  - sign (i->second[d].position_)));
                   Real limit = (center + (both ? which * gap / 2 : 0));
-                  lr.ledger_extent_.at (-which)
-                    = which * max (which * lr.ledger_extent_[-which], which * limit);
+                  lr.max_ledger_extent_.at (-which)
+                    = which * max (which * lr.max_ledger_extent_[-which],
+                                   which * limit);
                 }
             }
         }
     }
 
-  // create ledgers for note heads
-  Real ledgerlinethickness
-    = Staff_symbol::get_ledger_line_thickness (staff);
-  for (vsize i = heads.size (); i--;)
+  // Iterate through ledger requests and the data they have about each
+  // note head to generate the final extents for all ledger lines.
+  // Note heads that are different widths produce different ledger
+  // extents and these are merged so the widest extent prevails
+  // (the union of the intervals) for each ledger line.
+  for (Ledger_requests::iterator i (reqs.begin ());
+       i != reqs.end (); i++)
     {
-      Item *h = dynamic_cast<Item *> (heads[i]);
-
-      int pos = Staff_symbol_referencer::get_rounded_position (h);
-      vector<Real> ledger_positions = Staff_symbol::ledger_positions (staff, pos);
-      if (!ledger_positions.empty ())
+      for (DOWN_and_UP (d))
         {
-          int ledger_count = ledger_positions.size ();
-          Interval head_size = h->extent (common[X_AXIS], X_AXIS);
-          Interval ledger_size = head_size;
-          ledger_size.widen (ledger_size.length () * length_fraction);
-
-          if (pos && !staff_extent.contains (pos))
+          Ledger_request &lr = i->second[d];
+          for (vsize h = 0; h < lr.heads_.size (); h++)
             {
-              Interval max_size = reqs[h->get_column ()->get_rank ()]
-                                  [Direction (sign (pos))].ledger_extent_;
-
-              if (!max_size.is_empty ())
-                ledger_size.intersect (max_size);
+              vector<Real> &ledger_posns = lr.heads_[h].ledger_positions_;
+              Interval &ledger_size = lr.heads_[h].ledger_extent_;
+              Interval &head_size = lr.heads_[h].head_extent_;
+              Interval &acc_extent = lr.heads_[h].accidental_extent_;
+
+              // Limit ledger extents to a maximum to preserve space
+              // between ledgers when note heads get close.
+              if (!lr.max_ledger_extent_.is_empty ())
+                ledger_size.intersect (lr.max_ledger_extent_);
+
+              // Iterate through the ledgers for a given note head.
+              for (vsize l = 0; l < ledger_posns.size (); l++)
+                {
+                  Real lpos = ledger_posns[l];
+                  Interval x_extent = ledger_size;
+
+                  // Notes with accidental signs get shorter ledgers.
+                  // (Only happens for the furthest note in the column.)
+                  if (l == 0 && !acc_extent.is_empty ())
+                    {
+                      Real dist
+                        = linear_combination (Drul_array<Real> (acc_extent[RIGHT],
+                                                                head_size[LEFT]),
+                                              0.0);
+
+                      Real left_shorten = max (-ledger_size[LEFT] + dist, 0.0);
+                      x_extent[LEFT] += left_shorten;
+                      /*
+                        TODO: shorten 2 ledger lines for the case
+                        natural + downstem.
+                      */
+                    }
+                  if (lr.ledger_extents_.find (lpos) == lr.ledger_extents_.end ())
+                    lr.ledger_extents_[lpos] = x_extent;
+                  else
+                    lr.ledger_extents_[lpos].unite (x_extent);
+                }
             }
+        }
+    }
 
-          for (int i = 0; i < ledger_count; i++)
-            {
-              Real lpos = ledger_positions[i];
-              Interval x_extent = ledger_size;
-
-              if (i == 0)
-                if (Grob *g = unsmob<Grob> (h->get_object ("accidental-grob")))
-                  {
-                    Interval accidental_size = g->extent (common[X_AXIS], X_AXIS);
-                    Real d
-                      = linear_combination (Drul_array<Real> (accidental_size[RIGHT],
-                                                              head_size[LEFT]),
-                                            0.0);
-
-                    Real left_shorten = max (-ledger_size[LEFT] + d, 0.0);
-
-                    x_extent[LEFT] += left_shorten;
-                    /*
-                      TODO: shorten 2 ledger lines for the case natural +
-                      downstem.
-                    */
-                  }
+  // Create the stencil for the ledger line spanner by iterating
+  // through the ledger requests and their data on ledger extents.
+  Stencil ledgers;
+  Real ledgerlinethickness
+    = Staff_symbol::get_ledger_line_thickness (staff);
 
+  for (Ledger_requests::iterator i (reqs.begin ());
+       i != reqs.end (); i++)
+    {
+      for (DOWN_and_UP (d))
+        {
+          map<Real, Interval> &lex = i->second[d].ledger_extents_;
+          for (map<Real, Interval>::iterator k = lex.begin ();
+               k != lex.end (); k++)
+            {
               Real blotdiameter = ledgerlinethickness;
+              Real lpos = k->first;
+              Interval x_extent = k->second;
               Interval y_extent
                 = Interval (-0.5 * (ledgerlinethickness),
                             +0.5 * (ledgerlinethickness));
@@ -316,7 +377,7 @@ Ledger_line_spanner::print (SCM smob)
         }
     }
 
-  ledgers.translate_axis (-me->relative_coordinate (common[X_AXIS], X_AXIS),
+  ledgers.translate_axis (-me->relative_coordinate (common_x, X_AXIS),
                           X_AXIS);
 
   return ledgers.smobbed_copy ();
index 94092984b598dec062cf1c496cff025939597b8e..7381ab5caa7fc0200326f4ffd0556560d5d2691b 100644 (file)
@@ -23,7 +23,7 @@ That's it.  For more information, visit http://lilypond.org .
 
 %}
 
-\version "2.19.39"  % necessary for upgrading to future LilyPond versions.
+\version "2.19.40"  % necessary for upgrading to future LilyPond versions.
 
 \header{
   title = "A scale in LilyPond"
index b2984a0833d8e8ed963a2c0a5d7b06b2d5c1f75f..6225500a8f3b3406c405ff39437f3db9173671c7 100644 (file)
@@ -32,7 +32,7 @@ Good luck with LilyPond!  Happy engraving.
 
 %}
 
-\version "2.19.39"  % necessary for upgrading to future LilyPond versions.
+\version "2.19.40"  % necessary for upgrading to future LilyPond versions.
 
 \header{
   title = "A scale in LilyPond"
index 0309639d0cf24f579c0bc4dc8b0d0ed6f9ce5e3b..45f8d4c26b1205c24cafd0b538acf02d4192ea6c 100644 (file)
@@ -6,10 +6,10 @@
 #, fuzzy
 msgid ""
 msgstr ""
-"Project-Id-Version: lilypond 2.19.39\n"
+"Project-Id-Version: lilypond 2.19.40\n"
 "Report-Msgid-Bugs-To: http://post.gmane.org/post.php?group=gmane.comp.gnu."
 "lilypond.bugs\n"
-"POT-Creation-Date: 2016-03-27 15:42+0100\n"
+"POT-Creation-Date: 2016-04-17 12:02+0100\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -3103,119 +3103,119 @@ msgstr ""
 msgid "giving up"
 msgstr ""
 
-#: parser.yy:480 parser.yy:963 parser.yy:1044 parser.yy:1264
+#: parser.yy:480 parser.yy:971 parser.yy:1052 parser.yy:1272
 msgid "bad expression type"
 msgstr ""
 
-#: parser.yy:875 parser.yy:1474 parser.yy:1519
+#: parser.yy:883 parser.yy:1482 parser.yy:1527
 msgid "not a context mod"
 msgstr ""
 
-#: parser.yy:1070
+#: parser.yy:1078
 msgid "Missing music in \\score"
 msgstr ""
 
-#: parser.yy:1107
+#: parser.yy:1115
 msgid "\\paper cannot be used in \\score, use \\layout instead"
 msgstr ""
 
-#: parser.yy:1142
+#: parser.yy:1150
 msgid "Spurious expression in \\score"
 msgstr ""
 
-#: parser.yy:1172
+#: parser.yy:1180
 msgid "need \\paper for paper block"
 msgstr ""
 
-#: parser.yy:1347
+#: parser.yy:1355
 msgid "music expected"
 msgstr ""
 
-#: parser.yy:1357 parser.yy:1391
+#: parser.yy:1365 parser.yy:1399
 msgid "unexpected post-event"
 msgstr ""
 
-#: parser.yy:1399
+#: parser.yy:1407
 msgid "Ignoring non-music expression"
 msgstr ""
 
-#: parser.yy:1715
+#: parser.yy:1723 parser.yy:1742
 msgid "not a key"
 msgstr ""
 
-#: parser.yy:2588 parser.yy:2706 parser.yy:2719 parser.yy:2728
+#: parser.yy:2611 parser.yy:2729 parser.yy:2742 parser.yy:2751
 msgid "bad grob property path"
 msgstr ""
 
-#: parser.yy:2686
+#: parser.yy:2709
 msgid "only \\consists and \\remove take non-string argument."
 msgstr ""
 
-#: parser.yy:2747
+#: parser.yy:2770
 msgid "bad context property path"
 msgstr ""
 
-#: parser.yy:2832
+#: parser.yy:2855
 msgid "markup expected"
 msgstr ""
 
-#: parser.yy:2844
+#: parser.yy:2867
 msgid "simple string expected"
 msgstr ""
 
-#: parser.yy:2861
+#: parser.yy:2884
 msgid "symbol expected"
 msgstr ""
 
-#: parser.yy:2997
+#: parser.yy:3028
 msgid "not a rhythmic event"
 msgstr ""
 
-#: parser.yy:3047
+#: parser.yy:3078
 msgid "post-event expected"
 msgstr ""
 
-#: parser.yy:3056 parser.yy:3061
+#: parser.yy:3087 parser.yy:3092
 msgid "have to be in Lyric mode for lyrics"
 msgstr ""
 
-#: parser.yy:3137
+#: parser.yy:3168
 msgid "expecting string or post-event as script definition"
 msgstr ""
 
-#: parser.yy:3241
+#: parser.yy:3272
 msgid "not an articulation"
 msgstr ""
 
-#: parser.yy:3307 parser.yy:3359
+#: parser.yy:3338 parser.yy:3390
 msgid "not a duration"
 msgstr ""
 
-#: parser.yy:3380
+#: parser.yy:3411
 msgid "bass number expected"
 msgstr ""
 
-#: parser.yy:3472
+#: parser.yy:3503
 msgid "have to be in Note mode for notes"
 msgstr ""
 
-#: parser.yy:3511
+#: parser.yy:3542
 msgid "have to be in Chord mode for chords"
 msgstr ""
 
-#: parser.yy:3554
+#: parser.yy:3585
 msgid "markup outside of text script or \\lyricmode"
 msgstr ""
 
-#: parser.yy:3559
+#: parser.yy:3590
 msgid "unrecognized string, not in text script or \\lyricmode"
 msgstr ""
 
-#: parser.yy:3711 parser.yy:3720
+#: parser.yy:3742 parser.yy:3751
 msgid "not an unsigned integer"
 msgstr ""
 
-#: parser.yy:3807
+#: parser.yy:3838
 msgid "not a markup"
 msgstr ""
 
index d3234b332913e0fcbaade4d3b525dc7a21838711..ca3372ca92557b2d32129ea705f692f2e8977be0 100644 (file)
   (if (ly:get-option 'embed-source-code)
       (let ((source-list (delete-duplicates
                           (remove (lambda (str)
-                                    (string-contains str
-                                      (ly:get-option 'datadir)))
+                                    (or
+                                     (string-contains str
+                                       (ly:get-option 'datadir))
+                                     (string=? str
+                                       "<included string>")))
                             (ly:source-files)))))
          (display "\n/pdfmark where
 {pop} {userdict /pdfmark /cleartomark load put} ifelse" port)