Ir al Hogar Ver Índice Buscar Enlaces Acerca de nosotros
[LinuxFocus Image]
[Navegation Bar]
  Noticias   Archivos   Compañías   Consejos 

El Lenguaje PostScript

por Emre Demiralp


Guárdate las burlas, llegará el día en que las uses.
-Proverbio turco-.

Introducción

Dibujos

Texto

Colores

Más información

Introducción

Éste es el primero de una serie de artículos sobre PostScript. La idea principal no es enseñar todos y cada uno de los detalles de este software, sino dar suficiente material para las personas que encuentran en el PostScript un lenguaje de programación para la preparación de documentos interesante y divertido. A pesar de que no pretendemos escribir un documento técnico ni un libro de texto ni una biblia sobre este tema, intentaremos presentar la información necesaria y suficiente sobre PostScript.

Las ideas principales sobre las que está hecho el PostScript fueron creadas hace veinte años por John Gaffney en la Evans & Sutherland Computer Corporation. Al principio se llamaba "Design System" pero más tarde fue desarrollado bajo el nombre de PostScript por Adobe Systems Incorporated como una herramienta independiente de la plataforma y del dispositivo para la descripción de páginas. Adobe Systems Incorporated fue formado por Chuck Geschke and John Warnock en 1982. C. Geschke y J. Warnock emprendieron un nuevo diseño e implementación del lenguaje, al que Doug Brotz, Billi Paxton, y Ed Taft hicieron grandes contribuciones. Actualmente es una de las herramientas de preparación de documentos más importantes, aunque no es utilizada directamente por la mayoría de usuarios. Sus capacidades están completamente a alto nivel, sin embargo muchos usuarios que no quieren entrar en los detalles de este potente lenguaje prefieren usar las otras herramientas de usuario final, que están basadas principalmente en la filosofía "What You See Is What You Get". Para decir la verdad, muchas herramientas WYSIWYG usan formatos de fichero PostScript para mantener la documentación de los productos o para usarlos como interface con otros trabajos como la impresión. Por ello, podemos decir que aún sobrevive como un viejo amigo que sirve como una potente asistencia para muchos trabajos del ordenador relativos a dibujar, colorear, procesar imágenes, separación de colores, simulación y animación incluso si no se nos muestra explícitamente durante el proceso. Por otro lado, si quieres aprender su estructura para programarlo, encontrarás que no es muy difícil.

Los comandos de PostScript se ejecutan a través de algún intérprete. Entre los que existen, un software muy conocido está disponible gratuitamente en el dominio público de Internet. Se llama "ghostscript" por Aladdin Enterprise. Existe también un útil interfase gráfico, "ghostview", distribuido por la misma organización. El proyecto GNU tiene también sus propias versiones de ghostscript. Estas están disponibles en todas las plataformas Linux y todas las distribuciones principales las contienen en su instalación estándar. Aquí usaremos ghostscript y ciertas de sus estructuras y propiedades específicas, aunque los programas de ejemplo se pueden ejecutar a través de otros intérpretes. Asumimos que tenemos activado el servidor de X Window y abierta una ventana xterm. Si queremos usar ghostscript entonces cada comando y grupo de comandos se dará en el prompt de comandos que aparece después de lanzar el comando

Initializing... done. Ghostscript 2.6.2 (4/19/95) Copyright (C) 1990-1995 Aladdin Enterprises, Menlo Park, CA. All rights reserved. Ghostscript comes with NO WARRANTY: see the file COPYING for details.
GS>_


Una ventana blanca propia se abrirá al mismo tiempo que aparece este prompt. Si queremos cerrar la sesión ghostscript, lo único que tenemos que hacer es ejecutar el comando quit en el prompt GS>. También podemos salir con EOF (Ctrl-D).

Ghostscipt también puede ejecutar los comandos obteniéndolos de un fichero. En este caso abrimos un fichero llamado, por ejemplo, sample.ps . Todos los comandos que queremos que ghostscript ejecute están escritos en este fichero. Entonces podemos llamar al contenido de este fichero un programa PostScript. El contenido completo de este programa o sus comandos individuales será consecutivamente ejecutado por ghostscript si ejecutamos el siguiente comando en el prompt de la shell de la ventana de xterm de linux

