Member of The Internet Defense League Últimos cambios
Últimos Cambios
Blog personal: El hilo del laberinto Geocaching

Firefox 3 y las impresoras PostScript

Última Actualización: 13 de abril de 2008 - Domingo

Firefox 3 será un buen producto, pero cuando se publique saldrá con algunos defectos que considero muy graves. Es una lástima, pero no son una prioridad. Es de esperar que, a medida que el producto madure (revisiones posteriores de Firefox 3), al menos no sea "peor" que el actual Firefox 2. Mientras tanto toca presionar a la gente de Mozilla, por un lado, y capear el temporal lo mejor posible, por otro.

Algunos de los problemas ya los he documentado con anterioridad. En esta ocasión me centraré en los problemas de impresión.

La impresión en Firefox 3 está muy mejorada respecto a su predecesor. Ahora sí podemos decir que lo que vemos en la pantalla va a ser lo que salga por la impresora. El esfuerzo realizado (migrar todo Gecko a Cairo) ha sido monumental. El resultado final es bueno, y aún lo será más a medida que Cairo mejore: aceleración hardware, SVG avanzado, gráficos independientes de la resolución...

Pero no todo son rosas. Para empezar, Gecko incluye una copia propia de la librería Cairo. Es decir, no utiliza la versión instalada en el sistema operativo. Eso está bien porque Cairo evoluciona rápido y la versión instalada en el sistema probablemente sea inapropiada. Como contrapartida, no podemos beneficiarnos de las personalizaciones que hayas realizado en nuestra propia versión de Cairo (para aquellos que compilamos todo, claro). Sería interesante que Firefox utilizase una versión u otra en función de una variable de entorno, por ejemplo. Así podríamos tener lo mejor de ambos mundos. Tal vez, algún día...

Mi problema con la impresión de Firefox 3 empezó en septiembre u octubre de 2007. De repente, un día, los gráficos dejaron de salir. El texto salía perfecto, pero los gráficos me aparecían como bloques sólidos en negro. El bug se comunicó a Mozilla.

Tras investigar el asunto despacito, llegué a la conclusión de que en una actualización de Cairo en Firefox 3 se había cambiado la generación PostScript de la versión 2 del lenguaje a la versión 3. La versión 3 es más avanzada, lógicamente, pero no todas las impresoras lo soportan. Era mi caso. Costó un par de meses conseguir que Mozilla volviese a la versión 2 del lenguaje.

Ahora que la impresora ya imprime, el nuevo problema es el rendimiento: imprimir un documento con colores (especialmente, gráficos) es más lento que en Firefox 2. De hecho MUCHO más lento. La situación empeoró muchísimo tras la migración de Firefox 3 de su caja de diálogo de impresión propia a la estándar de GNOME (si eres usuario de KDE, te fastidias...). En ese cambio se perdieron muchas funcionalidades, pero la que nos afecta aquí es la capacidad de convertir los documentos en color a tonos de gris.

Los detalles están documentados en el Bugzilla de Mozilla. El resumen es: imprimir un gráfico "pequeño" en Firefox 3 es... ¡51 veces más lento que en viejo Firefox 2!.

Es de esperar que la diferencia se vaya limando en revisiones futuras de Cairo (parece ser el caso en los últimos builds) pero, si no cambian las cosas, siempre habrá una pérdida de rendimiento de 3:1 respecto a Firefox 2 por el simple hecho de que en Firefox 2 podemos imprimir una imagen en gris, ahorrando a la impresora el duro trabajo (para su CPU anémica y su poca memoria) de realizar la conversión.

Visto lo visto, y que el asunto no tiene pinta de mejorar en el futuro (y que necesito imprimir "rápido"), la única opción es currárselo uno mismo. Es decir, de alguna manera "mágica" hay que coger un documento PostScript, analizarlo, convertir la información de color a gris, generar un nuevo documento PostScript con esos cambios, y enviarlo a la impresora. De hecho lo mejor sería pasar directamente a la conversión a semitonos (que es lo que imprime realmente una impresora en blanco y negro), ahorrando el máximo de trabajo posible a la impresora. Pero por mucho que busqué, no encontré ningún programa capaz de realizar esa función.

Pero este enfoque está equivocado. El objetivo no es tomar un PostScript y generar un documento PostScript nuevo más fácil de manejar para la impresora. El objetivo real es conseguir que la impresión sea lo más rápida posible. No hay que centrarse en una tecnología concreta.

