Initial commit, 3-52-19 alpha
[cls.git] / src / c / postscript.c
blob6ddbfb9a9e4a87bfff62524cc4775107aed160a3
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 */
7 /* system: */
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
18 ** implied warranty.
21 #include "xlisp.h"
23 LOCAL VOID putrlitem _((int rlitem));
24 LOCAL VOID putrlbuffer _((void));
25 LOCAL VOID putitem _((void));
27 #ifdef DODO
28 sample()
30 scale = 1.0;
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++ )
40 psputbit( 0 );
42 psputrest( );
44 #endif /* DODO */
46 /**************************************************************************/
47 /** **/
48 /** Global Variables **/
49 /** **/
50 /**************************************************************************/
52 static int item, bitsperitem, bitshift, rlitemsperline;
53 static int repeat, itembuf[128], count, repeatitem, repeatcount;
54 static FILE *fp;
56 /**************************************************************************/
57 /** **/
58 /** Public Interface **/
59 /** **/
60 /**************************************************************************/
62 /* set up global variables and print the postscript preamble */
63 psputinit(file, cols, rows, scale )
64 FILEP file;
65 int cols, rows;
66 double scale;
68 int scols, srows, left, bottom, top, right;
70 #ifdef FILETABLE
71 fp = filetab[file].fp;
72 #else
73 fp = file;
74 #endif
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 );
80 right = left + scols;
81 top = bottom + srows;
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);
86 fprintf(fp, "\n" );
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" );
101 fprintf(fp, "\n" );
102 fprintf(fp,
103 "%d %d translate\t%% move to lower left corner of box\n",
104 left, bottom );
105 fprintf(fp, "%d %d scale\t\t%% scale box\n", scols, srows );
106 fprintf(fp, "\n" );
107 fprintf(fp, "%d %d 1\t\t\t%% width height bits/sample\n", cols, rows );
108 fprintf(fp,
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" );
113 rlitemsperline = 0;
114 item = 0;
115 bitsperitem = 0;
116 bitshift = 7;
118 repeat = 1;
119 count = 0;
122 /* enter a bit into the image */
123 psputbit(b)
124 int b;
126 if ( bitsperitem == 8 ) {
127 putitem( );
129 if ( ! b )
130 item += 1 << bitshift;
131 bitsperitem++;
132 bitshift--;
135 /* clean up and print the showpage command */
136 psputrest( )
138 if ( bitsperitem > 0 )
139 putitem( );
140 if ( count > 0 )
141 putrlbuffer( );
142 fprintf(fp, "\nshowpage\n" );
145 /**************************************************************************/
146 /** **/
147 /** Internal Routines **/
148 /** **/
149 /**************************************************************************/
151 LOCAL VOID putrlitem( rlitem )
152 int rlitem;
154 if ( rlitemsperline == 30 ) {
155 putc('\n', fp);
156 rlitemsperline = 0;
158 rlitemsperline++;
159 fprintf(fp, "%02x", rlitem );
162 LOCAL VOID putrlbuffer( )
164 int i;
166 if ( repeat ) {
167 putrlitem( 256 - count );
168 putrlitem( repeatitem );
170 else {
171 putrlitem( count - 1 );
172 for ( i = 0; i < count; i++ )
173 putrlitem( itembuf[i] );
175 repeat = 1;
176 count = 0;
179 LOCAL VOID putitem( )
181 int i;
183 if ( count == 128 )
184 putrlbuffer( );
186 if ( repeat && count == 0 ) {
187 /* Still initializing a repeat buf. */
188 itembuf[count] = repeatitem = item;
189 count++;
191 else if ( repeat ) {
192 /* Repeating - watch for end of run. */
193 if ( item == repeatitem ) {
194 /* Run continues. */
195 itembuf[count] = item;
196 count++;
198 else {
199 /* Run ended - is it long enough to dump? */
200 if ( count > 2 ) {
201 /* Yes, dump a repeat-mode buffer and start a new one. */
202 putrlbuffer( );
203 itembuf[count] = repeatitem = item;
204 count++;
206 else {
207 /* Not long enough - convert to non-repeat mode. */
208 repeat = 0;
209 itembuf[count] = repeatitem = item;
210 count++;
211 repeatcount = 1;
215 else {
216 /* Not repeating - watch for a run worth repeating. */
217 if ( item == repeatitem ) {
218 /* Possible run continues. */
219 repeatcount++;
220 if ( repeatcount > 3 ) {
221 /* Long enough - dump non-repeat part and start repeat. */
222 count = count - ( repeatcount - 1 );
223 putrlbuffer( );
224 count = repeatcount;
225 for ( i = 0; i < count; i++ )
226 itembuf[i] = item;
228 else {
229 /* Not long enough yet - continue as non-repeat buf. */
230 itembuf[count] = item;
231 count++;
234 else {
235 /* Broken run. */
236 itembuf[count] = repeatitem = item;
237 count++;
238 repeatcount = 1;
242 item = 0;
243 bitsperitem = 0;
244 bitshift = 7;