Der JavaScript-PostScript-Filter Zu den JavaScript-Seiten

Hier PS-Text einfügen:

Ergebnis:

Report:

How to...

Das is' 'n Ding. Ein PostScript-Filter in JavaScript. Der Filter braucht aber einige Vorraussetzungen, um zu funktionieren.

  1. Der PostScript-Text muss mit dem Adobe Universal PostSript-Druckertreiber Version 5.2 erzeugt worden sein.
    Der Installer für den Druckertreiber für Windows XP lässt sich auf den Adobe-Web-Seiten runterladen. Die folgende Google-Suche sollte Erfolg bringen: Link für Google-Suche.

  2. Bei der Installation kann man erst mal den Default-Drucker von Adobe auswählen oder eine andere PPD-Datei, die man gerade zur Verfügung hat.

    Für den eigentlichen Druck sollte man dann z. B. den Apple Laserwriter oder einen ähnlich kompatiblen Drucker installieren. Dazu nutzt man die normalen Druckerinstallationsdialoge von Windows (die SimplePrinterDesription-Dateien nutzen), wenn man keine passenden PPD-Dateien hat.

    Für farbige Ausdrucke sind Distiller.PPDs gut geeignet.

  3. Bei der Druckerauswahl im Windows-Druckdialog stellt man in den erweiterten Einstellungen am Besten auf die PostScript-Optionen:
    • PostScript-Ausgabeoptionen: Portabiltität optimieren
    • PostScript-Sprachebene: 1
    • TrueType-Downloadoptionen: Umriss (oder Automatisch)
    • Bitmaps komprimieren: Nein (Bitmaps werden eh nicht untestützt)
  4. Anschließend druckt man dann in eine Datei, wenn der Drucker nicht sowieso an FILE angeschlossen ist.

    Die erstellte Datei müsste etwa so beginnen:

    %!PS-Adobe-3.0
    %%Title: ...
    %%Creator: PScript5.dll Version 5.2.2
    ...

    Das %!PS-Adobe-3.0 wird am Anfang der Konvertierung überprüft. Wenn die Zeichenfolge nicht vorhanden ist, läuft der Filter nicht! Ebenso ist das mit den Zeichenfolgen %%Page: 1 und /mysetup.

    Wichtig: Eine PostScript-Datei die nicht "ab Werk" diese Passagen enthält kann mit dem JavaScript-PostScript-Filter nicht funktionieren!

    Das Creator-Kommentar PScript5.dll Version 5.2 ist für das Funktionieren des Filters wichtig, wird im Filter aber nicht ausgewertet.

  5. Den erhaltenen PostScript-Text kann man dann in das obige Formularfeld mit der Beschriftung Hier PS-Text einfügen: reinkopieren.

    Anschließend muss man nur noch auf den Schalter Übersetzen klicken, der sich gleich unter dem Formularfeld befindet.

    Je nach Länge der PostScript-Daten ist der Filter dann einige Zeit beschäftigt. Falls Fehler auftreten geht's schneller ;)

    Der übersetzte Text erscheint dann im Ergebnisfeld. Von dort kann man ihn in die Zwischenablage kopieren und von dort wiederum in IsoPad zur Begutachtung einfügen.

    Schwupps - schon isses fertig :)

Fallstricke und Rettungsanker

Die Idee, an die Grafikdaten einer Anwendung über die Druckerausgabe zu kommen, klingt zwar sehr universell, gerade bei PostScript-Ausgaben gibt es allerdings einige Spezialfälle zu beachten.

Die Grafikspeziallisten unter den Computerprogrammen lieben es, beim Drucken exzessiv das Passthrought-Feature zu nutzen. Das heißt, dass nicht der Druckertreiber den PS-Text erzeugt, sondern das druckende Programm seinen optimierten Druckcode vom Druckertreiber nur bis zur Datei durchschleusen lässt. Programme wie Illustrator, PDF-Reader, Coreldraw und andere Grafikprogramme machen das so.

Programme wie Mircosoft Word oder OpenOffice-Writer hingegen drucken, wie es sich gehört und erzeugen in der Regel gut verwertbare PostScript-Dateien. So bleibt immer die Möglichkeit mit einem Grafikprogramm eine Vektorgrafik zu erzeugen, diese von einem Textverarbeitungsprogramm interpretierend einzulesen (keine EPS-Dateien) und sie dann von dort zu drucken.

