Ir al contenido

PGD | §3.4 – Gráficos

§3.3 – Procedimientos PostScript

Dado que el objetivo de diseño de PostScript es la de poder construir cualquier tipo de elemento gráfico, debemos esperar contar con un poderoso conjunto de operadores para este fin. Hasta ahora sólo hemos visto uno, rectfill, para la construcción y llenado de un rectángulo; veremos ahora los elementos con los que contamos para construir figuras geométricas de complejidad arbitraria.

Elección de un color

En todo momento el intérprete mantiene una serie de parámetros implícitos que se utilizan al realizar ciertas operaciones. Por ejemplo, el color actual es uno de ellos: es el color que se utilizará para cualquier operación que genere una marca en la página. Inicialmente el intérprete asume que el color actual es negro hasta que nosotros lo cambiemos por otro mediante cualquiera de estos operadores:

r g b setrgbcolor Establece un color en RGB
c m y k setcmykcolor Establece un color en CMYK
n setgray Establece un color como nivel de gris

En el cuadro precedente, los símbolos r, g, b, los c, m, y, k, y n, representan las cantidades de los componentes de un color definido en RGB, en CMYK y como nivel de gris respectivamente. Estos valores deben especificarse en una escala normalizada de 0 a 1 y no como porcentajes o valores digitales 0 – 255. Por ejemplo,

%!
1 0 0 setrgbcolor           % rojo en RGB
1 0.5 0 setregbcolor        % naranja en RGB
0.75 0 0.75 0 setcmykcolor  % 75% de verde en CMYK
0.2 0.2 0 0 setcmykcolor    % 20% de azul en CMYK
0 setgray                   % negro
1 setgray                   % blanco

Debe notarse que, contrariamente a lo que puede imaginarse, el parámetro que espera setgray no es un nivel de “tinta” como si fuera CMYK, sino un nivel de luz como RGB: es por ello que 1 setgray equivale a 1 1 1 setrgbcolor y representa blanco.

Trazado de figuras (paths)

PostScript permite crear cualquier tipo de figura, por compleja que sea, para lo cual podemos unir secuencias de líneas, arcos de circunferencia y curvas de tipo cúbico, tanto cerradas como abiertas. Este parámetro implícito se denomina trazado actual (current path) y representa la figura que actualmente almacena el intérprete. Esto requiere a su vez definir las posiciones de los puntos extremos de cada línea o curva trazada. Los operadores que nos permiten hacer esto son newpath, moveto, lineto, arc, curveto y closepath, entre otros.

newpath Inicia un nuevo trazado, descartando el anterior si existiera
x y moveto Definir (x, y) como las coordenadas del punto de inicio, y establecerlo como punto actual
x y lineto Trazar una línea desde el punto actual hasta el punto (x, y), y establecer este último como punto actual
x y r i f arc Trazar un arco de la circunferencia con centro en (x, y), radio r, desde el ángulo inicial ⍺i hasta el ángulo final ⍺f (medidos en grados), y establecer el punto final como punto actual
x1 y1 x2 y2 x3 y3 curveto Trazar una curva de Bézier desde el punto actual hasta el (x3, y3), usando (x1, y1) y (x2, y2) como puntos de control, y establecer el punto final como punto actual
closepath Finaliza el trazado en curso, completando con una línea desde el punto actual al inicial del trazado de ser necesario

Veamos el código siguiente como un ejemplo de aplicación:

%!                          % firma PostScript
/mm {25.4 div 72 mul} def   % definimos conversión de mm a puntos
newpath                     % inicio de un nuevo path
100 mm 100 mm moveto        % empezamos en (100 mm, 100 mm)
200 mm 100 mm lineto        % línea hasta (200 mm, 100 mm)
200 mm 200 mm lineto        % línea hasta (200 mm, 200 mm)
closepath                   % cerrar el path: resulta un triángulo
1 0 0 setrgbcolor           % elegir color rojo
fill                        % llenar el triángulo
showpage                    % terminamos: mostrar resultado.
ps-path-sample
Resultado de la ejecución del código anterior en una página A4.