gs sample.ps

y el display (si el programa pide la creación de un display, claro. De hecho, PostScript se puede usar para otras cosas, como cálculos matemáticos, operaciones de pilas, etc. Las mencionaremos en futuros artículos de esta serie) aparecerá en la ventana de ghostscript. Si el programa produce más de una página entonces la ventana de ghostscript muestra la primera y el prompt showpage aparece en la línea de comandos de ghostscript solicitando enter key pressing para ver la siguiente página.

PostScript usa Reverse Polish Notation (RPN - como las calculadoras de bolsillo de HP). En otras palabras, los parámetros de un comando se dan antes que el comando. Los comandos se separan con espacios en blanco. Usa operaciones de pila para procesar datos y ejecutar comandos. Hay cuatro pilas disponibles en PostScript: la pila de operandos, la de diccionario, la de ejecución y la de estado gráfico. La pila de operandos contiene objetos PostScript arbitrarios que son los operandos y resultados de los operadores PostScript que se están ejecutando. Podemos dar algunos ejemplos de operaciones aritméticas. Por ejemplo,

20 30 add 10 sub 

produce 40, ya que 20 30 add crea 50 y sub produce 40 al usar 50 junto con 10. mul (multiplicación) y div (división) funcionan de la misma manera. El nombre '=' esta asociado con un procedimiento que saca un objeto de la pila de operadores y escribe una representación textual de su valor al fichero estándar de salida, seguido de una nueva línea. == tiene un efecto similar, pero escribe una representación sintáctica de su operando el fichero estándar de salida. El comando pop extrae el elemento superior de la pila de operandos y lo elimina. Hablaremos de las pilas más detalladamente en posteriores artículos de esta serie.

¿Cómo se usa PostScript para dibujar figuras?

Podemos empezar dibujando figuras con PostScript considerando la estructura geométrica de la página que será diseñada. Las posiciones de los puntos de una página se denotan mediante pixels, que son 1/72 de pulgada en el lenguaje PostScript. La esquina inferior derecha de la página es el punto con coordenadas (0,0) y el tamaño horizontal y vertical de la página son de 612 y 792 respectivamente. Estos tamaños son para la hoja tipo letter. Hay otras posibilidades de tamaños para otros tipos de papel, como

note con 540 y 720 o
legal con 612 y 1008 o
a4 con 595 y 842 .

Estos son comandos normales de gs. El comando 'a4' modificará el tamaño de tu hoja de dibujo al tamaño adecuado.

La definición del tamaño del papel se puede encontrar en el fichero de inicialización cuyo nombre es gs_statd.ps. Se puede encontrar en /usr/lib/ghostscript para Slackware. Puedes definir cualquier tamaño de papel no estándar haciendo los añadidos y modificaciones convenientes en este fichero como mencionaremos más adelante en esta serie de artículos. Aquí asumimos que usamos el tamaño de papel por defecto letter en esta presentación.

El segundo paso después de poner el papel al tamaño deseado al dibujar una figura es situar el cursor el principio del dibujo. Esto se puede conseguir con el comando

x y moveto

donde x e y denotan respectivamente las coordenadas horizontal y vertical del punto donde se situará el cursor. x e y son números puros y considerados en unidades de píxel. Como puedes ver, la estructura funcional de PostScript es ligeramente diferente de otros lenguajes de programación como C, Fortran. moveto es el comando que realiza la acción, en otras palabras, es el que mueve el cursor al sitio cuyas coordenadas vienen dadas por x e y. Como PostScript usa una pila, primero se meten los parámetros consecutivamente en la pila. Entonces se da el comando. Cuando entra en la pila, acepta los dos objetos anteriores como sus parámetros. La sintaxis es diferente para el usuario que está familiarizado con otros lenguajes como C, Fortran. Por eso hemos insistido en este tema aquí. Como conclusión diremos que todo comando que necesite parámetros se dará después de sus parámetros.