Im Zeifelsfall hilft ein Blick in den PS-Kode. Mit ein bisschen Übung, sieht man schnell woran's eventuell grundsätzlich hapert.

 

Einige Anmerkungen für eigene Experimente

Wer selber ein bisschen mit dem Filter rumprobieren will, sollte als erstes die Fehlermeldungen wieder einschalten, indem er den großen try-catch-Block in der Funktion PS_Trace () ausschaltet.

Das Report-Feld fürs Debugging wird aus dem JavaScript mittels der Funktionen Report () und ReportLF () angesprochen. Wer mag, darf aber auch das beliebte alert () benutzen.

Der Test-Schalter unter dem Report-Feld ruft die Funktion Test (), in der mehr oder weniger nützliche Tests ablaufen, deren Ergebnisse - je nach dem - in das Report-Feld geschrieben werden können.

Die koordinatorische Hauptarbeit des Filters leistet die Funktion PS_Trace (). Sie holt mit Hilfe der Klasse Tokenizer die PostScript-Anweisungen aus dem Text und entscheidet anhand der bekannten Befehle, was mit der Anweisung zu geschehen hat (deshalb muss die PS-Datei vom Adobe Druckertreiber sein). Einige Anweisungen bewirken die Ausgabe von Linien, andere werden erstmal auf den Stack befördert, eine der nächsten holt sie dann wieder vom Stack und so weiter.

Weitere Klassen sind:

  • Path für die Verwaltung der XY-Koordinaten der Linien und Kurven,
  • Font, Fonts für die Schriften und das Character-Encoding,
  • Matrix für die Tranformationsmatrizen der ganzen Grafik und der Schriftenskalierung,
  • GraphicState für die Zustandsermittung der Grafikmaschine,
  • IsoPad für die IsoPad-Grafikausgabe.

Da der Filter kein echter PostScript-Interpreter ist, verzichtet er auf die Analyse der PostScript-Dictionaries und implementiert nur die Funktionen, die zum Erhalt der Linien- und Text-Informationen notwendig sind. Deshalb kann es passieren, dass in einer PS-Datei Anweisungen auftauchen, die im Filter nicht interpretiert werden.

Will man diese Anweisungen einbauen, muss man in der Funktion PS_Trace () die jeweiligen Erweiterungen kodieren.

Der JavaScript-PostScript-Filter kann mit relativ wenig Aufwand auch andere Ausgaben erzeugen. Naheliegend sind natürlich nicht-binäre Formate z. B. SVG, DXF o. Ä.
Ich würde mich freuen von solchen Aktivitäten zu hören und die Ergebnisse mal in Augenschein nehmen zu können.

Ach ja ...
Der JavaScript-PostScript-Filter darf frei kopiert werden. Wer ihn im Original oder weiterentwickelt in einem kommerziellen oder nichtkommerziellen Paket verwertet, muss den Filterteil auch wieder frei weitergeben und darf für den Filterteil keine einschränkenden Lizenzbedingungen formulieren. Falls jemand den Filter in eine Compiler-Sprache umschreibt wäre eine Erwähnung des Originals angebracht.

 

Der Beispiel-PS-Text

An einigen Stellen wurde Text ausgelassen, der vom Filter eh nicht interpretiert wird. Die Stellen sind mit % ... gekennzeichnet. Ein paar Textobjekte wurden zusammengefasst.

%!PS-Adobe-3.0
%%Title: Microsoft Word - Grafik und Text.doc
%%Creator: PScript5.dll Version 5.2.2
% ...
/mysetup [ 72 600 V 0 0 -72 600 V 0 842.0003 ] def 
% ...
%%Page: 1 1
%%PageBoundingBox: 0 0 595 842
%%EndPageComments
userdict begin /pagesave save def end
%%BeginPageSetup
/DeviceRGB dup setcolorspace /colspABC exch def
mysetup concat colspRefresh
%%EndPageSetup

userdict begin /VMsave save def end
0 0 0 1 scol 49464 VM?
% ...
F /F0 0 /0 T /Times-Roman mF 
/F0S53 F0 [83 0 0 -83 0 0 ] mFS
F0S53 Ji 
590 664 M (Ein )S  727 664 M (paar )S  892 664 M (Tests )S  1088 664 M (für )S  1206 664 M (den )S
1348 664 M (Filter.)S
43166 VM?

%%BeginResource: font Helvetica
% ...
%%EndResource

