1 /* postscript - XLISP-STAT postscript hard copy routines. */
2 /* XLISP-STAT 2.1 Copyright (c) 1990, by Luke Tierney */
3 /* Additions to Xlisp 2.1, Copyright (c) 1989 by David Michael Betz */
4 /* You may give out copies of this software; for conditions see the */
5 /* file COPYING included with this distribution. */
6 /* Postscript adapted from file pbmtops.c of Jef Poskanzer's pbm */
9 /* pbmtops.c - read a portable bitmap and produce a PostScript bitmap file
11 ** Copyright (C) 1988 by Jef Poskanzer.
13 ** Permission to use, copy, modify, and distribute this software and its
14 ** documentation for any purpose and without fee is hereby granted, provided
15 ** that the above copyright notice appear in all copies and that both that
16 ** copyright notice and this permission notice appear in supporting
17 ** documentation. This software is provided "as is" without express or
23 LOCAL VOID putrlitem
_((int rlitem
));
24 LOCAL VOID putrlbuffer
_((void));
25 LOCAL VOID putitem
_((void));
32 /* Compute padding to round cols up to the nearest multiple of 8. */
33 padright
= ( ( cols
+ 7 ) / 8 ) * 8 - cols
;
35 psputinit(file
, cols
, rows
, scale
);
36 for ( row
= 0; row
< rows
; row
++ ) {
37 for ( col
= 0; col
< cols
; col
++ )
38 psputbit( bits
[row
][col
] );
39 for ( col
= 0; col
< padright
; col
++ )
46 /**************************************************************************/
48 /** Global Variables **/
50 /**************************************************************************/
52 static int item
, bitsperitem
, bitshift
, rlitemsperline
;
53 static int repeat
, itembuf
[128], count
, repeatitem
, repeatcount
;
56 /**************************************************************************/
58 /** Public Interface **/
60 /**************************************************************************/
62 /* set up global variables and print the postscript preamble */
63 psputinit(file
, cols
, rows
, scale
)
68 int scols
, srows
, left
, bottom
, top
, right
;
71 fp
= filetab
[file
].fp
;
76 scols
= cols
* scale
* 0.96 + 0.5; /* 0.96 is the multiple of */
77 srows
= rows
* scale
* 0.96 + 0.5; /* 72/300 that is closest to 1 */
78 left
= 300 - ( scols
/2 );
79 bottom
= 400 - ( srows
/2 );
83 fprintf(fp
, "%%!PS\n");
84 fprintf(fp
, "%%%%Creator:XLISP-STAT postscript image\n");
85 fprintf(fp
, "%%%%BoundingBox: %d %d %d %d\n", left
, bottom
, right
, top
);
87 fprintf(fp
, "/rlestr1 1 string def\n" );
88 fprintf(fp
, "/rlestr 128 string def\n" );
89 fprintf(fp
, "/readrlestring {\n" );
90 fprintf(fp
, " currentfile rlestr1 readhexstring pop 0 get\n" );
91 fprintf(fp
, " dup 127 le {\n" );
92 fprintf(fp
, " currentfile rlestr 0 4 3 roll 1 add getinterval\n" );
93 fprintf(fp
, " readhexstring pop\n" );
94 fprintf(fp
, " } {\n" );
95 fprintf(fp
, " 256 exch sub dup\n" );
96 fprintf(fp
, " currentfile rlestr1 readhexstring pop 0 get\n" );
97 fprintf(fp
, " exch 0 exch 1 exch 1 sub { rlestr exch 2 index put } for\n" );
98 fprintf(fp
, " pop rlestr exch 0 exch getinterval\n" );
99 fprintf(fp
, " } ifelse\n" );
100 fprintf(fp
, "} bind def\n" );
103 "%d %d translate\t%% move to lower left corner of box\n",
105 fprintf(fp
, "%d %d scale\t\t%% scale box\n", scols
, srows
);
107 fprintf(fp
, "%d %d 1\t\t\t%% width height bits/sample\n", cols
, rows
);
109 "[ %d 0 0 -%d 0 %d ]\t%% transformation matrix\n", cols
, rows
, rows
);
110 fprintf(fp
, "{ readrlestring }\t%% proc\n" );
111 fprintf(fp
, "image\n" );
122 /* enter a bit into the image */
126 if ( bitsperitem
== 8 ) {
130 item
+= 1 << bitshift
;
135 /* clean up and print the showpage command */
138 if ( bitsperitem
> 0 )
142 fprintf(fp
, "\nshowpage\n" );
145 /**************************************************************************/
147 /** Internal Routines **/
149 /**************************************************************************/
151 LOCAL VOID
putrlitem( rlitem
)
154 if ( rlitemsperline
== 30 ) {
159 fprintf(fp
, "%02x", rlitem
);
162 LOCAL VOID
putrlbuffer( )
167 putrlitem( 256 - count
);
168 putrlitem( repeatitem
);
171 putrlitem( count
- 1 );
172 for ( i
= 0; i
< count
; i
++ )
173 putrlitem( itembuf
[i
] );
179 LOCAL VOID
putitem( )
186 if ( repeat
&& count
== 0 ) {
187 /* Still initializing a repeat buf. */
188 itembuf
[count
] = repeatitem
= item
;
192 /* Repeating - watch for end of run. */
193 if ( item
== repeatitem
) {
195 itembuf
[count
] = item
;
199 /* Run ended - is it long enough to dump? */
201 /* Yes, dump a repeat-mode buffer and start a new one. */
203 itembuf
[count
] = repeatitem
= item
;
207 /* Not long enough - convert to non-repeat mode. */
209 itembuf
[count
] = repeatitem
= item
;
216 /* Not repeating - watch for a run worth repeating. */
217 if ( item
== repeatitem
) {
218 /* Possible run continues. */
220 if ( repeatcount
> 3 ) {
221 /* Long enough - dump non-repeat part and start repeat. */
222 count
= count
- ( repeatcount
- 1 );
225 for ( i
= 0; i
< count
; i
++ )
229 /* Not long enough yet - continue as non-repeat buf. */
230 itembuf
[count
] = item
;
236 itembuf
[count
] = repeatitem
= item
;