Brevemente, este programa funciona así: luego de definir el procedimiento mm para convertir milímetros a puntos, decimos al intérprete mediante moveto que nos posicionamos en el punto ubicado a 100 mm desde la izquierda y 100 mm desde abajo: este es ahora el punto actual. Luego, mediante lineto trazamos una línea desde el punto actual hasta otro punto, ubicado en la misma posición horizontal pero a 200 mm del margen izquierdo (es decir, a 100 mm del anterior); este último se convierte ahora en el nuevo punto actual. Un nuevo lineto traza una línea vertical desde el último punto hasta otro a 100 mm hacia arriba. Cerramos el trazo con closepath; este operador tiene por objeto trazar una línea desde el último punto alcanzado hasta el comienzo del trazo.

Al definir un trazado debemos tener en cuenta que:

La definición de un trazado en PostScript no realiza marcas en la página. Para ello, es necesario ejecutar un operador de “pintado”, según se desee llenar o contornear la figura definida.

Para pintar esta figura cerrada, elegimos el color rojo en RGB utilizando setrgbcolor y llenamos mediante fill.

Operadores para el manejo de texto

Hasta ahora sólo hemos empleado datos numéricos, pero PostScript permite una gran variedad de tipos de operandos. Es posible manipular texto, considerado como cadenas de caracteres (strings), y seleccionar una fuente (font) para escribir esos caracteres en alguna posición de la página.

En PostScript se considera string cualquier secuencia de caracteres encerrada entre paréntesis. Por ejemplo, si escribo

(Esto es una cadena de caracteres en PostScript)

el intérprete colocará en la pila todo el texto contenido entre los paréntesis, y será tratado como un único dato de tipo texto. De esta manera sirve como operando para aquellas operaciones que esperan texto entre sus datos. Por ejemplo, la operación length espera un string en la pila y deja como resultado el número de caracteres que contiene. Es decir, el código

(Esto es una cadena de caracteres en PostScript) length

dejará en la pila el resultado 46.

La aplicación más natural de este tipo de dato es el trazado de texto en la página. Para ello se emplea el operador show, que toma un string de la pila y lo traza según los parámetros actuales del estado gráfico, esto es, a partir de la posición actual, usando la fuente y el color actuales.

Esto nos permite introducir un nuevo tipo de dato: la fuente. En efecto, PostScript trata una fuente como un dato; para poner una fuente en la pila necesitamos que PostScript nos suministre una. Esto se realiza esencialmente mediante tres operadores: findfont, scalefont y setfont. El primero espera un nombre en la pila y devuelve la fuente identificada por ese nombre. Por ejemplo, la secuencia

/Helvetica findfont

nos deja en la pila la fuente cuyo nombre es Helvetica. El segundo espera una fuente y un tamaño en puntos, y nos deja esa misma fuente escalada a ese tamaño[1]. Es decir, si completamos la secuencia anterior así:

/Helvetica findfont 96 scalefont

tendremos en la pila la fuente Helvetica en un cuerpo de 96 puntos. Por último, el operador setfont establece una fuente como la fuente actual en el estado gráfico. Por lo tanto, las instrucciones siguientes:

%!
/mm {25.4 div 72 mul} def
/Helvetica findfont 96 scalefont setfont
1 0 1 0 setcmykcolor
20 mm 140 mm moveto
(Hola) show
showpage

establecerán la fuente actual a Helvetica con un tamaño de 96 puntos y escribirán la frase “Hola” en color verde, cerca del borde izquierdo y aproximadamente centrada verticalmente en una página de tamaño A4.

ps-fonts
Resultado de la ejecución del código anterior en una página A4.
§3.5 – Errores PostScript >

1 La fuente devuelta por findfont tiene un tamaño intrínseco de 1 punto, por lo cual es necesario utilizar scalefont para “multiplicar” ese tamaño por el factor de escala apropiado para llevarla a las dimensiones requeridas. Por lo tanto, si no se usa scalefont el texto se imprimirá con un cuerpo de 1 pt.