]> git.donarmstrong.com Git - lilypond.git/commitdiff
Merge branch 'lilypond/translation'
authorFrancisco Vila <francisco.vila@hispalinux.es>
Sun, 28 Aug 2011 14:57:04 +0000 (16:57 +0200)
committerFrancisco Vila <francisco.vila@hispalinux.es>
Sun, 28 Aug 2011 14:57:04 +0000 (16:57 +0200)
65 files changed:
Documentation/de/notation/ancient.itely
Documentation/de/notation/keyboards.itely
Documentation/es/notation/ancient.itely
Documentation/es/notation/keyboards.itely
Documentation/fr/notation/ancient.itely
Documentation/fr/notation/keyboards.itely
Documentation/learning/tweaks.itely
Documentation/notation/ancient.itely
Documentation/notation/changing-defaults.itely
Documentation/notation/keyboards.itely
Documentation/snippets/adding-a-figured-bass-above-or-below-the-notes.ly
Documentation/snippets/adding-orchestral-cues-to-a-vocal-score.ly
Documentation/snippets/ancient-fonts.ly
Documentation/snippets/changing-a-single-notes-size-in-a-chord.ly
Documentation/snippets/clip-systems.ly
Documentation/snippets/controlling-tuplet-bracket-visibility.ly
Documentation/snippets/displaying-complex-chords.ly
Documentation/snippets/dynamics-custom-text-spanner-postfix.ly
Documentation/snippets/guitar-slides.ly
Documentation/snippets/lyrics-alignment.ly
Documentation/snippets/modifying-default-values-for-articulation-shorthand-notation.ly
Documentation/snippets/new/ancient-fonts.ly [new file with mode: 0644]
Documentation/snippets/new/displaying-complex-chords.ly
Documentation/snippets/new/guitar-slides.ly
Documentation/snippets/new/unfretted-headword.ly
Documentation/snippets/preventing-extra-naturals-from-being-automatically-added.ly
Documentation/snippets/unfretted-headword.ly
Documentation/web/ly-examples/granados.ly
input/regression/color.ly
input/regression/flags-default.ly
input/regression/flags-in-scheme.ly
input/regression/flags-straight-stockhausen-boulez.ly
input/regression/flags-straight.ly
input/regression/graphviz.ly
input/regression/grid-lines.ly
input/regression/les-nereides.ly
input/regression/mozart-hrn3-defs.ily
input/regression/quote-overrides.ly
input/regression/stem-length-estimation.ly
input/regression/stem-length-override.ly [new file with mode: 0644]
input/regression/stem-pure-height-beamed.ly [new file with mode: 0644]
lily/beam-quanting.cc
lily/beam.cc
lily/dot-column.cc
lily/flag.cc [new file with mode: 0644]
lily/include/item.hh
lily/include/stem.hh
lily/item.cc
lily/note-spacing.cc
lily/rhythmic-column-engraver.cc
lily/staff-spacing.cc
lily/stem-engraver.cc
lily/stem-tremolo.cc
lily/stem.cc
lily/tie-formatting-problem.cc
lily/tuplet-bracket.cc
ly/engraver-init.ly
ly/grace-init.ly
ly/gregorian.ly
ly/property-init.ly
scm/define-grob-properties.scm
scm/define-grobs.scm
scm/flag-styles.scm
scm/music-functions.scm
scm/output-lib.scm

index d8a3a0fff8a0f9a71a6e00f2da6dacc9da38f652..185c2b1267bb89807362bd540a8239624f25a38a 100644 (file)
@@ -762,7 +762,7 @@ werden.  Neben dem Standardstil (@code{default}) ist
 nur (@code{mensural}) unterstützt.
 
 @lilypond[quote,fragment,ragged-right,verbatim]
-\override Stem #'flag-style = #'mensural
+\override Flag #'style = #'mensural
 \override Stem #'thickness = #1.0
 \override NoteHead #'style = #'mensural
 \autoBeamOff
index ba7f8924e7f3704c07a963a6a8e697b3e55c1fc1..6032d2eb4904d4008522d62e8bb449f245b62b42 100644 (file)
@@ -462,7 +462,7 @@ Hälsen, die nach unten zeigen.
         % extend the stems to reach the other staff
         \override Stem #'length = #12
         % do not print extra flags
-        \override Stem #'flag-style = #'no-flag
+        \override Flag #'style = #'no-flag
         % prevent beaming as needed
         a8 g4 f8 f bes\noBeam g4
       }
index 822f1ae16b8d48bb4c8aa80331bdee60ef4f5e96..cfde2c3de823292a174106c5967275e1c9c8e85d 100644 (file)
@@ -759,7 +759,7 @@ Aparte del estilo de corchete por defecto @code{default}, sólo está
 contemplado el estilo @code{mensural}
 
 @lilypond[quote,fragment,ragged-right,verbatim]
-\override Stem #'flag-style = #'mensural
+\override Flag #'style = #'mensural
 \override Stem #'thickness = #1.0
 \override NoteHead #'style = #'mensural
 \autoBeamOff
index dda15e148ed53bb39ada1913820f132ec814b5db..47dc5d61b4af21279e168e5b160a0f88abe13131 100644 (file)
@@ -460,7 +460,7 @@ Se pueden hacer acordes que cruzan los pentagramas:
         % extend the stems to reach the other staff
         \override Stem #'length = #12
         % do not print extra flags
-        \override Stem #'flag-style = #'no-flag
+        \override Flag #'style = #'no-flag
         % prevent beaming as needed
         a8 g4 f8 f bes\noBeam g4
       }
index f62408459bef060331385baaeccf1457a783d5ec..c149225e9b4e0f1a7198def8eeee4004fa677365 100644 (file)
@@ -551,7 +551,7 @@ seuls styles actuellement pris en charge sont @code{default} et
 @code{mensural}.
 
 @lilypond[quote,fragment,ragged-right,verbatim]
-\override Stem #'flag-style = #'mensural
+\override Flag #'style = #'mensural
 \override Stem #'thickness = #1.0
 \override NoteHead #'style = #'mensural
 \autoBeamOff
index 9a0ed9e98794fd8bc8e4ed543407a964a7593255..9a5623913d0f20c15a6f96af75bdf8bcda150ab9 100644 (file)
@@ -457,7 +457,7 @@ celle de l'autre portée.
         % extend the stems to reach the other staff
         \override Stem #'length = #12
         % do not print extra flags
-        \override Stem #'flag-style = #'no-flag
+        \override Flag #'style = #'no-flag
         % prevent beaming as needed
         a8 g4 f8 f bes\noBeam g4
       }
index 9f1c5dd0b5d43c52a8746e7dbfc0a561a4286e8e..a13fff3fe00d44c8d13b86d672f8a860502d1ba1 100644 (file)
@@ -3466,6 +3466,7 @@ cross voices:
 <<
   {
     \once \override Stem #'transparent = ##t
+    \once \override Flag #'transparent = ##t
     b8~ b\noBeam
   }
 \\
@@ -3481,6 +3482,7 @@ too much, we can lengthen the stem by setting the
 <<
   {
     \once \override Stem #'transparent = ##t
+    \once \override Flag #'transparent = ##t
     \once \override Stem #'length = #8
     b8~ b\noBeam
   }
index fe835fd077a41a19c6415da7536d34f607ff3a4c..55b4aead72d46b0d83e6e6bbd0e268099d40dff0 100644 (file)
@@ -732,7 +732,7 @@ select ancient flags.  Besides the @code{default} flag style,
 only the @code{mensural} style is supported.
 
 @lilypond[quote,fragment,ragged-right,verbatim]
-\override Stem #'flag-style = #'mensural
+\override Flag #'style = #'mensural
 \override Stem #'thickness = #1.0
 \override NoteHead #'style = #'mensural
 \autoBeamOff
@@ -1116,6 +1116,7 @@ Editio Vaticana style do clef
   \override Staff.StaffSymbol #'color = #red
   \override Staff.LedgerLineSpanner #'color = #red
   \override Voice.Stem #'transparent = ##t
+  \override Voice.Flag #'transparent = ##t
   \override NoteHead #'style = #'vaticana.punctum
   \clef "vaticana-do2"
   c
@@ -1131,6 +1132,7 @@ Editio Vaticana style fa clef
   \override Staff.StaffSymbol #'color = #red
   \override Staff.LedgerLineSpanner #'color = #red
   \override Voice.Stem #'transparent = ##t
+  \override Voice.Flag #'transparent = ##t
   \override NoteHead #'style = #'vaticana.punctum
   \clef "vaticana-fa2"
   c
@@ -1147,6 +1149,7 @@ Editio Medicaea style do clef
   \override Staff.StaffSymbol #'color = #red
   \override Staff.LedgerLineSpanner #'color = #red
   \override Voice.Stem #'transparent = ##t
+  \override Voice.Flag #'transparent = ##t
   \override NoteHead #'style = #'medicaea.punctum
   \clef "medicaea-do2"
   c
@@ -1162,6 +1165,7 @@ Editio Medicaea style fa clef
   \override Staff.StaffSymbol #'color = #red
   \override Staff.LedgerLineSpanner #'color = #red
   \override Voice.Stem #'transparent = ##t
+  \override Voice.Flag #'transparent = ##t
   \override NoteHead #'style = #'medicaea.punctum
   \clef "medicaea-fa2"
   c
@@ -1178,6 +1182,7 @@ hufnagel style do clef
   \override Staff.StaffSymbol #'color = #red
   \override Staff.LedgerLineSpanner #'color = #red
   \override Voice.Stem #'transparent = ##t
+  \override Voice.Flag #'transparent = ##t
   \override NoteHead #'style = #'hufnagel.punctum
   \clef "hufnagel-do2"
   c
@@ -1193,6 +1198,7 @@ hufnagel style fa clef
   \override Staff.StaffSymbol #'color = #red
   \override Staff.LedgerLineSpanner #'color = #red
   \override Voice.Stem #'transparent = ##t
+  \override Voice.Flag #'transparent = ##t
   \override NoteHead #'style = #'hufnagel.punctum
   \clef "hufnagel-fa2"
   c
@@ -1207,6 +1213,7 @@ hufnagel style combined do/fa clef
   \override Staff.StaffSymbol #'color = #red
   \override Staff.LedgerLineSpanner #'color = #red
   \override Voice.Stem #'transparent = ##t
+  \override Voice.Flag #'transparent = ##t
   \override NoteHead #'style = #'hufnagel.punctum
   \clef "hufnagel-do-fa"
   c