Ahora estamos preparados para empezar a dibujar la figura. Empecemos con una figura sencilla, un segmento recto. Para dibujarlo, lo único que tenemos que hacer es ejecutar el comando

xx yy lineto

donde xx e yy denotan la situación del punto final del segmento. Su punto inicial es la posición actual del cursor, x e y . Así pues, este comando construye un segmento recto entre x y y xx yy . El dibujo necesita los comandos de definición de camino newpath y stroke. Escribamos un programa PostScript para dibujar un rectángulo. Se puede hacer usando la información anterior. El programa que suponemos que se grabará en el fichero sample1.ps puede ser así

newpath
100 100 moveto
300 100 lineto
300 250 lineto
100 250 lineto
100 100 lineto
stroke

A pesar de que hemos dado cada comando en una línea separada, esto no es realmente necesario. Los podríamos dar todos en la misma línea insertando un espacio en blanco entre comandos consecutivos, como ya dijimos antes.

PostScript permite la introducción de comentarios, como otros lenguajes de programación. Todo lo que sigue a un signo de porcentaje hasta el final de la línea se interpreta como un comentario.

newpath
% Inicialización del cursor
100 100 moveto
% Dibujo del rectángulo
300 100 lineto
300 250 lineto
100 250 lineto
100 100 lineto
stroke

Si ejecutamos el comando gs sample1.ps en el prompt de una ventana de xterm, entonces aparece la conocida ventana de ghostscript conteniendo el dibujo del rectángulo. No necesitamos invocar el intérprete cada vez. De hecho, el comando
(sample1.ps) run
hace lo mismo desde el prompt GS>.

El comando stroke le dice al intérprete que dibuje la figura. En el programa anterior la ventana de ghostscript muestra el rectángulo con lados de 200 y 150 puntos en las direcciones horizontal y vertical.

Las líneas rectas no necesitan ser verticales o horizontales. Se pueden construir en cualquier dirección.

Como podrás ver cuando mostremos el resultado mediante ghostscript, este programa crea un triángulo. Puedes crear cualquier clase de figura que esté compuesta de segmentos usando los comandos moveto y lineto.

Hay dos comandos más que se pueden usar en las construcciones anteriores. Son los comandos rmoveto y rlineto . Necesitan dos parámetros y se usan así

x y rmoveto
x y rlineto

donde x e y son las distancias horizontal y vertical entre el punto inicial y final de cada acción. 'r' en rmove y rlineto significa 'relativo'. En otras palabras, el primer comando mueve el cursor x unidades horizontalmente a la derecha e y unidades hacia arriba desde su posición actual. El segundo comando actúa de manera similar, pero dibuja una línea y mueve el cursor al punto final en lugar de solo mover el cursor. Estos son comandos de referencia y los parámetros se dan tomando la posición inicial como el punto de referencia.

Todos los ejemplos anteriores usan una anchura de línea por defecto para dibujar. Este valor es de 1 píxel. Sin embargo, el usuario puede definir el ancho de línea del dibujo en cualquier punto del programa. Esto se puede hacer con el comando

x setlinewidth

donde x denota el anchura de la línea en píxels. El efecto de este comando continúa hasta que se modifique de nuevo la anchura de la línea en el programa. No hay limitación para el número de anchos de línea en un programa.

Naturalmente, dibujar en PostScript no está limitado a líneas rectas. Se pueden dibujar también arcos circulares. Para ello podemos usar el siguiente comando

x y r a b arc

donde x, y, r, a y b son las coordenadas horizontal y vertical del centro del arco circular, el radio del arco y el ángulo entre la parte positiva del eje horizontal y los rayos centrales que pasan a través del punto inicial y final del arco. Los ángulos se miden en sentido contrario a las agujas del reloj. Si el punto inicial del arco no es la posición actual del cursor, entonces se dibuja también una línea recta entre la posición actual del cursor y el inicio del arco. Para entender todo esto, puedes echarle un vistazo el siguiente programa PostScript.


3 setlinewidth
200 200 moveto
100 200 100 0 75 arc
stroke
300 300 moveto
400 500 200 20 50 arc
stroke

