Selbst erstellte Filter zum Ausdruck mit CUPS

Supportdatenbank (jsmeix_print-cups-filters)
Bezieht sich auf

SuSE Linux: Versionen ab 8.2

Anliegen

Sie möchten selbst erstellte Filter zum Ausdruck mit CUPS verwenden.

Voraussetzung ist ein Grundverständnis des Drucksystems und ein sicherer Umgang mit CUPS, Bash-Scripten und den üblichen Kommandozeilentools.

Index:

  1. Hintergrundinformation zum CUPS-Filtersystem
  2. Beispiele, wann selbst erstellte Filter nützlich sind:
  3. Druck von reinem ASCII-Text in druckerspezifischer Codierung
  4. Wahlweise PCL-Druck bei einem PostScript+PCL Drucker
  5. PostScript Vorverarbeitung mit Ghostscript bei einem PostScript Drucker
  6. Zusätzliche Filterschritte dem standardmässigen CUPS-Filtersystem hinzufügen
  7. Einschränkungen

Hintergrundinformation zum CUPS-Filtersystem

Normalerweise liefert das standardmässige CUPS-Filtersystem optimale Ergebnisse und bietet vielfältige Möglichkeiten, die Art der Druckausgabe individuell anzupassen, aber in Sonderfällen kann es sein, dass selbst erstellte Filter zum Einsatz kommen sollen.

Reihenfolge, in der die einzelnen Filter aktiv werden:

Das standardmässige CUPS-Filtersystem arbeitet wie es allgemein in /etc/cups/mime.types und /etc/cups/mime.convs und ggf. pro Warteschlange durch *cupsFilter Einträge in der PPD Datei festgelegt ist.

Einstellmöglichkeiten der einzelnen Filter:

  1. /usr/lib/cups/filter/texttops - siehe:
    CUPS Software Users Manual: Text Options
  2. /usr/lib/cups/filter/pstops - siehe:
    CUPS Software Users Manual: Document Options
  3. /usr/lib/cups/filter/foomatic-rip - siehe:
    CUPS Software Users Manual: Printer Options

Beispiele, wann selbst erstellte Filter nützlich sind:

Druck von reinem ASCII-Text in druckerspezifischer Codierung

Ein Nadeldrucker soll dafür verwendet werden, Formulare auf Endlospapier mit mehreren Durchschlägen auszufüllen.
Die Warteschlange für den Nadeldrucker soll dazu dem Drucker reinen ASCII-Text liefern, aber die Codierung der Zeichen soll dabei auf die des Nadeldruckers angepasst sein.

Wahlweise PCL-Druck bei einem PostScript+PCL Drucker

PostScript Drucker scheitern bei zu komplexen PostScript Dokumenten.
Insbesondere dann, wenn im PostScript Drucker nicht reichlich Speicher eingebaut ist, können im PostScript Dokument eingebettete Rastergrafiken in hoher Auflösung und/oder Farbtiefe nicht zu Papier gebracht werden.
Eine Bitmap-Grafik in 1200x1200 dpi benötigt 16 Mal so viel Speicherplatz wie in 300x300 dpi und 32-Bit Farbtiefe brauchen 32 Mal so viel wie 1-Bit Schwarzweißdarstellung.
Also braucht eine 1200x1200 dpi Bitmap-Grafik mit 32-Bit Farbtiefe über Fünfhundert Mal so viel Speicherplatz wie dieselbe Grafik in 1-Bit Schwarzweißdarstellung bei 300x300 dpi Auflösung.

Die direkte Lösung ist, im Anwendungsprogramm, was das PostScript Dokument produziert, die Auflösung und die Farbtiefe von eingebetteten Grafiken zu reduzieren.

Problematische PostScript Dokumente können auch vom Drucksystem wie oben beschrieben in PCL-Daten (ggf. in relativ geringer Auflösung und/oder Farbtiefe) umgewandelt werden.
PCL-Daten brauchen (je nach Auflösung und/oder Farbtiefe) wesentlich weniger Speicher im Drucker, um zu Papier gebracht zu werden.
Normalerweise können PostScript Drucker auch via PCL angesprochen werden. Meist haben PostScript+PCL Drucker eine automatische Erkennung des Datentyps und schalten automatisch zwischen PostScript- und PCL-Modus um.

Die einfachste Lösung ist, eine zusätzliche Warteschlange für einen PostScript+PCL Drucker anzulegen, die immer PCL-Daten liefert, indem für die zusätzliche Warteschlange eine PPD-Datei für einen kompatiblen PCL Drucker verwendet wird.