@@ -2501,7 +2508,9 @@ single-tone recitative to a fixed melodic gesture.  In these cases,
 one can use either @code{\override Stem #'transparent = ##t} or
 @code{\override Stem #'length = #0} instead, and restore the stem
 when needed with the corresponding @code{\once \override Stem
-#'transparent = ##f} (see example below).
+#'transparent = ##f} (see example below).  When using stems that
+carry flags, make sure to set @code{\override Flag #'transparent
+= ##t} as well.
 
 @b{Timing.} For unmetered chant, there are several alternatives.
 
@@ -2638,6 +2647,7 @@ spirLyr = \lyricmode {
       \remove "Time_signature_engraver"
       \override BarLine #'X-extent = #'(-1 . 1)
       \override Stem #'transparent = ##t
+      \override Flag #'transparent = ##t
       \override Beam #'transparent = ##t
       \override BarLine #'transparent = ##t
       \override TupletNumber #'transparent = ##t
index 0cd9812606d6b7455564c2589abb6d4767a690ee..e10986e7cffeeed7861b6f56846269834d8872f4 100644 (file)
@@ -854,6 +854,7 @@ The notes look like a slash, and have no stem,
 @example
 \override NoteHead #'style = #'slash
 \override Stem #'transparent = ##t
+\override Flag #'transparent = ##t
 @end example
 
 All these plug-ins have to cooperate, and this is achieved with a
@@ -876,6 +877,7 @@ Put together, we get
   squashedPosition = #0
   \override NoteHead #'style = #'slash
   \override Stem #'transparent = ##t
+  \override Flag #'transparent = ##t
   \alias Voice
 @}
 @end example
index ef294318fbc5201e8a2b02329e12f4511d555d15..a7b3394417b9e13fd5b2afa3960d7efc1eb392e1 100644 (file)
@@ -437,7 +437,7 @@ Chords that cross staves may be produced:
         % extend the stems to reach the other staff
         \override Stem #'length = #12
         % do not print extra flags
-        \override Stem #'flag-style = #'no-flag
+        \override Flag #'style = #'no-flag
         % prevent beaming as needed
         a8 g4 f8 f bes\noBeam g4
       }
index 2e4f38445baea241aee2a30bdfe6cd4d6490c6b4..209ffa228d03b7f6eaeac0122050443a1fe29205 100644 (file)
@@ -15,9 +15,9 @@
 Al escribir un bajo cifrado, podemos situar las cifras encima o debajo
 de las notas del bajo, mediante la definición de la propiedad
 @code{BassFigureAlignmentPositioning #'direction} (exclusivamente
-dentro de un contexto @code{Staff}).  Se puede elegir entre @code{UP}
-(o @code{1}, arriba), @code{CENTER} (o @code{0}, centrado) y
-@code{DOWN} (o @w{@code{-1}}, abajo).
+dentro de un contexto @code{Staff}). Se puede elegir entre @code{#UP}
+(o @code{#1}, arriba), @code{#CENTER} (o @code{#0}, centrado) y
+@code{#DOWN} (o @code{#-1}, abajo).
 
 Esta propiedad se puede cambiar tantas veces como queramos.  Utilice
 @code{\\once \\override} si no quiere que la sobreescritura se aplique
index 6645f1e2aeda25c2fa7290fa1b7c6a310e0f5728..9168972a8e47c22bb12cd78a52d87c642305b9d2 100644 (file)
@@ -16,8 +16,8 @@
 notas guía orquestales a la reducción de piano en una partitura vocal.
 La función musical @code{\\cueWhile} toma cuatro argumentos: la música
 de la que se toma la cita, como viene definida por @code{\\addQuote},
-el nombre que insertar antes de las notas guía, y después @code{UP} o
-@code{DOWN} para especificar @code{\\voiceOne} con el nombre encima
+el nombre que insertar antes de las notas guía, y después @code{#UP} o
+@code{#DOWN} para especificar @code{\\voiceOne} con el nombre encima
 del pentagrama o bien @code{\\voiceTwo} con el nombre debajo del
 pentagrama, y finalmente la música de piano con la que las notas guía
 deben aparecer en paralelo.  El nombre del instrumento citado se
@@ -41,7 +41,7 @@ zu einem Klavierauszug hinzufügen kann.  Die musikalische Funktion
 @code{\\cueWhile} braucht vier Argumente:  Die Noten, von denen die
 Stichnoten formatiert werden sollen, definiert durch @code{\\addQuote},
 die Bezeichnung, die mit den Noten angegeben werden soll, dann entweder
-@code{UP} (hoch) oder @code{DOWN} (runter) zur Angabe von entweder
+@code{#UP} (hoch) oder @code{#DOWN} (runter) zur Angabe von entweder
 @code{\\voiceOne} mit der Bezeichnung über dem System oder @code{\\voiceTwo}
 mit der Bezeichnung unter dem System, und schließlich die Klaviermusik,
 die parallel zu den Stichnoten gespielt werden soll.  Die Bezeichnung des
@@ -60,7 +60,7 @@ multiplie, vous pourriez avoir intérêt à créer votre propre fonction
 pour gérer ces repères.  La fonction musicale @code{\\cueWhile} prend
 quatre arguments@tie{}: la musique d'où provient la citation, telle que
 définie par @code{\\addQuote}, le nom qui sera mentionné en regard de
-cette citation, son positionnement -- @code{UP} ou @code{DOWN} selon
+cette citation, son positionnement -- @code{#UP} ou @code{#DOWN} selon
 qu'il sera attribué à @code{\\voiceOne} et placé au-dessus ou
 @code{\\voiceTwo} et placé en dessous -- et enfin la musique du piano
 qui interviendra en parallèle.  Le nom de l'instrument en question
index 6e84c4050af681dfac664800cd6c4fc00db57532..9dd34ccd176aa15ce4ed89b6d4db33665ef4524b 100644 (file)
@@ -1,14 +1,14 @@
-%% DO NOT EDIT this file manually; it is automatically
-%% generated from LSR http://lsr.dsi.unimi.it
-%% Make any changes in LSR itself, or in Documentation/snippets/new/ ,
-%% and then run scripts/auxiliar/makelsr.py
-%%
+% DO NOT EDIT this file manually; it is automatically
+% generated from Documentation/snippets/new
+% Make any changes in Documentation/snippets/new/
+% and then run scripts/auxiliar/makelsr.py
+%
+% This file is in the public domain.
+%% Note: this file works from version 2.15.9
 %% This file is in the public domain.
-\version "2.15.7"
+\version "2.15.9"
 
 \header {
-  lsrtags = "ancient-notation"
-
 %% Translation of GIT committish: 70f5f30161f7b804a681cd080274bfcdc9f4fe8c
   texidoces = "
 Aquí se muestran muchos de (¿o quizá todos?) los símbolos que
@@ -27,12 +27,11 @@ LilyPond prend en charge en matière de musique ancienne.
 "
   doctitlefr = "Gravure de musique ancienne"
 
+  lsrtags = "ancient-notation"
+
   texidoc = "
 Shown here are many (all?) of the symbols that are included in
 LilyPond's support for ancient notation.
-
-
-
 "
   doctitle = "Ancient fonts"
 } % begin verbatim
@@ -130,7 +129,8 @@ upperStaff = \new VaticanaStaff = "upperStaff" <<
 
       s32*1
       % \break % 12 (32*1)
-    }
+    } % begin verbatim
+
   >>
 >>
 
@@ -230,7 +230,7 @@ lowerStaff = \new MensuralStaff = "lowerStaff" <<
       \MensuralVoice
       \override NoteHead #'style = #'neomensural
       \override Rest #'style = #'neomensural
-      \override Stem #'flag-style = #'mensural
+      \override Flag #'style = #'mensural
       \override Stem #'thickness = #1.0
     }
     \context {
index 5e968b7ee887ead8d6531c2f78cfa1f38cfecc4b..c16f3478f944bcebb03556d76d30d1cd5bf751bb 100644 (file)
@@ -16,8 +16,8 @@ Se pueden modificar notas individuales de un acorde con la instrucción
 
 Dentro de un acorde (entre ángulos simples @code{< >}), antes de la
 nota que queremos alterar, situamos la instrucción @code{\\tweak}
-seguida por @code{'font-size} y definimos el tamaño adecuado como
-@w{@code{-2}} (una cabeza pequeña).
+seguida por @code{#'font-size} y definimos el tamaño adecuado como
+@code{#-2} (una cabeza pequeña).
 
 "
   doctitlees = "Modificar el tamaño de una nota suelta de un acorde"
index 28e5180bd6fcdc975dac6031f079fa050151eea7..88037d14067c37b22fd50b3a39c89cfcb74f360d 100644 (file)
@@ -14,7 +14,7 @@ Este código muestra cómo recortar (extraer) fragmentos a partir de una
 partitura completa.
 
 Este archivo tiene que procesarse de forma separada con la opción
-@option{-dclip-systems}; la página de fragmentos de código podría no
+@code{-dclip-systems}; la página de fragmentos de código podría no
 mostrar el resultado adecuadamente.
 
 La salida consiste en archivos con los nombres
index aa13409c287ccc6613d12974e6e88b0d1f651ac3..ced08599f210cb5a746e1d5c23768ce36596c967 100644 (file)
@@ -17,7 +17,7 @@ grupo de valoración especial es imprimir el corchete a no ser que haya
 una barra de la misma longitud que el grupo especial.  Para controlar
 la visibilidad de los corchetes de grupo, establezca la propiedad
 @code{'bracket-visibility} a @code{#t} (imprimir el corchete siempre),
-@code{#f} (no imprimirlo nunca) o @code{'if-no-beam} (imprimir el
+@code{#f} (no imprimirlo nunca) o @code{#'if-no-beam} (imprimir el
 corchete solamente si no hay barra).
 
 "
@@ -33,7 +33,7 @@ ligature.  LilyPond permet, au travers de la propriété
 @code{'bracket-visibility}, de contôler précisément leur
 affichage@tie{}: déterminée à @code{#t}, ils seront toujours
 imprimés@tie{}; @code{#f} permet de ne jamais les imprimer, et
-@code{'if-no-beam} les imprimera en l'absence de ligature.
+@code{#'if-no-beam} les imprimera en l'absence de ligature.
 
 "
   doctitlefr = "Contrôle de l'impression des crochets de nolet"
index f3cae3839df8f6453a51cba6cb1dc0b870dc951f..c0c9819cede1e228a656c3a3efba168a0f535963 100644 (file)
@@ -33,7 +33,7 @@ fixB = {
   \once \override NoteHead #'X-offset = #1.7
   \once \override Stem #'rotation = #'(45 0 0)
   \once \override Stem #'extra-offset = #'(-0.2 . -0.2)
-  \once \override Stem #'flag-style = #'no-flag
+  \once \override Flag #'style = #'no-flag
   \once \override Accidental #'extra-offset = #'(4 . 0)
 }
 
index 6ce32b861ef16bdc6c732ca58a4bbedea0172b7e..fc4b01f2fb06235fd771390122bd00b155d982e9 100644 (file)
@@ -37,7 +37,7 @@ zugewiesen.
   texidocfr = "
 Il s'agit de fonctions postfix pour personnaliser l'extension des
 crescendos textuels.  L'extension devrait débuter sur la première notte
-de la mesure.  Il faut utiliser @w{@code{-\mycresc}} -- comme une
+de la mesure.  Il faut utiliser @code{-\mycresc} -- comme une
 articulation -- sous peine que le départ de l'extension n'apparaisse
 qu'à la note suivante.
 "
index a8946c23755c1ea30a9f1ba86ee44c93d5f07325..c24104630358478fce2c6c83600211ba03690906 100644 (file)
@@ -39,6 +39,7 @@ hideFretNumber = {
   \once \override TabNoteHead #'transparent = ##t
   \once \override NoteHead #'transparent = ##t
   \once \override Stem #'transparent = ##t
+  \once \override Flag #'transparent = ##t
   \once \override NoteHead #'no-ledgers = ##t
   \once \override Glissando #'(bound-details left padding) = #0.3
 }
index 723ff567b242d9693f72baeda84db168b6926f7e..0eac0a745bdfb312f2aa8bb613d914f038be3c03 100644 (file)
@@ -13,9 +13,9 @@
   texidoces = "
 La alineación horizontal de la letra se puede ajustar sobreescribiendo
 la propiedad @code{self-alignment-X} del objeto @code{LyricText}.
-@w{@code{-1}} es izquierda, @code{0} es centrado y @code{1} es derecha;
-sin embargo, puede usar también @code{LEFT}, @code{CENTER} y
-@code{RIGHT}.
+@code{#-1} es izquierda, @code{#0} es centrado y @code{#1} es derecha;
+sin embargo, puede usar también @code{#LEFT}, @code{#CENTER} y
+@code{#RIGHT}.
 
 "
   doctitlees = "Alineación de la letra"
@@ -25,9 +25,9 @@ sin embargo, puede usar también @code{LEFT}, @code{CENTER} y
   texidocde = "
 Die horizontale Ausrichtung von Gesangstext kann eingestellt werden, indem
 man die @code{self-alignment-X}-Eigenschaft des @code{LyricText}-Objekts
-verändert.  @w{@code{-1}} bedeutet links, @code{0} bedeutet mittig und @code{1}
-bedeutet rechts, man kann aber genauso gut auch @code{LEFT}, @code{CENTER}
-und @code{RIGHT} benutzen.
+verändert.  @code{#-1} bedeutet links, @code{#0} bedeutet mittig und @code{#1}
+bedeutet rechts, man kann aber genauso gut auch @code{#LEFT}, @code{#CENTER}
+und @code{#RIGHT} benutzen.
 
 "
   doctitlede = "Ausrichtung von Gesangstext"
@@ -37,9 +37,9 @@ und @code{RIGHT} benutzen.
   texidocfr = "
 L'alignement horizontal des paroles peut se gérer à l'aide de la
 propriété @code{self-alignment-X} de l'objet @code{LyricText}.
-Les valeurs @w{@code{-1}} ou @code{LEFT} produiront un alignement par la
-gauche, les valeurs @code{0} ou @code{CENTER} un alignement centré, et
-les valeurs @code{1} ou @code{RIGHT} un alignement par la droite.
+Les valeurs @code{#-1} ou @code{#LEFT} produiront un alignement par la
+gauche, les valeurs @code{#0} ou @code{#CENTER} un alignement centré, et
+les valeurs @code{#1} ou @code{#RIGHT} un alignement par la droite.
 
 "
   doctitlefr = "Alignement des syllabes"
index 8c5e12f72f5a740476d49b0212cac4627c026024..552259dff9d16ff61860a4186f0cd7f1a1659875 100644 (file)
@@ -17,7 +17,7 @@ Las abreviaturas se encuentran definidas dentro del archivo
 @code{dashLarger}, @code{dashDot} y @code{dashUnderscore} reciben
 valores predeterminados.  Se pueden modificar estos valores
 predeterminados para las abreviaturas. Por ejemplo, para asociar
-la abreviatura @w{@code{-+}} (@code{dashPlus}) con el símbolo del
+la abreviatura @code{-+} (@code{dashPlus}) con el símbolo del
 semitrino en lugar del símbolo predeterminado +, asigne el valor
 @code{trill} a la variable @code{dashPlus}:
 
@@ -32,7 +32,7 @@ den Variablen @code{dashHat}, @code{dashPlus}, @code{dashDash},
 @code{dashBar}, @code{dashLarger}, @code{dashDot} und
 @code{dashUnderscore} Standardwerte zugewiesen werden.  Diese Standardwerte
 können verändert werden.  Um zum Beispiel die Abkürzung
-@w{@code{-+}} (@code{dashPlus}) mit dem Triller anstatt mit dem +-Symbol zu
+@code{-+} (@code{dashPlus}) mit dem Triller anstatt mit dem +-Symbol zu
 assoziieren, muss der Wert @code{trill} der Variable
 @code{dashPlus} zugewiesen werden:
 
@@ -46,7 +46,7 @@ Les raccourcis sont répertoriés dans le fichier
 @code{dashHat}, @code{dashPlus}, @code{dashDash}, @code{dashBar},
 @code{dashLarger}, @code{dashDot}, et @code{dashUnderscore} ainsi que
 leur valeur par défaut.  Ces valeurs peuvent être modifiées selon vos
-besoins.  Il suffit par exemple, pour affecter au raccourci @w{@code{-+}}
+besoins.  Il suffit par exemple, pour affecter au raccourci @code{-+}
 (@code{dashPlus}) le symbole du trille en lieu et place du @code{+}
 (caractère plus), d'assigner la valeur @code{trill} à la variable
 @code{dashPlus} :
diff --git a/Documentation/snippets/new/ancient-fonts.ly b/Documentation/snippets/new/ancient-fonts.ly
new file mode 100644 (file)
index 0000000..c48cef3
--- /dev/null
@@ -0,0 +1,225 @@
+%% This file is in the public domain.
+\version "2.15.9"
+
+\header {
+  lsrtags = "ancient-notation"
+
+  texidoc = "
+Shown here are many (all?) of the symbols that are included in
+LilyPond's support for ancient notation.
+"
+  doctitle = "Ancient fonts"
+} % begin verbatim
+
+upperStaff = \new VaticanaStaff = "upperStaff" <<
+  \context VaticanaVoice <<
+    \transpose c c {
+
+      \override NoteHead #'style = #'vaticana.punctum
+      \key es \major
+      \clef "vaticana-fa2"
+      c1 des e f ges
+
+      \override NoteHead #'style = #'vaticana.inclinatum
+      a! b ces'
+      \bar "|"
+      % \break % 1 (8*1)
+
+      \override NoteHead #'style = #'vaticana.quilisma
+      b! des'! ges! fes!
+      \breathe
+      \clef "vaticana-fa1"
+      \override NoteHead #'style = #'vaticana.plica
+      es d
+      \override NoteHead #'style = #'vaticana.reverse.plica
+      c d
+      \bar "|"
+      % \break %2 (8*1)
+
+      \override NoteHead #'style = #'vaticana.punctum.cavum
+      es f
+      \override NoteHead #'style = #'vaticana.lpes
+      g as
+      \override NoteHead #'style = #'vaticana.upes
+      bes as
+      \override NoteHead #'style = #'vaticana.vupes
+      g f
+      \override NoteHead #'style = #'vaticana.linea.punctum
+      \once \override Staff.BarLine #'bar-extent = #'(-1 . 1) \bar "|"
+      % \break % 3 (8*1)
+
+      es d
+      \override NoteHead #'style = #'vaticana.epiphonus
+      c d
+      \override NoteHead #'style = #'vaticana.cephalicus
+      es f
+
+      \override Staff.KeySignature #'glyph-name-alist = #alteration-medicaea-glyph-name-alist
+      \override Staff.Accidental #'glyph-name-alist = #alteration-medicaea-glyph-name-alist
+      \override Staff.Custos #'style = #'medicaea
+      \override NoteHead #'style = #'medicaea.punctum
+      \clef "medicaea-fa2"
+      ces des
+      \bar "|"
+      % \break % 4 (8*1)
+
+      e! f! ges
+      \clef "medicaea-do2"
+      \override NoteHead #'style = #'medicaea.inclinatum
+      a! b! ces'
+      \override NoteHead #'style = #'medicaea.virga
+      b! a!
+      \bar "|"
+      % \break % 5 (8*1)
+
+      ges fes
+      \clef "medicaea-fa1"
+      \override NoteHead #'style = #'medicaea.rvirga
+      e des ces
+
+      \override Staff.KeySignature #'glyph-name-alist = #alteration-hufnagel-glyph-name-alist
+      \override Staff.Accidental #'glyph-name-alist = #alteration-hufnagel-glyph-name-alist
+      \override Staff.Custos #'style = #'hufnagel
+      \override NoteHead #'style = #'hufnagel.punctum
+      \clef "hufnagel-fa2"
+      ces des es
+      \bar "|"
+      % \break % 6 (8*1)
+
+      fes ges
+      \clef "hufnagel-do2"
+      \override NoteHead #'style = #'hufnagel.lpes
+      as! bes! ces'
+      \override NoteHead #'style = #'hufnagel.virga
+      bes! as!
+      \bar "|"
+      % \break % 7 (8*1)
+
+      ges! fes!
+      \clef "hufnagel-do-fa"
+      \override NoteHead #'style = #'hufnagel.punctum
+      es! des ces des! es! fes!
+      \bar "||"
+      % \break % 8 (8*1)
+
+      s32*1
+      % \break % 12 (32*1)
+    }
+  >>
+>>
+
+lowerStaff = \new MensuralStaff = "lowerStaff" <<
+  \context MensuralVoice <<
+    \transpose c c {
+
+      \key a \major
+      cis'1 d'\breve gis'\breve e'\breve \[ e'\longa fis'\longa \]
+      \set Staff.forceClef = ##t
+      \clef "neomensural-c2"
+      cis1
+      \bar "|"
+      % \break % 2 (16*1)
+
+      \[ g\breve dis''\longa \]
+      b\breve \[ a\longa d\longa \]
+      \clef "petrucci-c2"
+      % \break % 4 (16*1)
+
+      fis1 ces1
+      \clef "petrucci-c2"
+      r\longa
+      \set Staff.forceClef = ##t
+      \clef "mensural-c2"
+      r\breve
+      \bar "|"
+      % \break % 5 (8*1)
+
+      r2
+      \clef "mensural-g"
+      r4 r8 r16 r16
+      \override NoteHead #'style = #'mensural
+      \override Rest #'style = #'mensural
+      \clef "petrucci-f"
+      c8 b, c16 b, c32 b, c64 b, c64 b,
+      d8 e d16 e d32 e d64 e d64 e
+      r\longa
+      \set Staff.forceClef = ##t
+      \clef "petrucci-f"
+      r\breve
+      \bar "|"
+      % \break % 6 (8*1)
+
+      r\breve
+      \clef "mensural-f"
+      r2 r4 r8 r16 r16
+
+      \set Staff.forceClef = ##t
+      \clef "mensural-f"
+      e\breve f g a1
+      \clef "mensural-g"
+      % \break % 7 (8*1)
+
+      \[ bes'!\longa a'!\longa c''!\longa \]
+      e'1 d' c' d' \bar "|"
+      \bar "|"
+      % \break % 9 (16*1)
+
+      bes'!\longa fis'!1 as'!1 ges'!\longa % lig
+      \set Staff.forceClef = ##t
+      \clef "mensural-g"
+      e'2 d' c' \bar "|"
+      % \break % 11 (16*1)
+
+      \set Staff.forceClef = ##t
+      \clef "petrucci-g"
+      c'2 d' e' f'
+      \clef "petrucci-g"
+      g' as'! bes'! cis''!
+      bes'! as'! gis'! fis'!
+      \set Staff.forceClef = ##t
+      \clef "mensural-g"
+      es'! des'! cis'!1 \bar "||"
+      % \break % 12 (8*1)
+    }
+  >>
+>>
+
+\paper {
+  line-thickness = #(/ staff-space 5.0)
+}
+
+\score {
+  <<
+    \upperStaff
+    \lowerStaff
+  >>
+  \layout {
+    indent = 0.0
+    line-width = 17.25\cm
+    \context {
+      \Score
+      timing = ##f
+    }
+    \context {
+      \MensuralVoice
+      \override NoteHead #'style = #'neomensural
+      \override Rest #'style = #'neomensural
+      \override Flag #'style = #'mensural
+      \override Stem #'thickness = #1.0
+    }
+    \context {
+      \MensuralStaff
+      \revert  BarLine #'transparent
+      \override KeySignature #'glyph-name-alist = #alteration-mensural-glyph-name-alist
+      clefGlyph = #"clefs.petrucci.c2"
+    }
+    \context {
+      \VaticanaStaff
+      \revert  BarLine #'transparent
+      \override StaffSymbol #'thickness = #2.0
+      \override KeySignature #'glyph-name-alist = #alteration-vaticana-glyph-name-alist
+      \override Custos #'neutral-position = #4
+    }
+  }
+}
+
index f2426dcc4ce01a55047eb07af60b851946706d38..f3efe63b7c2d6f9a109eb1ca5b0ebed2c6b5416a 100644 (file)
@@ -16,7 +16,7 @@ fixB = {
   \once \override NoteHead #'X-offset = #1.7
   \once \override Stem #'rotation = #'(45 0 0)
   \once \override Stem #'extra-offset = #'(-0.2 . -0.2)
-  \once \override Stem #'flag-style = #'no-flag
+  \once \override Flag #'style = #'no-flag
   \once \override Accidental #'extra-offset = #'(4 . 0)
 }
 
index 4657d94b858b75b9c9e9c677cbccd0e2eb68744f..bf431fa9facab9c31fa4dfb6e54c082f8fd610ea 100644 (file)
@@ -18,6 +18,7 @@ hideFretNumber = {
   \once \override TabNoteHead #'transparent = ##t
   \once \override NoteHead #'transparent = ##t
   \once \override Stem #'transparent = ##t
+  \once \override Flag #'transparent = ##t
   \once \override NoteHead #'no-ledgers = ##t
   \once \override Glissando #'(bound-details left padding) = #0.3
 }
index 72ea357e5379016893d98533b969f658df80d5bf..b4d2729c1d7f63f98c70d675224edf67307459ba 100644 (file)
@@ -92,7 +92,7 @@ tupletbp       = \once \override Staff.TupletBracket #'padding = #2.25
 %% Flag [Note Head - Stem]
 %%
 
-noflag         = \once \override Stem #'flag-style = #'no-flag
+noflag         = \once \override Flag #'style = #'no-flag
 
 %%%
 %%% Functions
index 4ca35369d6ed81451dcf3eaf59e8400baffb09a5..be7c22d585dbd8eb4d7b984b21d33623fda7b176 100644 (file)
@@ -17,7 +17,7 @@ Según las reglas estándar de composición
 tipográfica, se imprime un becuadro antes de un sostenido o un
 bemol cuando se tiene que cancelar una alteración anterior en la
 misma nota.  Para modificar este comportamiento, establezca el
-valor de la propiedad @code{extraNatural} a @code{#f} (falso)
+valor de la propiedad @code{extraNatural} a @code{##f} (falso)
 dentro del contexto de @code{Staff}.
 
 "
@@ -39,7 +39,7 @@ soll.  Um dieses Verhalten zu ändern, muss die Eigenschaft
 En accord avec les règles standards de l'écriture musicale, on grave
 un bécarre avant un dièse ou un bémol si on a besoin d'annuler une
 altération précédente.  Pour modifier ce comportement, assignez la propriété
-@code{extraNatural} du contexte @code{Staff} à la valeur @code{#f} (faux).
+@code{extraNatural} du contexte @code{Staff} à la valeur @code{##f} (faux).
 "
 
   doctitlefr = "Suppression des bécarres superflus"
index 025767c8b0622adef9a6dccaad599487b8c1e1e5..709a3997c68dd916ae9ede517c791b84c0bcd0d1 100644 (file)
@@ -100,7 +100,7 @@ tupletbp       = \once \override Staff.TupletBracket #'padding = #2.25
 %% Flag [Note Head - Stem]
 %%
 
-noflag         = \once \override Stem #'flag-style = #'no-flag
+noflag         = \once \override Flag #'style = #'no-flag
 
 %%%
 %%% Functions
index 607732e3598f35e32e05a3509bf28c787d776027..4521e658d070b89168afe54b2cc9f1a3560a7fbf 100644 (file)
@@ -57,14 +57,14 @@ upperVoiceTwo = \relative c'' {
   s32 s32_\appassmolto s8. \voiceOne r8 <bes'' es bes'>-> s4
   \override Stem #'cross-staff = ##t
   \override Stem #'length = #28
-  \override Stem #'flag-style = #'no-flag
+  \override Flag #'style = #'no-flag
   s8 \voiceTwo g,8 aes4 s4
 }
 
 middleVoiceOne = \relative c' {
   \override Stem #'cross-staff = ##t
   \override Stem #'length = #32
-  \override Stem #'flag-style = #'no-flag
+  \override Flag #'style = #'no-flag
   d!8\noBeam s8 s8 s8_\crmolto s4  % 1
   s4 <g bes\arpeggio>8[ <es' g>] \voiceOne e,8( dis16 e) | % 2
   \revert Stem #'length
@@ -78,7 +78,7 @@ middleVoiceTwo = \relative c' {
   s2. | % 1
   \override Stem #'cross-staff = ##t
   \override Stem #'length = #24
-  \override Stem #'flag-style = #'no-flag
+  \override Flag #'style = #'no-flag
   s2 \voiceTwo e!4 | % 2
   s4 \voiceTwo <bes c es f>8 <f' aes es'>16 d' <bes, f' aes c>8 <bes' fis'> | % 3
 }
index 8403fddfe131ebb443737e770cd54b21321b23f7..20cbd145d8c1d16fc139c6e5519661df3f683227 100644 (file)
@@ -21,5 +21,6 @@ Use the @code{\\override} and @code{\\revert} expressions to set the
   b
   \override NoteHead #'color = #green
   \override Stem #'color = #blue
+  \override Flag #'color = #magenta
   e8 es d dis e4 r
 }
index c74e64e767b75457a3c5fcbafcff55b665bd2479..674ad78ed9fd1ee97bb33172b44da12e92112a9c 100644 (file)
@@ -3,8 +3,8 @@
 
 \header {
   texidoc = "Default flag styles: '(), 'mensural and 'no-flag.
-  Compare all three methods to print them: (1) C++ default implementation, 
-  (2) Scheme implementation using the 'flag-style grob property and 
+  Compare all three methods to print them: (1) C++ default implementation,
+  (2) Scheme implementation using the 'style grob property and
   (3) setting the 'flag property explicitly to the desired Scheme function.
   All three systems should be absolutely identical."
 }
@@ -19,7 +19,7 @@ testnotes = { \autoBeamOff
   c''8 d''16 c''32 d''64 \acciaccatura {c''8} d''64
 }
 
-% Old settings: flag-style set to default, 'mensural, 'no-flag; using the
+% Old settings: style set to default, 'mensural, 'no-flag; using the
 % default C++ function ly:stem::calc-stem
 {
   \override Score.RehearsalMark #'self-alignment-X = #LEFT
@@ -29,11 +29,11 @@ testnotes = { \autoBeamOff
   \testnotes
 
   \mark "Symbol: 'mensural (C++)"
-  \override Stem #'flag-style = #'mensural
+  \override Flag #'style = #'mensural
   \testnotes
 
   \mark "Symbol: 'no-flag (C++)"
-  \override Stem #'flag-style = #'no-flag
+  \override Flag #'style = #'no-flag
   \testnotes
 }
 
@@ -42,17 +42,17 @@ testnotes = { \autoBeamOff
   \override Score.RehearsalMark #'self-alignment-X = #LEFT
   \time 2/4
 
-  \override Stem #'flag = #default-flag
-  \revert Stem #'flag-style
+  \override Flag #'stencil = #default-flag
+  \revert Flag #'style
   \mark "Default flags (Scheme)"
   \testnotes
 
   \mark "Symbol: 'mensural (Scheme)"
-  \override Stem #'flag-style = #'mensural
+  \override Flag #'style = #'mensural
   \testnotes
 
   \mark "Symbol: 'no-flag (Scheme)"
-  \override Stem #'flag-style = #'no-flag
+  \override Flag #'style = #'no-flag
   \testnotes
 }
 
@@ -62,14 +62,14 @@ testnotes = { \autoBeamOff
   \time 2/4
 
   \mark "Function: normal-flag"
-  \override Stem #'flag = #normal-flag
+  \override Flag #'stencil = #normal-flag
   \testnotes
 
   \mark "Function: mensural-flag"
-  \override Stem #'flag = #mensural-flag
+  \override Flag #'stencil = #mensural-flag
   \testnotes
 
   \mark "Function: no-flag"
-  \override Stem #'flag = #no-flag
+  \override Flag #'stencil = #no-flag
   \testnotes
 }
index b26f9b71d66d2087fb710fcaae749a8bb89e440a..75248fbcb90b882e129b2fdf1b263b8ac084ef3d 100644 (file)
@@ -1,7 +1,7 @@
 \version "2.14.0"
 
 \header {
-  texidoc = "The 'flag property of the Stem grob can be set to a custom
+  texidoc = "The 'stencil property of the Flag grob can be set to a custom
 scheme function to generate the glyph for the flag."
 }
 
@@ -9,26 +9,28 @@ scheme function to generate the glyph for the flag."
 % test notes, which will be shown in different style:
 testnotes = { \autoBeamOff c'8 d'16 c'32 d'64 \acciaccatura {c'8} d'64 c''8 d''16 c''32 d''64 \acciaccatura {c''8} d''64  }
 
-#(define-public (weight-flag stem-grob)
-  (let* ((log (- (ly:grob-property stem-grob 'duration-log) 2))
+#(define-public (weight-flag grob)
+  (let* ((stem-grob (ly:grob-parent grob X))
+         (log (- (ly:grob-property stem-grob 'duration-log) 2))
          (is-up (eqv? (ly:grob-property stem-grob 'direction) UP))
          (yext (if is-up (cons (* log -0.8) 0) (cons 0 (* log 0.8))))
          (flag-stencil (make-filled-box-stencil '(-0.4 . 0.4) yext))
-         (stroke-style (ly:grob-property stem-grob 'stroke-style))
+         (stroke-style (ly:grob-property grob 'stroke-style))
          (stroke-stencil (if (equal? stroke-style "grace") (make-line-stencil 0.2 -0.9 -0.4 0.9 -0.4) empty-stencil)))
     (ly:stencil-add flag-stencil stroke-stencil)))
 
 
 % Create a flag stencil by looking up the glyph from the font
-#(define (inverted-flag stem-grob)
-  (let* ((dir (if (eqv? (ly:grob-property stem-grob 'direction) UP) "d" "u"))
-         (flag (retrieve-glyph-flag "" dir "" stem-grob))
-         (line-thickness (ly:staff-symbol-line-thickness stem-grob))
+#(define (inverted-flag grob)
+  (let* ((stem-grob (ly:grob-parent grob X))
+         (dir (if (eqv? (ly:grob-property stem-grob 'direction) UP) "d" "u"))
+         (flag (retrieve-glyph-flag "" dir "" grob))
+         (line-thickness (ly:staff-symbol-line-thickness grob))
          (stem-thickness (ly:grob-property stem-grob 'thickness))
          (stem-width (* line-thickness stem-thickness))
-         (stroke-style (ly:grob-property stem-grob 'stroke-style))
+         (stroke-style (ly:grob-property grob 'stroke-style))
          (stencil (if (null? stroke-style) flag
-                         (add-stroke-glyph flag stem-grob dir stroke-style "")))
+                         (add-stroke-glyph flag grob dir stroke-style "")))
          (rotated-flag (ly:stencil-rotate-absolute stencil 180 0 0)))
     (ly:stencil-translate rotated-flag (cons (- (/ stem-width 2))  0))))
 
@@ -36,11 +38,11 @@ testnotes = { \autoBeamOff c'8 d'16 c'32 d'64 \acciaccatura {c'8} d'64 c''8 d''1
   \override Score.RehearsalMark #'self-alignment-X = #LEFT
   \time 2/4
   \mark "Function: weight-flag (custom)"
-  \override Stem #'flag = #weight-flag
+  \override Flag #'stencil = #weight-flag
   \testnotes
 
   \mark "Function: inverted-flag (custom)"
-  \override Stem #'flag = #inverted-flag
+  \override Flag #'stencil = #inverted-flag
   \testnotes
 
 }
index 7a13d64bae81ad7304dfadf755ae035736fbcc5f..3190abd2fd69e14f2002d56c6ed99d9d72d4f9bb 100644 (file)
@@ -17,7 +17,7 @@ stemLength = #(define-music-function (parser location length) (number?)
 {
     \autoBeamOff
     \time 3/8
-    \override Stem #'flag = #modern-straight-flag
+    \override Flag #'stencil = #modern-straight-flag
     \override Stem #'length-fraction = #'1.5
     r8
     \acciaccatura {
index 918985e6ef9d12ba071964ab58edaf27d3b0951c..f4b7a51dac0a5427560b9324f53346eee6e9c486 100644 (file)
@@ -13,11 +13,11 @@ testnotes = { \autoBeamOff c'8 d'16 c'32 d'64 \acciaccatura {c'8} d'64
   \override Score.RehearsalMark #'self-alignment-X = #LEFT
   \time 2/4
   \mark "modern straight"
-  \override Stem #'flag = #modern-straight-flag
+  \override Flag #'stencil = #modern-straight-flag
   \testnotes
 
   \mark "old straight (large angles)"
-  \override Stem #'flag = #old-straight-flag
+  \override Flag #'stencil = #old-straight-flag
   \testnotes
 %
 %   \mark "custom slant"
@@ -25,6 +25,6 @@ testnotes = { \autoBeamOff c'8 d'16 c'32 d'64 \acciaccatura {c'8} d'64
 % %                flag thickness and spacing
 % %                up-flag angle and length
 % %               down-flag angle and length
-%   \override Stem #'flag = #(straight-flag 0.35 0.8 -5 0.5 60 2.0)
+%   \override Flag #'stencil = #(straight-flag 0.35 0.8 -5 0.5 60 2.0)
 %   \testnotes
 }
index 42fab60ad331a0c058926c36bbcf85b657e1f547..d302a7d9910aae0eeb387ca9feed487ca0c74bd4 100644 (file)
@@ -8,8 +8,10 @@
 
 #(whitelist-grob 'NoteHead)
 #(whitelist-grob 'Stem)
+#(whitelist-grob 'Flag)
 #(whitelist-grob "NoteHead")
 #(whitelist-grob "Stem")
+#(whitelist-grob "Flag")
 
 #(map whitelist-symbol '(stencil style duration-log
                         stem-attachment end-position staff-position
index 57d1eaf372c3a78ac677fbf7baa9ec41c2771c35..c58d56ef6012752e2eeb1a0b3e01ce7c65d33e71 100644 (file)
@@ -74,6 +74,7 @@ skips =
     \override NoteHead #'transparent = ##t
     \override NoteHead #'no-ledgers = ##t
     \override Stem #'transparent = ##t
+    \override Flag #'transparent = ##t
     \override Beam #'transparent = ##t
     << \skips
 
index fad2500f5be59590e126c1804ad2d4356dd67e3e..6dc79306c8a3a1cbe28b7401325c929e864d570d 100644 (file)
@@ -154,7 +154,7 @@ bass = \new Voice \relative c{
     >>
 
     \grace {
-       \override Stem  #'stroke-style = #"grace"
+       \override Flag  #'stroke-style = #"grace"
 
         s8
         s16 s s
@@ -163,7 +163,7 @@ bass = \new Voice \relative c{
        \clef bass
        <e,,, e,>32(\sustainOff\sustainOn
 
-       \revert Stem #'stroke-style
+       \revert Flag #'stroke-style
     }
     <gis' e>2)
 
index 78ef6ab122c9878b4fa1578af34f0a5c4d32b59f..fb87ca910758b1c0e8aa4f47d32f20c7515cd790 100644 (file)
@@ -1,7 +1,7 @@
 % 
 
-longgrace = \override Stem  #'stroke-style = #'()
-endlonggrace = \revert Stem #'stroke-style
+longgrace = \override Flag  #'stroke-style = #'()
+endlonggrace = \revert Flag #'stroke-style
 ritenuto = \markup { \italic  "rit." }
 
 \version "2.14.0"
index 043864ed30b1c75d7e8e0f21033abc1258b3f4d6..be3dc3caf660292bcf1d157964def9ebe5eb14d2 100644 (file)
@@ -12,7 +12,7 @@
 }
 
 mus = \relative c' {
-  % Acciaccaturas contain a slur and  \override Stem #'stroke-style
+  % Acciaccaturas contain a slur and  \override Flag #'stroke-style
   % Thus, we're checking \override here
   c4 \acciaccatura d8 c4
   % Checking \set and \unset
@@ -23,12 +23,12 @@ mus = \relative c' {
   % Checking \once \override
   \once \override Stem #'thickness = #8.0 d8
   % Checking two overrides
-  \override Stem #'thickness = #8.0 \override Stem #'stroke-style = "grace"
+  \override Stem #'thickness = #8.0 \override Flag #'stroke-style = "grace"
   d8
   % reverting one of them
   \revert Stem #'thickness d8
   % and the other
-  \revert Stem #'stroke-style c8
+  \revert Flag #'stroke-style c8
 
   % checking tweaks
   c2-\tweak #'color #red ->
index fd3c194d7ca4f6cd43420433ad2ad0dfc2b8fafb..797fe160dd7baa5d11eb2e58f4be8cccaac02aee 100644 (file)
@@ -1,8 +1,9 @@
 \version "2.14.0"
 
 \header {
-  texidoc = "Stems with overridden 'length should not confuse height estimation.
-This example should fit snugly on one page.
+  texidoc = "Stems with overridden 'Y-extent should
+not confuse height estimation.  This example should fit snugly
+on one page.
 "
 }
 
@@ -25,7 +26,7 @@ This example should fit snugly on one page.
   \score {
     \new Voice {
       \voiceTwo
-      \override Stem #'length = #0
+      \override Stem #'Y-extent = #'(0.0 . 0.0)
       \repeat unfold 144 a4
     }
     \layout {
diff --git a/input/regression/stem-length-override.ly b/input/regression/stem-length-override.ly
new file mode 100644 (file)
index 0000000..7d0bc2d
--- /dev/null
@@ -0,0 +1,13 @@
+
+\version "2.15.9"
+
+\header {
+  texidoc = "Stem length can be overridden via the function
+stem::length
+"
+}
+
+\relative c' {
+  \override Stem #'Y-extent = #(stem::length 8)
+  e4 f'4
+}
diff --git a/input/regression/stem-pure-height-beamed.ly b/input/regression/stem-pure-height-beamed.ly
new file mode 100644 (file)
index 0000000..28cdc6d
--- /dev/null
@@ -0,0 +1,13 @@
+\version "2.15.9"
+
+\header {
+  texidoc = "Lilypond gets beamed stem pure heights correct
+to avoid outside staff collisions.
+"
+}
+
+{
+  \stemUp
+  gis''8 a bes'' a
+  bes''! a bes''! a
+}
index 8b0c9f2abc1facdfa332f4507102df9c0a31316c..106fffc74134713cbd74fc181ec48b7e44dd2857 100644 (file)
@@ -232,8 +232,7 @@ void Beam_scoring_problem::init_collisions (vector<Grob *> grobs)
                      - beam->relative_coordinate (common[Y_AXIS], Y_AXIS);
 
       Real factor = parameters.STEM_COLLISION_FACTOR;
-      if (!unsmob_grob (s->get_object ("beam"))
-          && !Stem::flag (s).is_empty ())
+      if (!unsmob_grob (s->get_object ("beam")))
         factor = 1.0;
       add_collision (x, y, factor);
     }
index 4acf18c1439f9aa5699e8d9c23dc68a8204b2c30..1ecd71a88ff5a87027c7aa987c67292a5954196d 100644 (file)
@@ -1549,10 +1549,10 @@ Beam::set_stem_lengths (SCM smob)
         stem_y += thick * 0.5 * get_grob_direction (s);
 
       /*
-        Do set_stemend for invisible stems too, so tuplet brackets
+        Do set_stem_positions for invisible stems too, so tuplet brackets
         have a reference point for sloping
        */
-      Stem::set_stemend (s, 2 * stem_y / staff_space);
+      Stem::set_stem_positions (s, 2 * stem_y / staff_space);
     }
 
   return posns;
index fff2359cc0376f774e46ab531798213e0dd62e40..46b13811be3c9c20c70826c9b13b195ee60064e0 100644 (file)
@@ -132,15 +132,12 @@ Dot_column::calc_positioning_done (SCM smob)
        i != stems.end (); i++)
     {
       Grob *stem = (*i);
-      Stencil flag = Stem::flag (stem);
-      if (!flag.is_empty ())
+      Grob *flag = Stem::flag (stem);
+      if (flag)
         {
-          Interval y = flag.extent (Y_AXIS)
-                       * (2 / ss)
-                       + Stem::stem_end_position (stem);
-
-          Interval x = stem->relative_coordinate (commonx, X_AXIS)
-                       + flag.extent (X_AXIS);
+          Grob *commony = stem->common_refpoint (flag, Y_AXIS);
+          Interval y = flag->extent (commony, Y_AXIS) * (2 / ss);
+          Interval x = flag->extent (commonx, X_AXIS);
 
           boxes.push_back (Box (x, y));
         }
diff --git a/lily/flag.cc b/lily/flag.cc
new file mode 100644 (file)
index 0000000..5aee4d9
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+  This file is part of LilyPond, the GNU music typesetter.
+
+  Copyright (C) 1996--2011 Han-Wen Nienhuys <hanwen@xs4all.nl>
+  Jan Nieuwenhuizen <janneke@gnu.org>
+
+  LilyPond is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  LilyPond is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "stem.hh"
+
+#include "directional-element-interface.hh"
+#include "font-interface.hh"
+#include "grob.hh"
+#include "international.hh"
+#include "output-def.hh"
+#include "staff-symbol-referencer.hh"
+#include "stencil.hh"
+#include "warn.hh"
+
+class Flag
+{
+public:
+  DECLARE_SCHEME_CALLBACK (print, (SCM));
+  DECLARE_SCHEME_CALLBACK (width, (SCM));
+  DECLARE_SCHEME_CALLBACK (calc_y_offset, (SCM));
+  DECLARE_SCHEME_CALLBACK (calc_x_offset, (SCM));
+  DECLARE_GROB_INTERFACE ();
+};
+
+
+
+MAKE_SCHEME_CALLBACK (Flag, width, 1);
+SCM
+Flag::width (SCM smob)
+{
+  Grob *me = unsmob_grob (smob);
+  Stencil *sten = unsmob_stencil (me->get_property ("stencil"));
+  if (!sten)
+    return ly_interval2scm (Interval (0.0, 0.0));
+
+  Grob *stem = me->get_parent (X_AXIS);
+
+  /*
+    TODO:
+    This reproduces a bad hard-coding that has been in the code for quite some time:
+    the bounding boxes for the flags are slightly off and need to be fixed.
+  */
+
+  return ly_interval2scm (sten->extent (X_AXIS) - stem->extent (stem, X_AXIS)[RIGHT]);
+}
+MAKE_SCHEME_CALLBACK (Flag, print, 1);
+SCM
+Flag::print (SCM smob)
+{
+  Grob *me = unsmob_grob (smob);
+  Grob *stem = me->get_parent (X_AXIS);
+
+  Direction d = get_grob_direction (stem);
+  int log = Stem::duration_log (stem);
+  string flag_style;
+
+  SCM flag_style_scm = me->get_property ("style");
+  if (scm_is_symbol (flag_style_scm))
+    flag_style = ly_symbol2string (flag_style_scm);
+
+  if (flag_style == "no-flag")
+    return Stencil ().smobbed_copy ();
+
+  bool adjust = true;
+
+  string staffline_offs;
+  if (flag_style == "mensural")
+    /* Mensural notation: For notes on staff lines, use different
+       flags than for notes between staff lines.  The idea is that
+       flags are always vertically aligned with the staff lines,
+       regardless if the note head is on a staff line or between two
+       staff lines.  In other words, the inner end of a flag always
+       touches a staff line.
+    */
+    {
+      if (adjust)
+        {
+          Real ss = Staff_symbol_referencer::staff_space (me);
+          int p = (int) (rint (stem->extent (stem, Y_AXIS)[d] * 2 / ss));
+          staffline_offs
+            = Staff_symbol_referencer::on_line (stem, p) ? "0" : "1";
+        }
+      else
+        staffline_offs = "2";
+    }
+  else
+    staffline_offs = "";
+
+  char dir = (d == UP) ? 'u' : 'd';
+  string font_char = flag_style
+                     + to_string (dir) + staffline_offs + to_string (log);
+  Font_metric *fm = Font_interface::get_default_font (me);
+  Stencil flag = fm->find_by_name ("flags." + font_char);
+  if (flag.is_empty ())
+    me->warning (_f ("flag `%s' not found", font_char));
+
+  /*
+    TODO: maybe property stroke-style should take different values,
+    e.g. "" (i.e. no stroke), "single" and "double" (currently, it's
+    '() or "grace").  */
+  SCM stroke_style_scm = me->get_property ("stroke-style");
+  if (scm_is_string (stroke_style_scm))
+    {
+      string stroke_style = ly_scm2string (stroke_style_scm);
+      if (!stroke_style.empty ())
+        {
+          string font_char = flag_style + to_string (dir) + stroke_style;
+          Stencil stroke = fm->find_by_name ("flags." + font_char);
+          if (stroke.is_empty ())
+            {
+              font_char = to_string (dir) + stroke_style;
+              stroke = fm->find_by_name ("flags." + font_char);
+            }
+          if (stroke.is_empty ())
+            me->warning (_f ("flag stroke `%s' not found", font_char));
+          else
+            flag.add_stencil (stroke);
+        }
+    }
+
+  return flag.smobbed_copy ();
+}
+
+MAKE_SCHEME_CALLBACK (Flag, calc_y_offset, 1);
+SCM
+Flag::calc_y_offset (SCM smob)
+{
+  Grob *me = unsmob_grob (smob);
+  Grob *stem = me->get_parent (X_AXIS);
+  Direction d = get_grob_direction (stem);
+
+  Real blot
+    = me->layout ()->get_dimension (ly_symbol2scm ("blot-diameter"));
+
+  Real y2 = stem->extent (stem, Y_AXIS)[d];
+
+  return scm_from_double (y2 - d * blot / 2);
+}
+
+MAKE_SCHEME_CALLBACK (Flag, calc_x_offset, 1);
+SCM
+Flag::calc_x_offset (SCM smob)
+{
+  Grob *me = unsmob_grob (smob);
+  Grob *stem = me->get_parent (X_AXIS);
+  return scm_from_double (stem->extent (stem, X_AXIS)[RIGHT]);
+}
+
+ADD_INTERFACE (Flag,
+               "A flag that gets attached to a stem."
+               "The style property is  symbol determining"
+               " what style of flag glyph is typeset on a"
+               " @code{Stem}.  Valid options include @code{'()}"
+               " for standard flags, @code{'mensural} and"
+               " @code{'no-flag}, which switches off the flag.",
+
+               /* properties */
+               "style "
+               "stroke-style "
+              );
\ No newline at end of file
index 3fa1fcddc2324502317e95e313915af755e8b2a7..945866632e190866d86f3ef0d76ba5d9b62f1c2c 100644 (file)
@@ -52,6 +52,7 @@ public:
   virtual void handle_prebroken_dependencies ();
   virtual Interval_t<int> spanned_rank_interval () const;
   virtual Interval pure_height (Grob *ref, int start, int end);
+  virtual void cache_pure_height (Interval height);
   DECLARE_GROB_INTERFACE ();
 protected:
   virtual void discretionary_processing ();
index b18b39e53a0035769da90726590c3a631363d1b6..c8e0f6939c80a65c997ba4eea098fd82ef1d7591 100644 (file)
@@ -40,35 +40,42 @@ public:
   static void add_head (Grob *me, Grob *n);
   static Stem_info get_stem_info (Grob *);
   static Real chord_start_y (Grob *);
-  static void set_stemend (Grob *, Real);
+  static void set_stem_positions (Grob *, Real);
+  static void cache_pure_height (Grob *, Interval, Interval);
   static Slice beam_multiplicity (Grob *);
   static Direction get_default_dir (Grob *);
   static Real thickness (Grob *);
+  static Real beam_end_corrective (Grob *);
   static int head_count (Grob *);
   static bool is_invisible (Grob *);
   static bool is_normal_stem (Grob *);
   static bool is_cross_staff (Grob *);
   static Interval head_positions (Grob *);
-  static Real stem_end_position (Grob *);
-  static Stencil flag (Grob *);
-  static Stencil get_translated_flag (Grob *);
+  static Interval internal_pure_height (Grob *, bool);
+  static Interval internal_height (Grob *, bool);
+  static bool is_valid_stem (Grob *);
+  static Grob *get_reference_head (Grob *);
+  static Real internal_calc_stem_end_position (Grob *, bool);
+  static Real internal_calc_stem_begin_position (Grob *, bool);
+
   DECLARE_GROB_INTERFACE ();
   static void set_spacing_hints (Grob *);
+  static Grob *flag (Grob *);
 
   DECLARE_SCHEME_CALLBACK (print, (SCM));
   DECLARE_SCHEME_CALLBACK (calc_default_direction, (SCM));
   DECLARE_SCHEME_CALLBACK (offset_callback, (SCM element));
   DECLARE_SCHEME_CALLBACK (calc_direction, (SCM));
   DECLARE_SCHEME_CALLBACK (calc_beaming, (SCM));
-  DECLARE_SCHEME_CALLBACK (calc_length, (SCM));
   DECLARE_SCHEME_CALLBACK (calc_stem_begin_position, (SCM));
+  DECLARE_SCHEME_CALLBACK (pure_calc_stem_begin_position, (SCM, SCM, SCM));
   DECLARE_SCHEME_CALLBACK (calc_stem_end_position, (SCM));
+  DECLARE_SCHEME_CALLBACK (pure_calc_stem_end_position, (SCM, SCM, SCM));
   DECLARE_SCHEME_CALLBACK (calc_stem_info, (SCM));
   DECLARE_SCHEME_CALLBACK (calc_positioning_done, (SCM));
   DECLARE_SCHEME_CALLBACK (width, (SCM smob));
   DECLARE_SCHEME_CALLBACK (pure_height, (SCM, SCM, SCM));
   DECLARE_SCHEME_CALLBACK (height, (SCM));
   DECLARE_SCHEME_CALLBACK (calc_cross_staff, (SCM));
-  DECLARE_SCHEME_CALLBACK (calc_flag, (SCM));
 };
 #endif
index bf67f3c6dda4d578255a7a3f211c6e28d54c66c1..6a468a6830607f6522f786c7dc15cfefdebdd5b8 100644 (file)
@@ -245,11 +245,17 @@ Item::pure_height (Grob *g, int start, int end)
   if (cached_pure_height_valid_)
     return cached_pure_height_ + pure_relative_y_coordinate (g, start, end);
 
-  cached_pure_height_ = Grob::pure_height (this, start, end);
-  cached_pure_height_valid_ = true;
+  cache_pure_height (Grob::pure_height (this, start, end));
   return cached_pure_height_ + pure_relative_y_coordinate (g, start, end);
 }
 
+void
+Item::cache_pure_height (Interval height)
+{
+  cached_pure_height_ = height;
+  cached_pure_height_valid_ = true;
+}
+
 ADD_INTERFACE (Item,
                "Grobs can be distinguished in their role in the horizontal"
                " spacing.  Many grobs define constraints on the spacing by"
index 9a71c00a598b9bee8aa42cf8de12769fb6d0470e..5cffd5d2053333df09d6782217b10fff2eeb929a 100644 (file)
@@ -31,6 +31,7 @@
 #include "separation-item.hh"
 #include "spacing-interface.hh"
 #include "staff-spacing.hh"
+#include "staff-symbol-referencer.hh"
 #include "stem.hh"
 #include "warn.hh"
 
@@ -273,17 +274,8 @@ Note_spacing::stem_dir_correction (Grob *me, Item *rcolumn,
           Interval hp = Stem::head_positions (stem);
           if (!hp.is_empty ())
             {
-              Real chord_start = hp[stem_dir];
-
-              /*
-                can't look at stem-end-position, since that triggers
-                beam slope computations.
-              */
-              Real stem_end = hp[stem_dir]
-                              + stem_dir * robust_scm2double (stem->get_property ("length"), 7);
-
-              stem_posns[d] = Interval (min (chord_start, stem_end),
-                                        max (chord_start, stem_end));
+              Real ss = Staff_symbol_referencer::staff_space (stem);
+              stem_posns[d] = stem->pure_height (stem, 0, INT_MAX) * (2 / ss);
               head_posns[d].unite (hp);
             }
         }
index 985b7b08a76ba51e0c0748dc926c043133491af8..ca767cc7af5bbfd68468dc7adb41d6eb73b9b423 100644 (file)
@@ -55,6 +55,7 @@ class Rhythmic_column_engraver : public Engraver
 {
   vector<Grob *> rheads_;
   Grob *stem_;
+  Grob *flag_;
   Grob *note_column_;
   Grob *arpeggio_;
 
@@ -62,6 +63,7 @@ class Rhythmic_column_engraver : public Engraver
 protected:
 
   DECLARE_ACKNOWLEDGER (stem);
+  DECLARE_ACKNOWLEDGER (flag);
   DECLARE_ACKNOWLEDGER (rhythmic_head);
   DECLARE_ACKNOWLEDGER (arpeggio);
   void process_acknowledged ();
@@ -72,6 +74,7 @@ Rhythmic_column_engraver::Rhythmic_column_engraver ()
 {
 
   stem_ = 0;
+  flag_ = 0;
   note_column_ = 0;
   arpeggio_ = 0;
 }
@@ -105,6 +108,8 @@ Rhythmic_column_engraver::process_acknowledged ()
           Pointer_group_interface::add_grob (note_column_, ly_symbol2scm ("elements"), arpeggio_);
           note_column_->set_object ("arpeggio", arpeggio_->self_scm ());
         }
+      if (flag_)
+        Pointer_group_interface::add_grob (note_column_, ly_symbol2scm ("elements"), flag_);
     }
 }
 
@@ -114,6 +119,12 @@ Rhythmic_column_engraver::acknowledge_stem (Grob_info i)
   stem_ = i.grob ();
 }
 
+void
+Rhythmic_column_engraver::acknowledge_flag (Grob_info i)
+{
+  flag_ = i.grob ();
+}
+
 void
 Rhythmic_column_engraver::acknowledge_rhythmic_head (Grob_info i)
 {
@@ -132,9 +143,11 @@ Rhythmic_column_engraver::stop_translation_timestep ()
   note_column_ = 0;
   stem_ = 0;
   arpeggio_ = 0;
+  flag_ = 0;
 }
 
 ADD_ACKNOWLEDGER (Rhythmic_column_engraver, stem);
+ADD_ACKNOWLEDGER (Rhythmic_column_engraver, flag);
 ADD_ACKNOWLEDGER (Rhythmic_column_engraver, rhythmic_head);
 ADD_ACKNOWLEDGER (Rhythmic_column_engraver, arpeggio);
 
index 7c4ece46433c5f6be6477a52bc0d3d492d331f3f..6a509d391e2961d1f452588f1bc1c35eef1dee69 100644 (file)
@@ -56,17 +56,7 @@ Staff_spacing::optical_correction (Grob *me, Grob *g, Interval bar_height)
       Direction d = get_grob_direction (stem);
       if (Stem::is_normal_stem (stem) && d == DOWN)
         {
-
-          /*
-            can't look at stem-end-position, since that triggers
-            beam slope computations.
-          */
-          Real stem_start = Stem::head_positions (stem) [d];
-          Real stem_end = stem_start
-                          + d * robust_scm2double (stem->get_property ("length"), 7);
-
-          Interval stem_posns (min (stem_start, stem_end),
-                               max (stem_end, stem_start));
+          Interval stem_posns = stem->pure_height (stem, 0, INT_MAX);
 
           stem_posns.intersect (bar_height);
 
index 6890b5b041c410f56186d1c8733eb4613e313179..04184a90203891e73fd53086ce50c34b8938b981 100644 (file)
@@ -38,6 +38,7 @@ class Stem_engraver : public Engraver
 {
   Grob *stem_;
   Grob *tremolo_;
+  vector <Grob *> maybe_flags_;
   Stream_event *rhythmic_ev_;
   Stream_event *tremolo_ev_;
 
@@ -49,6 +50,8 @@ protected:
   DECLARE_TRANSLATOR_LISTENER (tremolo);
   DECLARE_ACKNOWLEDGER (rhythmic_head);
   void stop_translation_timestep ();
+  void finalize ();
+  void kill_unused_flags ();
 };
 
 Stem_engraver::Stem_engraver ()
@@ -65,7 +68,6 @@ Stem_engraver::make_stem (Grob_info gi)
   /* Announce the cause of the head as cause of the stem.  The
      stem needs a rhythmic structure to fit it into a beam.  */
   stem_ = make_item ("Stem", gi.grob ()->self_scm ());
-
   if (tremolo_ev_)
     {
       /* Stem tremolo is never applied to a note by default,
@@ -158,11 +160,37 @@ Stem_engraver::acknowledge_rhythmic_head (Grob_info gi)
     }
 
   Stem::add_head (stem_, gi.grob ());
+
+  if (Stem::is_normal_stem (stem_)
+      && Stem::duration_log (stem_) > 2)
+    {
+      Item *flag = make_item ("Flag", stem_->self_scm ());
+      flag->set_parent (stem_, X_AXIS);
+      stem_->set_object ("flag", flag->self_scm ());
+      maybe_flags_.push_back (flag);
+    }
+}
+
+void
+Stem_engraver::kill_unused_flags ()
+{
+  for (vsize i = 0; i < maybe_flags_.size (); i++)
+    if (unsmob_grob (maybe_flags_[i]->get_parent (X_AXIS)->get_object ("beam")))
+      maybe_flags_[i]->suicide ();
+}
+
+void
+Stem_engraver::finalize ()
+{
+  kill_unused_flags ();
 }
 
 void
 Stem_engraver::stop_translation_timestep ()
 {
+  if (scm_is_string (get_property ("whichBar")))
+    kill_unused_flags ();
+
   tremolo_ = 0;
   if (stem_)
     {
@@ -205,7 +233,8 @@ ADD_TRANSLATOR (Stem_engraver,
                 /* read */
                 "tremoloFlags "
                 "stemLeftBeamCount "
-                "stemRightBeamCount ",
+                "stemRightBeamCount "
+                "whichBar ",
 
                 /* write */
                 ""
index 2036d9a89072e2ef8019761674ebabd45b8d8c23..cc4589827e69d13b37da34030d98ca5a5fe1658c 100644 (file)
@@ -216,10 +216,9 @@ Stem_tremolo::translated_stencil (Grob *me, Real slope)
   Real beam_translation = get_beam_translation (me);
 
   int beam_count = beam ? (Stem::beam_multiplicity (stem).length () + 1) : 0;
-  Real ss = Staff_symbol_referencer::staff_space (me);
 
   Real end_y
-    = Stem::stem_end_position (stem) * ss / 2
+    = stem->extent (stem, Y_AXIS)[stemdir]
       - stemdir * max (beam_count, 1) * beam_translation;
 
   if (!beam && Stem::duration_log (stem) >= 3)
@@ -234,6 +233,7 @@ Stem_tremolo::translated_stencil (Grob *me, Real slope)
     {
       /* we shouldn't position relative to the end of the stem since the stem
          is invisible */
+      Real ss = Staff_symbol_referencer::staff_space (me);
       vector<int> nhp = Stem::note_head_positions (stem);
       Real note_head = (stemdir == UP ? nhp.back () : nhp[0]) * ss / 2;
       end_y = note_head + stemdir * 1.5;
index e83ffd9893226a95672f70ebf284d7cd8d926733..7245e3c07fae7053aa0d4d9e0edf4378d42281d9 100644 (file)
   along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
 */
 
+/*
+  Note that several internal functions have a calc_beam bool argument.
+  This argument means: "If set, acknowledge the fact that there is a beam
+  and deal with it.  If not, give me the measurements as if there is no beam."
+  Most pure functions are called WITHOUT calc_beam, whereas non-pure functions
+  are called WITH calc_beam.
+
+  The only exception to this is ::pure_height, which calls internal_pure_height
+  with "true" for calc_beam in order to trigger the calculations of other
+  pure heights in case there is a beam.  It passes false, however, to
+  internal_height and internal_pure_height for all subsequent iterations.
+*/
+
 #include "stem.hh"
 #include "spanner.hh"
 
@@ -105,15 +118,46 @@ Stem::chord_start_y (Grob *me)
 }
 
 void
-Stem::set_stemend (Grob *me, Real se)
+Stem::set_stem_positions (Grob *me, Real se)
 {
   // todo: margins
   Direction d = get_grob_direction (me);
 
+  Grob *beam = unsmob_grob (me->get_object ("beam"));
   if (d && d * head_positions (me)[get_grob_direction (me)] >= se * d)
     me->warning (_ ("weird stem size, check for narrow beams"));
 
-  me->set_property ("stem-end-position", scm_from_double (se));
+  Interval height = me->pure_height (me, 0, INT_MAX);
+  Real half_space = Staff_symbol_referencer::staff_space (me) * 0.5;
+
+  height[d] = se * half_space + beam_end_corrective (me);
+
+  Real stemlet_length = robust_scm2double (me->get_property ("stemlet-length"),
+                                           0.0);
+  bool stemlet = stemlet_length > 0.0;
+
+  Grob *lh = get_reference_head (me);
+
+  if (!lh)
+    {
+      if (stemlet && beam)
+        {
+          Real beam_translation = Beam::get_beam_translation (beam);
+          Real beam_thickness = Beam::get_beam_thickness (beam);
+          int beam_count = beam_multiplicity (me).length () + 1;
+
+          height[-d] = (height[d] - d
+                        * (0.5 * beam_thickness
+                        + beam_translation * max (0, (beam_count - 1))
+                        + stemlet_length));
+        }
+      else if (!stemlet && beam)
+        height[-d] = height[d];
+      else if (stemlet && !beam)
+        me->programming_error ("Can't have a stemlet without a beam.");
+    }
+
+  me->set_property ("Y-extent", ly_interval2scm (height));
 }
 
 /* Note head that determines hshift for upstems
@@ -241,47 +285,60 @@ Stem::pure_height (SCM smob,
                    SCM /* end */)
 {
   Grob *me = unsmob_grob (smob);
-  Interval iv;
+  return ly_interval2scm (internal_pure_height (me, true));
+}
 
+Interval
+Stem::internal_pure_height (Grob *me, bool calc_beam)
+{
   if (!is_normal_stem (me))
-    return ly_interval2scm (iv);
+    return Interval (0.0, 0.0);
 
-  Real ss = Staff_symbol_referencer::staff_space (me);
-  Real rad = Staff_symbol_referencer::staff_radius (me);
+  Grob *beam = unsmob_grob (me->get_object ("beam"));
+
+  Interval iv = internal_height (me, false);
 
-  if (!to_boolean (me->get_property ("cross-staff")))
+  if (!beam)
+    return iv;
+  if (!to_boolean (me->get_property ("cross-staff")) && calc_beam)
     {
-      Real len_in_halfspaces;
-      SCM user_set_len_scm = me->get_property_data ("length");
-      if (scm_is_number (user_set_len_scm))
-        len_in_halfspaces = scm_to_double (user_set_len_scm);
-      else
-        len_in_halfspaces = scm_to_double (calc_length (smob));
-      Real len = len_in_halfspaces * ss / 2;
+      Interval overshoot;
       Direction dir = get_grob_direction (me);
+      Direction d = DOWN;
+      do
+        overshoot[d] = d == dir ? dir * infinity_f : iv[d];
+      while (flip (&d) != DOWN);
 
-      Interval hp = head_positions (me);
-      if (dir == UP)
-        iv = Interval (0, len);
-      else
-        iv = Interval (-len, 0);
+      vector<Interval> heights;
+      vector<Grob *> my_stems;
+      extract_grob_set (beam, "normal-stems", normal_stems);
+      for (vsize i = 0; i < normal_stems.size (); i++)
+        if (normal_stems[i] != me && get_grob_direction (normal_stems[i]) == dir)
+          {
+            heights.push_back (Stem::internal_pure_height (normal_stems[i], false));
+            my_stems.push_back (normal_stems[i]);
+            iv.unite (heights.back ());
+          }
+      for (vsize i = 0; i < my_stems.size (); i++)
+        cache_pure_height (my_stems[i], iv, heights[i]);
+      iv.intersect (overshoot);
+    }
 
-      if (!hp.is_empty ())
-        {
-          iv.translate (hp[dir] * ss / 2);
-          iv.add_point (hp[-dir] * ss / 2);
-        }
+  return iv;
+}
 
-      /* extend the stem (away from the head) to cover the staff */
-      if (dir == UP)
-        iv[UP] = max (iv[UP], rad * ss);
-      else
-        iv[DOWN] = min (iv[DOWN], -rad * ss);
-    }
-  else
-    iv = Interval (-rad * ss, rad * ss);
+void
+Stem::cache_pure_height (Grob *me, Interval iv, Interval my_iv)
+{
+  Interval overshoot;
+  Direction dir = get_grob_direction (me);
+  Direction d = DOWN;
+  do
+    overshoot[d] = d == dir ? dir * infinity_f : my_iv[d];
+  while (flip (&d) != DOWN);
 
-  return ly_interval2scm (iv);
+  iv.intersect (overshoot);
+  dynamic_cast<Item *> (me)->cache_pure_height (iv);
 }
 
 MAKE_SCHEME_CALLBACK (Stem, calc_stem_end_position, 1)
@@ -289,44 +346,39 @@ SCM
 Stem::calc_stem_end_position (SCM smob)
 {
   Grob *me = unsmob_grob (smob);
+  return scm_from_double (internal_calc_stem_end_position (me, true));
+}
 
+MAKE_SCHEME_CALLBACK (Stem, pure_calc_stem_end_position, 3)
+SCM
+Stem::pure_calc_stem_end_position (SCM smob,
+                                   SCM, /* start */
+                                   SCM /* end */)
+{
+  Grob *me = unsmob_grob (smob);
+  return scm_from_double (internal_calc_stem_end_position (me, false));
+}
+
+Real
+Stem::internal_calc_stem_end_position (Grob *me, bool calc_beam)
+{
   if (!head_count (me))
-    return scm_from_double (0.0);
+    return 0.0;
 
-  if (Grob *beam = get_beam (me))
+  Grob *beam = get_beam (me);
+  Real ss = Staff_symbol_referencer::staff_space (me);
+  if (beam && calc_beam)
     {
       (void) beam->get_property ("quantized-positions");
-      return me->get_property ("stem-end-position");
+      return me->extent (me, Y_AXIS)[get_grob_direction (me)] * ss * 2;
     }
 
   vector<Real> a;
 
   /* WARNING: IN HALF SPACES */
-  Real length = robust_scm2double (me->get_property ("length"), 7);
-
-  Direction dir = get_grob_direction (me);
-  Interval hp = head_positions (me);
-  Real stem_end = dir ? hp[dir] + dir * length : 0;
-
-  /* TODO: change name  to extend-stems to staff/center/'()  */
-  bool no_extend = to_boolean (me->get_property ("no-stem-extend"));
-  if (!no_extend && dir * stem_end < 0)
-    stem_end = 0.0;
-
-  return scm_from_double (stem_end);
-}
-
-/* Length is in half-spaces (or: positions) here. */
-MAKE_SCHEME_CALLBACK (Stem, calc_length, 1)
-SCM
-Stem::calc_length (SCM smob)
-{
-  Grob *me = unsmob_grob (smob);
-
   SCM details = me->get_property ("details");
   int durlog = duration_log (me);
 
-  Real ss = Staff_symbol_referencer::staff_space (me);
   Real staff_rad = Staff_symbol_referencer::staff_radius (me);
   Real length = 7;
   SCM s = ly_assoc_get (ly_symbol2scm ("lengths"), details, SCM_EOL);
@@ -370,7 +422,7 @@ Stem::calc_length (SCM smob)
 
   /* Tremolo stuff.  */
   Grob *t_flag = unsmob_grob (me->get_object ("tremolo-flag"));
-  if (t_flag && !unsmob_grob (me->get_object ("beam")))
+  if (t_flag && (!unsmob_grob (me->get_object ("beam")) || !calc_beam))
     {
       /* Crude hack: add extra space if tremolo flag is there.
 
@@ -398,8 +450,16 @@ Stem::calc_length (SCM smob)
       length = max (length, minlen + 1.0);
     }
 
-  return scm_from_double (length);
+  Real stem_end = dir ? hp[dir] + dir * length : 0;
+
+  /* TODO: change name  to extend-stems to staff/center/'()  */
+  bool no_extend = to_boolean (me->get_property ("no-stem-extend"));
+  if (!no_extend && dir * stem_end < 0)
+    stem_end = 0.0;
+
+  return stem_end;
 }
+
 /* The log of the duration (Number of hooks on the flag minus two)  */
 int
 Stem::duration_log (Grob *me)
@@ -557,29 +617,29 @@ Stem::calc_default_direction (SCM smob)
   return scm_from_int (dir);
 }
 
+// note - height property necessary to trigger quantized beam positions
+// otherwise, we could just use Grob::stencil_height_proc
 MAKE_SCHEME_CALLBACK (Stem, height, 1);
 SCM
 Stem::height (SCM smob)
 {
   Grob *me = unsmob_grob (smob);
-  if (!is_normal_stem (me))
-    return ly_interval2scm (Interval ());
-
-  Direction dir = get_grob_direction (me);
+  return ly_interval2scm (internal_height (me, true));
+}
 
-  Grob *beam = get_beam (me);
-  if (beam)
-    {
-      /* trigger set-stem-lengths. */
-      beam->get_property ("quantized-positions");
-    }
+Grob*
+Stem::get_reference_head (Grob *me)
+{
+  return to_boolean (me->get_property ("avoid-note-head"))
+         ? last_head (me)
+         : first_head (me);
+}
 
-  /*
-    Can't get_stencil (), since that would cache stencils too early.
-    This causes problems with beams.
-   */
-  Stencil *stencil = unsmob_stencil (print (smob));
-  Interval iv = stencil ? stencil->extent (Y_AXIS) : Interval ();
+Real
+Stem::beam_end_corrective (Grob *me)
+{
+  Grob *beam = unsmob_grob (me->get_object ("beam"));
+  Direction dir = get_grob_direction (me);
   if (beam)
     {
       if (dir == CENTER)
@@ -587,116 +647,36 @@ Stem::height (SCM smob)
           programming_error ("no stem direction");
           dir = UP;
         }
-      iv[dir] += dir * Beam::get_beam_thickness (beam) * 0.5;
+      return dir * Beam::get_beam_thickness (beam) * 0.5;
     }
-
-  return ly_interval2scm (iv);
+  return 0.0;
 }
 
-Real
-Stem::stem_end_position (Grob *me)
+Interval
+Stem::internal_height (Grob *me, bool calc_beam)
 {
-  return robust_scm2double (me->get_property ("stem-end-position"), 0);
-}
+  if (!is_valid_stem (me))
+    return Interval ();
 
-MAKE_SCHEME_CALLBACK (Stem, calc_flag, 1);
-SCM
-Stem::calc_flag (SCM smob)
-{
-  Grob *me = unsmob_grob (smob);
+  Direction dir = get_grob_direction (me);
 
-  int log = duration_log (me);
-  /*
-    TODO: maybe property stroke-style should take different values,
-    e.g. "" (i.e. no stroke), "single" and "double" (currently, it's
-    '() or "grace").  */
-  string flag_style;
-
-  SCM flag_style_scm = me->get_property ("flag-style");
-  if (scm_is_symbol (flag_style_scm))
-    flag_style = ly_symbol2string (flag_style_scm);
-
-  if (flag_style == "no-flag")
-    return Stencil ().smobbed_copy ();
-
-  bool adjust = true;
-
-  string staffline_offs;
-  if (flag_style == "mensural")
-    /* Mensural notation: For notes on staff lines, use different
-       flags than for notes between staff lines.  The idea is that
-       flags are always vertically aligned with the staff lines,
-       regardless if the note head is on a staff line or between two
-       staff lines.  In other words, the inner end of a flag always
-       touches a staff line.
-    */
-    {
-      if (adjust)
-        {
-          int p = (int) (rint (stem_end_position (me)));
-          staffline_offs
-            = Staff_symbol_referencer::on_line (me, p) ? "0" : "1";
-        }
-      else
-        staffline_offs = "2";
-    }
-  else
-    staffline_offs = "";
-
-  char dir = (get_grob_direction (me) == UP) ? 'u' : 'd';
-  string font_char = flag_style
-                     + to_string (dir) + staffline_offs + to_string (log);
-  Font_metric *fm = Font_interface::get_default_font (me);
-  Stencil flag = fm->find_by_name ("flags." + font_char);
-  if (flag.is_empty ())
-    me->warning (_f ("flag `%s' not found", font_char));
-
-  SCM stroke_style_scm = me->get_property ("stroke-style");
-  if (scm_is_string (stroke_style_scm))
+  Grob *beam = get_beam (me);
+  if (beam && calc_beam)
     {
-      string stroke_style = ly_scm2string (stroke_style_scm);
-      if (!stroke_style.empty ())
-        {
-          string font_char = flag_style + to_string (dir) + stroke_style;
-          Stencil stroke = fm->find_by_name ("flags." + font_char);
-          if (stroke.is_empty ())
-            {
-              font_char = to_string (dir) + stroke_style;
-              stroke = fm->find_by_name ("flags." + font_char);
-            }
-          if (stroke.is_empty ())
-            me->warning (_f ("flag stroke `%s' not found", font_char));
-          else
-            flag.add_stencil (stroke);
-        }
+      /* trigger set-stem-lengths. */
+      (void) beam->get_property ("quantized-positions");
+      return me->extent (me, Y_AXIS);
     }
 
-  return flag.smobbed_copy ();
-}
+  Real y2 = internal_calc_stem_end_position (me, calc_beam);
+  Real y1 = internal_calc_stem_begin_position (me, calc_beam);
 
-Stencil
-Stem::flag (Grob *me)
-{
-  int log = duration_log (me);
-  if (log < 3
-      || unsmob_grob (me->get_object ("beam")))
-    return Stencil ();
+  Real half_space = Staff_symbol_referencer::staff_space (me) * 0.5;
 
-  if (!is_normal_stem (me))
-    return Stencil ();
+  Interval stem_y  = Interval (min (y1, y2), max (y2, y1)) * half_space;
+  stem_y[dir] += beam_end_corrective (me);
 
-  // This get_property call already evaluates the scheme function with
-  // the grob passed as argument! Thus, we only have to check if a valid
-  // stencil is returned.
-  SCM flag_style_scm = me->get_property ("flag");
-  if (Stencil *flag = unsmob_stencil (flag_style_scm))
-    {
-      return *flag;
-    }
-  else
-    {
-      return Stencil ();
-    }
+  return stem_y;
 }
 
 MAKE_SCHEME_CALLBACK (Stem, width, 1);
@@ -709,17 +689,12 @@ Stem::width (SCM e)
 
   if (is_invisible (me))
     r.set_empty ();
-  else if (unsmob_grob (me->get_object ("beam"))
-           || abs (duration_log (me)) <= 2)
+  else
     {
       r = Interval (-1, 1);
       r *= thickness (me) / 2;
     }
-  else
-    {
-      r = Interval (-1, 1) * thickness (me) * 0.5;
-      r.unite (flag (me).extent (X_AXIS));
-    }
+
   return ly_interval2scm (r);
 }
 
@@ -735,12 +710,32 @@ SCM
 Stem::calc_stem_begin_position (SCM smob)
 {
   Grob *me = unsmob_grob (smob);
+  return scm_from_double (internal_calc_stem_begin_position (me, true));
+}
+
+MAKE_SCHEME_CALLBACK (Stem, pure_calc_stem_begin_position, 3);
+SCM
+Stem::pure_calc_stem_begin_position (SCM smob,
+                                     SCM, /* start */
+                                     SCM /* end */)
+{
+  Grob *me = unsmob_grob (smob);
+  return scm_from_double (internal_calc_stem_begin_position (me, false));
+}
+
+Real
+Stem::internal_calc_stem_begin_position (Grob *me, bool calc_beam)
+{
+  Grob *beam = get_beam (me);
+  Real ss = Staff_symbol_referencer::staff_space (me);
+  if (beam && calc_beam)
+    {
+      (void) beam->get_property ("quantized-positions");
+      return me->extent (me, Y_AXIS)[-get_grob_direction (me)] * ss * 2;
+    }
+
   Direction d = get_grob_direction (me);
-  Real half_space = Staff_symbol_referencer::staff_space (me) * 0.5;
-  Grob *lh
-    = to_boolean (me->get_property ("avoid-note-head"))
-      ? last_head (me)
-      : first_head (me);
+  Grob *lh = get_reference_head (me);
 
   Real pos = Staff_symbol_referencer::get_position (lh);
 
@@ -750,64 +745,51 @@ Stem::calc_stem_begin_position (SCM smob)
       Real y_attach = Note_head::stem_attachment_coordinate (head, Y_AXIS);
 
       y_attach = head_height.linear_combination (y_attach);
-      pos += d * y_attach / half_space;
+      pos += d * y_attach * 2 / ss;
     }
 
-  return scm_from_double (pos);
+  return pos;
 }
 
-MAKE_SCHEME_CALLBACK (Stem, print, 1);
-SCM
-Stem::print (SCM smob)
+bool
+Stem::is_valid_stem (Grob *me)
 {
-  Grob *me = unsmob_grob (smob);
-  Grob *beam = get_beam (me);
-
-  Stencil mol;
-  Direction d = get_grob_direction (me);
-
+  /* TODO: make the stem start a direction ?
+     This is required to avoid stems passing in tablature chords.  */
   Real stemlet_length = robust_scm2double (me->get_property ("stemlet-length"),
                                            0.0);
   bool stemlet = stemlet_length > 0.0;
 
-  /* TODO: make the stem start a direction ?
-     This is required to avoid stems passing in tablature chords.  */
-  Grob *lh
-    = to_boolean (me->get_property ("avoid-note-head"))
-      ? last_head (me)
-      : first_head (me);
+  Grob *lh = get_reference_head (me);
+  Grob *beam = unsmob_grob (me->get_object ("beam"));
 
   if (!lh && !stemlet)
-    return SCM_EOL;
+    return false;
 
   if (!lh && stemlet && !beam)
-    return SCM_EOL;
+    return false;
 
   if (lh && robust_scm2int (lh->get_property ("duration-log"), 0) < 1)
-    return SCM_EOL;
+    return false;
 
   if (is_invisible (me))
-    return SCM_EOL;
+    return false;
 
-  Real y2 = robust_scm2double (me->get_property ("stem-end-position"), 0.0);
-  Real y1 = y2;
-  Real half_space = Staff_symbol_referencer::staff_space (me) * 0.5;
+  return true;
+}
 
-  if (lh)
-    y2 = robust_scm2double (me->get_property ("stem-begin-position"), 0.0);
-  else if (stemlet)
-    {
-      Real beam_translation = Beam::get_beam_translation (beam);
-      Real beam_thickness = Beam::get_beam_thickness (beam);
-      int beam_count = beam_multiplicity (me).length () + 1;
-
-      y2 -= d
-            * (0.5 * beam_thickness
-               + beam_translation * max (0, (beam_count - 1))
-               + stemlet_length) / half_space;
-    }
+MAKE_SCHEME_CALLBACK (Stem, print, 1);
+SCM
+Stem::print (SCM smob)
+{
+  Grob *me = unsmob_grob (smob);
+  if (!is_valid_stem (me))
+    return SCM_EOL;
 
-  Interval stem_y (min (y1, y2), max (y2, y1));
+  Interval stem_y = me->extent (me, Y_AXIS);
+  Direction dir = get_grob_direction (me);
+
+  stem_y[dir] -= beam_end_corrective (me);
 
   // URG
   Real stem_width = thickness (me);
@@ -815,34 +797,15 @@ Stem::print (SCM smob)
     = me->layout ()->get_dimension (ly_symbol2scm ("blot-diameter"));
 
   Box b = Box (Interval (-stem_width / 2, stem_width / 2),
-               Interval (stem_y[DOWN] * half_space, stem_y[UP] * half_space));
+               stem_y);
 
+  Stencil mol;
   Stencil ss = Lookup::round_filled_box (b, blot);
   mol.add_stencil (ss);
 
-  mol.add_stencil (get_translated_flag (me));
-
   return mol.smobbed_copy ();
 }
 
-Stencil
-Stem::get_translated_flag (Grob *me)
-{
-  Stencil fl = flag (me);
-  if (!fl.is_empty ())
-    {
-      Direction d = get_grob_direction (me);
-      Real blot
-        = me->layout ()->get_dimension (ly_symbol2scm ("blot-diameter"));
-      Real stem_width = thickness (me);
-      Real half_space = Staff_symbol_referencer::staff_space (me) * 0.5;
-      Real y2 = robust_scm2double (me->get_property ("stem-end-position"), 0.0);
-      fl.translate_axis (y2 * half_space - d * blot / 2, Y_AXIS);
-      fl.translate_axis (stem_width / 2, X_AXIS);
-    }
-  return fl;
-}
-
 /*
   move the stem to right of the notehead if it is up.
 */
@@ -1070,6 +1033,12 @@ Stem::calc_cross_staff (SCM smob)
   return scm_from_bool (is_cross_staff (unsmob_grob (smob)));
 }
 
+Grob*
+Stem::flag (Grob *me)
+{
+  return unsmob_grob (me->get_object ("flag"));
+}
+
 /* FIXME:  Too many properties  */
 ADD_INTERFACE (Stem,
                "The stem represents the graphical stem.  In addition, it"
@@ -1108,9 +1077,7 @@ ADD_INTERFACE (Stem,
                "direction "
                "duration-log "
                "flag "
-               "flag-style "
                "french-beaming "
-               "length "
                "length-fraction "
                "max-beam-connect "
                "neutral-direction "
@@ -1118,11 +1085,8 @@ ADD_INTERFACE (Stem,
                "note-heads "
                "positioning-done "
                "rests "
-               "stem-begin-position "
-               "stem-end-position "
                "stem-info "
                "stemlet-length "
-               "stroke-style "
                "thickness "
                "tremolo-flag "
               );
index 3e76c120b1a0468cc15df15637202c80e098b5d9..098bf00a11bfd40f81651f845dbcc1e62a27fb3c 100644 (file)
@@ -149,8 +149,9 @@ Tie_formatting_problem::set_column_chord_outline (vector<Item *> bounds,
           else
             {
               if (use_horizontal_spacing_ || !Stem::get_beam (stem))
-                stem_end_position = Stem::stem_end_position (stem) * staff_space * .5;
+                stem_end_position = stem->extent (stem, Y_AXIS)[get_grob_direction (stem)];
               else
+                // May want to change this to the stem's pure height...
                 stem_end_position = Stem::note_head_positions (stem)[get_grob_direction (stem)]
                                     * staff_space * .5;
             }
@@ -170,9 +171,13 @@ Tie_formatting_problem::set_column_chord_outline (vector<Item *> bounds,
 
           if (dir == LEFT)
             {
-              Box flag_box = Stem::get_translated_flag (stem).extent_box ();
-              flag_box.translate ( Offset (x[RIGHT], X_AXIS));
-              boxes.push_back (flag_box);
+              Grob *flag = Stem::flag (stem);
+              if (flag)
+                {
+                  Grob* commony = stem->common_refpoint (flag, Y_AXIS);
+                  boxes.push_back (Box (flag->extent (x_refpoint_, X_AXIS),
+                                        flag->extent (commony, Y_AXIS)));
+                }
             }
         }
       else
index c6dfa799924a5c4b169406cf26854c1b865d0f24..67a00b4b2b86af0f8e46c617e78b25d02745271a 100644 (file)
@@ -553,18 +553,12 @@ Tuplet_bracket::calc_position_and_height (Grob *me_grob, Real *offset, Real *dy)
       && Note_column::get_stem (columns[0])
       && Note_column::get_stem (columns.back ()))
     {
-      /*
-        trigger set_stem_ends
-      */
-      (void) par_beam->get_property ("quantized-positions");
-
       Drul_array<Grob *> stems (Note_column::get_stem (columns[0]),
                                 Note_column::get_stem (columns.back ()));
 
-      Real ss = 0.5 * Staff_symbol_referencer::staff_space (me);
-      Real lp = ss * robust_scm2double (stems[LEFT]->get_property ("stem-end-position"), 0.0)
+      Real lp = stems[LEFT]->extent (stems[LEFT], Y_AXIS)[get_grob_direction (stems[LEFT])]
                 + stems[LEFT]->get_parent (Y_AXIS)->relative_coordinate (commony, Y_AXIS);
-      Real rp = ss * robust_scm2double (stems[RIGHT]->get_property ("stem-end-position"), 0.0)
+      Real rp = stems[RIGHT]->extent (stems[RIGHT], Y_AXIS)[get_grob_direction (stems[RIGHT])]
                 + stems[RIGHT]->get_parent (Y_AXIS)->relative_coordinate (commony, Y_AXIS);
 
       *dy = rp - lp;
index badb701e08579e8aa7bb4f70ec8b027eaaae0380..a2ba6551f678d11061d13afae9d6bcc90a6946a1 100644 (file)
@@ -675,6 +675,7 @@ automatically when an output definition (a @code{\score} or
   graceSettings = #`(
     (Voice Stem direction ,UP)
     (Voice Stem font-size -3)
+    (Voice Flag font-size -3)
     (Voice NoteHead font-size -3)
     (Voice TabNoteHead font-size -4)
     (Voice Dots font-size -3)
@@ -781,9 +782,8 @@ context."
   \remove "Accidental_engraver"
   %% make the Stems as short as possible to minimize their influence
   %% on the slur::calc-control-points routine
-  \override Stem #'length = #0
   \override Stem #'no-stem-extend = ##t
-  \override Stem #'flag-style = #'no-flag
+  \override Flag #'style = #'no-flag
   \override Stem #'details = #'((lengths 0 0 0 0 0 0)
                                 (beamed-lengths 0 0 0)
                                 (beamed-minimum-free-lengths 0 0 0)
index 6850541afaeb1c8bb209c42208f0a68b1955ffdd..4ee3be0179e3a6c155d035eb557d19bc5f78bf8f 100644 (file)
@@ -21,18 +21,18 @@ stopAppoggiaturaMusic =  {
 
 startAcciaccaturaMusic =  {
     s1*0\startGraceSlur
-    \override Stem  #'stroke-style = #"grace"
+    \override Flag  #'stroke-style = #"grace"
 }
 
 stopAcciaccaturaMusic =  {
-    \revert Stem #'stroke-style
+    \revert Flag #'stroke-style
     s1*0\stopGraceSlur
 }
 
 startSlashedGraceMusic =  {
-  \override Stem  #'stroke-style = #"grace"
+  \override Flag #'stroke-style = #"grace"
 }
 
 stopSlashedGraceMusic =  {
-  \revert Stem #'stroke-style
+  \revert Flag #'stroke-style
 }
index 0b8e0680beb76ecb72f1d005b37b1c4921ba54f6..6475a719c1b1de20a6ed03fede4fffd224deb9dd 100644 (file)
@@ -301,6 +301,7 @@ neumeDemoLayout = \layout {
        \consists Vaticana_ligature_engraver
        \override NoteHead #'style = #'vaticana.punctum
        \override Stem #'transparent = ##t
+       \override Flag #'transparent = ##t
     }
 }
 
index 0175bb798fe405134afd05236f81f182001af729..02acc1b4e6c50f263e44496f6ba14b6a864265ac 100644 (file)
@@ -233,6 +233,7 @@ hideNotes = {
   \override NoteHead #'transparent = ##t
   \override NoteHead #'no-ledgers = ##t
   \override Stem #'transparent = ##t
+  \override Flag #'transparent = ##t
   \override Beam #'transparent = ##t
   \override Accidental #'transparent = ##t
 }
@@ -240,6 +241,7 @@ unHideNotes = {
   \revert Accidental #'transparent
   \revert Beam #'transparent
   \revert Stem #'transparent
+  \revert Flag #'transparent
   \revert NoteHead #'transparent
   \revert NoteHead #'no-ledgers
   \revert Dots #'transparent
@@ -424,7 +426,7 @@ tabFullNotation = {
   % stems (the half note gets a double stem)
   \revert TabVoice.Stem #'length
   \revert TabVoice.Stem #'no-stem-extend
-  \revert TabVoice.Stem #'flag-style
+  \revert TabVoice.Flag #'style
   \revert TabVoice.Stem #'details
   \revert TabVoice.Stem #'transparent
   \override TabVoice.Stem #'stencil = #tabvoice::draw-double-stem-for-half-notes
@@ -544,30 +546,35 @@ voiceOneStyle = {
   \override NoteHead #'style = #'diamond
   \override NoteHead #'color = #red
   \override Stem #'color = #red
+  \override Flag #'color = #red
   \override Beam #'color = #red
 }
 voiceTwoStyle = {
   \override NoteHead #'style = #'triangle
   \override NoteHead #'color = #blue
   \override Stem #'color = #blue
+  \override Flag #'color = #blue
   \override Beam #'color = #blue
 }
 voiceThreeStyle = {
   \override NoteHead #'style = #'xcircle
   \override NoteHead #'color = #green
   \override Stem #'color = #green
+  \override Flag #'color = #green
   \override Beam #'color = #green
 }
 voiceFourStyle = {
   \override NoteHead #'style = #'cross
   \override NoteHead #'color = #magenta
   \override Stem #'color = #magenta
+  \override Flag #'color = #magenta
   \override Beam #'color = #magenta
 }
 voiceNeutralStyle = {
   \revert NoteHead #'style
   \revert NoteHead #'color
   \revert Stem #'color
+  \revert Flag #'color
   \revert Beam #'color
 }
 
index a45f1053d178aa69bee605845be3c4ca7a7931a0..c8619d9afe4e33da418d11e231a980bd41ef022c 100644 (file)
@@ -272,17 +272,7 @@ Y@tie{}dimension by this much.")
 ;;
 ;; f
 ;;
-     (flag ,ly:stencil? "A function returning the full flag stencil
-for the @code{Stem}, which is passed to the function as the only
-argument.  The default ly:stem::calc-stencil function uses the
-@code{flag-style} property to determine the correct glyph for the
-flag.  By providing your own function, you can create arbitrary
-flags.")
      (flag-count ,number? "The number of tremolo beams.")
-     (flag-style ,symbol? "A symbol determining what style of flag
-glyph is typeset on a @code{Stem}.  Valid options include @code{'()}
-for standard flags, @code{'mensural} and @code{'no-flag}, which
-switches off the flag.")
      (font-encoding ,symbol? "The font encoding is the broadest
 category for selecting a font.  Currently, only lilypond's system
 fonts (Emmentaler) are using this property.  Available
@@ -846,10 +836,6 @@ the @code{staff-staff-spacing} property of the staff's
 structure.")
      (stem-attachment ,number-pair? "An @code{(@var{x} . @var{y})}
 pair where the stem attaches to the notehead.")
-     (stem-begin-position ,number? "Where does the stem begin (the
-position of the support-head)?")
-     (stem-end-position ,number? "Where does the stem end (the end is
-opposite to the support-head)?")
      ;;[TODO: doco]
      (stem-spacing-correction ,number? "Optical correction amount for
 stems that are placed in tight configurations.  For opposite
@@ -1020,6 +1006,7 @@ the grob where this is set in.")
 in addition to notes and stems.")
 
      (figures ,ly:grob-array? "Figured bass objects for continuation line.")
+     (flag ,ly:grob? "A pointer to a @code{Flag} object.")
 
      (glissando-index ,integer? "The index of a glissando in its note
 column.")
index 3055af219bfb916547a7e1e1b9bad26fa48e2c4a..bbb750fbe4f06836638a013cbdfc853e689103f3 100644 (file)
        (clip-edges . #t)
        (collision-interfaces . (beam-interface
                                 clef-interface
+                                flag-interface
                                 inline-accidental-interface
                                 key-signature-interface
                                 note-head-interface
                                text-interface
                                text-script-interface))))))
 
+    (Flag
+     . (
+       (stencil . ,ly:flag::print)
+       (X-extent . ,ly:flag::width)
+       (X-offset . ,ly:flag::calc-x-offset)
+       (Y-offset . ,ly:flag::calc-y-offset)
+       (meta . ((class . Item)
+                (interfaces . (flag-interface
+                                font-interface))))))
+
     (FootnoteItem
      . (
        (annotation-balloon . #f)
 
        (direction . ,ly:stem::calc-direction)
        (duration-log . ,stem::calc-duration-log)
-       (flag . ,ly:stem::calc-flag)
-       (length . ,ly:stem::calc-length)
        (neutral-direction . ,DOWN)
        (positioning-done . ,ly:stem::calc-positioning-done)
-       (stem-begin-position . ,ly:stem::calc-stem-begin-position)
-       (stem-end-position . ,ly:stem::calc-stem-end-position)
        (stem-info . ,ly:stem::calc-stem-info)
        (stencil . ,ly:stem::print)
        (thickness . 1.3)
        (Y-extent . ,ly:stem::height)
        (Y-offset . ,ly:staff-symbol-referencer::callback)
        (meta . ((class . Item)
-                (interfaces . (font-interface
-                               stem-interface))))))
+                (interfaces . (stem-interface))))))
 
     (StemTremolo
      . (
    ly:note-head::print
    ly:dots::print
    ly:clef::print
+   ly:flag::print
+   default-flag
+   normal-flag
+   mensural-flag
+   no-flag
+   modern-straight-flag
+   old-straight-flag
    ly:key-signature-interface::print
    ly:percent-repeat-item-interface::beat-slash
    ly:text-interface::print
     (,ly:side-position-interface::y-aligned-side . ,ly:side-position-interface::pure-y-aligned-side)
     (,ly:slur::height . ,ly:slur::pure-height)
     (,ly:slur::outside-slur-callback . ,ly:slur::pure-outside-slur-callback)
+    (,ly:stem::calc-stem-end-position . ,ly:stem::pure-calc-stem-end-position)
     (,ly:stem::height . ,ly:stem::pure-height)
     (,ly:system::height . ,ly:system::calc-pure-height)))
 
   (list
    parenthesize-elements
    laissez-vibrer::print
+   ly:flag::calc-y-offset
    ly:rest::y-offset-callback
    ly:staff-symbol-referencer::callback
    ly:staff-symbol::height))
index 9e1a268e4d54ca8e9f91fc2c9a67589467835cde..018ebf50748c76d052aff8ad87e7db91007311ed 100644 (file)
@@ -19,7 +19,7 @@
 ;;;;  notably the old-straight-flag and the modern-straight-flag styles.
 
 
-(define-public (no-flag stem-grob)
+(define-public (no-flag grob)
   "No flag: Simply return empty stencil."
   empty-stencil)
 
@@ -29,7 +29,7 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
-(define-public (add-stroke-straight stencil stem-grob dir log stroke-style
+(define-public (add-stroke-straight stencil grob dir log stroke-style
                                     offset length thickness stroke-thickness)
   "Add the stroke for acciaccatura to the given flag stencil.
 The stroke starts for up-flags at `upper-end-of-flag + (0,length/2)'
@@ -39,7 +39,8 @@ whole length, while `flag-x-width' is just the x-extent and thus depends on
 the angle!  Other combinations don't look as good.
 
 For down-stems the y-coordinates are simply mirrored."
-  (let* ((start (offset-add offset (cons 0  (* (/ length 2) dir))))
+  (let* ((stem-grob (ly:grob-parent grob X))
+         (start (offset-add offset (cons 0  (* (/ length 2) dir))))
          (end (offset-add (cons 0 (cdr offset))
                           (cons (- (/ (car offset) 2)) (* (- (+ thickness (car offset))) dir))))
          (stroke (make-line-stencil stroke-thickness (car start) (cdr start) (car end) (cdr end))))
@@ -65,13 +66,14 @@ For down-stems the y-coordinates are simply mirrored."
 
 All lengths are scaled according to the font size of the note."
 
-  (lambda (stem-grob)
-    (let* ((log (ly:grob-property stem-grob 'duration-log))
+  (lambda (grob)
+    (let* ((stem-grob (ly:grob-parent grob X))
+           (log (ly:grob-property stem-grob 'duration-log))
            (dir (ly:grob-property stem-grob 'direction))
            (stem-up (eqv? dir UP))
-           (layout (ly:grob-layout stem-grob))
+           (layout (ly:grob-layout grob))
            ; scale with the note size (e.g. for grace notes)
-           (factor (magstep (ly:grob-property stem-grob 'font-size 0)))
+           (factor (magstep (ly:grob-property grob 'font-size 0)))
            (grob-stem-thickness (ly:grob-property stem-grob 'thickness))
            (line-thickness (ly:output-def-lookup layout 'line-thickness))
            (half-stem-thickness (/ (* grob-stem-thickness line-thickness) 2))
@@ -95,9 +97,9 @@ All lengths are scaled according to the font size of the note."
            (stencil (ly:round-filled-polygon points half-stem-thickness))
            ; Log for 1/8 is 3, so we need to subtract 3
            (flag-stencil (buildflag stencil (- log 3) stencil spacing))
-           (stroke-style (ly:grob-property stem-grob 'stroke-style)))
+           (stroke-style (ly:grob-property grob 'stroke-style)))
     (if (equal? stroke-style "grace")
-      (add-stroke-straight flag-stencil stem-grob
+      (add-stroke-straight flag-stencil grob
                            dir log
                            stroke-style
                            flag-end flag-length
@@ -105,16 +107,16 @@ All lengths are scaled according to the font size of the note."
                            (* half-stem-thickness 2))
       flag-stencil))))
 
-(define-public (modern-straight-flag stem-grob)
+(define-public (modern-straight-flag grob)
   "Modern straight flag style (for composers like Stockhausen, Boulez, etc.).
 The angles are 18 and 22 degrees and thus smaller than for the ancient style
 of Bach, etc."
-  ((straight-flag 0.55 1 -18 1.1 22 1.2) stem-grob))
+  ((straight-flag 0.55 1 -18 1.1 22 1.2) grob))
 
-(define-public (old-straight-flag stem-grob)
+(define-public (old-straight-flag grob)
   "Old straight flag style (for composers like Bach).  The angles of the
 flags are both 45 degrees."
-  ((straight-flag 0.55 1 -45 1.2 45 1.4) stem-grob))
+  ((straight-flag 0.55 1 -45 1.2 45 1.4) grob))
 
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -122,23 +124,24 @@ flags are both 45 degrees."
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
-; NOTE: By default, lilypond uses the C++ method Stem::calc-flag
-; (ly:stem::calc-flag is the corresponding Scheme interface) to generate the
+; NOTE: By default, lilypond uses the C++ method Flag::stencil
+; (ly:flag::stencil is the corresponding Scheme interface) to generate the
 ; flag stencil. The following functions are simply a reimplementation in
 ; Scheme, so that one has that functionality available in Scheme, if one
 ; wants to write a flag style, which modifies one of the standard flags
 ; by some stencil operations.
 
 
-(define-public (add-stroke-glyph stencil stem-grob dir stroke-style flag-style)
+(define-public (add-stroke-glyph stencil grob dir stroke-style flag-style)
   "Load and add a stroke (represented by a glyph in the font) to the given
 flag stencil."
   (if (not (string? stroke-style))
     stencil
     ; Otherwise: look up the stroke glyph and combine it with the flag
-    (let* ((font-char (string-append "flags." flag-style dir stroke-style))
+    (let* ((stem-grob (ly:grob-parent grob X))
+           (font-char (string-append "flags." flag-style dir stroke-style))
            (alt-font-char (string-append "flags." dir stroke-style))
-           (font (ly:grob-default-font stem-grob))
+           (font (ly:grob-default-font grob))
            (tmpstencil (ly:font-get-glyph font font-char))
            (stroke-stencil (if (ly:stencil-empty? tmpstencil)
                                (ly:font-get-glyph font alt-font-char)
@@ -150,10 +153,11 @@ flag stencil."
         (ly:stencil-add stencil stroke-stencil)))))
 
 
-(define-public (retrieve-glyph-flag flag-style dir dir-modifier stem-grob)
+(define-public (retrieve-glyph-flag flag-style dir dir-modifier grob)
   "Load the correct flag glyph from the font."
-  (let* ((log (ly:grob-property stem-grob 'duration-log))
-         (font (ly:grob-default-font stem-grob))
+  (let* ((stem-grob (ly:grob-parent grob X))
+         (log (ly:grob-property stem-grob 'duration-log))
+         (font (ly:grob-default-font grob))
          (font-char (string-append "flags." flag-style dir dir-modifier (number->string log)))
          (flag (ly:font-get-glyph font font-char)))
     (if (ly:stencil-empty? flag)
@@ -161,18 +165,19 @@ flag stencil."
     flag))
 
 
-(define-public (create-glyph-flag flag-style dir-modifier stem-grob)
+(define-public (create-glyph-flag flag-style dir-modifier grob)
   "Create a flag stencil by looking up the glyph from the font."
-  (let* ((dir (if (eqv? (ly:grob-property stem-grob 'direction) UP) "u" "d"))
-         (flag (retrieve-glyph-flag flag-style dir dir-modifier stem-grob))
-         (stroke-style (ly:grob-property stem-grob 'stroke-style)))
+  (let* ((stem-grob (ly:grob-parent grob X))
+         (dir (if (eqv? (ly:grob-property stem-grob 'direction) UP) "u" "d"))
+         (flag (retrieve-glyph-flag flag-style dir dir-modifier grob))
+         (stroke-style (ly:grob-property grob 'stroke-style)))
     (if (null? stroke-style)
       flag
-      (add-stroke-glyph flag stem-grob dir stroke-style flag-style))))
+      (add-stroke-glyph flag grob dir stroke-style flag-style))))
 
 
 
-(define-public (mensural-flag stem-grob)
+(define-public (mensural-flag grob)
   "Mensural flags: Create the flag stencil by loading the glyph from the font.
 Flags are always aligned with staff lines, so we need to check the end point
 of the stem: For stems ending on staff lines, use different flags than for
@@ -181,48 +186,57 @@ aligned with the staff lines, regardless of whether the note head is on a
 staff line or between two staff lines.  In other words, the inner end of
 a flag always touches a staff line."
 
-  (let* ((adjust #t)
-         (stem-end (inexact->exact (round (ly:grob-property stem-grob 'stem-end-position))))
+  (let* ((stem-grob (ly:grob-parent grob X))
+         (adjust #t)
+         (d (ly:grob-property stem-grob 'direction))
+         (ss (ly:staff-symbol-staff-space stem-grob))
+         (stem-end (inexact->exact (round (* (index-cell
+                                               (ly:grob-extent stem-grob
+                                                               stem-grob
+                                                               Y)
+                                               d)
+                                             (/ 2 ss)))))
          ; For some reason the stem-end is a real instead of an integer...
          (dir-modifier (if (ly:position-on-line? stem-grob stem-end) "1" "0"))
          (modifier (if adjust dir-modifier "2")))
-    (create-glyph-flag "mensural" modifier stem-grob)))
+    (create-glyph-flag "mensural" modifier grob)))
 
 
 
-(define-public ((glyph-flag flag-style) stem-grob)
+(define-public ((glyph-flag flag-style) grob)
   "Simulatesthe default way of generating flags: Look up glyphs
 @code{flags.style[ud][1234]} from the feta font and use it for the flag
 stencil."
-  (create-glyph-flag flag-style "" stem-grob))
+  (create-glyph-flag flag-style "" grob))
 
 
 
-(define-public (normal-flag stem-grob)
+(define-public (normal-flag grob)
   "Create a default flag."
-  (create-glyph-flag "" "" stem-grob))
+  (create-glyph-flag "" "" grob))
 
 
 
-(define-public (default-flag stem-grob)
+(define-public (default-flag grob)
   "Create a flag stencil for the stem.  Its style will be derived from the
-@code{'flag-style} Stem property.  By default, @code{lilypond} uses a
+@code{'style} Flag property.  By default, @code{lilypond} uses a
 C++ Function (which is slightly faster) to do exactly the same as this
 function.  However, if one wants to modify the default flags, this function
 can be used to obtain the default flag stencil, which can then be modified
 at will.  The correct way to do this is:
 
 @example
-\\override Stem #'flag = #default-flag
-\\override Stem #'flag-style = #'mensural
+\\override Flag #'stencil = #default-flag
+\\override Flag #'style = #'mensural
 @end example
 "
-  (let* ((flag-style-symbol (ly:grob-property stem-grob 'flag-style))
+  (let* ((stem-grob (ly:grob-parent grob X))
+         (flag-style-symbol (ly:grob-property grob 'style))
          (flag-style (if (symbol? flag-style-symbol)
                          (symbol->string flag-style-symbol)
                          "")))
     (cond
-        ((equal? flag-style "") (normal-flag stem-grob))
-        ((equal? flag-style "mensural") (mensural-flag stem-grob))
-        ((equal? flag-style "no-flag") (no-flag stem-grob))
-        (else ((glyph-flag flag-style) stem-grob)))))
+        ((equal? flag-style "") (normal-flag grob))
+        ((equal? flag-style "mensural") (mensural-flag grob))
+        ((equal? flag-style "no-flag") (no-flag grob))
+        (else ((glyph-flag flag-style) grob)))))
index 8cdd53955f61790bd5e4b3378c7bcc6c74ac9f9b..d7fedb689d9cf3e69a445ec7c4731ce176fe75b0 100644 (file)
@@ -424,6 +424,7 @@ in @var{grob}."
      (make-property-set 'graceSettings
                        ;; TODO: take this from voicedGraceSettings or similar.
                        '((Voice Stem font-size -3)
+                         (Voice Flag font-size -3)
                          (Voice NoteHead font-size -3)
                          (Voice TabNoteHead font-size -4)
                          (Voice Dots font-size -3)
index 025590e5bae0e001db8f089a96b811485faa1198..e76c46cdb18ddbfade41573a913de1b5dd889671 100644 (file)
   (ly:duration-log
    (ly:event-property (event-cause grob) 'duration)))
 
+(define-public (stem::length val)
+  (lambda (grob)
+    (let* ((d (ly:grob-property grob 'direction))
+           (ss (ly:staff-symbol-staff-space grob))
+           (beg (ly:stem::calc-stem-begin-position grob))
+           (y1 (* beg (* 0.5 ss)))
+           (y2 (* ((if (eqv? d DOWN) - +) beg val) (* 0.5 ss))))
+      (if (eqv? d DOWN)
+          (cons y2 y1)
+          (cons y1 y2)))))
+
 (define-public (note-head::calc-duration-log grob)
   (min 2
        (ly:duration-log