Así pues, debemos tener cuidado y poner el cursor al principio del arco si no queremos la línea extra mencionada más arriba. Sin embargo, hay otra manera de solucionar el problema. De hecho, al punto actual se le puede dar un valor vacío. En otras palabras, al principio del camino no hay ningún valor para los parámetros. No hay ninguna asignación para la posición del cursor. Una vez se inicia el dibujo, el punto final del camino se convierte en el punto actual. Si ejecutamos el comando newpath entonces PostScript borra la asignación para el punto del cursor y actúa como si el dibujo comenzara desde el principio. Así pues, el programa anterior se puede modificar sustituyendo la quinta línea con una línea que contenga solo el comando newpath. Si lo hacemos y lo ejecutamos veremos que obtenemos el mismo dibujo, excepto la línea recta extra.

Un camino se inicia ejecutando el operador newpath. Esto inicializa el camino actual al camino vacía. El camino se construye entonces ejecutando comandos que añadan segmentos al camino actual.

El comando arc se puede usar para dibujar un círculo completo. Es suficiente dar como ángulo inicial y final 0 y 360 respectivamente. Si se hace bajo un newpath se obtiene un círculo completo. El comando arc también se puede usar para producir elipses. Usaremos para ello las propiedades de escalado de PostScript. El usuario puede reescalar las unidades horizontales y verticales de manera separada mediante el siguiente comando

x y scale

donde x e y denotan respectivamente los factores de escalado horizontal y vertical. Esto significa que cuando estos factores son igual a 1 no afecta en nada al dibujo. El efecto de escalado se mantiene hasta que se ejecuta el siguiente comando de escalado. El siguiente comando de escalado que se ejecuta no anula el efecto del anterior, sino que combina su propio efecto con el anterior. Supongamos que los parámetros del comando de escalado anterior fueron x1, y1 y los parámetros del siguiente comando son x2, y2 , entonces el efecto combinado de ambos tiene los factores de escalado x1*x2, y1*y2 . Este efecto se debe tener presente para evitar efectos indeseados en el display, como que algunos caminos se salgan de la superficie del papel. PostScript asume la no existencia de escalado por defecto. El siguiente programa PostScript, que suponemos que está grabado en el fichero sample4.ps , es un ejemplo para explicar el escalado.

3 setlinewidth
200 200 100 0 360 arc
stroke
newpath
2 1 scale
200 300 50 0 360 arc
stroke
newpath
1 4 scale
100 150 40 0 360 arc
stroke

Como se puede ver, la escala afecta a todos los tamaños, incluyendo el ancho de línea. El ancho de línea de las elipses y el círculo creado por el programa anterior son diferentes debido a esta razón.

PostScript tiene dos comandos más para dibujar arcos. Uno de ellos, arcn , es casi lo mismo que arc excepto en la dirección de dibujo. arcn dibuja el arco en el sentido de las agujas del reloj. El tercer comando de dibujo de arcos dibuja un arco circular que es tangente a dos líneas dadas en sus puntos finales. Se puede ejecutar así

x1 y1 x2 y2 r arcto xt1 yt1 xt2 yt2

donde xt1, yt1, xt2, yt2 denotan los coordenadas horizontales y verticales del arco, mientras que los puntos finales de las líneas tangentes tienen los valores x0, y0, x1, y1 y x1, y1, x2, y2 respectivamente y r es el radio del arco. Si el camino no es nuevo o el punto actual no coincide con el inicio del arco entonces se añade al camino una línea que une el punto actual con el inicio del arco. Al final del dibujo el punto actual es xt2, yt2 .

PostScript tiene también un comando basado en el algoritmo de Bezier que se puede usar de manera efectiva en la interpolación o extrapolación de unos datos dados para dibujar. Esto comando se llama curveto y se puede usar para formar el dibujo basado en la interpolación o extrapolación de un conjunto de datos dado. El comando se usa así

x1 y1 x2 y2 x3 y3 curveto