Hay que abrir opciones.

Mi impresora soporta PCL. PCL es un lenguaje ligero y eficiente, comparado con PostScript. Una prueba de concepto me demostró que imprimir en PCL es mucho más rápido y ligero que PostScript. El problema es que todo el sistema de impresión se centra en PostScript. Es necesario introducir algún paso intermedio que realice la conversión de PostScript a PCL justo antes de enviar el trabajo a la impresora.

Ese sistema existe, ya está programado. Se trata del popular programa GhostScript. GhostScript es un intérprete de PostScript para ordenadores personales, donde los recursos (CPU y memoria) son básicamente ilimitados, comparados con una impresora. Y, lo mejor de todo, GhostScript tiene un "backend" PCL. En definitiva, GhostScript puede tomar un fichero PostScript y generar el PCL correspondiente, de forma fiel y rápida.

El problema ahora es "conectar" GhostScript con el sistema de impresión. En mi caso, CUPS. Por supuesto, el procedimiento está muy mal documentado, información fragmentaria, parcial, anticuada... Tras invertir horas intentado definir una instancia adicional de mi impresora habitual, con el filtro PS->PCL, acabé tirando todo ese esfuerzo por la ventana y adoptando la vía directa: driver directo de impresión.

Los pasos son:

  • Modificamos el fichero PPD de la impresora (típicamente en "/etc/cups/ppd/"). Sencillamente añadimos una línea de este estilo:
    *cupsFilter: "application/vnd.cups-postscript 0 ps2pcl-jcea"
    

  • Creamos el driver en "/usr/lib/cups/filter/ps2pcl-jcea". Le damos los mismos permisos que el resto de "drivers". El nuevo "driver" es un fichero "shell", con el siguiente contenido:
    #!/bin/bash
    
    # debug info in /var/log/cups/error_log
    set -x
    
    # set inputfile to where the input comes from
    inputfile="-"
    [ -n "$6" ] && inputfile="$6"
    # printing
    # Primero usamos el driver "ljet4", pero queda horroroso con graficos.
    # Con "lj4dith" queda mucho mejor, pero bastante mas oscuro
    gs -q -dBATCH -dPARANOIDSAFER -dNOPAUSE -sDEVICE=lj4dith -r600 -sOutputFile=- $inputfile
    

  • Reiniciamos CUPS.

El "driver" recibe el fichero PostScript (por la entrada estándar o como un "path" de un fichero) y se lo envía a GhostScript, que nos devolverá un fichero PCL que CUPS envía a la impresora.

La impresión, ahora, "vuela".

Dos detalles:

  • "Cableamos" la resolución de los documentos a 600 DPIs. Esto es algo a mejorar en el futuro.

  • Hay dos "drivers" PCL que nos interesan: "ljet4" y "lj4dith". La diferencia es que uno utiliza semitonos (de una forma bastante "cutre", por cierto; la calidad para texto es buena, pero los gráficos muestran muchas "bandas"). La otra opción usa dithering Floyd-Steinberg. El resultado es muy bueno, pero demasiado oscuro para mi gusto. No obstante es la mejor opción si queremos que los gráficos se vean bien. Nuevamente, es algo a mejorar en el futuro.

Actualización

La última versión de Firefox 3 ha actualizado la librería Cairo, que incluye bastantes mejoras en el PostScript generado. El resultado final es que ahora imprimir una imagen en color es más rápido que imprimir la misma imagen en grises en Firefox 2. Esta mejora dice mucho de la calidad del sistema de impresión de Firefox 2 :-).

Mantengo mi driver PS->PCL, ya que beneficia a todos los programas que usen esta impresora, no solo a Firefox. Además, sigue siendo más rápido.

Pero es bueno saber que no es imprescindible, sobre todo por esa sensación que tengo de que el "dithering" genera imágenes demasiado oscuras, cosa que no ocurre cuando la impresora se ocupa de esos detalles.


Historia

  • 13/abr/08: Actualización: las últimas versiones de Firefox 3 imprimen muy rápido.

  • 13/abr/08: Primera versión de este documento.



Python Zope ©2008 jcea@jcea.es

Más información sobre los OpenBadges

Donación BitCoin: 19niBN42ac2pqDQFx6GJZxry2JQSFvwAfS