OSTRACISM CO.

Ghostscript 5.1を使ったプリンタサーバ


 Netatalkを使ってファイル共有に加え、一応プリンタサーバにしている。しかし、我が家のプリンタはPostScriptじゃなくPCL5(HP LaserJet 4PJ)なのである。そこでGhostscript 5.1を使ってPostScriptプリンタのフリをさせている。
 クライアント(MacOS X)側のPPDファイルはLaserJet 4Mを使用。

/etc/printcap
----------
ljet4ps:sh:lp=/dev/lp0:\
        :sd=/var/spool/lpd/:\
        :lf=/var/log/lpd-errs:\
        :if=/usr/local/lib/ps2ljet4:
----------

/usr/local/lib/ps2ljet4
----------
#!/bin/sh
PATH="/bin:/usr/bin"; export PATH

IF=/var/tmp/ps2ljet4.$$.ps
OF=/var/tmp/ps2ljet4.$$.ljet4

/usr/local/lib/fixpsbracket > $IF || exit 2
##cat > $IF || exit 2
{ echo quit; } | \
/usr/local/bin/gs -q -dSAFER -dNOPAUSE -sDEVICE=ljet4 -sOutputFile=$OF $IF 2>/dev/null >/var/log/gslog || exit 2
cat $OF || exit 2

rm $IF
rm $OF
exit 0
----------

 問題は日本語版Acrobat Reader 4以降の出力するPostScriptで、エラーがでて印刷されないのだ。
 エラーログを追いかけると、%%BeginDataと%%EndDataに挟まれたデータ領域で、閉じる括弧だけがこつぜんと現れることに問題がある。
 しかたがないので、その括弧を消すプログラムを書いた。上記ps2ljet4で、catだけで良い部分がfixpsbracketになっている。

fixpsbracket.c
----------
/*
    PostScriptデータのうち
    %%BeginDataと%%EndDataに囲まれたデータ中の
    対応しない括弧('>')を消去するプログラム。

    2002.09.19 
    OSTRA / Takeshi Yoneki
*/

#include <stdio.h>

#define BUFFER_MAX          32000
#define BUFFER_HALF         16000

#define MODE_NORMAL         0
#define MODE_DATA           1

char buffer[BUFFER_MAX];
char *buff1;
char *buff2;

int readBuff2(long *count)
{
    long i;
    int done = 0;
    *count = 0;
    memset(buff2, 0, BUFFER_HALF);
    for (i = 0; i < BUFFER_HALF; i++)
    {
        int data = getchar();
        if (data == EOF)
        {
            done = 1;
            break;
        }
        buff2[i] = (char)data;
        *count = i + 1;
    }
    return done;
}

int equalString(char *s, char *buf, int count)
{
    int i;
    for (i = 0; i < count; i++)
    {
        if (s[i] != buf[i])
            return 0;
    }
    return 1;
}

main()
{
    long pos = 0;
    long rest = 0;
    int bReadAll = 0;
    long prevRead;
    int mode = MODE_NORMAL;
    int kakko = 0;

    buff1 = buffer;
    buff2 = &buffer[BUFFER_HALF];

    bReadAll = readBuff2(&prevRead);
    for (; prevRead > 0;)
    {
        memcpy(buff1, buff2, BUFFER_HALF);
        memset(buff2, 0, BUFFER_HALF);
        rest = prevRead;
        if (bReadAll == 0)
        {
            bReadAll = readBuff2(&prevRead);
            rest += prevRead;
        }
        else
            prevRead = 0;

        for (pos = 0; pos < BUFFER_HALF && pos < rest; pos++)
        {
            if (mode == MODE_NORMAL)
            {
                if (equalString("%%BeginData", &buff1[pos], 11))
                    mode = MODE_DATA;
            }
            else
            {
                if (equalString("%%EndData", &buff1[pos], 9))
                    mode = MODE_NORMAL;
            }

            if (mode == MODE_DATA)
            {
                if (buff1[pos] == '>')
                    kakko++;
                if (buff1[pos] == '<')
                    kakko--;
            }

            if (kakko < 0)
                kakko = 0;
            else
                putchar(buff1[pos]);
        }
    }

    exit(0);
}
----------

 しばらくこれで様子をみる。

2002.09.27
追記

 サーバをリプレースしてLinuxをSlackware 8.1にしたらGhostscript 7.05が入っていたので、試しに上記プログラムfixpsbracketを使わずにPDFを印刷したら、なにげなく印刷できた。
 そんなわけで、fixpsbracketは不要なプログラムとなった。

2002.10.08
「ホーム」へ戻る
OSTRACISM CO.
OSTRA / Takeshi Yoneki