/* postscript - XLISP-STAT postscript hard copy routines. */
/* XLISP-STAT 2.1 Copyright (c) 1990, by Luke Tierney */
/* Additions to Xlisp 2.1, Copyright (c) 1989 by David Michael Betz */
/* You may give out copies of this software; for conditions see the */
/* file COPYING included with this distribution. */
/* Postscript adapted from file pbmtops.c of Jef Poskanzer's pbm */
/* system: */
/* pbmtops.c - read a portable bitmap and produce a PostScript bitmap file
**
** Copyright (C) 1988 by Jef Poskanzer.
**
** Permission to use, copy, modify, and distribute this software and its
** documentation for any purpose and without fee is hereby granted, provided
** that the above copyright notice appear in all copies and that both that
** copyright notice and this permission notice appear in supporting
** documentation. This software is provided "as is" without express or
** implied warranty.
*/
#include "xlisp.h"
LOCAL VOID putrlitem _((int rlitem));
LOCAL VOID putrlbuffer _((void));
LOCAL VOID putitem _((void));
#ifdef DODO
sample()
{
scale = 1.0;
/* Compute padding to round cols up to the nearest multiple of 8. */
padright = ( ( cols + 7 ) / 8 ) * 8 - cols;
psputinit(file, cols, rows, scale );
for ( row = 0; row < rows; row++ ) {
for ( col = 0; col < cols; col++ )
psputbit( bits[row][col] );
for ( col = 0; col < padright; col++ )
psputbit( 0 );
}
psputrest( );
}
#endif /* DODO */
/**************************************************************************/
/** **/
/** Global Variables **/
/** **/
/**************************************************************************/
static int item, bitsperitem, bitshift, rlitemsperline;
static int repeat, itembuf[128], count, repeatitem, repeatcount;
static FILE *fp;
/**************************************************************************/
/** **/
/** Public Interface **/
/** **/
/**************************************************************************/
/* set up global variables and print the postscript preamble */
psputinit(file, cols, rows, scale )
FILEP file;
int cols, rows;
double scale;
{
int scols, srows, left, bottom, top, right;
#ifdef FILETABLE
fp = filetab[file].fp;
#else
fp = file;
#endif
scols = cols * scale * 0.96 + 0.5; /* 0.96 is the multiple of */
srows = rows * scale * 0.96 + 0.5; /* 72/300 that is closest to 1 */
left = 300 - ( scols/2 );
bottom = 400 - ( srows/2 );
right = left + scols;
top = bottom + srows;
fprintf(fp, "%%!PS\n");
fprintf(fp, "%%%%Creator:XLISP-STAT postscript image\n");
fprintf(fp, "%%%%BoundingBox: %d %d %d %d\n", left, bottom, right, top);
fprintf(fp, "\n" );
fprintf(fp, "/rlestr1 1 string def\n" );
fprintf(fp, "/rlestr 128 string def\n" );
fprintf(fp, "/readrlestring {\n" );
fprintf(fp, " currentfile rlestr1 readhexstring pop 0 get\n" );
fprintf(fp, " dup 127 le {\n" );
fprintf(fp, " currentfile rlestr 0 4 3 roll 1 add getinterval\n" );
fprintf(fp, " readhexstring pop\n" );
fprintf(fp, " } {\n" );
fprintf(fp, " 256 exch sub dup\n" );
fprintf(fp, " currentfile rlestr1 readhexstring pop 0 get\n" );
fprintf(fp, " exch 0 exch 1 exch 1 sub { rlestr exch 2 index put } for\n" );
fprintf(fp, " pop rlestr exch 0 exch getinterval\n" );
fprintf(fp, " } ifelse\n" );
fprintf(fp, "} bind def\n" );
fprintf(fp, "\n" );
fprintf(fp,
"%d %d translate\t%% move to lower left corner of box\n",
left, bottom );
fprintf(fp, "%d %d scale\t\t%% scale box\n", scols, srows );
fprintf(fp, "\n" );
fprintf(fp, "%d %d 1\t\t\t%% width height bits/sample\n", cols, rows );
fprintf(fp,
"[ %d 0 0 -%d 0 %d ]\t%% transformation matrix\n", cols, rows, rows );
fprintf(fp, "{ readrlestring }\t%% proc\n" );
fprintf(fp, "image\n" );
rlitemsperline = 0;
item = 0;
bitsperitem = 0;
bitshift = 7;
repeat = 1;
count = 0;
}
/* enter a bit into the image */
psputbit(b)
int b;
{
if ( bitsperitem == 8 ) {
putitem( );
}
if ( ! b )
item += 1 << bitshift;
bitsperitem++;
bitshift--;
}
/* clean up and print the showpage command */
psputrest( )
{
if ( bitsperitem > 0 )
putitem( );
if ( count > 0 )
putrlbuffer( );
fprintf(fp, "\nshowpage\n" );
}
/**************************************************************************/
/** **/
/** Internal Routines **/
/** **/
/**************************************************************************/
LOCAL VOID putrlitem( rlitem )
int rlitem;
{
if ( rlitemsperline == 30 ) {
putc('\n', fp);
rlitemsperline = 0;
}
rlitemsperline++;
fprintf(fp, "%02x", rlitem );
}
LOCAL VOID putrlbuffer( )
{
int i;
if ( repeat ) {
putrlitem( 256 - count );
putrlitem( repeatitem );
}
else {
putrlitem( count - 1 );
for ( i = 0; i < count; i++ )
putrlitem( itembuf[i] );
}
repeat = 1;
count = 0;
}
LOCAL VOID putitem( )
{
int i;
if ( count == 128 )
putrlbuffer( );
if ( repeat && count == 0 ) {
/* Still initializing a repeat buf. */
itembuf[count] = repeatitem = item;
count++;
}
else if ( repeat ) {
/* Repeating - watch for end of run. */
if ( item == repeatitem ) {
/* Run continues. */
itembuf[count] = item;
count++;
}
else {
/* Run ended - is it long enough to dump? */
if ( count > 2 ) {
/* Yes, dump a repeat-mode buffer and start a new one. */
putrlbuffer( );
itembuf[count] = repeatitem = item;
count++;
}
else {
/* Not long enough - convert to non-repeat mode. */
repeat = 0;
itembuf[count] = repeatitem = item;
count++;
repeatcount = 1;
}
}
}
else {
/* Not repeating - watch for a run worth repeating. */
if ( item == repeatitem ) {
/* Possible run continues. */
repeatcount++;
if ( repeatcount > 3 ) {
/* Long enough - dump non-repeat part and start repeat. */
count = count - ( repeatcount - 1 );
putrlbuffer( );
count = repeatcount;
for ( i = 0; i < count; i++ )
itembuf[i] = item;
}
else {
/* Not long enough yet - continue as non-repeat buf. */
itembuf[count] = item;
count++;
}
}
else {
/* Broken run. */
itembuf[count] = repeatitem = item;
count++;
repeatcount = 1;
}
}
item = 0;
bitsperitem = 0;
bitshift = 7;
}
syntax highlighted by Code2HTML, v. 0.9.1