Mehrere Warteschlangen für denselben Drucker haben aber den Nachteil, dass alle Warteschlangen für den Drucker abzufragen sind, um alle anstehenden bzw. aktiven Druckjobs für den Drucker angezeigt zu bekommen.
Bei einem einzelnen Drucker oder bei einem Einzelplatzsystem ist das kein Problem, aber wenn mehrere Drucker im Netzwerk von vielen Benutzern verwendet werden, sind mehrere Warteschlangen pro Drucker zu unübersichtlich.
Daher soll es nur eine einzige Warteschlange pro PostScript+PCL Drucker geben, die wahlweise auch PCL-Daten liefern kann, um problematische PostScript Dokumente via PCL (ggf. in relativ geringer Auflösung und/oder Farbtiefe) drucken zu können.

PostScript Vorverarbeitung mit Ghostscript bei einem PostScript Drucker

Erfolgt die Vorverarbeitung mit Ghostscript über eine zusätzliche Warteschlange und handelt es sich um einen PostScript+PCL Drucker, so sind zusammen mit der Möglichkeit für PCL-Druck drei Warteschlangen für denselben Drucker nötig.
Die Nachteile von mehreren Warteschlangen pro Drucker sind oben beschrieben.
Daher soll sowohl PostScript Vorverarbeitung als auch PCL-Druck über eine einzige Warteschlange pro Drucker möglich sein.

Zusätzliche Filterschritte dem standardmässigen CUPS-Filtersystem hinzufügen

Oft liefern gewisse Anwendungsprogramme problematische bzw. fehlerhafte PostScript Dokumente, was dementsprechend eine fehlerhafte bzw. unmögliche Druckausgabe zur Folge hat.
In gewissen Fällen ist es möglich, die PostScript Daten zu korrigieren, so dass die Druckausgabe korrekt erfolgt bzw. zumindest möglich ist.
Ist die Korrektur der PostScript Daten per Script automatisierbar, dann kann das Korrekturscript als zusätzlicher Filterschritt zum standardmässigen CUPS-Filtersystem hinzugefügt werden.
Da hierdurch das Korrekturscript nicht optional, sondern in jedem Fall ausgeführt wird, sind besondere Vorsicht und gründliche Tests nötig, damit durch das Korrekturscript nicht mehr Probleme im standardmässigen CUPS-Filtersystem entstehen, als gelöst werden.

Vorgehen für diese Beispiele:

Druck von reinem ASCII-Text in druckerspezifischer Codierung

  1. Die Warteschlange für den Nadeldrucker wird wie üblich mit einer Foomatic PPD-Datei passend zum Modell des Nadeldruckers angelegt.

  2. In der PPD-Datei /etc/cups/ppd/Warteschlange.ppd wird direkt unter der Zeile
    *cupsFilter: "application/vnd.cups-postscript 0 foomatic-rip"
    eine zusätzliche Zeile
    *cupsFilter: "text/plain 0 TextToPrinter"
    
    eingefügt.
    Ein *cupsFilter Eintrag in der PPD Datei dient immer zur Umwandlung in druckerspezifische Daten, die danach direkt zum Drucker geschickt werden.
    Somit werden nun speziell für diese Warteschlange alle Daten vom Mime Typ text/plain ohne dass andere Filter zwischengeschaltet werden, mit /usr/lib/cups/filter/TextToPrinter direkt in druckerspezifische Daten umgewandelt.
    Wenn Daten vom Mime Typ text/plain gedruckt werden, hat das für diese Warteschlange zur Folge, dass es keine Möglichkeit gibt, die Druckausgabe individuell anzupassen, weil dazu die entsprechenden CUPS- und Foomatic-Filter benötigt werden.

  3. /usr/lib/cups/filter/TextToPrinter ist das selbst zu erstellende Filter-Script zur druckerspezifischen Umcodierung von ASCII-Text.
    Dieses Script ist genau passend zum Druckermodell zu erstellen.

    In vielen Fällen haben Nadeldrucker eine zum IBM-PC kompatible Zeichencodierung eingebaut.
    Mit dem Befehl recode "lat1..ibmpc" erfolgt eine Umcodierung in die IBM-PC kompatible Zeichencodierung.
    Wenn der Drucker an der ersten parallelen Schnittstelle angeschlossen ist, dann sollte mit einem Befehl der folgenden Art

    echo -en "\rZeile 1\nUmlaute: ÄÖÜäöüß\nZeile 3\f" | recode "lat1..ibmpc" >/dev/lp0
    
    getestet werden, ob recode "lat1..ibmpc" die richtige druckerspezifische Codierung liefert.
    Wenn nein, dann bietet recode noch viele andere Umcodierungen und im Notfall hilft ein Nachgeschaltetes tr oder sed, um einzelne Zeichen oder Zeichenfolgen individuell umzucodieren.

    Das folgende Script gibt die druckbaren Zeichen mit deren oktalen Codes aus:

    #! /bin/bash
    # carriage return before printing
    echo -en "\r"
    # print printable 8-bit characters (CR, NL, TAB, BS, 32-126, 128-254)
    echo -en "the special characters horizontal tab and backspace:\r\n"
    echo -en "the next line consists of 5 horizontal tabs each followed by I\r\n"
    echo -en "\tI\tI\tI\tI\tI\r\n"
    echo -en "the next line consists of C backspace and =\r\n"
    echo -en "C\b=\r\n"
    echo -en "the printout of C backspace and = may look like an Euro sign\r\n"
    echo -en "\nthe printable 7-bit octal codes (040-176) and characters:\r\n"
    for i in 04 05 06 07 10 11 12 13 14 15 16
    do for j in 0 1 2 3 4 5 6 7
       do echo -en "${i}${j} \\${i}${j}  "
       done
       echo -en "\r\n"
    done
    for i in 170 171 172 173 174 175 176
    do echo -en "${i} \\${i}  "
    done
    if test "$1" = "7"
    then
    # form feed after printing
      echo -en "\r\f"
      exit 0
    fi
    echo -en "\r\n"
    if test "$1" = "a"
    then
      echo -en "\nthe 8-bit octal codes (200-237) and characters:\r\n"
      for i in 20 21 22 23
      do for j in 0 1 2 3 4 5 6 7
         do echo -en "${i}${j} \\${i}${j}  "
         done
         echo -en "\r\n"
      done
    fi
    echo -en "\nthe printable 8-bit octal codes (240-376) and characters:\r\n"
    for i in 24 25 26 27 30 31 32 33 34 35 36
    do for j in 0 1 2 3 4 5 6 7
       do echo -en "${i}${j} \\${i}${j}  "
       done
       echo -en "\r\n"
    done
    for i in 370 371 372 373 374 375 376
    do echo -en "${i} \\${i}  "
    done
    # form feed after printing
    echo -en "\r\f"
    
    Ohne weitere Parameter werden die normalerweise problemlos druckbaren 8-bit Codes ausgegeben.
    Wird 7 als Parameter angegeben, werden nur die druckbaren 7-bit ASCII-Codes ausgegeben.
    Mit dem Parameter a werden alle evtl. druckbaren 8-bit Codes ausgegeben. Dadurch werden aber normalerweise die Terminaleinstellungen zerstört, so dass der Parameter a nicht für eine Bildschirmausgabe zu empfehlen ist.
    Wenn der Drucker an der ersten parallelen Schnittstelle angeschlossen ist, dann kann dieses Script mit einem Aufruf der folgenden Art
    Script a >/dev/lp0
    
    dazu verwendet werden, dass der Drucker seinen eingebauten Zeichensatz ausgibt.
    Damit kann dann die nötige Umcodierung genau ermittelt werden.

    Falls obiger recode Befehl die richtige druckerspezifische Codierung liefert, könnte /usr/lib/cups/filter/TextToPrinter wie folgt aussehen:

    #! /bin/bash
    # see http://localhost:631/spm.html#WRITING_FILTERS
    # debug info in /var/log/cups/error_log
    set -x
    # have the input at fd0 (stdin) in any case
    [ -n "$6" ] && exec <"$6"
    # carriage return before printing
    echo -en "\r"
    # printing
    recode "lat1..ibmpc"
    # form feed after printing
    echo -en "\f"
    

  4. Das Filter-Script muss Eigentümer, Gruppe und Zugriffsrechte analog zu den anderen Filtern in /usr/lib/cups/filter/ haben.

  5. Der cupsd ist neu zu laden bzw. neu zu starten.

  6. Tests:

  7. Optional:

Wahlweise PCL-Druck bei einem PostScript+PCL Drucker

  1. Die Warteschlange für den PostScript+PCL Drucker wird wie üblich mit der PPD-Datei des Herstellers für das spezielle Druckermodell angelegt oder als generischer PostScript Drucker mit der generischen CUPS PPD-Datei /usr/share/cups/model/Postscript.ppd.gz oder mit der generischen Foomatic PPD-Datei /usr/share/cups/model/Generic/PostScript_Printer-Postscript.ppd.gz.

  2. Wurde die generische Foomatic PPD-Datei verwendet, dann wird /etc/cups/ppd/Warteschlange.ppd wie folgt verändert:
    *cupsFilter: "application/postscript-problematic 0 PsToPCL"
    *cupsFilter: "application/vnd.cups-postscript 0 foomatic-rip"
    
    ansonsten werden in /etc/cups/ppd/Warteschlange.ppd analog zur generischen Foomatic PPD-Datei folgende Zeilen eingefügt:
    *cupsFilter: "application/postscript-problematic 0 PsToPCL"
    *cupsFilter: "application/vnd.cups-postscript 0 ToPrinter"
    
    Ein *cupsFilter Eintrag in der PPD Datei dient immer zur Umwandlung in druckerspezifische Daten, die danach direkt zum Drucker geschickt werden.
    Somit werden nun speziell für diese Warteschlange alle Daten vom Mime Typ application/postscript-problematic ohne dass andere Filter zwischengeschaltet werden, mit /usr/lib/cups/filter/PsToPCL direkt in druckerspezifische Daten umgewandelt.
    Wenn Daten vom Mime Typ application/postscript-problematic gedruckt werden, hat das für diese Warteschlange zur Folge, dass es keine Möglichkeit gibt, die Druckausgabe individuell anzupassen, weil dazu die entsprechenden CUPS- und Foomatic-Filter benötigt werden.

  3. Der neue Mime Typ application/postscript-problematic wird in /etc/cups/mime.types als zusätzliche Zeile
    application/postscript-problematic
    
    eingetragen, denn sonst akzeptiert CUPS diesen Mime Typ nicht.
    Vergl. dazu aber auch CUPS Software Administrators Manual: Adding Filetypes and Filters.

  4. /usr/lib/cups/filter/PsToPCL ist das selbst zu erstellende Filter-Script zur Umwandlung von PostScript nach PCL.
    Dieses Script ist genau passend zum Druckermodell zu erstellen.

    In den meisten Fällen verstehen PostScript+PCL Drucker die Druckersprache PCL5e, die von den Ghostscript-Treibern ljet4 und lj4dith für Floyd-Steinberg Dithering und ljet4d für Duplexdruck mit Auflösungen bis zu 600 dpi geliefert werden.
    Wenn der Drucker an der ersten parallelen Schnittstelle angeschlossen ist, dann sollte mit einem Ghostscript-Aufruf der folgenden Art

    gs -q -dBATCH -dNOPAUSE -sDEVICE=ljet4 -sOutputFile=/dev/lp0 /usr/share/doc/packages/ghostscript/examples/colorcir.ps
    
    getestet werden, ob ljet4 (bzw. die anderen PCL5e-Treiber) die richtigen druckerspezifischen Daten liefert.
    Wenn nein, dann bietet Ghostscript noch andere PCL-Treiber, siehe den Supportdatenbank-Artikel "Drucker-Kauf und Kompatibilität" (http://sdb.suse.de/de/sdb/html/jsmeix_print-kompatibel.html).

    Falls mit obigem gs Befehl die Farbellipse korrekt ausgedruckt wurde, könnte /usr/lib/cups/filter/PsToPCL wie folgt aussehen, um Daten vom Mime Typ application/postscript-problematic mit ljet4 nach PCL5e in 300 dpi Auflösung umzuwandeln:

    #! /bin/bash
    # see http://localhost:631/spm.html#WRITING_FILTERS
    # debug info in /var/log/cups/error_log
    set -x
    # have the input at fd0 (stdin) in any case
    [ -n "$6" ] && exec <"$6"
    # printing
    gs -q -dBATCH -dPARANOIDSAFER -dNOPAUSE -sDEVICE=ljet4 -r300 -sOutputFile=- -
    

  5. Alle anderen Daten sind vom Mime Typ application/vnd.cups-postscript und diese werden entweder von /usr/lib/cups/filter/foomatic-rip weiterverarbeitet, oder von /usr/lib/cups/filter/ToPrinter direkt an den Drucker geschickt.
    /usr/lib/cups/filter/ToPrinter sieht z.B. so aus:
    #! /bin/bash
    # see http://localhost:631/spm.html#WRITING_FILTERS
    # debug info in /var/log/cups/error_log
    set -x
    # have the input at fd0 (stdin) in any case
    [ -n "$6" ] && exec <"$6"
    # printing
    cat -
    

  6. Die Filter-Scripte müssen Eigentümer, Gruppe und Zugriffsrechte analog zu den anderen Filtern in /usr/lib/cups/filter/ haben.

  7. Der cupsd ist neu zu laden bzw. neu zu starten.

  8. Mit der CUPS Option
    -o document-format=application/postscript-problematic
    
    kann auf der Kommandozeile der Mime Typ des zu druckenden PostScript Dokuments auf application/postscript-problematic festgelegt werden.
    Je nachdem, ob diese Option gesetzt ist oder nicht, erfolgt die spezielle Verarbeitung nur mit /usr/lib/cups/filter/PsToPCL oder es erfolgt die übliche CUPS-Filterung.
    Da Ghostscript als Eingabe von stdin nur PostScript Daten akzeptiert, kann der Mime Typ application/postscript-problematic nur bei PostScript Dokumenten verwendet werden.

    Testdruck von PostScript mit /usr/lib/cups/filter/PsToPCL:

    lp -d Warteschlange -o document-format=application/postscript-problematic /usr/share/doc/packages/ghostscript/examples/colorcir.ps
    
    In /var/log/cups/error_log findet sich dann:
    I ... Started filter /usr/lib/cups/filter/PsToPCL
    ...
    D ... + '[' -n /var/spool/cups/... ']'
    D ... + exec
    D ... + gs -q -dBATCH -dPARANOIDSAFER -dNOPAUSE -sDEVICE=ljet4 -r300 -sOutputFile=- -
    

  9. Optional:

PostScript Vorverarbeitung mit Ghostscript bei einem PostScript Drucker

  1. Die Warteschlange für den PostScript Drucker wird wie üblich mit der PPD-Datei des Herstellers für das spezielle Druckermodell angelegt oder als generischer PostScript Drucker mit der generischen CUPS PPD-Datei oder mit der generischen Foomatic PPD-Datei (siehe oben).

  2. Ein neuer Mime Typ application/postscript-pswrite wird in /etc/cups/mime.types als zusätzliche Zeile
    application/postscript-pswrite
    
    eingetragen.
    Vergl. dazu aber auch CUPS Software Administrators Manual: Adding Filetypes and Filters.

  3. In /etc/cups/mime.convs wird eine zusätzliche Zeile
    application/postscript-pswrite application/postscript 33 PsWrite
    
    eingetragen.
    Vergl. dazu aber auch CUPS Software Administrators Manual: Adding Filetypes and Filters.

    Somit werden nun alle Daten vom Mime Typ application/postscript-pswrite mit /usr/lib/cups/filter/PsWrite in Daten vom Mime Typ application/postscript umgewandelt.
    Diese Filterung ist für alle Warteschlangen verfügbar.
    Wenn Daten vom Mime Typ application/postscript-pswrite gedruckt werden, hat das zur Folge, dass die meisten Möglichkeiten, die Druckausgabe individuell anzupassen, erhalten bleiben, weil Daten vom Mime Typ application/postscript die üblichen CUPS- und ggf. Foomatic-Filter durchlaufen. Oft funktionieren jedoch die Möglichkeiten von /usr/lib/cups/filter/pstops gemäss
    CUPS Software Users Manual: Document Options nicht zusammen mit der PostScript Vorverarbeitung, aber zumindest die druckerspezifischen Optionen gemäss der PPD-Datei sollten auch zusammen mit der PostScript Vorverarbeitung funktionieren.

  4. Zur PostScript Vorverarbeitung mit Ghostscript wird der Ghostscript Treiber pswrite verwendet.
    Wenn der Drucker an der ersten parallelen Schnittstelle angeschlossen ist, dann sollte mit einem Ghostscript-Aufruf der folgenden Art
    gs -q -dBATCH -dNOPAUSE -sDEVICE=pswrite -sOutputFile=/dev/lp0 /usr/share/doc/packages/ghostscript/examples/colorcir.ps
    
    gs -q -dBATCH -dNOPAUSE -sDEVICE=pswrite -dLanguageLevel=2 -sOutputFile=/dev/lp0 /usr/share/doc/packages/ghostscript/examples/colorcir.ps
    
    gs -q -dBATCH -dNOPAUSE -sDEVICE=pswrite -dLanguageLevel=1 -sOutputFile=/dev/lp0 /usr/share/doc/packages/ghostscript/examples/colorcir.ps
    
    getestet werden, ob bzw. welcher LanguageLevel die richtigen druckerspezifischen Daten liefert.
    Bei einem PostScript Level 1 Drucker könnte der Filter /usr/lib/cups/filter/PsWrite wie folgt aussehen
    #! /bin/bash
    # see http://localhost:631/spm.html#WRITING_FILTERS
    # debug info in /var/log/cups/error_log
    set -x
    # set inputfile to where the input comes from
    inputfile="-"
    [ -n "$6" ] && inputfile="$6"
    # printing
    gs -q -dBATCH -dPARANOIDSAFER -dNOPAUSE -sDEVICE=pswrite -dLanguageLevel=1 -sOutputFile=- $inputfile
    

  5. Das Filter-Script muss Eigentümer, Gruppe und Zugriffsrechte analog zu den anderen Filtern in /usr/lib/cups/filter/ haben.

  6. Der cupsd ist neu zu laden bzw. neu zu starten.

  7. Mit der CUPS Option
    -o document-format=application/postscript-pswrite
    
    kann auf der Kommandozeile der Mime Typ des zu druckenden PostScript Dokuments auf application/postscript-pswrite festgelegt werden.
    Je nachdem, ob diese Option gesetzt ist oder nicht, erfolgt die spezielle Vorverarbeitung mit /usr/lib/cups/filter/PsWrite oder es erfolgt nur die übliche CUPS-Filterung.
    Da /usr/lib/cups/filter/PsWrite der erste Filter in der Kette ist erhält er gemäss CUPS Software Programmers Manual: Writing Filters: Command-Line Arguments den Input direkt aus der CUPS-Spooldatei, so dass die Vorverarbeitung auch für PDF Dokumente möglich ist.

    Testdruck von PostScript mit /usr/lib/cups/filter/PsWrite:

    lp -d Warteschlange -o document-format=application/postscript-pswrite /usr/share/doc/packages/ghostscript/examples/colorcir.ps
    
    In /var/log/cups/error_log findet sich dann:
    I ... Started filter /usr/lib/cups/filter/PsWrite
    I ... Started filter /usr/lib/cups/filter/pstops
    ...
    D ... + gs -q -dBATCH -dPARANOIDSAFER -dNOPAUSE -sDEVICE=pswrite -dLanguageLevel=1 -sOutputFile=- /var/spool/cups/...
    

  8. Optional:

Zusätzliche Filterschritte dem standardmässigen CUPS-Filtersystem hinzufügen

  1. Ein neuer Mime Typ application/postscript-prefiltered wird in /etc/cups/mime.types als zusätzliche Zeile
    application/postscript-prefiltered
    
    eingetragen.
    Vergl. dazu aber auch CUPS Software Administrators Manual: Adding Filetypes and Filters.

  2. In /etc/cups/mime.convs wird eine zusätzliche Zeile eingetragen und die pstops Zeile wird wie folgt geändert:
    application/postscript application/postscript-prefiltered 10 PsPrefilter
    application/postscript-prefiltered application/vnd.cups-postscript 66 pstops
    
    Vergl. dazu aber auch CUPS Software Administrators Manual: Adding Filetypes and Filters.

    Somit werden nun alle Daten vom Mime Typ application/postscript mit /usr/lib/cups/filter/PsPrefilter vorgefiltert und in Daten vom Mime Typ application/postscript-prefiltered umgewandelt und diese Daten werden dann von standardmässigen CUPS-Filter /usr/lib/cups/filter/pstops weiterverarbeitet.

    Alle Möglichkeiten, die Druckausgabe individuell anzupassen, sollten hierbei erhalten bleiben, weil die Daten die üblichen CUPS- und ggf. Foomatic-Filter durchlaufen.
    Voraussetzung ist, dass /usr/lib/cups/filter/PsPrefilter für jegliche Daten vom Mime Typ application/postscript korrekt arbeitet.

  3. /usr/lib/cups/filter/PsPrefilter ist das selbst zu erstellende Filter-Script zur Vorverarbeitung von PostScript-Daten.

    Angenommen, es ist CUPS Version 1.1.15 im Einsatz und das Problem, was im Supportdatenbank-Artikel "Kein Landscape Druck mit CUPS" (http://sdb.suse.de/de/sdb/html/jsmeix_print-cups-landscape-81.html) beschrieben ist, soll mit einem PostScript Prefilter-Script behoben werden, dann könnte /usr/lib/cups/filter/PsPrefilter wie folgt aussehen:

    #! /bin/bash
    # see http://localhost:631/spm.html#WRITING_FILTERS
    # debug info in /var/log/cups/error_log
    set -x
    # have the input at fd0 (stdin) in any case
    [ -n "$6" ] && exec <"$6"
    # prefiltering
    sed -e 's/Orientation: Landscape/Orientation: Portrait/'
    
    In den folgenden Schritten wird an diesem Beispiel demonstriert, wie wichtig gründliche Tests sind, damit durch das Korrekturscript nicht mehr Probleme im standardmässigen CUPS-Filtersystem entstehen, als gelöst werden.

  4. Das Filter-Script muss Eigentümer, Gruppe und Zugriffsrechte analog zu den anderen Filtern in /usr/lib/cups/filter/ haben.

  5. Der cupsd ist neu zu laden bzw. neu zu starten.

  6. Tests:

    Der letzte Test sollte einen fehlerhaften Ausdruck liefern, denn es sollte fälschlicherweise folgende Zeile im Ausdruck erscheinen
    sed -e 's/Orientation: Portrait/Orientation: Portrait/'
    
    Der Grund ist, dass die PostScript Ausgabe von /usr/lib/cups/filter/texttops die Zeichenfolge "Orientation: Landscape" aus /usr/lib/cups/filter/PsPrefilter enthält, die aber im folgenden Filterschritt mit eben diesem /usr/lib/cups/filter/PsPrefilter in die Zeichenfolge "Orientation: Portrait" umgewandelt wird, was dann auch so gedruckt wird.

  7. /usr/lib/cups/filter/PsPrefilter kann verbessert werden, indem die zu ersetztende Zeichenfolge möglichst genau angegeben wird:
    #! /bin/bash
    # see http://localhost:631/spm.html#WRITING_FILTERS
    # debug info in /var/log/cups/error_log
    set -x
    # have the input at fd0 (stdin) in any case
    [ -n "$6" ] && exec <"$6"
    # prefiltering
    sed -e 's/^%%Orientation: Landscape$/%%Orientation: Portrait/'
    

  8. Erneute Tests:

    Nun sollte sowohl der fehlgeschlagene Test oben, als auch

    echo '%%Orientation: Landscape' | a2ps -1 -r -o - | lp -d Warteschlange
    
    korrekt gedruckt werden, aber
    lp -d Warteschlange -o landscape /usr/lib/cups/filter/PsPrefilter
    
    wird bei CUPS Version 1.1.15 nicht im Landscape-Modus gedruckt, sondern im Portrait-Modus wobei aber der Text schon passend für den Landscape-Modus positioniert ist. Ab CUPS Version 1.1.18 funktioniert es korrekt.

    Der Grund für den fehlerhaften Ausdruck bei CUPS Version 1.1.15 ist, dass durch die Option -o landscape die Zeile
    %%Orientation: Landscape
    in der PostScript Ausgabe von /usr/lib/cups/filter/texttops steht, die den folgenden Filter /usr/lib/cups/filter/pstops veranlasst, die Darstellung um 90 Grad zu drehen, damit es im Landscape-Modus gedruckt wird.
    Durch /usr/lib/cups/filter/PsPrefilter wird aber genau das verhindert.

    Bei CUPS Version 1.1.18 wird statt des %%Orientation Eintrags die CUPS spezifische Zeile
    %cupsRotation: 90
    verwendet, um das CUPS Filtersystem zu einer Drehung der Darstellung um 90 Grad zu veranlassen.

  9. Erneute Verbesserung des Filters für CUPS Version 1.1.15

    Das Verhindern der 90 Grad Drehung muss bei CUPS Version 1.1.15 abhängig davon erfolgen, welches Programm die PostScript Daten erzeugt hat.
    Das erzeugende Programm steht normalerweise in der %%Creator Zeile wie z.B. bei /usr/lib/cups/filter/texttops, a2ps, NetScape und Mozilla:

    %%Creator: texttops/CUPS ...
    %%Creator: a2ps version ...
    %%Creator: Mozilla (NetScape) ...
    %%Creator: Mozilla PostScript module ...
    
    Dementsprechend kann /usr/lib/cups/filter/PsPrefilter verbessert werden, indem die 90 Grad Drehung nur in den bekannten Problemfällen verhindert wird und ansonsten bleiben die PostScript Daten unverändert:
    #! /bin/bash
    # see http://localhost:631/spm.html#WRITING_FILTERS
    # debug info in /var/log/cups/error_log
    set -x
    # have the input at fd0 (stdin) in any case
    [ -n "$6" ] && exec <"$6"
    # for simple testing with "egrep" have the input as regular file
    cleanup() { EXIT_CODE=$? ; rm -f $INPUT &>/dev/null ; exit $EXIT_CODE ; }
    trap 'cleanup' 0 1 2 3 15
    MY_NAME=${0##*/}
    INPUT=$( mktemp /var/spool/cups/tmp/$MY_NAME.XXXXXX ) || exit 1
    cat - >$INPUT
    # prefiltering only for particular PostScript "Creator" patterns
    if egrep -q '^%%Creator: a2ps|^%%Creator: Mozilla' $INPUT
    then sed -e 's/^%%Orientation: Landscape$/%%Orientation: Portrait/' $INPUT
         exit $?
    fi
    # otherwise no prefiltering
    cat $INPUT
    

  10. Abschliessende Tests:

    Analog zum Punkt 6. wird nun auch die Zeile "%%Creator: a2ps" getestet, um zu prüfen, dass das "sed" Kommando nicht fälschlicherweise ausgeführt wird, wenn /usr/lib/cups/filter/texttops die PostScript Daten erzeugt hat:

    echo -e '%%Orientation: Landscape\n%%Creator: a2ps' | lp -d Warteschlange
    
    echo -e '%%Orientation: Landscape\n%%Creator: a2ps' | lp -d Warteschlange -o landscape
    
    echo -e '%%Orientation: Landscape\n%%Creator: a2ps' | a2ps -1 -o - | lp -d Warteschlange
    
    echo -e '%%Orientation: Landscape\n%%Creator: a2ps' | a2ps -1 -r -o - | lp -d Warteschlange
    
    Ausdruck aus Netscape und Mozilla im Portrait-Modus und im Landscape-Modus
    
    Der Ausdruck aus Mozilla im Landscape-Modus funktioniert bei älteren Mozilla Versionen (z.B. bei Version 1.0) seitens Mozilla nicht, da die Auswahl "Landscape" nicht gespeichert wird - d.h. Mozilla erzeugt die Druckausgabe immer für den standardmässigen Portrait-Modus.

Einschränkungen

Sowohl der wahlweise PCL-Druck bei einem PostScript+PCL Drucker als auch die PostScript Vorverarbeitung bei einem PostScript Drucker sind keine Allheilmittel, um jegliches PostScript und/oder PDF Dokument zumindest irgendwie ausgedruckt zu bekommen.

In beiden Fällen muss zumindest Ghostscript das PostScript und/oder PDF Dokument verarbeiten können.
Wenn sowohl der PostScript-Interpreter im Drucker, als auch Ghostscript an dem Dokument scheitern, dann ist dieses Dokument in der Regel so kaputt, dass es keine Möglichkeit gibt, es zu Papier zu bringen.

Gelingt ein bestimmter Ausdruck aus einem Anwendungsprogramm nicht, so kann evtl. die PostScript-Ausgabe des Anwendungsprogramms nicht oder nicht vollständig vom Drucksystem verarbeitet werden.
Zum Test druckt man aus dem Anwendungsprogramm, was das problematische PostScript und/oder PDF Dokument erstellt hat, in eine PostScript-Datei bzw. man nimmt das schon vorhandene PostScript und/oder PDF Dokument, das dann unter der grafischen Oberfläche mit

gs -r60 Dateiname
Seite für Seite angezeigt werden kann.
Durch drücken der Eingabetaste im Terminalfenster wird die PostScript- bzw. PDF-Datei Seite für Seite angezeigt und das kann jederzeit mit der Tastenkombination [Strg]+[C] beendet werden.
Wird die PostScript- bzw. PDF-Datei nicht in einem zweiten Fenster korrekt dargestellt, oder erscheinen im Terminalfenster wo der gs-Befehl eingegeben wurde, Ghostscript-Fehlermeldungen, dann zeigt dies, dass die PostScript-Ausgabe des Anwendungsprogramms nicht von Ghostscript verarbeitet werden kann.
Manchmal passiert das nur bei speziellen Zeichen oder Schriften, die das Anwendungsprogramm nicht so in PostScript ausgibt, daß es von Ghostscript bzw. vom Drucker verarbeitet werden kann, aber ohne Verwendung dieser Zeichen oder Schriften würde es funktionieren - siehe z.B. den Supportdatenbank-Artikel "StarOffice 5.1a druckt manche Dokumente nicht" (http://sdb.suse.de/de/sdb/html/jsmeix_print-64-staroffice.html).

Stichwörter: DRUCKEN, DRUCKER, CUPS, FILTER, NADELDRUCKER, MATRIXDRUCKER, POSTSCRIPT, PDF, PCL, JCL, PJL

Kategorien: Fragen und Antworten , Dokumentation , Drucker

Feedback willkommen: Send Mail to jsmeix@suse.de (Geben Sie bitte folgendes Stichwort an: SDB-jsmeix_print-cups-filters)
SDB-jsmeix_print-cups-filters, Copyright SuSE Linux AG, Nürnberg, Germany - Version: 21. May 2003
SuSE Linux AG - Zuletzt generiert: 18. Jul 2003 von jsmeix (sdb_gen 1.40.0)