5.4 Desplazamientos y alineaciones

LilyPond necesita saber dónde colocar todos y cada uno de los objetos gráficos. Esta información de la colocación se almacena utilizando coordenadas relativas: la posición de un grob se define de forma relativa a la posición de su ancestro (si, en lugar de ello, tuviésemos que emplear coordenadas absolutas como por ejemplo las distancias a partir de los límites de la página, sería muy difícil mantener las relaciones espaciales entre unos grobs y otros).

Cada uno de los grobs sabe qué objeto es su ancestro en el eje respectivo. Por ejemplo, un grob Flag (corchete) sabe que su x-parent (el ancestro en el eje x) es un determinado grob Stem (plica).

Las coordenadas relativas que describen la ubicación de un grob se almacenan en propiedades de grob llamadas X-offset (desplazamiento en X) y Y-offset (desplazamiento en Y). Estas se miden en espacios de pentagrama. X-offset es el desplazamiento horizontal entre el punto de referencia del grob y el punto de referencia del x-parent del grob (y de forma similar con Y-offset).

¿Qué es un punto de referencia? Es un punto especial que define la posición del grob. Piense en ello de forma geomátrica: si tiene que definir dónde se sitúa una figura sobre el plano, normalmente diría algo como “la esquina inferior izquierda de este cuadrado tiene como coordenadas (0, 2)”, o “el centro de este círculo está en (-1, 3)”. ‘Esquina inferior izquierda’ y ‘centro’ serían los puntos de referencia para el cuadrado y el círculo, respectivamente.

Esta ilustración muestra dónde se ubican los puntos de referencia de determinados grobs, indicados como puntos rojos (por ejemplo, la línea central del pentagrama para las barras de compás y las plicas, la intersección entre la línea de base y el extremo izquierdo en el caso de una caja de texto, o el centro vertical en el lado izquierdo para una cabeza de nota).

{
  \override NoteHead.style = #'altdefault     % for breve

  \time 4/2 g'2-> c''\fermata as'1^"Yogi" |
  b'\breve _"Larry" |
  \mark "Twinkle" e''8 s4.. \bar "|."
}
[image of music]

Sobreescribiendo los valores X-offset o Y-offset podemos mover grobs de forma relativa a sus respectivos padres o ancestros:

{
  \override Script.X-offset = 3               % fermata, accent
  \override TextScript.X-offset = 2           % "Yogi", "Larry"
  \override Stem.X-offset = -2
  \override Score.RehearsalMark.Y-offset = 5  % "Twinkle"

  \override NoteHead.style = #'altdefault     % for breve

  \time 4/2 g'2-> c''\fermata as'1^"Yogi" |
  b'\breve _"Larry" |
  \mark "Twinkle" e''8 s4.. \bar "|."
}
[image of music]

Observe que el grob Flag (corchete) se ha movido juntamente con su grob Stem (plica).

Nota: Cambiar X-offset o Y-offset no siempre funciona como se espera, véase Aligning objects.

Ahora vamos a explicar otra pareja de propiedades: X-extent y Y-extent. Cada una de ellas es un par de números (internamente, LilyPond le llama a esto un intervalo), y almacenan las dimensiones de un grob relativas a su punto de referencia. Por ejemplo, X-extent igual a (-1 . 4) significa que el borde izquierdo del grob está 1 espacio de pentagrama a la izquierda de su punto de referencia, y el borde derecho está 4 espacios de pentagrama a la derecha del punto de referencia, dando una anchura total del 4 - (-1) = 4 + 1 = 5 espacios de pentagrama. Ambos números dentro de un ámbito de dimensiones pueden ser positivos; por ejemplo, (2 . 3) es una extensión válida: significa que el grob en su totalidad está a la derecha de su punto de referencia, y el ancho del grob es 3 - 2 = 1 espacio de pentagrama. De forma similar, ambos números pueden ser negativos; estas situaciones son bastante poco usuales pero no suponen ningún dolor de cabeza para LilyPond. La situación más común (al menos para X-extent) es que el primer número sea 0, lo que significa que el punto de referencia está justo en el extremo izquierdo del grob.