donde la curva empieza en el punto actual, cuyas coordenadas son x0, y0 . Es tangente a la línea entre los puntos x0, y0 y x1, y1 en el punto inicial. La curva acaba en el punto x3, y3 y es tangente a la línea entre x2, y2 y x3, y3 . Por defecto estos cuatro puntos se supone que son diferentes y determinan la forma de la figura.

Herramientas de escritura en PostScript

PostScript tiene varias fuentes que se usan como fuentes estándares para autoedición. Tiene también herramientas de creación de fuentes a las que se puede acceder definiendo pilas de diccionario donde las fuentes están disponibles. El siguiente programa en PostScript puede ser un ejemplo.

/Times-Roman findfont
15 scalefont
setfont
100 500 moveto
(I love PostScript!) show
/Times-Italic findfont
20 scalefont
setfont
100 450 moveto
(I love PostScript!) show
/Times-Bold findfont
25 scalefont
setfont
100 400 moveto
(I love PostScript!) show
/Helvetica findfont
30 scalefont
setfont
100 350 moveto
(I love PostScript!) show
/Courier findfont
35 scalefont
setfont
100 300 moveto
(I love PostScript!) show
/Helvetica-Bold findfont
40 scalefont
setfont
100 250 moveto
(I love PostScript!) show
showpage

Como se puede deducir del programa, el comando findfont se usa para obtener un acceso a la estructura de la fuente deseada. El nombre de la fuente comienza por / y se le da al comando como un parámetro (donde / le dice al intérprete que meta este valor en la pila tal como está. Cuando entremos más tarde en detalle en las operaciones de pila este punto quedará más claro). Después de la selección del comando, la escala se define mediante el comando scalefont . El factor de escala se da como un número precediendo al comando. Después del escalado de la fuente, el comando setfont deja la fuente disponible para usarla en el programa. Después de situar el cursor con el comando moveto con los parámetros adecuados, el texto entre paréntesis se pasa como parámetro al comando show . El comando showpage finaliza el display del material escrito. El programa anterior utiliza diferentes tipos y tamaños de fuentes con el mismo texto en diferentes posiciones. El número de fuentes disponibles para PostScript se puede encontrar buscando las situaciones de las fuentes en la estructura de directorios del sistema linux que utilices. El texto se puede ajustar con líneas, curvas y otras herramientas. Así pues cualquier tipo de escritura, en principio, es posible. Es solo una cuestión de diseño.

Cómo pintamos y usamos los colores en PostScript

El lenguaje PostScript está equipado con muchas facilidades para pintar figuras o crear dibujos con colores. Empezaremos primero mencionando los comandos de color. PostScript usa el negro como color por defecto, a no ser que se ejecute un comando de especificación de color. Por ello la salida de todos los programas anteriores eran dibujos en blanco y negro. Para usar colores en la salida de PostScript podemos usar tres comandos de coloreado diferentes. El primero se basa en el formato de color rgb . En este formato, cada color se supone compuesto de tres colores principales: rojo, verde y azul. A las componentes del color se les pueden dar parámetros de intensidad individuales, que pueden tomar valores entre 0 y 256. Los parámetros de intensidad pueden aceptar valores decimales de hasta tres dígitos de precisión, como 111.223. El comando esperado por PostScript debe ser dado de la siguiente manera.

x y z setrgbcolor

donde x,y,z son los parámetros de intensidad para las componentes rojo, verde y azul y setrgbcolor es el comando. En esta convención, 1 0 0 setrgbcolor crea el color rojo, mientras que 0 1 0 setrgbcolorcrea el verde. El negro corresponde al caso donde todos los parámetros de intensidad valen 1. Los comandos de color continúan afectando a todos los dibujos hasta que se ejecute el siguiente comando de color. Cuando esto pasa, el efecto del comando anterior se anula totalmente, y el nuevo valor vale para todo. El número de veces que se puede utilizar es ilimitado. Usando adecuadamente los valores del color puedes crear tus dibujos como quieras. Es una cuestión de arte y depende de ti.

La segunda utilidad de control del color se basa en un formato de cuatro componentes del color. Se llama el formato de color cmyk . Las cuatro componentes básicas del color son cyan, magenta, amarillo y negro respectivamente. Cada componente de color contribuye al color final según una intensidad que puede variar entre 0 y 1. El comando de PostScript correspondiente es

