make -C $LILYPOND_BUILD_DIR po-replace
mv $LILYPOND_BUILD_DIR/po/lilypond.pot po/
gedit Documentation/web/news-front.itexi Documentation/web/news.itexi
+gedit VERSION
@end example
+@itemize
+@item
+VERSION_DEVEL = the current development version (previous VERSION_DEVEL + 0.01)
+
+@item
+VERSION_STABLE = the current stable version (probably no change here)
+
+@end itemize
+
@item
Commit, push, switch back to master (or wherever else):
@example
+git commit -m "Release: bump VERSION_DEVEL." VERSION
git commit -m "PO: update template." po/lilypond.pot
git commit -m "Release: update news." Documentation/web/
git push origin HEAD:release/unstable
or something like:
@example
-make LILYPOND_BRANCH=stable/2.12 lilypond
+make LILYPOND_BRANCH=stable/2.16 lilypond
@end example
-@item Check the regtest comparison in @file{uploads/webtest/} for
+@item
+Check the regtest comparison in @file{uploads/webtest/} for
any unintentional breakage. More info in
@ref{Precompiled regression tests}.
-@item If any work was done on GUB since the last release, upload
+@item
+If any work was done on GUB since the last release, upload
binaries to a temporary location, ask for feedback, and wait a day
or two in case there's any major problems.
test-lily/rsync-test.py
@end example
-@code{graham} owns v2.13; @code{han-wen} owns v2.12.
-
@item Upload GUB by running:
@example
@enumerate
-@item Update the current staging branch with the current news:
+@item
+Update the current staging branch with the current news:
@example
git fetch
git merge origin/release/unstable
@end example
-@item Update @file{VERSION} in lilypond git and upload changes:
+@item
+Update @file{VERSION} in lilypond git and upload changes:
@example
-vi VERSION
+gedit VERSION
@end example
@itemize
@item
VERSION = what you just did +0.0.1
-
-@item
-DEVEL_VERSION = what you just did (i.e. is now online)
-
-@item
-STABLE_VERSION = what's online (probably no change here)
-
@end itemize
@example
-git commit -m "Release: bump version." VERSION
+git commit -m "Release: bump VERSION." VERSION
git push origin HEAD:staging
@end example
preparing your change. In that case, you need to restart the Post
Release process. Otherwise, proceed:
-@item (for now) do a @code{make doc} and manually upload:
-
-@example
-### upload-lily-web-media.sh
-#!/bin/sh
-BUILD_DIR=$HOME/src/build-lilypond
-
-PICS=$BUILD_DIR/Documentation/pictures/out-www/
-EXAMPLES=$BUILD_DIR/Documentation/ly-examples/out-www/
-
-cd $BUILD_DIR
-rsync -a $PICS graham@@lilypond.org:media/pictures
-rsync -a $EXAMPLES graham@@lilypond.org:media/ly-examples
-@end example
-
@item Wait a few hours for the website to update.
@item Email release notice to @code{info-lilypond}
Guide, node Updating translation committishes.
@end ignore
-@c \version "2.17.18"
+@c \version "2.17.19"
@c Translators: Till Paala
"It has two lines."
}
}
- \vspace #0.1 % adds vertical spacing between verses
+ \combine \null \vspace #0.1 % adds vertical spacing between verses
\line { \bold "3."
\column {
"This is verse three."
"It has two lines."
}
}
- \vspace #0.1 % adds vertical spacing between verses
+ \combine \null \vspace #0.1 % adds vertical spacing between verses
\line { \bold "5."
\column {
"This is verse five."
Guide, node Updating translation committishes..
@end ignore
-@c \version "2.17.18"
+@c \version "2.17.19"
@node Música vocal
@section Música vocal
"It has two lines."
}
}
- \vspace #0.1 % adds vertical spacing between verses
+ \combine \null \vspace #0.1 % adds vertical spacing between verses
\line { \bold "3."
\column {
"This is verse three."
"It has two lines."
}
}
- \vspace #0.1 % adds vertical spacing between verses
+ \combine \null \vspace #0.1 % adds vertical spacing between verses
\line { \bold "5."
\column {
"This is verse five."
Guide, node Updating translation committishes..
@end ignore
-@c \version "2.17.18"
+@c \version "2.17.19"
@c Translators: Valentin Villenave, Jean-Charles Malahieude
@c Translation checkers: Jean-Jacques Gerbaud
"Je me suis fait sécher..."
}
}
- \vspace #0.1 % ajout d'espace vertical entre les couplets
+ \combine \null \vspace #0.1 % ajout d'espace vertical entre les couplets
\line { \bold "3."
\column {
"Chante, rossignol, chante,"
"Sans l'avoir mérité..."
}
}
- \vspace #0.1 % ajout d'espace vertical entre les couplets
+ \combine \null \vspace #0.1 % ajout d'espace vertical entre les couplets
\line { \bold "5."
\column {
"Je voudrais que la rose"
Guide, node Updating translation committishes..
@end ignore
-@c \version "2.17.18"
+@c \version "2.17.19"
@c Translators: Yoshiki Sawada
@c Translation status: post-GDP
"It has two lines."
}
}
- \vspace #0.1 % 次の歌詞との間に垂直方向のスペースを入れます
+ \combine \null \vspace #0.1 % 次の歌詞との間に垂直方向のスペースを入れます
\line { \bold "3."
\column {
"This is verse three."
"It has two lines."
}
}
- \vspace #0.1 % 次の歌詞との間に垂直方向のスペースを入れます
+ \combine \null \vspace #0.1 % 次の歌詞との間に垂直方向のスペースを入れます
\line { \bold "5."
\column {
"This is verse five."
@lilypond[verbatim,ragged-right,quote]
<<
- \new Staff = myStaff
+ \new Staff = "myStaff"
\figuremode {
<4>4 <10 6>8 s8
<6 4>4 <6 4>
}
%% Put notes on same Staff as figures
- \context Staff = myStaff
+ \context Staff = "myStaff"
{
\clef bass
c4 c'8 r8 c4 c'
@lilypond[verbatim,ragged-right,quote]
<<
- \new Staff = myStaff
+ \new Staff = "myStaff"
\figuremode {
<4>4 <10 6>8 s8
\bassFigureStaffAlignmentDown
<6 4>4 <6 4>
}
%% Put notes on same Staff as figures
- \context Staff = myStaff
+ \context Staff = "myStaff"
{
\clef bass
c4 c'8 r8 c4 c'
@endpredefined
The lines of a staff belong to the @code{StaffSymbol} grob (including
-ledger lines) can be modified using @code{StaffSymbol} properties, but
+ledger lines) and can be modified using @code{StaffSymbol} properties, but
these modifications must be made before the staff is (re)started.
-The number of staff lines can be altered,
+The number of staff lines can be altered:
@lilypond[verbatim,quote,relative=2]
f4 d \stopStaff
@end lilypond
The position of each staff line can also be altered. A list of
-numbers sets each line's position. @code{0} corresponds to the normal
+numbers sets each line's position. @code{0}@tie{}corresponds to the normal
center line, and the normal line positions are
@code{(-4@tie{}-2@tie{}0@tie{}2@tie{}4)}. A single staff line is
printed for every value entered so that the number of staff lines, as
The @code{\stopStaff} is needed in the example to revert the
@code{\override} for the whole @code{StaffSymbol}.
-@lilypond[fragment,quote,relative=1]
-\override Staff.StaffSymbol.line-positions = #'(-8 0 2 4)
+@lilypond[verbatim,quote,relative=1]
+\override Staff.StaffSymbol.line-positions = #'(-8 0 2 4)
d4 e f g
\stopStaff
\startStaff
only a few ossia staves are needed.
@lilypond[verbatim,quote]
-\new Staff = main \relative c'' {
+\new Staff = "main" \relative c'' {
c4 b d c
<<
{ c4 b d c }
@lilypond[verbatim,quote,ragged-right]
<<
- \new Staff = ossia \with {
+ \new Staff = "ossia" \with {
\remove "Time_signature_engraver"
\override Clef.transparent = ##t
fontSize = #-3
c4 b c2
<<
{ e4 f e2 }
- \context Staff = ossia {
+ \context Staff = "ossia" {
\startStaff e4 g8 f e2 \stopStaff
}
>>
c4 b c2
<<
{ g4 a g2 }
- \context Staff = ossia {
+ \context Staff = "ossia" {
\startStaff g4 e8 f g2 \stopStaff
}
>>
@lilypond[verbatim,quote,ragged-right]
<<
- \new Staff = ossia \with {
+ \new Staff = "ossia" \with {
\remove "Time_signature_engraver"
\override Clef.transparent = ##t
fontSize = #-3
Guide, node Updating translation committishes..
@end ignore
-@c \version "2.17.18"
+@c \version "2.17.19"
@node Vocal music
@section Vocal music
"It has two lines."
}
}
- \vspace #0.1 % adds vertical spacing between verses
+ \combine \null \vspace #0.1 % adds vertical spacing between verses
\line { \bold "3."
\column {
"This is verse three."
"It has two lines."
}
}
- \vspace #0.1 % adds vertical spacing between verses
+ \combine \null \vspace #0.1 % adds vertical spacing between verses
\line { \bold "5."
\column {
"This is verse five."
%% and then run scripts/auxiliar/makelsr.py
%%
%% This file is in the public domain.
-\version "2.17.15"
+\version "2.17.19"
\header {
lsrtags = "paper-and-layout, staff-notation, syntax-and-expressions"
\header {
title = \markup
\column {
- \vspace #1
+ \combine \null \vspace #1
"Exercise: Improve the given choral"
" "
}
@c used for news about the upcoming release; see CG 10.2
@newsItem
-@subsubheading LilyPond 2.17.18 released! @emph{May 11, 2013}
+@subsubheading LilyPond 2.17.19 released! @emph{May 26, 2013}
-We are happy to announce the release of LilyPond 2.17.18. This
+We are happy to announce the release of LilyPond 2.17.19. This
release contains the usual number of bugfixes and 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
* don't duplicate entries from news-front.itexi
@end ignore
+@newsItem
+@subsubheading LilyPond 2.17.18 released! @emph{May 11, 2013}
+
+We are happy to announce the release of LilyPond 2.17.18. This
+release contains the usual number of bugfixes and 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.16 version.
+
+@newsEnd
+
@newsItem
@subsubheading LilyPond 2.17.17 released! @emph{April 27, 2013}
note = {(@uref{http://lilypond.org/website/pdf/graham-sustainability-FOSS.pdf, PDF 333k})}
}
+@inproceedings{hollerweger01,
+ title = {Lilypond: music notation for everyone!},
+ author = {Margarethe Maierhofer-Lischka & Florian Hollerweger},
+ booktitle = {Linux Audio Conference 2013 (LAC2013)},
+ year = 2013,
+ note = {(@uref{http://lilypond.org/website/pdf/lilypond_lac2013.pdf, PDF 890k})}
+}
PACKAGE_NAME=LilyPond
MAJOR_VERSION=2
MINOR_VERSION=17
-PATCH_LEVEL=19
+PATCH_LEVEL=20
MY_PATCH_LEVEL=
VERSION_STABLE=2.16.2
-VERSION_DEVEL=2.17.18
+VERSION_DEVEL=2.17.19
\relative c' {
\balloonGrobText #'Stem #'(3 . 4) \markup { "I'm a Stem" }
<c-\balloonText #'(-2 . -2) \markup { \simple #"hoi" } >8
+ \balloonLengthOn
+ \balloonGrobText #'Rest #'(-1 . -2) \markup{ "Rest" }
+ r
+ \balloonLengthOff
+ \balloonGrobText #'Script #'(-1 . -1) \markup{ "Accent" }
+ c4->
}
}
\markup \override #'(fret-diagram-details . ((finger-code . below-string))) {
\myFretDiagram
- \hspace #4
\override #'(size . 1.5) \myFretDiagram
- \hspace #8
\override #'(size . 3) \myFretDiagram
}
-\version "2.17.12"
+\version "2.17.19"
\header {
texidoc = "@code{\\note-by-number} and @code{\\note} support
\markup {
\column {
- \vspace #1
+ \combine \null \vspace #1
\underline "Note-head-styles:"
\override #'(baseline-skip . 6)
\show-note-styles #styles-list
\markup {
\column {
- \vspace #1
+ \combine \null \vspace #1
\underline "Modern-straight-flag:"
\override #'(flag-style . modern-straight-flag)
\show-note-styles #'(default)
\markup {
\column {
- \vspace #1
+ \combine \null \vspace #1
\underline "Old-straight-flag:"
\override #'(flag-style . old-straight-flag)
\show-note-styles #'(default)
-\version "2.17.9"
+\version "2.17.19"
\header {
texidoc = "The rest markup function works for a variety of style, dot and
semipetrucci
kievan)))))
-\markup \column { \bold "Simple Rests" \vspace #0.1 }
+\markup \column { \bold "Simple Rests" \combine \null \vspace #0.1 }
\showSimpleRest #"."
-\markup \column { \vspace #0.1 \bold "MultiMeasureRests" \vspace #0.1 }
+\markup \column { \combine \null \vspace #0.1 \bold "MultiMeasureRests" \combine \null \vspace #0.1 }
\showMultiMeasureRests
-\version "2.16.0"
+\version "2.17.19"
\header {
texidoc = "
A list of special character ASCII aliases can be easily included.
\italic \justify {
№2 – &OE;dipe…
}
- \vspace #0.5
+ \combine \null \vspace #0.5
\bold "Lyric example:"
}
\new Lyrics \lyricmode {
\paper {
#(define page-breaking ly:optimal-breaking)
- page-spacing-weight = #10
+ page-spacing-weight = #100 % default is 10
ragged-last-bottom = ##t
}
\relative c' {
+ <>_"this page stretched horizontally"
\repeat unfold 5 {a b c d} \pageBreak
+ <>_"this page with natural spacing"
\repeat unfold 5 {a b c d}
}
ragged-last-bottom = ##f
oddHeaderMarkup = \markup {
- \override #'(baseline-skip . 1)
+ \override #'(baseline-skip . 2.5)
\center-column {
\box \fill-line { \teeny " " " " }
\on-the-fly #first-page "first-page-header-text"
evenHeaderMarkup = \oddHeaderMarkup
oddFooterMarkup = \markup \fill-line {
- \override #'(baseline-skip . 0.5)
+ \override #'(baseline-skip . 1)
\center-column {
\on-the-fly #first-page "first-page-footer-text"
\on-the-fly #last-page "last-page-footer-text"
+++ /dev/null
-\version "2.16.0"
-#(set-default-paper-size "a6")
-
-\header {
- texidoc = "The space between systems can be limited when there is too
-much space left on the page by setting @code{page-limit-inter-system-space}."
-}
-
-\book {
- \paper {
- page-limit-inter-system-space = ##t
- page-limit-inter-system-space-factor = 1.4
-
- ragged-last-bottom = ##f
-
- oddFooterMarkup = \markup "page bottom"
- evenFooterMarkup = \markup "page bottom"
- oddHeaderMarkup = \markup \fill-line {
- "page top" \fromproperty #'page:page-number-string }
- evenHeaderMarkup = \markup \fill-line {
- "page top" \fromproperty #'page:page-number-string }
- }
- \new Staff << \repeat unfold 9 { g'4 g' g' g' \break }
- { s1*2 \pageBreak
- s1*3 \pageBreak } >>
-}
\version "2.16.0"
\header {
- texidoc = "Slurs that depend on a cross-staff beam are not calculated until
-after line-breaking and after inside-going articulations have been placed."
+ texidoc = "Slurs that depend on a cross-staff beam are not calculated until after line-breaking."
}
\paper { ragged-right=##t }
\score {
\new PianoStaff <<
- \context Staff = rh \relative c'' { c8([ d) \change Staff = lh c,] r
- \stemDown c'8 \change Staff = rh c_( \change Staff = lh c_\marcato c)}
- \context Staff = lh { s1 }
+ \context Staff = rh \relative c'' { c8([ d) \change Staff = lh c,] }
+ \context Staff = lh { s4. }
>>
}
Box::translate (Offset o)
{
for (Axis i = X_AXIS; i < NO_AXES; incr (i))
- interval_a_[i] += o[i];
+ if (!is_empty (i))
+ interval_a_[i] += o[i];
}
void
bool
Box::is_empty () const
{
- return interval_a_[X_AXIS].is_empty ()
- || interval_a_[Y_AXIS].is_empty ();
+ return is_empty (X_AXIS) && is_empty (Y_AXIS);
+}
+
+bool
+Box::is_empty (Axis a) const
+{
+ Interval empty;
+ empty.set_empty ();
+ return interval_a_[a][LEFT] == empty[LEFT]
+ && interval_a_[a][RIGHT] == empty[RIGHT];
}
Box::Box (Interval ix, Interval iy)
last_column_ = 0;
force_ = 0;
Stencil *st = unsmob_stencil (pb->get_property ("stencil"));
- Interval stencil_extent = st->is_empty () ? Interval (0, 0)
+ Interval stencil_extent = st->is_empty (Y_AXIS) ? Interval (0, 0)
: st->extent (Y_AXIS);
shape_ = Line_shape (stencil_extent, stencil_extent); // pretend it goes all the way across
tallness_ = 0;
for (int i = scm_to_int (c); i--;)
{
- d.translate_axis (2 * dw, X_AXIS);
mol.add_at_edge (X_AXIS, RIGHT, d, dw);
}
}
Interval &operator [] (Axis a);
Real area () const;
bool is_empty () const;
+ bool is_empty (Axis a) const;
Offset center () const;
Set dimensions to empty, or to (Interval (0, 0), Interval (0, 0) */
void set_empty (bool);
void add_at_edge (Axis a, Direction d, const Stencil &m, Real padding);
+ void stack (Axis a, Direction d, const Stencil &m, Real padding, Real mindist);
void add_stencil (Stencil const &m);
void translate (Offset);
Stencil translated (Offset) const;
Interval extent (Axis) const;
Box extent_box () const;
bool is_empty () const;
+ bool is_empty (Axis) const;
Stencil in_color (Real r, Real g, Real b) const;
static SCM skylines_from_stencil (SCM, Real, Axis);
};
(e->get_maybe_pure_property (a == X_AXIS
? "horizontal-skylines"
: "vertical-skylines",
- pure,
+ pure || cross_staff,
start,
end));
sky_ = sky;
for (vsize i = 0; i < boxes.size (); i++)
- if (!boxes[i].is_empty ())
+ if (!boxes[i].is_empty (X_AXIS)
+ && !boxes[i].is_empty (Y_AXIS))
buildings.push_front (Building (boxes[i], horizon_axis, sky));
buildings_ = internal_build_skyline (&buildings);
Skyline::Skyline (Box const &b, Axis horizon_axis, Direction sky)
{
sky_ = sky;
- Building front (b, horizon_axis, sky);
- single_skyline (front, &buildings_);
- normalize ();
+ if (!b.is_empty (X_AXIS) && !b.is_empty (Y_AXIS))
+ {
+ Building front (b, horizon_axis, sky);
+ single_skyline (front, &buildings_);
+ normalize ();
+ }
}
void
}
/* do the same filtering as in Skyline (vector<Box> const&, etc.) */
- if (b.is_empty ())
+ if (b.is_empty (X_AXIS) || b.is_empty (Y_AXIS))
return;
my_bld.splice (my_bld.begin (), buildings_);
}
LY_DEFINE (ly_stencil_empty_p, "ly:stencil-empty?",
- 1, 0, 0, (SCM stil),
- "Return whether @var{stil} is empty.")
+ 1, 1, 0, (SCM stil, SCM axis),
+ "Return whether @var{stil} is empty. If an optional"
+ " @var{axis} is supplied, the emptiness check is"
+ " restricted to that axis.")
{
Stencil *s = unsmob_stencil (stil);
LY_ASSERT_SMOB (Stencil, stil, 1);
- return scm_from_bool (s->is_empty ());
+ if (SCM_UNBNDP (axis))
+ return scm_from_bool (s->is_empty ());
+ LY_ASSERT_TYPE (is_axis, axis, 2);
+ return scm_from_bool (s->is_empty (Axis (scm_to_int (axis))));
}
LY_DEFINE (ly_stencil_combine_at_edge, "ly:stencil-combine-at-edge",
return result.smobbed_copy ();
}
+LY_DEFINE (ly_stencil_stack, "ly:stencil-stack",
+ 4, 2, 0, (SCM first, SCM axis, SCM direction,
+ SCM second,
+ SCM padding,
+ SCM mindist),
+ "Construct a stencil by stacking @var{second} next to @var{first}."
+ " @var{axis} can be 0 (x-axis) or@tie{}1 (y-axis)."
+ " @var{direction} can be -1 (left or down) or@tie{}1 (right or"
+ " up). The stencils are juxtaposed with @var{padding} as extra"
+ " space. @var{first} and @var{second} may also be @code{'()} or"
+ " @code{#f}. As opposed to @code{ly:stencil-combine-at-edge},"
+ " metrics are suited for successively accumulating lines of"
+ " stencils. Also, @var{second} stencil is drawn last.\n\n"
+ "If @var{mindist} is specified, reference points are placed"
+ " apart at least by this distance. If either of the stencils"
+ " is spacing, @var{padding} and @var{mindist} do not apply.")
+{
+ Stencil *s1 = unsmob_stencil (first);
+ Stencil *s2 = unsmob_stencil (second);
+ Stencil result;
+
+ SCM_ASSERT_TYPE (s1 || first == SCM_BOOL_F || first == SCM_EOL,
+ first, SCM_ARG1, __FUNCTION__, "Stencil, #f or ()");
+ SCM_ASSERT_TYPE (s2 || second == SCM_BOOL_F || second == SCM_EOL,
+ second, SCM_ARG4, __FUNCTION__, "Stencil, #f or ()");
+ LY_ASSERT_TYPE (is_axis, axis, 2);
+ LY_ASSERT_TYPE (is_direction, direction, 3);
+
+ Real p = 0.0;
+ if (padding != SCM_UNDEFINED)
+ {
+ LY_ASSERT_TYPE (scm_is_number, padding, 5);
+ p = scm_to_double (padding);
+ }
+ Real d = -infinity_f;
+ if (!SCM_UNBNDP (mindist))
+ {
+ LY_ASSERT_TYPE (scm_is_number, mindist, 6);
+ d = scm_to_double (mindist);
+ }
+
+ if (s1)
+ result = *s1;
+
+ if (s2)
+ result.stack (Axis (scm_to_int (axis)),
+ Direction (scm_to_int (direction)), *s2, p, d);
+
+ return result.smobbed_copy ();
+}
+
LY_DEFINE (ly_stencil_add, "ly:stencil-add",
0, 0, 1, (SCM args),
"Combine stencils. Takes any number of arguments.")
"@item\n"
"The vertical and horizontal extents of the object, given as"
" pairs. If an extent is unspecified (or if you use"
- " @code{(1000 . -1000)} as its value), it is taken to be empty.\n"
+ " @code{empty-interval} as its value), it is taken to be empty.\n"
"@end enumerate\n")
{
SCM_ASSERT_TYPE (!scm_is_pair (expr)
bool
Stencil::is_empty () const
-/* If only one of X- or Y-extent is empty; such a stencil can be useful
- * for backspacing, as with \hspace #-2, so we do not consider it empty.
- */
{
return (expr_ == SCM_EOL
- || (dim_[X_AXIS].is_empty ()
- && dim_[Y_AXIS].is_empty ()));
+ || dim_.is_empty ());
+}
+
+bool
+Stencil::is_empty (Axis a) const
+{
+ return dim_.is_empty (a);
}
SCM
incr (a);
}
- expr_ = scm_list_n (ly_symbol2scm ("translate-stencil"),
- ly_offset2scm (o),
- expr_, SCM_UNDEFINED);
+ if (!scm_is_null (expr_))
+ expr_ = scm_list_n (ly_symbol2scm ("translate-stencil"),
+ ly_offset2scm (o),
+ expr_, SCM_UNDEFINED);
if (!is_empty ())
dim_.translate (o);
}
Stencil::add_stencil (Stencil const &s)
{
SCM cs = ly_symbol2scm ("combine-stencil");
- if (scm_is_pair (expr_)
+ if (scm_is_null (expr_))
+ expr_ = s.expr_;
+ else if (scm_is_null (s.expr_))
+ ;
+ else if (scm_is_pair (expr_)
&& scm_is_eq (cs, scm_car (expr_)))
{
if (scm_is_pair (s.expr_)
void
Stencil::align_to (Axis a, Real x)
{
- if (is_empty ())
+ if (is_empty (a))
return;
Interval i (extent (a));
}
/* See scheme Function. */
+
+// Any stencil that is empty in the orthogonal axis is spacing.
+// Spacing is not subjected to the max (0) rule and can thus be
+// negative.
+
void
Stencil::add_at_edge (Axis a, Direction d, Stencil const &s, Real padding)
{
- Interval my_extent = dim_[a];
- Interval i (s.extent (a));
- Real his_extent;
- if (i.is_empty ())
+ // Material that is empty in the axis of reference has only limited
+ // usefulness for combining. We still retain as much information as
+ // available since there may be uses like setting page links or
+ // background color or watermarks, and off-axis extents.
+
+ if (is_empty (a))
{
- programming_error ("Stencil::add_at_edge: adding empty stencil.");
- his_extent = 0.0;
+ add_stencil (s);
+ return;
}
- else
- his_extent = i[-d];
- Real offset = (my_extent.is_empty () ? 0.0 : my_extent[d] - his_extent)
- + d * padding;
+ Interval first_extent = extent (a);
+
+ if (s.is_empty (a))
+ {
+ Stencil toadd (s);
+ // translation does not affect axis-empty extent box.
+ toadd.translate_axis (first_extent[d], a);
+ add_stencil (toadd);
+ return;
+ }
+
+ Interval next_extent = s.extent (a);
+
+ bool first_is_spacing = is_empty (other_axis (a));
+ bool next_is_spacing = s.is_empty (other_axis (a));
+
+ Real offset = first_extent[d] - next_extent[-d];
+
+ if (!(first_is_spacing || next_is_spacing))
+ {
+ offset += d * padding;
+ }
Stencil toadd (s);
toadd.translate_axis (offset, a);
add_stencil (toadd);
}
+// Stencil::stack is mainly used for assembling lines or columns
+// of stencils. For the most common case of adding at the right, the
+// reference point of the added stencil is usually placed at the right
+// edge of the current one, unless the added stencil has a negative
+// left extent in which case its left edge is placed at the right edge
+// of the current one.
+//
+// Spacing is special in that it is applied without padding. Spacing
+// at the right edge shifts the right edge accordingly.
+//
+// For spacing at the left edge, there are several approaches. In
+// order to get to predictable behavior, we want to have at least a
+// continuous approach. An obvious idea is to do a "translate" by the
+// appropriate amount. Doing that while retaining the nominal left
+// edge seems like the most straightforward way.
+
+void
+Stencil::stack (Axis a, Direction d, Stencil const &s, Real padding, Real mindist)
+{
+ // Material that is empty in the axis of reference can't be sensibly
+ // stacked. We just revert to add_at_edge behavior then.
+
+ if (is_empty (a))
+ {
+ Stencil toadd (s);
+ toadd.add_stencil (*this);
+ expr_ = toadd.expr ();
+ dim_ = toadd.extent_box ();
+ return;
+ }
+
+ Interval first_extent = extent (a);
+
+ if (s.is_empty (a))
+ {
+ Stencil toadd (s);
+ toadd.translate_axis (first_extent[d], a);
+ toadd.add_stencil (*this);
+ expr_ = toadd.expr ();
+ dim_ = toadd.extent_box ();
+ return;
+ }
+
+ Interval next_extent = s.extent (a);
+
+ // It is somewhat tedious to special-case all spacing, but it turns
+ // out that not doing so makes it astonishingly hard to make the
+ // code do the correct thing.
+
+ // If first is spacing, we translate second accordingly without
+ // letting this affect its backward edge.
+ if (is_empty (other_axis (a)))
+ {
+ Stencil toadd (s);
+ Real offset = d * first_extent.delta ();
+ toadd.translate_axis (offset, a);
+ toadd.add_stencil (*this);
+ expr_ = toadd.expr ();
+ dim_ = toadd.extent_box ();
+ dim_[a][-d] = next_extent[-d];
+ dim_[a][d] = next_extent[d] + offset;
+ return;
+ }
+
+ // If next is spacing, similar action:
+ if (s.is_empty (other_axis (a)))
+ {
+ Stencil toadd (s);
+ Real offset = first_extent [d];
+ toadd.translate_axis (offset, a);
+ toadd.add_stencil (*this);
+ expr_ = toadd.expr ();
+ dim_ = toadd.extent_box ();
+ dim_[a][-d] = first_extent[-d];
+ dim_[a][d] = first_extent[d] + d * next_extent.delta ();
+ return;
+ }
+
+
+ Real offset = first_extent[d];
+
+ // If the added stencil has a backwardly protruding edge, we make
+ // room for it when combining.
+
+ if (d * next_extent [-d] < 0)
+ offset -= next_extent [-d];
+
+ offset += d * padding;
+
+ if (offset * d < mindist)
+ offset = d * mindist;
+
+ Stencil toadd (s);
+ toadd.translate_axis (offset, a);
+ toadd.add_stencil (*this);
+ expr_ = toadd.expr ();
+ dim_ = toadd.extent_box ();
+ dim_[a][-d] = first_extent [-d];
+ dim_[a][d] = next_extent [d] + offset;
+}
+
+
Stencil
Stencil::in_color (Real r, Real g, Real b) const
{
\paper {
tocTitleMarkup = \markup \huge \column {
\fill-line { \null "Table of Contents" \null }
- \hspace #1
+ \null
}
tocItemMarkup = \markup \fill-line {
\fromproperty #'toc:text \fromproperty #'toc:page
#, fuzzy
msgid ""
msgstr ""
-"Project-Id-Version: lilypond 2.17.18\n"
+"Project-Id-Version: lilypond 2.17.19\n"
"Report-Msgid-Bugs-To: http://post.gmane.org/post.php?group=gmane.comp.gnu."
"lilypond.bugs\n"
-"POT-Creation-Date: 2013-05-11 16:02+0100\n"
+"POT-Creation-Date: 2013-05-26 16:46+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"
"values"
msgstr ""
-#: page-layout-problem.cc:403
+#: page-layout-problem.cc:402
msgid ""
"A page layout problem has been initiated that cannot accommodate footnotes."
msgstr ""
-#: page-layout-problem.cc:732
+#: page-layout-problem.cc:731
msgid ""
"cannot fit music on page: ragged-spacing was requested, but page was "
"compressed"
msgstr ""
-#: page-layout-problem.cc:735
+#: page-layout-problem.cc:734
#, c-format
msgid "cannot fit music on page: overflow is %f"
msgstr ""
-#: page-layout-problem.cc:737
+#: page-layout-problem.cc:736
msgid "compressing music to fit"
msgstr ""
-#: page-layout-problem.cc:1197
+#: page-layout-problem.cc:1199
msgid "staff-affinities should only decrease"
msgstr ""
msgid "unknown parent class `~a'"
msgstr ""
-#: define-markup-commands.scm:986
+#: define-markup-commands.scm:985
msgid "no systems found in \\score markup, does it have a \\layout block?"
msgstr ""
-#: define-markup-commands.scm:2772
+#: define-markup-commands.scm:2781
#, scheme-format
msgid "Cannot find glyph ~a"
msgstr ""
-#: define-markup-commands.scm:3198
+#: define-markup-commands.scm:3207
#, scheme-format
msgid "no brace found for point size ~S "
msgstr ""
-#: define-markup-commands.scm:3199
+#: define-markup-commands.scm:3208
#, scheme-format
msgid "defaulting to ~S pt"
msgstr ""
-#: define-markup-commands.scm:3443
+#: define-markup-commands.scm:3452
#, scheme-format
msgid "not a valid duration string: ~a"
msgstr ""
-#: define-markup-commands.scm:3654
+#: define-markup-commands.scm:3663
#, scheme-format
msgid "not a valid duration string: ~a - ignoring"
msgstr ""
"applied to function @var{getter}."
msgstr ""
-#: lily-library.scm:977
+#: lily-library.scm:974
#, scheme-format
msgid "unknown unit: ~S"
msgstr ""
-#: lily-library.scm:1002
+#: lily-library.scm:999
#, scheme-format
msgid "no \\version statement found, please add~afor future compatibility"
msgstr ""
str = re.sub ('cueClefOctavationStyle', 'cueClefTranspositionStyle', str)
return str
+@rule((2, 17, 19), r"\column { \vspace #2 } -> \column { \combine \null \vspace #2 }")
+def conv(str):
+ def vspace_replace(m):
+
+# vspace now always adds space and does not, for example, change the
+# impact of either baselineskip or descenders on the line above.
+#
+# We can't simulate the old behavior in a simpler manner. A command
+# of its own is not really warranted since this behavior combines
+# badly enough with other spacing considerations (like baselineskip
+# and descenders) as to make it not all that useful. So this
+# conversion rule is here more for compatibility's sake rather than
+# preserving desirable behavior.
+
+ str = re.sub (r"(\\\\?)vspace(\s)", r"\1combine \1null \1vspace\2", m.group(0))
+ return str
+
+ str = re.sub (r"\\(?:left-|right-|center-|)column\s*\{" + brace_matcher (20) + r"\}",
+ vspace_replace, str)
+ return str
+
# Guidelines to write rules (please keep this at the end of this file)
#
# - keep at most one rule per version; if several conversions should be done,
(make-line-markup (list empty-markup))
(conditional-kern-before
(alteration->text-accidental-markup alteration)
- (= alteration FLAT) 0.2)))
+ (= alteration FLAT) 0.094725)))
(define (accidental->markup-italian alteration)
"Return accidental markup for ALTERATION, for use after an italian chord root name."
(make-hspace-markup 0.2)
(make-line-markup
(list
- (make-hspace-markup (if (= alteration FLAT) 0.7 0.5))
+ (make-hspace-markup (if (= alteration FLAT) 0.57285385 0.5))
(make-raise-markup 0.7 (alteration->text-accidental-markup alteration))
(make-hspace-markup (if (= alteration SHARP) 0.2 0.1))
))))
. (
(annotation-balloon . #t)
(annotation-line . #t)
+ (extra-spacing-width . (+inf.0 . -inf.0))
(stencil . ,ly:balloon-interface::print)
(text . ,(grob::calc-property-by-copy 'text))
(X-offset . ,(grob::calc-property-by-copy 'X-offset))
(Y-offset . ,(grob::calc-property-by-copy 'Y-offset))
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(meta . ((class . Item)
(interfaces . (balloon-interface
font-interface
;; utility functions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(define-public empty-stencil (ly:make-stencil '() '(1 . -1) '(1 . -1)))
+(define-public empty-stencil (ly:make-stencil '()
+ empty-interval empty-interval))
(define-public point-stencil (ly:make-stencil "" '(0 . 0) '(0 . 0)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define-markup-command (hspace layout props amount)
(number?)
#:category align
- #:properties ((word-space))
"
@cindex creating horizontal spaces in text
three
}
@end lilypond"
- (let ((corrected-space (- amount word-space)))
- (ly:make-stencil "" (cons 0 corrected-space) '(0 . 0))))
+ (ly:make-stencil "" (cons 0 amount) empty-interval))
(define-markup-command (vspace layout props amount)
(number?)
}
@end lilypond"
(let ((amount (* amount 3.0)))
- (ly:make-stencil "" (cons 0 0) (cons 0 amount))))
+ (ly:make-stencil "" empty-interval (cons 0 amount))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(let ((stencils (interpret-markup-list layout props args)))
(if (= text-direction LEFT)
(set! stencils (reverse stencils)))
- (stack-stencil-line
- word-space
- (remove ly:stencil-empty? stencils))))
+ (stack-stencil-line word-space stencils)))
(define-markup-command (concat layout props args)
(markup-list?)
;; justify only stretches lines.
(* 0.7 base-space)
base-space))
+ (define (stencil-space stencil line-start)
+ (if (ly:stencil-empty? stencil X)
+ 0
+ (cdr (ly:stencil-extent
+ (ly:stencil-stack (if line-start
+ empty-stencil
+ point-stencil)
+ X RIGHT stencil)
+ X))))
(define (take-list width space stencils
accumulator accumulated-width)
"Return (head-list . tail) pair, with head-list fitting into width"
(if (null? stencils)
(cons accumulator stencils)
(let* ((first (car stencils))
- (first-wid (cdr (ly:stencil-extent (car stencils) X)))
- (newwid (+ space first-wid accumulated-width)))
+ (first-wid (stencil-space first (null? accumulator)))
+ (newwid (+ (if (or (ly:stencil-empty? first Y)
+ (ly:stencil-empty? first X))
+ 0 space)
+ first-wid accumulated-width)))
(if (or (null? accumulator)
(< newwid width))
(take-list width space
'() 0.0))
(line-stencils (car line-break))
(space-left (- line-width
- (apply + (map (lambda (x) (cdr (ly:stencil-extent x X)))
- line-stencils))))
+ (stencil-space
+ (stack-stencil-line 0 line-stencils)
+ #t)))
+ (line-words (count (lambda (s) (not (or (ly:stencil-empty? s Y)
+ (ly:stencil-empty? s X))))
+ line-stencils))
(line-word-space (cond ((not justify) space)
;; don't stretch last line of paragraph.
;; hmmm . bug - will overstretch the last line in some case.
((null? (cdr line-break))
base-space)
- ((null? line-stencils) 0.0)
- ((null? (cdr line-stencils)) 0.0)
- (else (/ space-left (1- (length line-stencils))))))
- (line (stack-stencil-line line-word-space
+ ((< line-words 2) space)
+ (else (/ space-left (1- line-words)))))
+ (line (stack-stencil-line line-word-space
(if (= text-dir RIGHT)
(reverse line-stencils)
line-stencils))))
(word-space)
(text-direction RIGHT))
"Internal markup list command used to define @code{\\justify} and @code{\\wordwrap}."
- (wordwrap-stencils (remove ly:stencil-empty?
- (interpret-markup-list layout props args))
+ (wordwrap-stencils (interpret-markup-list layout props args)
justify
word-space
(or line-width
para-strings))
(para-lines (map (lambda (words)
(let* ((stencils
- (remove ly:stencil-empty?
- (map (lambda (x)
- (interpret-markup layout props x))
- words))))
+ (map (lambda (x)
+ (interpret-markup layout props x))
+ words)))
(wordwrap-stencils stencils
justify word-space
line-width text-direction)))
}
@end lilypond"
(let ((arg-stencils (interpret-markup-list layout props args)))
- (stack-lines -1 0.0 baseline-skip
- (remove ly:stencil-empty? arg-stencils))))
+ (stack-lines -1 0.0 baseline-skip arg-stencils)))
(define-markup-command (dir-column layout props args)
(markup-list?)
(cons (acons key val (car chain)) (cdr chain)))
(define-public (stack-stencil-line space stencils)
- "Adjoin a list of STENCILS along the X axis, leaving SPACE between the
- end of each stencil and the reference point of the following stencil."
- (if (and (pair? stencils)
- (ly:stencil? (car stencils)))
-
- (if (and (pair? (cdr stencils))
- (ly:stencil? (cadr stencils)))
- (let* ((tail (stack-stencil-line space (cdr stencils)))
- (head (car stencils))
- (xoff (+ space (interval-end (ly:stencil-extent head X)))))
- (ly:stencil-add head
- (ly:stencil-translate-axis tail xoff X)))
- (car stencils))
- (ly:make-stencil '() '(0 . 0) '(0 . 0))))
-
+ "Adjoin a list of @var{stencils} along the X axis, leaving
+@var{space} between the end of each stencil and the beginning of the
+following stencil. Stencils with empty Y extent are not given
+@var{space} before them and don't avoid overlapping other stencils."
+ (stack-stencils X RIGHT space (filter ly:stencil? stencils)))
;;; convert a full markup object to an approximate pure string representation
ly:stencil-combine-at-edge
ly:stencil-expr
ly:stencil-extent
+ ly:stencil-stack
ly:stencil-translate
ly:stencil-translate-axis
ly:stencil?
(define-public (stack-stencils axis dir padding stils)
"Stack stencils @var{stils} in direction @var{axis}, @var{dir}, using
@var{padding}."
- (cond
- ((null? stils) empty-stencil)
- ((null? (cdr stils)) (car stils))
- (else (ly:stencil-combine-at-edge
- (car stils) axis dir (stack-stencils axis dir padding (cdr stils))
- padding))))
-
-(define-public (stack-stencils-padding-list axis dir padding stils)
+ (reduce
+ (lambda (next front)
+ (ly:stencil-stack front axis dir next padding))
+ empty-stencil
+ stils))
+
+(define-public (stack-stencils-padding-list axis dir paddings stils)
"Stack stencils @var{stils} in direction @var{axis}, @var{dir}, using
-a list of @var{padding}."
- (cond
- ((null? stils) empty-stencil)
- ((null? (cdr stils)) (car stils))
- (else (ly:stencil-combine-at-edge
- (car stils)
- axis dir
- (stack-stencils-padding-list axis dir (cdr padding) (cdr stils))
- (car padding)))))
+a list of @var{paddings}."
+ (if (null? stils)
+ empty-stencil
+ (fold
+ (lambda (next padding front)
+ (ly:stencil-stack front axis dir next padding))
+ (car stils)
+ (cdr stils)
+ paddings)))
(define-public (centered-stencil stencil)
"Center stencil @var{stencil} in both the X and Y directions."
(define-public (stack-lines dir padding baseline stils)
"Stack vertically with a baseline skip."
- (define result empty-stencil)
- (define last-y #f)
- (do
- ((last-stencil #f (car p))
- (p stils (cdr p)))
-
- ((null? p))
-
- (if (number? last-y)
- (begin
- (let* ((dy (max (+ (* dir (interval-bound (ly:stencil-extent last-stencil Y) dir))
- padding
- (* (- dir) (interval-bound (ly:stencil-extent (car p) Y) (- dir))))
- baseline))
- (y (+ last-y (* dir dy))))
-
-
-
- (set! result
- (ly:stencil-add result (ly:stencil-translate-axis (car p) y Y)))
- (set! last-y y)))
- (begin
- (set! last-y 0)
- (set! result (car p)))))
-
- result)
-
+ (reduce-right
+ (lambda (next back) (ly:stencil-stack next Y dir back padding baseline))
+ empty-stencil
+ (map
+ (lambda (s)
+ ;; X-empty stencils may add vertical space. A stencil that is
+ ;; merely Y-empty counts as horizontal spacing. Since we want
+ ;; those to register as lines of their own (is this a good
+ ;; idea?), we make them a separately visible line.
+ (if (and (ly:stencil-empty? s Y)
+ (not (ly:stencil-empty? s X)))
+ (ly:make-stencil (ly:stencil-expr s) (ly:stencil-extent s X) '(0 . 0))
+ s))
+ stils)))
(define-public (bracketify-stencil stil axis thick protrusion padding)
"Add brackets around @var{stil}, producing a new stencil."
(set! stil
(ly:stencil-combine-at-edge stil (other-axis axis) 1 rb padding))
(set! stil
- (ly:stencil-combine-at-edge lb (other-axis axis) 1 stil padding))
+ (ly:stencil-combine-at-edge stil (other-axis axis) -1 lb padding))
stil))
(define (make-parenthesis-stencil
y-extent half-thickness (- width) angularity))
(rp (make-parenthesis-stencil
y-extent half-thickness width angularity)))
- (set! stencil (ly:stencil-combine-at-edge lp X RIGHT stencil padding))
+ (set! stencil (ly:stencil-combine-at-edge stencil X LEFT lp padding))
(set! stencil (ly:stencil-combine-at-edge stencil X RIGHT rp padding))
stencil))
(if (markup? markup)
(interpret-markup layout props markup)
- (ly:make-stencil '() '(1 . -1) '(1 . -1)))))
+ empty-stencil)))