El ejemplo precedente muestra esto de una forma muy adecuada: tanto el borde izquierdo del accento como el del calderón están a la izquierda del punto de referencia; lo mismo vale para la cabeza de nota de breve (aquí hemos seleccionado el estilo 'altdefault para las cabezas de forma que esto sea más visible).

Ahora supongamos que queremos posicionar un grob RehearsalMark (marca de ensayo) de tal manera que el borde derecho esté alineado con una barra de compás (de forma predeterminada, LilyPond centra la marca de ensayo horizontalmente). Con X-offset igual a cero (esto es, su punto de referencia está alineado con el ancestro, que es igual a la línea de compás en esta situación), el objeto gráfico RehearsalMark se posiciona de la siguiente manera:

{
  \override Score.RehearsalMark.X-offset = 0
  b4 b b b \mark "Twinkle" b b b b
}
[image of music]

Así pues, tenemos que desplazarlo. ¿Recuerda lo que significa el segundo número dentro de X-extent? Es la posición del borde derecho del grob relativo a su punto de referencia. Si sustraemos este valor a partir del cero, obtendremos el X-offset que buscamos:

{
  % value -10.4 found by trial and error
  \override Score.RehearsalMark.X-offset = -10.4
  b4 b b b \mark "Twinkle" b b b b
}
[image of music]

¿Qué pasaría si quisiéramos centrar un grob sobre el punto de referencia de su ancestro? Es sencillo: calculemos el desplazamiento entre el punto de referencia del grob y el centro de sus dimensiones. He aquí algunos ejemplos:

Ya existe una función (con un nombre súper largo) que puede efectuar estos cálculos por nosotros:

\override GrobName.X-offset =
  #ly:self-alignment-interface::x-aligned-on-self

y solamente tenemos que especificar qué tipo de alineación deseamos:

\override GrobName.self-alignment-X = #RIGHT

Este código dice al procedimiento que encuentre el desplazamiento entre el punto de referencia de un grob y su borde derecho, y lo use como el desplazamiento en x, lo que hará que el grob resulte alineado por la derecha.

De manera que si cambiamos las dimensiones de un grob, estaremos afectando a la manera en que se alinea (porque LilyPond pensará que las dimensiones del grob son diferentes):

{
  \override Score.RehearsalMark.X-extent = #'(0 . 8)
  \override Score.RehearsalMark.self-alignment-X = #RIGHT
  b4 b b b \mark "Twinkle" b b b b
}
[image of music]

Asimismo, si las dimensiones de un grob son vacías (es decir, no es una pareja de intervalos), procedmientos como x-aligned-on-self no tendrán ninguna información sobre las dimensiones de, grob, y entonces no será capaz de calcular ningún desplazamiento (se limitará a devolver un valor 0). En otras palabras, un grob con unas dimensiones vacías solo se puede ‘alinear’ sobre su punto de referencia porque no hay otra información se se pueda usar para alinearlo:

{
  \override Score.RehearsalMark.X-extent = ##f
  b4 b b b \mark "Twinkle" b b b b
}
[image of music]

Observe que unas dimensiones vacías y unas dimensiones nulas dan como resultado la misma posición:

{
  \override Score.RehearsalMark.X-extent = #'(0 . 0)
  b4 b b b \mark "Twinkle" b b b b
}
[image of music]

Sin embargo, unas dimensiones vacías (o nulas, o cualquier otra dimensión) no nos impiden ubicar el grob en cualquier posición que deseemos: es solo que no podemos usar procedimientos de alineación para ello. Aún podemos especificar cualquier desplazamiento que queramos, y funcionará de la manera usual:

{
  \override Score.RehearsalMark.X-extent = ##f
  \override Score.RehearsalMark.X-offset = -10.4
  b4 b b b \mark "Twinkle" b b b b
}
[image of music]

Ahora, hay una cosa más que no podemos olvidar: el ancestro de un grob tiene también sus propias dimensiones, y tenemos que tenerlas en cuenta. Por ejemplo, si escribimos

{ a'1 }
\addlyrics {
  \override LyricText.X-offset =
    #ly:self-alignment-interface::x-aligned-on-self
  \override LyricText.self-alignment-X = #CENTER
  nn
}
[image of music]

El grob LyricText estará centrado, pero sobre el punto de referencia de su ancestro (esto es, el centro de la sílaba estará alineado con el punto de referencia de la cabeza de la nota). Si queremos que el centro del grob LyricText se alinee con el centro de su grob NoteHead padre, tenemos que usar un procedimiento distinto: aligned-on-x-parent. Funciona de manera muy similar a x-aligned-on-self, pero además de calcular un desplazamiento basado en las propias dimensiones del grob, usa también las dimensiones del objeto padre y calcula las posiciones relativas al centro del tamaño total:

{ a'1 }
\addlyrics {
  \override LyricText.X-offset =
    #ly:self-alignment-interface::aligned-on-x-parent
  \override LyricText.self-alignment-X = #CENTER
  nn
}
[image of music]

Manual de aprendizaje de GNU LilyPond v2.25.29 (development-branch).