F /F1 0 /0 T /Helvetica mF 
/F1S96 F1 [150 0 0 -150 0 0 ] mFS
F1S96 Ji 
590 1882 M (So, )S  
43914 VM?

%%BeginResource: font Helvetica-Bold
% ...
%%EndResource

F /F2 0 /0 T /Helvetica-Bold mF 
/F2S96 F2 [150 0 0 -150 0 0 ] mFS
F2S96 Ji 
857 1882 M (das)S  
F1S96 Ji 
1115 1882 M ( )S 
1157 1882 M (w)S  1265 1882 M (a)S  1348 1882 M (r)S  1398 1882 M (')S  1427 1882 M (s)S  1502 1882 M ( )S  
57080 VM?

%%BeginResource: font Helvetica-Oblique
% ...
%%EndResource

F /F3 0 /0 T /Helvetica-Oblique mF 
/F3S96 F3 [150 0 0 -150 0 0 ] mFS
F3S96 Ji 
1544 1882 M (a)S 
1627 1882 M (u)S  1710 1882 M (c)S  1785 1882 M (h)S  
F1S96 Ji 
1868 1882 M ( )S 
1910 1882 M (schon.)S  
1 0 0 1 scol 1 Lj 0 Lc 8 Lw solid N 600 1080 M 1020 780 I K 
0.602 0.801 0 1 scol 17 Lw N 1020 780 M 1380 1080 I K 
0 0 1 1 scol 25 Lw [ 100 75 50 75 ] 0 sd N 1380 1080 M 900 1380 I K 
1 0 1 1 scol 33 Lw solid N 900 1380 M 1500 1560 I K 
0 0 1 1 scol 1 Lc 25 Lw N 2520 1230 M 2520 1047 2345 900 2130 900 -c 1914 900 1740 1047 1740 1230 -c 1740 1412 1914 1560 2130 1560 -c 2345 1560 2520 1412 2520 1230 -c C 
: 1 0 0 1 scol  O ; K 
LH
VMsave restore
pagesave restore
(%%[Page: 1]%%) = 
%%PageTrailer

%%Trailer
%%BoundingBox: 0 0 595 842
%%DocumentNeededResources: 
%%DocumentSuppliedResources: 
%%+ procset Pscript_WinNT_VMErrorHandler 5.0 0
%%+ procset Pscript_FatalError 5.0 0
%%+ procset Pscript_Win_Basic 5.0 0
%%+ procset Pscript_Win_Utils_L1 5.0 0
%%+ procset Pscript_Text 5.0 0
%%+ procset Pscript_TextFE 5.0 0
%%+ procset Pscript_TextV 5.0 0
%%+ procset Pscript_TextBold 5.0 0
%%+ procset Pscript_Win_GdiObject 5.0 0
%%+ procset Pscript_Win_GdiObject_L1 5.0 0
%%+ procset Pscript_Win_Dib_L1 5.0 0
%%+ procset Pscript_T42Hdr 5.0 0
%%+ procset Pscript_T3Hdr 5.0 0
%%+ procset Pscript_Nup 5.0 0
%%+ procset Pscript_Encoding0 5.0 0
%%+ procset Pscript_Encoding161 5.0 0
%%+ procset Pscript_Encoding162 5.0 0
%%+ procset Pscript_Encoding177 5.0 0
%%+ procset Pscript_Encoding178 5.0 0
%%+ procset Pscript_Encoding186 5.0 0
%%+ procset Pscript_Encoding204 5.0 0
%%+ procset Pscript_Encoding238 5.0 0
%%+ procset Pscript_Encoding256 5.0 0
%%+ procset Pscript_Encoding257 5.0 0
%%+ procset Pscript_WinNT_Compat 5.0 0
%%+ font Times-Roman
%%+ font Helvetica
%%+ font Helvetica-Bold
%%+ font Helvetica-Oblique
/Pscript_WinNT_Full /ProcSet findresource dup /terminate get exec
Pscript_WinNT_Compat dup /terminate get exec
%%Pages: 1
(%%[LastPage]%%) = 
%%EOF

 

Die Todo-Liste und Sonstiges

Es gibt noch einige Sachen zu tun. Z. B. könnten die Text noch rotiert werden u. Ä.

Falls jemand Fehler findet, würde ich mich über eine Nachricht mit Fehlerbeschreibung freuen.

Zu den JavaScript-Seiten | Homepage | EMail an Thilo Brai.

<< JavaScript-Grafik | Längen umrechnen >>