w x y z setcmykcolor

donde w, x, y, z son los parámetros de intensidad para las componentes de color cyan, magenta, amarillo y negro, respectivamente. Los valores fraccionarios decimales se pueden usar también para los valores de intensidad. Este comando continúa su efecto sobre todo hasta que el siguiente comando se ejecuta. Cuando esto ocurre, los nuevos valores dominan sobre los anteriores. No hay limitación sobre el número de veces que se puede usar en un programa.

El tercer comando es el siguiente

x y z sethsbcolor

donde x, y, z son los valores de los parámetros de intensidad de tres diferentes propiedades del color. El primero corresponde a color (hue), que determina la localización del color en el espectro de la luz. El segundo, saturación y el tercero brillo corresponden a la saturación y brillo del color. Este formato se prefiere cuando las propiedades a controlar son la localización del color en el espectro mediante un bucle, o el brillo y/o la saturación. El lector que no esté familiarizado con hsbcolor puede comprobar el uso de xfig bajo linux.

El comando más importante de PostScript para pintar es fill y closepath . El siguiente programa de ejemplo, que se supone grabado en el fichero sample6.ps , clarifica importantes aspectos al pintar y colorear con PostScript.

1 1 0 0 setcmykcolor
100 100 moveto
300 100 lineto
300 250 lineto
100 250 lineto
100 100 lineto
stroke
1 0.5 0.8 0 setcmykcolor
5 setlinewidth
200 200 moveto
400 300 lineto
300 300 lineto
closepath fill
stroke
1 0 0 setrgbcolor
3 setlinewidth
200 200 moveto
100 200 100 0 75 arc
stroke
newpath
400 500 200 20 50 arc
stroke
0 0 1 0.2 setcmykcolor
3 setlinewidth
200 200 100 0 360 arc
stroke
1 0 0 setrgbcolor
newpath
2 1 scale
200 300 50 0 360 arc
gsave fill grestore stroke
stroke
0 1 0 setrgbcolor
newpath
1 4 scale
100 150 40 0 360 arc
gsave fill grestore stroke

donde el comando closepath cierra un camino abierto uniendo dos puntos finales con una línea recta, mientras que fill sirve para llenar el interior del camino cerrado con el color actual.

PostScript puede también crear tonos de gris. Esto se puede hacer con el siguiente comando

x setgray

donde x es la intensidad del color gris y su valor puede variar desde 0, que corresponde a negro, hasta 1, que corresponde a blanco. El siguiente programa grabado bajo el nombre de sample7.ps está hecho de manera que se explique a sí mismo.

0.2 setgray
10 setlinewidth
100 700 moveto
200 0 rlineto
stroke
newpath
0.3 setgray
100 600 moveto
200 0 rlineto
stroke
newpath
0.4 setgray
100 500 moveto
200 0 rlineto
stroke
newpath
0.5 setgray
100 400 moveto
200 0 rlineto
stroke
newpath
0.6 setgray
100 300 moveto
200 0 rlineto
stroke
newpath
0.7 setgray
100 200 moveto
200 0 rlineto
stroke
newpath
0.8 setgray
100 100 moveto
200 0 rlineto
stroke

Antes de finalizar esta presentación, podemos recomendar escribir programas más complicados para los usuarios que encuentran en PostScript una interesante herramienta. En los siguientes artículos de esta serie daremos más detalles sobre el lenguaje PostScript. Todas las preguntas y recomendaciones serán bienvenidas.

El autor agradece a Oliver Thilmann por sus útiles comentarios sobre la organización y presentación de este artículo.


Traducido por Hugo Lastras Membrive y César Ordiñana

Más información:
  • Consulta los libros de Adobe Systems Inc. publicados por Addison-Wesley: PostScript Language
    (Tres volumenes: Tutorial and Cookbook, Language Reference, Program Design)


© 1998 Emre Demiralp
Páginas Web mantenidas por Miguel A Sepúlveda.