xref: /plan9-contrib/sys/src/cmd/postscript/p9bitpost/pslib.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
1*7dd7cddfSDavid du Colombier #include <u.h>
2*7dd7cddfSDavid du Colombier #include <libc.h>
3*7dd7cddfSDavid du Colombier #include <draw.h>
4*7dd7cddfSDavid du Colombier #include <memdraw.h>
5*7dd7cddfSDavid du Colombier #include <bio.h>
6*7dd7cddfSDavid du Colombier #include "pslib.h"
7*7dd7cddfSDavid du Colombier /* implement PsLib;
8*7dd7cddfSDavid du Colombier /*
9*7dd7cddfSDavid du Colombier /* include "sys.m";
10*7dd7cddfSDavid du Colombier /* 	sys: Sys;
11*7dd7cddfSDavid du Colombier /*
12*7dd7cddfSDavid du Colombier /* include "draw.m";
13*7dd7cddfSDavid du Colombier /* 	draw : Draw;
14*7dd7cddfSDavid du Colombier /* Image, Display,Rect,Point : import draw;
15*7dd7cddfSDavid du Colombier /*
16*7dd7cddfSDavid du Colombier /* include "bufio.m";
17*7dd7cddfSDavid du Colombier /* 	bufmod : Bufio;
18*7dd7cddfSDavid du Colombier /*
19*7dd7cddfSDavid du Colombier /* include "tk.m";
20*7dd7cddfSDavid du Colombier /* 	tk: Tk;
21*7dd7cddfSDavid du Colombier /* 	Toplevel: import tk;
22*7dd7cddfSDavid du Colombier /*
23*7dd7cddfSDavid du Colombier /* Iobuf : import bufmod;
24*7dd7cddfSDavid du Colombier /*
25*7dd7cddfSDavid du Colombier /* include "string.m";
26*7dd7cddfSDavid du Colombier /* 	str : String;
27*7dd7cddfSDavid du Colombier /*
28*7dd7cddfSDavid du Colombier /* include "daytime.m";
29*7dd7cddfSDavid du Colombier /* 	time : Daytime;
30*7dd7cddfSDavid du Colombier /*
31*7dd7cddfSDavid du Colombier /* include "pslib.m";
32*7dd7cddfSDavid du Colombier /*
33*7dd7cddfSDavid du Colombier /* ASCII,RUNE,IMAGE : con iota;
34*7dd7cddfSDavid du Colombier /*
35*7dd7cddfSDavid du Colombier */
36*7dd7cddfSDavid du Colombier struct iteminfo {
37*7dd7cddfSDavid du Colombier 	int itype;
38*7dd7cddfSDavid du Colombier 	int offset;		/* offset from the start of line. */
39*7dd7cddfSDavid du Colombier 	int width;		/* width.... */
40*7dd7cddfSDavid du Colombier 	int ascent;		/* ascent of the item */
41*7dd7cddfSDavid du Colombier 	int font;		/* font */
42*7dd7cddfSDavid du Colombier 	int line;		/* line its on */
43*7dd7cddfSDavid du Colombier 	char *buf;
44*7dd7cddfSDavid du Colombier };
45*7dd7cddfSDavid du Colombier 
46*7dd7cddfSDavid du Colombier struct lineinfo {
47*7dd7cddfSDavid du Colombier 	int xorg;
48*7dd7cddfSDavid du Colombier 	int yorg;
49*7dd7cddfSDavid du Colombier 	int width;
50*7dd7cddfSDavid du Colombier 	int height;
51*7dd7cddfSDavid du Colombier 	int ascent;
52*7dd7cddfSDavid du Colombier };
53*7dd7cddfSDavid du Colombier 
54*7dd7cddfSDavid du Colombier 
55*7dd7cddfSDavid du Colombier /* font_arr := array[256] of {* => (-1,"")};
56*7dd7cddfSDavid du Colombier /* remap := array[20] of (string,string);
57*7dd7cddfSDavid du Colombier /*
58*7dd7cddfSDavid du Colombier /* PXPI : con 100;
59*7dd7cddfSDavid du Colombier /* PTPI : con 100;
60*7dd7cddfSDavid du Colombier /*
61*7dd7cddfSDavid du Colombier */
62*7dd7cddfSDavid du Colombier char *noinit = "pslib not properly initialized";
63*7dd7cddfSDavid du Colombier /*
64*7dd7cddfSDavid du Colombier */
65*7dd7cddfSDavid du Colombier static int boxes;
66*7dd7cddfSDavid du Colombier static int debug;
67*7dd7cddfSDavid du Colombier static int totitems;
68*7dd7cddfSDavid du Colombier static int totlines;
69*7dd7cddfSDavid du Colombier static int curfont;
70*7dd7cddfSDavid du Colombier static char *def_font;
71*7dd7cddfSDavid du Colombier static int def_font_type;
72*7dd7cddfSDavid du Colombier static int curfonttype;
73*7dd7cddfSDavid du Colombier static int pagestart;
74*7dd7cddfSDavid du Colombier static int started;
75*7dd7cddfSDavid du Colombier 
76*7dd7cddfSDavid du Colombier static int bps;
77*7dd7cddfSDavid du Colombier static int width;
78*7dd7cddfSDavid du Colombier static int height;
79*7dd7cddfSDavid du Colombier static int iwidth;
80*7dd7cddfSDavid du Colombier static int iheight;
81*7dd7cddfSDavid du Colombier static int xstart;
82*7dd7cddfSDavid du Colombier static int ystart;
83*7dd7cddfSDavid du Colombier static double xmagnification = 1.0, ymagnification = 1.0;
84*7dd7cddfSDavid du Colombier static int rotation = 0;
85*7dd7cddfSDavid du Colombier static int landscape = 0;
86*7dd7cddfSDavid du Colombier static char *Patch = nil;
87*7dd7cddfSDavid du Colombier 
88*7dd7cddfSDavid du Colombier /* ctxt 		: ref Draw->Context;
89*7dd7cddfSDavid du Colombier /* t 		: ref Toplevel;
90*7dd7cddfSDavid du Colombier */
91*7dd7cddfSDavid du Colombier char*
92*7dd7cddfSDavid du Colombier psinit(int box, int deb) { /* d: ref Toplevel, */
93*7dd7cddfSDavid du Colombier /* 	t=d; */
94*7dd7cddfSDavid du Colombier 	debug = deb;
95*7dd7cddfSDavid du Colombier 	totlines=0;
96*7dd7cddfSDavid du Colombier 	totitems=0;
97*7dd7cddfSDavid du Colombier 	pagestart=0;
98*7dd7cddfSDavid du Colombier 	boxes=box; /* #box; */
99*7dd7cddfSDavid du Colombier 	curfont=0;
100*7dd7cddfSDavid du Colombier /* 	e := loadfonts();
101*7dd7cddfSDavid du Colombier /* 	if (e != "")
102*7dd7cddfSDavid du Colombier /* 		return e;
103*7dd7cddfSDavid du Colombier */
104*7dd7cddfSDavid du Colombier 	started=1;
105*7dd7cddfSDavid du Colombier 	return "";
106*7dd7cddfSDavid du Colombier }
107*7dd7cddfSDavid du Colombier 
108*7dd7cddfSDavid du Colombier /* stats() : (int,int,int)
109*7dd7cddfSDavid du Colombier /* {
110*7dd7cddfSDavid du Colombier /* 	return 	(totitems,totlines,curfont);
111*7dd7cddfSDavid du Colombier /* }
112*7dd7cddfSDavid du Colombier /*
113*7dd7cddfSDavid du Colombier /* loadfonts() : string
114*7dd7cddfSDavid du Colombier /* {
115*7dd7cddfSDavid du Colombier /* 	input : string;
116*7dd7cddfSDavid du Colombier /* 	iob:=bufmod->open("/fonts/psrename",bufmod->OREAD);
117*7dd7cddfSDavid du Colombier /* 	if (iob==nil)
118*7dd7cddfSDavid du Colombier /* 		return sys->sprint("can't open /fonts/psrename: %r");
119*7dd7cddfSDavid du Colombier /* 	i:=0;
120*7dd7cddfSDavid du Colombier /* 	while((input=iob.gets('\n'))!=nil){
121*7dd7cddfSDavid du Colombier /* 		(tkfont,psfont):=str->splitl(input," ");
122*7dd7cddfSDavid du Colombier /* 		psfont=psfont[1:len psfont -1];
123*7dd7cddfSDavid du Colombier /* 		remap[i]=(tkfont,psfont);
124*7dd7cddfSDavid du Colombier /* 		i++;
125*7dd7cddfSDavid du Colombier /* 	}
126*7dd7cddfSDavid du Colombier /* 	return "";
127*7dd7cddfSDavid du Colombier /* }
128*7dd7cddfSDavid du Colombier /*
129*7dd7cddfSDavid du Colombier */
130*7dd7cddfSDavid du Colombier static char *username;
131*7dd7cddfSDavid du Colombier 
132*7dd7cddfSDavid du Colombier int
133*7dd7cddfSDavid du Colombier preamble(Biobuf *ioutb, Rectangle bb) {
134*7dd7cddfSDavid du Colombier 
135*7dd7cddfSDavid du Colombier 	if (!started) return 1;
136*7dd7cddfSDavid du Colombier 	username = getuser();
137*7dd7cddfSDavid du Colombier 	if(bb.max.x == 0 && bb.max.y == 0) {
138*7dd7cddfSDavid du Colombier 		bb.max.x = 612;
139*7dd7cddfSDavid du Colombier 		bb.max.y = 792;
140*7dd7cddfSDavid du Colombier 	}
141*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "%%!PS-Adobe-3.0\n");
142*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "%%%%Creator: PsLib 1.0 (%s)\n",username);
143*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "%%%%CreationDate: %s", ctime(time(nil)));
144*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "%%%%Pages: (atend) \n");
145*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "%%%%BoundingBox: %d %d %d %d\n", bb.min.x, bb.min.y, bb.max.x, bb.max.y);
146*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "%%%%EndComments\n");
147*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "%%%%BeginProlog\n");
148*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "/doimage {\n");
149*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "/grey exch def\n");
150*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "/bps exch def\n");
151*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "/width exch def\n");
152*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "/height exch def\n");
153*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "/xstart exch def\n");
154*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "/ystart exch def\n");
155*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "/iwidth exch def\n");
156*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "/ascent exch def\n");
157*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "/iheight exch def\n");
158*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "gsave\n");
159*7dd7cddfSDavid du Colombier 	if(boxes)
160*7dd7cddfSDavid du Colombier 		Bprint(ioutb, "xstart ystart iwidth iheight rectstroke\n");
161*7dd7cddfSDavid du Colombier /*	# if bps==8, use inferno colormap; else (bps < 8) it's grayscale or true color */
162*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "bps 8 eq grey false eq and {\n");
163*7dd7cddfSDavid du Colombier 	Bprint(ioutb, " [/Indexed /DeviceRGB 255 <\n");
164*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "  ffffff ffffaa ffff55 ffff00 ffaaff ffaaaa ffaa55 ffaa00 ff55ff ff55aa ff5555 ff5500\n");
165*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "  ff00ff ff00aa ff0055 ff0000 ee0000 eeeeee eeee9e eeee4f eeee00 ee9eee ee9e9e ee9e4f\n");
166*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "  ee9e00 ee4fee ee4f9e ee4f4f ee4f00 ee00ee ee009e ee004f dd0049 dd0000 dddddd dddd93\n");
167*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "  dddd49 dddd00 dd93dd dd9393 dd9349 dd9300 dd49dd dd4993 dd4949 dd4900 dd00dd dd0093\n");
168*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "  cc0088 cc0044 cc0000 cccccc cccc88 cccc44 cccc00 cc88cc cc8888 cc8844 cc8800 cc44cc\n");
169*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "  cc4488 cc4444 cc4400 cc00cc aaffaa aaff55 aaff00 aaaaff bbbbbb bbbb5d bbbb00 aa55ff\n");
170*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "  bb5dbb bb5d5d bb5d00 aa00ff bb00bb bb005d bb0000 aaffff 9eeeee 9eee9e 9eee4f 9eee00\n");
171*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "  9e9eee aaaaaa aaaa55 aaaa00 9e4fee aa55aa aa5555 aa5500 9e00ee aa00aa aa0055 aa0000\n");
172*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "  990000 93dddd 93dd93 93dd49 93dd00 9393dd 999999 99994c 999900 9349dd 994c99 994c4c\n");
173*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "  994c00 9300dd 990099 99004c 880044 880000 88cccc 88cc88 88cc44 88cc00 8888cc 888888\n");
174*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "  888844 888800 8844cc 884488 884444 884400 8800cc 880088 55ff55 55ff00 55aaff 5dbbbb\n");
175*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "  5dbb5d 5dbb00 5555ff 5d5dbb 777777 777700 5500ff 5d00bb 770077 770000 55ffff 55ffaa\n");
176*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "  4fee9e 4fee4f 4fee00 4f9eee 55aaaa 55aa55 55aa00 4f4fee 5555aa 666666 666600 4f00ee\n");
177*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "  5500aa 660066 660000 4feeee 49dddd 49dd93 49dd49 49dd00 4993dd 4c9999 4c994c 4c9900\n");
178*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "  4949dd 4c4c99 555555 555500 4900dd 4c0099 550055 550000 440000 44cccc 44cc88 44cc44\n");
179*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "  44cc00 4488cc 448888 448844 448800 4444cc 444488 444444 444400 4400cc 440088 440044\n");
180*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "  00ff00 00aaff 00bbbb 00bb5d 00bb00 0055ff 005dbb 007777 007700 0000ff 0000bb 000077\n");
181*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "  333333 00ffff 00ffaa 00ff55 00ee4f 00ee00 009eee 00aaaa 00aa55 00aa00 004fee 0055aa\n");
182*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "  006666 006600 0000ee 0000aa 000066 222222 00eeee 00ee9e 00dd93 00dd49 00dd00 0093dd\n");
183*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "  009999 00994c 009900 0049dd 004c99 005555 005500 0000dd 000099 000055 111111 00dddd\n");
184*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "  00cccc 00cc88 00cc44 00cc00 0088cc 008888 008844 008800 0044cc 004488 004444 004400\n");
185*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "  0000cc 000088 000044 000000>\n");
186*7dd7cddfSDavid du Colombier 	Bprint(ioutb, " ] setcolorspace\n");
187*7dd7cddfSDavid du Colombier 	Bprint(ioutb, " /decodemat [0 255] def\n");
188*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "}\n");
189*7dd7cddfSDavid du Colombier /*	# else, bps != 8 */
190*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "{\n");
191*7dd7cddfSDavid du Colombier /* is it greyscale or is it 24-bit color? */
192*7dd7cddfSDavid du Colombier 	Bprint(ioutb, " grey true eq {\n");
193*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "  [/DeviceGray] setcolorspace\n");
194*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "  /decodemat [1 0] def\n");
195*7dd7cddfSDavid du Colombier 	Bprint(ioutb, " }\n");
196*7dd7cddfSDavid du Colombier 	Bprint(ioutb, " {\n");
197*7dd7cddfSDavid du Colombier /* must be color */
198*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "  [/DeviceRGB] setcolorspace\n");
199*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "  /bps 8 def\n");
200*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "  /decodemat [1 0 1 0 1 0] def\n");
201*7dd7cddfSDavid du Colombier 	Bprint(ioutb, " }\n");
202*7dd7cddfSDavid du Colombier 	Bprint(ioutb, " ifelse\n");
203*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "}\n");
204*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "ifelse\n");
205*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "/xmagnification %g def\n", xmagnification);
206*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "/ymagnification %g def\n", ymagnification);
207*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "/rotation %d def\n", rotation);
208*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "xstart ystart translate rotation rotate\n");
209*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "iwidth xmagnification mul iheight ymagnification mul scale\n");
210*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "<<\n");
211*7dd7cddfSDavid du Colombier 	Bprint(ioutb, " /ImageType 1\n");
212*7dd7cddfSDavid du Colombier 	Bprint(ioutb, " /Width width \n");
213*7dd7cddfSDavid du Colombier 	Bprint(ioutb, " /Height height \n");
214*7dd7cddfSDavid du Colombier 	Bprint(ioutb, " /BitsPerComponent bps %% bits/sample\n");
215*7dd7cddfSDavid du Colombier 	Bprint(ioutb, " /Decode decodemat %% Brazil/Inferno cmap or DeviceGray value\n");
216*7dd7cddfSDavid du Colombier 	Bprint(ioutb, " /ImageMatrix [width 0 0 height neg 0 height]\n");
217*7dd7cddfSDavid du Colombier 	Bprint(ioutb, " /DataSource currentfile /ASCII85Decode filter\n");
218*7dd7cddfSDavid du Colombier 	Bprint(ioutb, ">> \n");
219*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "image\n");
220*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "grestore\n");
221*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "} def\n");
222*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "%%%%EndProlog\n");
223*7dd7cddfSDavid du Colombier 	if (Patch != nil)
224*7dd7cddfSDavid du Colombier 		Bprint(ioutb, "%s\n", Patch);
225*7dd7cddfSDavid du Colombier 	return 0;
226*7dd7cddfSDavid du Colombier }
227*7dd7cddfSDavid du Colombier 
228*7dd7cddfSDavid du Colombier int
229*7dd7cddfSDavid du Colombier trailer(Biobuf *ioutb ,int pages) {
230*7dd7cddfSDavid du Colombier 	if(!started)
231*7dd7cddfSDavid du Colombier 		return 1;
232*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "%%%%Trailer\n%%%%Pages: %d\n%%%%EOF\n", pages);
233*7dd7cddfSDavid du Colombier 	return 0;
234*7dd7cddfSDavid du Colombier }
235*7dd7cddfSDavid du Colombier 
236*7dd7cddfSDavid du Colombier void
237*7dd7cddfSDavid du Colombier printnewpage(int pagenum, int end, Biobuf *ioutb)
238*7dd7cddfSDavid du Colombier {
239*7dd7cddfSDavid du Colombier 	if (!started) return;
240*7dd7cddfSDavid du Colombier 	if (end){
241*7dd7cddfSDavid du Colombier /*		# bounding box */
242*7dd7cddfSDavid du Colombier 		if (boxes){
243*7dd7cddfSDavid du Colombier 			Bprint(ioutb, "18 18 moveto 594 18 lineto 594 774 lineto 18 774 lineto closepath stroke\n");
244*7dd7cddfSDavid du Colombier 		}
245*7dd7cddfSDavid du Colombier 		Bprint(ioutb, "showpage\n%%%%EndPage %d %d\n", pagenum, pagenum);
246*7dd7cddfSDavid du Colombier 	} else
247*7dd7cddfSDavid du Colombier 		Bprint(ioutb, "%%%%Page: %d %d\n", pagenum, pagenum);
248*7dd7cddfSDavid du Colombier }
249*7dd7cddfSDavid du Colombier 
250*7dd7cddfSDavid du Colombier /* int
251*7dd7cddfSDavid du Colombier /* printimage(FILE *ioutb, struct lineinfo line, struct iteminfo imag) {
252*7dd7cddfSDavid du Colombier /* 	int RM;
253*7dd7cddfSDavid du Colombier /*
254*7dd7cddfSDavid du Colombier /* 	RM=612-18;
255*7dd7cddfSDavid du Colombier /* 	class:=tk->cmd(t,"winfo class "+imag.buf);
256*7dd7cddfSDavid du Colombier /* #sys->print("Looking for [%s] of type [%s]\n",imag.buf,class);
257*7dd7cddfSDavid du Colombier /* 	if (line.xorg+imag.offset+imag.width>RM)
258*7dd7cddfSDavid du Colombier /* 		imag.width=RM-line.xorg-imag.offset;
259*7dd7cddfSDavid du Colombier /* 	case class {
260*7dd7cddfSDavid du Colombier /* 		"button" or "menubutton" =>
261*7dd7cddfSDavid du Colombier /* 			# try to get the text out and print it....
262*7dd7cddfSDavid du Colombier /* 			ioutb.puts(sys->sprint("%d %d moveto\n",line.xorg+imag.offset,
263*7dd7cddfSDavid du Colombier /* 							line.yorg));
264*7dd7cddfSDavid du Colombier /* 			msg:=tk->cmd(t,sys->sprint("%s cget -text",imag.buf));
265*7dd7cddfSDavid du Colombier /* 			ft:=tk->cmd(t,sys->sprint("%s cget -font",imag.buf));
266*7dd7cddfSDavid du Colombier /* 			sys->print("font is [%s]\n",ft);
267*7dd7cddfSDavid du Colombier /* 			ioutb.puts(sys->sprint("%d %d %d %d rectstroke\n",
268*7dd7cddfSDavid du Colombier /* 						line.xorg+imag.offset,line.yorg,imag.width,
269*7dd7cddfSDavid du Colombier /* 						line.height));
270*7dd7cddfSDavid du Colombier /* 			return (class,msg);
271*7dd7cddfSDavid du Colombier /* 		"label" =>
272*7dd7cddfSDavid du Colombier /* 			(im,im2,err) := tk->imageget(t,imag.buf);
273*7dd7cddfSDavid du Colombier /* 			if (im!=nil){
274*7dd7cddfSDavid du Colombier /* 				bps := 1<<im.ldepth;
275*7dd7cddfSDavid du Colombier /* 				ioutb.puts(sys->sprint("%d %d %d %d %d %d %d %d doimage\n",
276*7dd7cddfSDavid du Colombier /* 						im.r.dy(),line.ascent,im.r.dx(),line.yorg,
277*7dd7cddfSDavid du Colombier /* 						line.xorg+imag.offset,im.r.dy(), im.r.dx(), bps));
278*7dd7cddfSDavid du Colombier /* 				imagebits(ioutb,im);
279*7dd7cddfSDavid du Colombier /* 			}
280*7dd7cddfSDavid du Colombier /* 			return (class,"");
281*7dd7cddfSDavid du Colombier /* 		"entry" =>
282*7dd7cddfSDavid du Colombier /* 			ioutb.puts(sys->sprint("%d %d moveto\n",line.xorg+imag.offset,
283*7dd7cddfSDavid du Colombier /* 					line.yorg));
284*7dd7cddfSDavid du Colombier /* 			ioutb.puts(sys->sprint("%d %d %d %d rectstroke\n",
285*7dd7cddfSDavid du Colombier /* 					line.xorg+imag.offset,line.yorg,imag.width,
286*7dd7cddfSDavid du Colombier /* 					line.height));
287*7dd7cddfSDavid du Colombier /* 			return (class,"");
288*7dd7cddfSDavid du Colombier /* 		* =>
289*7dd7cddfSDavid du Colombier /* 			sys->print("Unhandled class [%s]\n",class);
290*7dd7cddfSDavid du Colombier /* 			return (class,"Error");
291*7dd7cddfSDavid du Colombier /*
292*7dd7cddfSDavid du Colombier /* 	}
293*7dd7cddfSDavid du Colombier /* 	return ("","");
294*7dd7cddfSDavid du Colombier /* }
295*7dd7cddfSDavid du Colombier /*
296*7dd7cddfSDavid du Colombier /* printline(ioutb: ref Iobuf,line : lineinfo,items : array of iteminfo)
297*7dd7cddfSDavid du Colombier /* {
298*7dd7cddfSDavid du Colombier /* 	xstart:=line.xorg;
299*7dd7cddfSDavid du Colombier /* 	wid:=xstart;
300*7dd7cddfSDavid du Colombier /* 	# items
301*7dd7cddfSDavid du Colombier /* 	if (len items == 0) return;
302*7dd7cddfSDavid du Colombier /* 	for(j:=0;j<len items;j++){
303*7dd7cddfSDavid du Colombier /* 		msg:="";
304*7dd7cddfSDavid du Colombier /* 		class:="";
305*7dd7cddfSDavid du Colombier /* 		if (items[j].itype==IMAGE)
306*7dd7cddfSDavid du Colombier /* 			(class,msg)=printimage(ioutb,line,items[j]);
307*7dd7cddfSDavid du Colombier /* 		if (items[j].itype!=IMAGE || class=="button"|| class=="menubutton"){
308*7dd7cddfSDavid du Colombier /* 			setfont(ioutb,items[j].font);
309*7dd7cddfSDavid du Colombier /* 			if (msg!=""){
310*7dd7cddfSDavid du Colombier /* 				# position the text in the center of the label
311*7dd7cddfSDavid du Colombier /* 				# moveto curpoint
312*7dd7cddfSDavid du Colombier /* 				# (msg) stringwidth pop xstart sub 2 div
313*7dd7cddfSDavid du Colombier /* 				ioutb.puts(sys->sprint("%d %d moveto\n",xstart+items[j].offset,
314*7dd7cddfSDavid du Colombier /* 						line.yorg+line.height-line.ascent));
315*7dd7cddfSDavid du Colombier /* 				ioutb.puts(sys->sprint("(%s) dup stringwidth pop 2 div",
316*7dd7cddfSDavid du Colombier /* 								msg));
317*7dd7cddfSDavid du Colombier /* 				ioutb.puts(" 0 rmoveto show\n");
318*7dd7cddfSDavid du Colombier /* 			}
319*7dd7cddfSDavid du Colombier /* 			else {
320*7dd7cddfSDavid du Colombier /* 				ioutb.puts(sys->sprint("%d %d moveto\n",
321*7dd7cddfSDavid du Colombier /* 					xstart+items[j].offset,line.yorg+line.height
322*7dd7cddfSDavid du Colombier /* 					-line.ascent));
323*7dd7cddfSDavid du Colombier /* 				ioutb.puts(sys->sprint("(%s) show\n",items[j].buf));
324*7dd7cddfSDavid du Colombier /* 			}
325*7dd7cddfSDavid du Colombier /* 		}
326*7dd7cddfSDavid du Colombier /* 		wid=xstart+items[j].offset+items[j].width;
327*7dd7cddfSDavid du Colombier /* 	}
328*7dd7cddfSDavid du Colombier /* 	if (boxes)
329*7dd7cddfSDavid du Colombier /* 		ioutb.puts(sys->sprint("%d %d %d %d rectstroke\n",line.xorg,line.yorg,
330*7dd7cddfSDavid du Colombier /* 									wid,line.height));
331*7dd7cddfSDavid du Colombier /* }
332*7dd7cddfSDavid du Colombier /*
333*7dd7cddfSDavid du Colombier /* setfont(ioutb: ref Iobuf,font : int){
334*7dd7cddfSDavid du Colombier /* 	ftype : int;
335*7dd7cddfSDavid du Colombier /* 	fname : string;
336*7dd7cddfSDavid du Colombier /* 	if ((curfonttype&font)!=curfonttype){
337*7dd7cddfSDavid du Colombier /* 		for(f:=0;f<curfont;f++){
338*7dd7cddfSDavid du Colombier /* 			(ftype,fname)=font_arr[f];
339*7dd7cddfSDavid du Colombier /* 				if ((ftype&font)==ftype)
340*7dd7cddfSDavid du Colombier /* 					break;
341*7dd7cddfSDavid du Colombier /* 		}
342*7dd7cddfSDavid du Colombier /* 		if (f==curfont){
343*7dd7cddfSDavid du Colombier /* 			fname=def_font;
344*7dd7cddfSDavid du Colombier /* 			ftype=def_font_type;
345*7dd7cddfSDavid du Colombier /* 		}
346*7dd7cddfSDavid du Colombier /* 		ioutb.puts(sys->sprint("%s setfont\n",fname));
347*7dd7cddfSDavid du Colombier /* 		curfonttype=ftype;
348*7dd7cddfSDavid du Colombier /* 	}
349*7dd7cddfSDavid du Colombier /* }
350*7dd7cddfSDavid du Colombier /*
351*7dd7cddfSDavid du Colombier /* parseTkline(ioutb: ref Iobuf,input : string) : string
352*7dd7cddfSDavid du Colombier /* {
353*7dd7cddfSDavid du Colombier /* 	if (!started) return noinit;
354*7dd7cddfSDavid du Colombier /* 	thisline : lineinfo;
355*7dd7cddfSDavid du Colombier /* 	PS:=792-18-18;	# page size in points
356*7dd7cddfSDavid du Colombier /* 	TM:=792-18;	# top margin in points
357*7dd7cddfSDavid du Colombier /* 	LM:=18;		# left margin 1/4 in. in
358*7dd7cddfSDavid du Colombier /* 	BM:=18;		# bottom margin 1/4 in. in
359*7dd7cddfSDavid du Colombier /* 	x : int;
360*7dd7cddfSDavid du Colombier /* 	(x,input)=str->toint(input,10);
361*7dd7cddfSDavid du Colombier /* 	thisline.xorg=(x*PTPI)/PXPI;
362*7dd7cddfSDavid du Colombier /* 	(x,input)=str->toint(input,10);
363*7dd7cddfSDavid du Colombier /* 	thisline.yorg=(x*PTPI)/PXPI;
364*7dd7cddfSDavid du Colombier /* 	(x,input)=str->toint(input,10);
365*7dd7cddfSDavid du Colombier /* 	thisline.width=(x*PTPI)/PXPI;
366*7dd7cddfSDavid du Colombier /* 	(x,input)=str->toint(input,10);
367*7dd7cddfSDavid du Colombier /* 	thisline.height=(x*PTPI)/PXPI;
368*7dd7cddfSDavid du Colombier /* 	(x,input)=str->toint(input,10);
369*7dd7cddfSDavid du Colombier /* 	thisline.ascent=(x*PTPI)/PXPI;
370*7dd7cddfSDavid du Colombier /* 	(x,input)=str->toint(input,10);
371*7dd7cddfSDavid du Colombier /* 	# thisline.numitems=x;
372*7dd7cddfSDavid du Colombier /* 	if (thisline.width==0 || thisline.height==0)
373*7dd7cddfSDavid du Colombier /* 		return "";
374*7dd7cddfSDavid du Colombier /* 	if (thisline.yorg+thisline.height-pagestart>PS){
375*7dd7cddfSDavid du Colombier /* 		pagestart=thisline.yorg;
376*7dd7cddfSDavid du Colombier /* 		return "newpage";
377*7dd7cddfSDavid du Colombier /* 		# must resend this line....
378*7dd7cddfSDavid du Colombier /* 	}
379*7dd7cddfSDavid du Colombier /* 	thisline.yorg=TM-thisline.yorg-thisline.height+pagestart;
380*7dd7cddfSDavid du Colombier /* 	thisline.xorg+=LM;
381*7dd7cddfSDavid du Colombier /* 	(items, err) :=getline(totlines,input);
382*7dd7cddfSDavid du Colombier /* 	if(err != nil)
383*7dd7cddfSDavid du Colombier /* 		return err;
384*7dd7cddfSDavid du Colombier /* 	totitems+=len items;
385*7dd7cddfSDavid du Colombier /* 	totlines++;
386*7dd7cddfSDavid du Colombier /* 	printline(ioutb,thisline,items);
387*7dd7cddfSDavid du Colombier /* 	return "";
388*7dd7cddfSDavid du Colombier /* }
389*7dd7cddfSDavid du Colombier /*
390*7dd7cddfSDavid du Colombier /*
391*7dd7cddfSDavid du Colombier /* getfonts(input: string) : string
392*7dd7cddfSDavid du Colombier /* {
393*7dd7cddfSDavid du Colombier /* 	if (!started) return "Error";
394*7dd7cddfSDavid du Colombier /* 	tkfont,psfont : string;
395*7dd7cddfSDavid du Colombier /* 	j : int;
396*7dd7cddfSDavid du Colombier /* 	retval := "";
397*7dd7cddfSDavid du Colombier /* 	if (input[0]=='%')
398*7dd7cddfSDavid du Colombier /* 			return "";
399*7dd7cddfSDavid du Colombier /* 	# get a line of the form
400*7dd7cddfSDavid du Colombier /* 	# 5::/fonts/lucida/moo.16.font
401*7dd7cddfSDavid du Colombier /* 	# translate it to...
402*7dd7cddfSDavid du Colombier /* 	# 32 f32.16
403*7dd7cddfSDavid du Colombier /* 	# where 32==1<<5 and f32.16 is a postscript function that loads the
404*7dd7cddfSDavid du Colombier /* 	# appropriate postscript font (from remap)
405*7dd7cddfSDavid du Colombier /* 	# and writes it to fonts....
406*7dd7cddfSDavid du Colombier /* 	(bits,font):=str->toint(input,10);
407*7dd7cddfSDavid du Colombier /* 	if (bits!=-1)
408*7dd7cddfSDavid du Colombier /* 		bits=1<<bits;
409*7dd7cddfSDavid du Colombier /* 	else{
410*7dd7cddfSDavid du Colombier /* 		bits=1;
411*7dd7cddfSDavid du Colombier /* 		def_font_type=bits;
412*7dd7cddfSDavid du Colombier /* 		curfonttype=def_font_type;
413*7dd7cddfSDavid du Colombier /* 	}
414*7dd7cddfSDavid du Colombier /* 	font=font[2:];
415*7dd7cddfSDavid du Colombier /* 	for(i:=0;i<len remap;i++){
416*7dd7cddfSDavid du Colombier /* 		(tkfont,psfont)=remap[i];
417*7dd7cddfSDavid du Colombier /* 		if (tkfont==font)
418*7dd7cddfSDavid du Colombier /* 			break;
419*7dd7cddfSDavid du Colombier /* 	}
420*7dd7cddfSDavid du Colombier /* 	if (i==len remap)
421*7dd7cddfSDavid du Colombier /* 		psfont="Times-Roman";
422*7dd7cddfSDavid du Colombier /* 	(font,nil)=str->splitr(font,".");
423*7dd7cddfSDavid du Colombier /* 	(nil,font)=str->splitr(font[0:len font-1],".");
424*7dd7cddfSDavid du Colombier /* 	(fsize,nil):=str->toint(font,10);
425*7dd7cddfSDavid du Colombier /* 	fsize=(PTPI*3*fsize)/(2*PXPI);
426*7dd7cddfSDavid du Colombier /* 	enc_font:="f"+string bits+"."+string fsize;
427*7dd7cddfSDavid du Colombier /* 	ps_func:="/"+enc_font+" /"+psfont+" findfont "+string fsize+
428*7dd7cddfSDavid du Colombier /* 							" scalefont def\n";
429*7dd7cddfSDavid du Colombier /* 	sy_font:="sy"+string fsize;
430*7dd7cddfSDavid du Colombier /* 	xtra_func:="/"+sy_font+" /Symbol findfont "+string fsize+
431*7dd7cddfSDavid du Colombier /* 							" scalefont def\n";
432*7dd7cddfSDavid du Colombier /* 	for(i=0;i<len font_arr;i++){
433*7dd7cddfSDavid du Colombier /* 		(j,font)=font_arr[i];
434*7dd7cddfSDavid du Colombier /* 		if (j==-1) break;
435*7dd7cddfSDavid du Colombier /* 	}
436*7dd7cddfSDavid du Colombier /* 	if (j==len font_arr)
437*7dd7cddfSDavid du Colombier /* 		return "Error";
438*7dd7cddfSDavid du Colombier /* 	font_arr[i]=(bits,enc_font);
439*7dd7cddfSDavid du Colombier /* 	if (bits==1)
440*7dd7cddfSDavid du Colombier /* 		def_font=enc_font;
441*7dd7cddfSDavid du Colombier /* 	curfont++;
442*7dd7cddfSDavid du Colombier /* 	retval+= ps_func;
443*7dd7cddfSDavid du Colombier /* 	retval+= xtra_func;
444*7dd7cddfSDavid du Colombier /* 	return retval;
445*7dd7cddfSDavid du Colombier /* }
446*7dd7cddfSDavid du Colombier /*
447*7dd7cddfSDavid du Colombier /* deffont() : string
448*7dd7cddfSDavid du Colombier /* {
449*7dd7cddfSDavid du Colombier /* 	return def_font;
450*7dd7cddfSDavid du Colombier /* }
451*7dd7cddfSDavid du Colombier /*
452*7dd7cddfSDavid du Colombier /* getline(k : int,  input : string) : (array of iteminfo, string)
453*7dd7cddfSDavid du Colombier /* {
454*7dd7cddfSDavid du Colombier /* 	lineval,args : string;
455*7dd7cddfSDavid du Colombier /* 	j, nb : int;
456*7dd7cddfSDavid du Colombier /* 	lw:=0;
457*7dd7cddfSDavid du Colombier /* 	wid:=0;
458*7dd7cddfSDavid du Colombier /* 	flags:=0;
459*7dd7cddfSDavid du Colombier /* 	item_arr := array[32] of {* => iteminfo(-1,-1,-1,-1,-1,-1,"")};
460*7dd7cddfSDavid du Colombier /* 	curitem:=0;
461*7dd7cddfSDavid du Colombier /* 	while(input!=nil){
462*7dd7cddfSDavid du Colombier /* 		(nil,input)=str->splitl(input,"[");
463*7dd7cddfSDavid du Colombier /* 		if (input==nil)
464*7dd7cddfSDavid du Colombier /* 			break;
465*7dd7cddfSDavid du Colombier /* 		com:=input[1];
466*7dd7cddfSDavid du Colombier /* 		input=input[2:];
467*7dd7cddfSDavid du Colombier /* 		case com {
468*7dd7cddfSDavid du Colombier /* 			'A' =>
469*7dd7cddfSDavid du Colombier /* 				nb=0;
470*7dd7cddfSDavid du Colombier /* 				# get the width of the item
471*7dd7cddfSDavid du Colombier /* 				(wid,input)=str->toint(input,10);
472*7dd7cddfSDavid du Colombier /* 				wid=(wid*PTPI)/PXPI;
473*7dd7cddfSDavid du Colombier /* 				if (input[0]!='{')
474*7dd7cddfSDavid du Colombier /* 					return (nil, sys->sprint(
475*7dd7cddfSDavid du Colombier /* 						"line %d item %d Bad Syntax : '{' expected",
476*7dd7cddfSDavid du Colombier /* 							k,curitem));
477*7dd7cddfSDavid du Colombier /* 				# get the args.
478*7dd7cddfSDavid du Colombier /* 				(args,input)=str->splitl(input,"}");
479*7dd7cddfSDavid du Colombier /* 				# get the flags.
480*7dd7cddfSDavid du Colombier /* 				# assume there is only one int flag..
481*7dd7cddfSDavid du Colombier /* 				(flags,args)=str->toint(args[1:],16);
482*7dd7cddfSDavid du Colombier /* 				if (args!=nil && debug){
483*7dd7cddfSDavid du Colombier /* 					sys->print("line %d item %d extra flags=%s\n",
484*7dd7cddfSDavid du Colombier /* 							k,curitem,args);
485*7dd7cddfSDavid du Colombier /* 				}
486*7dd7cddfSDavid du Colombier /* 				if (flags<1024) flags=1;
487*7dd7cddfSDavid du Colombier /* 				item_arr[curitem].font=flags;
488*7dd7cddfSDavid du Colombier /* 				item_arr[curitem].offset=lw;
489*7dd7cddfSDavid du Colombier /* 				item_arr[curitem].width=wid;
490*7dd7cddfSDavid du Colombier /* 				lw+=wid;
491*7dd7cddfSDavid du Colombier /* 				for(j=1;j<len input;j++){
492*7dd7cddfSDavid du Colombier /* 					if ((input[j]==')')||(input[j]=='('))
493*7dd7cddfSDavid du Colombier /* 							lineval[len lineval]='\\';
494*7dd7cddfSDavid du Colombier /* 					if (input[j]=='[')
495*7dd7cddfSDavid du Colombier /* 						nb++;
496*7dd7cddfSDavid du Colombier /* 					if (input[j]==']')
497*7dd7cddfSDavid du Colombier /* 						if (nb==0)
498*7dd7cddfSDavid du Colombier /* 							break;
499*7dd7cddfSDavid du Colombier /* 						else
500*7dd7cddfSDavid du Colombier /* 							nb--;
501*7dd7cddfSDavid du Colombier /* 					lineval[len lineval]=input[j];
502*7dd7cddfSDavid du Colombier /* 				}
503*7dd7cddfSDavid du Colombier /* 				if (j<len input)
504*7dd7cddfSDavid du Colombier /* 					input=input[j:];
505*7dd7cddfSDavid du Colombier /* 				item_arr[curitem].buf=lineval;
506*7dd7cddfSDavid du Colombier /* 				item_arr[curitem].line=k;
507*7dd7cddfSDavid du Colombier /* 				item_arr[curitem].itype=ASCII;
508*7dd7cddfSDavid du Colombier /* 				curitem++;
509*7dd7cddfSDavid du Colombier /* 				lineval="";
510*7dd7cddfSDavid du Colombier /* 			'R' =>
511*7dd7cddfSDavid du Colombier /* 				nb=0;
512*7dd7cddfSDavid du Colombier /* 				# get the width of the item
513*7dd7cddfSDavid du Colombier /* 				(wid,input)=str->toint(input,10);
514*7dd7cddfSDavid du Colombier /* 				wid=(wid*PTPI)/PXPI;
515*7dd7cddfSDavid du Colombier /* 				if (input[0]!='{')
516*7dd7cddfSDavid du Colombier /* 					return (nil, "Bad Syntax : '{' expected");
517*7dd7cddfSDavid du Colombier /* 				# get the args.
518*7dd7cddfSDavid du Colombier /* 				(args,input)=str->splitl(input,"}");
519*7dd7cddfSDavid du Colombier /* 				# get the flags.
520*7dd7cddfSDavid du Colombier /* 				# assume there is only one int flag..
521*7dd7cddfSDavid du Colombier /* 				(flags,args)=str->toint(args[1:],16);
522*7dd7cddfSDavid du Colombier /* 				if (args!=nil && debug){
523*7dd7cddfSDavid du Colombier /* 					sys->print("line %d item %d Bad Syntax args=%s",
524*7dd7cddfSDavid du Colombier /* 							k,curitem,args);
525*7dd7cddfSDavid du Colombier /* 				}
526*7dd7cddfSDavid du Colombier /* 				item_arr[curitem].font=flags;
527*7dd7cddfSDavid du Colombier /* 				item_arr[curitem].offset=lw;
528*7dd7cddfSDavid du Colombier /* 				item_arr[curitem].width=wid;
529*7dd7cddfSDavid du Colombier /* 				lw+=wid;
530*7dd7cddfSDavid du Colombier /* 				for(j=1;j<len input;j++){
531*7dd7cddfSDavid du Colombier /* 					if (input[j]=='[')
532*7dd7cddfSDavid du Colombier /* 						nb++;
533*7dd7cddfSDavid du Colombier /* 					if (input[j]==']')
534*7dd7cddfSDavid du Colombier /* 						if (nb==0)
535*7dd7cddfSDavid du Colombier /* 							break;
536*7dd7cddfSDavid du Colombier /* 						else
537*7dd7cddfSDavid du Colombier /* 							nb--;
538*7dd7cddfSDavid du Colombier /* 					case input[j] {
539*7dd7cddfSDavid du Colombier /* 						8226 => # bullet
540*7dd7cddfSDavid du Colombier /* 							lineval+="\\267 ";
541*7dd7cddfSDavid du Colombier /* 						169 =>  # copyright
542*7dd7cddfSDavid du Colombier /* 							lineval+="\\251 ";
543*7dd7cddfSDavid du Colombier /* 							curitem++;
544*7dd7cddfSDavid du Colombier /* 						* =>
545*7dd7cddfSDavid du Colombier /* 							lineval[len lineval]=input[j];
546*7dd7cddfSDavid du Colombier /* 					}
547*7dd7cddfSDavid du Colombier /* 				}
548*7dd7cddfSDavid du Colombier /* 				if (j>len input)
549*7dd7cddfSDavid du Colombier /* 					input=input[j:];
550*7dd7cddfSDavid du Colombier /* 				item_arr[curitem].buf=lineval;
551*7dd7cddfSDavid du Colombier /* 				item_arr[curitem].line=k;
552*7dd7cddfSDavid du Colombier /* 				item_arr[curitem].itype=RUNE;
553*7dd7cddfSDavid du Colombier /* 				curitem++;
554*7dd7cddfSDavid du Colombier /* 				lineval="";
555*7dd7cddfSDavid du Colombier /* 			'N' or 'C'=>
556*7dd7cddfSDavid du Colombier /* 				# next item
557*7dd7cddfSDavid du Colombier /* 				for(j=0;j<len input;j++)
558*7dd7cddfSDavid du Colombier /* 					if (input[j]==']')
559*7dd7cddfSDavid du Colombier /* 						break;
560*7dd7cddfSDavid du Colombier /* 				if (j>len input)
561*7dd7cddfSDavid du Colombier /* 					input=input[j:];
562*7dd7cddfSDavid du Colombier /* 			'T' =>
563*7dd7cddfSDavid du Colombier /* 				(wid,input)=str->toint(input,10);
564*7dd7cddfSDavid du Colombier /* 				wid=(wid*PTPI)/PXPI;
565*7dd7cddfSDavid du Colombier /* 				item_arr[curitem].offset=lw;
566*7dd7cddfSDavid du Colombier /* 				item_arr[curitem].width=wid;
567*7dd7cddfSDavid du Colombier /* 				lw+=wid;
568*7dd7cddfSDavid du Colombier /* 				lineval[len lineval]='\t';
569*7dd7cddfSDavid du Colombier /* 				# next item
570*7dd7cddfSDavid du Colombier /* 				for(j=0;j<len input;j++)
571*7dd7cddfSDavid du Colombier /* 					if (input[j]==']')
572*7dd7cddfSDavid du Colombier /* 						break;
573*7dd7cddfSDavid du Colombier /* 				if (j>len input)
574*7dd7cddfSDavid du Colombier /* 					input=input[j:];
575*7dd7cddfSDavid du Colombier /* 				item_arr[curitem].buf=lineval;
576*7dd7cddfSDavid du Colombier /* 				item_arr[curitem].line=k;
577*7dd7cddfSDavid du Colombier /* 				item_arr[curitem].itype=ASCII;
578*7dd7cddfSDavid du Colombier /* 				curitem++;
579*7dd7cddfSDavid du Colombier /* 				lineval="";
580*7dd7cddfSDavid du Colombier /* 			'W' =>
581*7dd7cddfSDavid du Colombier /* 				(wid,input)=str->toint(input,10);
582*7dd7cddfSDavid du Colombier /* 				wid=(wid*PTPI)/PXPI;
583*7dd7cddfSDavid du Colombier /* 				item_arr[curitem].offset=lw;
584*7dd7cddfSDavid du Colombier /* 				item_arr[curitem].width=wid;
585*7dd7cddfSDavid du Colombier /* 				item_arr[curitem].itype=IMAGE;
586*7dd7cddfSDavid du Colombier /* 				lw+=wid;
587*7dd7cddfSDavid du Colombier /* 				# next item
588*7dd7cddfSDavid du Colombier /* 				for(j=1;j<len input;j++){
589*7dd7cddfSDavid du Colombier /* 					if (input[j]==']')
590*7dd7cddfSDavid du Colombier /* 						break;
591*7dd7cddfSDavid du Colombier /* 					lineval[len lineval]=input[j];
592*7dd7cddfSDavid du Colombier /* 				}
593*7dd7cddfSDavid du Colombier /* 				item_arr[curitem].buf=lineval;
594*7dd7cddfSDavid du Colombier /* 				if (j>len input)
595*7dd7cddfSDavid du Colombier /* 					input=input[j:];
596*7dd7cddfSDavid du Colombier /* 				curitem++;
597*7dd7cddfSDavid du Colombier /* 				lineval="";
598*7dd7cddfSDavid du Colombier /* 			* =>
599*7dd7cddfSDavid du Colombier /* 				# next item
600*7dd7cddfSDavid du Colombier /* 				for(j=0;j<len input;j++)
601*7dd7cddfSDavid du Colombier /* 					if (input[j]==']')
602*7dd7cddfSDavid du Colombier /* 						break;
603*7dd7cddfSDavid du Colombier /* 				if (j>len input)
604*7dd7cddfSDavid du Colombier /* 					input=input[j:];
605*7dd7cddfSDavid du Colombier /*
606*7dd7cddfSDavid du Colombier /* 		}
607*7dd7cddfSDavid du Colombier /* 	}
608*7dd7cddfSDavid du Colombier /* 	return (item_arr[0:curitem], "");
609*7dd7cddfSDavid du Colombier /* }
610*7dd7cddfSDavid du Colombier */
611*7dd7cddfSDavid du Colombier 
612*7dd7cddfSDavid du Colombier void
613*7dd7cddfSDavid du Colombier cmap2ascii85(uchar *b, uchar *c) {
614*7dd7cddfSDavid du Colombier 	int i;
615*7dd7cddfSDavid du Colombier 	unsigned long i1;
616*7dd7cddfSDavid du Colombier 
617*7dd7cddfSDavid du Colombier /*	fprintf(stderr, "addr=0x%x %x %x %x %x\n", b, b[0], b[1], b[2], b[3]); */
618*7dd7cddfSDavid du Colombier 	b--;	/* one-index b */
619*7dd7cddfSDavid du Colombier 	c--;	/* one-index c */
620*7dd7cddfSDavid du Colombier 	i1 = (b[1]<<24)+(b[2]<<16)+(b[3]<<8)+b[4];
621*7dd7cddfSDavid du Colombier 	if(i1 == 0){
622*7dd7cddfSDavid du Colombier 		c[1] = 'z';
623*7dd7cddfSDavid du Colombier 		c[2] = '\0';
624*7dd7cddfSDavid du Colombier 		return;
625*7dd7cddfSDavid du Colombier 	}
626*7dd7cddfSDavid du Colombier 	for(i=0; i<=4; i++){
627*7dd7cddfSDavid du Colombier 		c[5-i] = '!' + (i1 % 85);
628*7dd7cddfSDavid du Colombier 		i1 /= 85;
629*7dd7cddfSDavid du Colombier 	}
630*7dd7cddfSDavid du Colombier 	c[6] = '\0';
631*7dd7cddfSDavid du Colombier }
632*7dd7cddfSDavid du Colombier 
633*7dd7cddfSDavid du Colombier static uchar *arr = nil;
634*7dd7cddfSDavid du Colombier ulong	onesbits = ~0;
635*7dd7cddfSDavid du Colombier void
636*7dd7cddfSDavid du Colombier imagebits(Biobuf *ioutb, Memimage *im)
637*7dd7cddfSDavid du Colombier {
638*7dd7cddfSDavid du Colombier 	int spb;
639*7dd7cddfSDavid du Colombier 	int bitoff;
640*7dd7cddfSDavid du Colombier 	int j, n, n4, i, bpl, nrest;
641*7dd7cddfSDavid du Colombier 	int lsf;
642*7dd7cddfSDavid du Colombier 	uchar c85[6], *data, *src, *dst;
643*7dd7cddfSDavid du Colombier 	Memimage *tmp;
644*7dd7cddfSDavid du Colombier 	Rectangle r;
645*7dd7cddfSDavid du Colombier 
646*7dd7cddfSDavid du Colombier 	tmp = nil;
647*7dd7cddfSDavid du Colombier 	if (debug)
648*7dd7cddfSDavid du Colombier 		fprint(2, "imagebits, r=%d %d %d %d, depth=%d\n",
649*7dd7cddfSDavid du Colombier 			im->r.min.x, im->r.min.y, im->r.max.x, im->r.max.y, im->depth);
650*7dd7cddfSDavid du Colombier 	width = Dx(im->r);
651*7dd7cddfSDavid du Colombier 	height = Dy(im->r);
652*7dd7cddfSDavid du Colombier 	bps = im->depth;	/* # bits per sample */
653*7dd7cddfSDavid du Colombier 	bitoff = 0;		/* # bit offset of beginning sample within first byte */
654*7dd7cddfSDavid du Colombier 	if (bps < 8) {
655*7dd7cddfSDavid du Colombier 		spb = 8 / bps;
656*7dd7cddfSDavid du Colombier 		bitoff = (im->r.min.x % spb) * bps;
657*7dd7cddfSDavid du Colombier 	}
658*7dd7cddfSDavid du Colombier 	if (bitoff != 0) {
659*7dd7cddfSDavid du Colombier /* 		# Postscript image wants beginning of line at beginning of byte */
660*7dd7cddfSDavid du Colombier 		r = im->r;
661*7dd7cddfSDavid du Colombier 		r.min.x -= bitoff/im->depth;
662*7dd7cddfSDavid du Colombier 		r.max.x -= bitoff/im->depth;
663*7dd7cddfSDavid du Colombier 		tmp = allocmemimage(r, im->chan);
664*7dd7cddfSDavid du Colombier 		if(tmp == nil){
665*7dd7cddfSDavid du Colombier 			fprint(2, "p9bitpost: allocmemimage failed: %r\n");
666*7dd7cddfSDavid du Colombier 			exits("alloc");
667*7dd7cddfSDavid du Colombier 		}
668*7dd7cddfSDavid du Colombier 		memimagedraw(tmp, r, im, im->r.min, nil, ZP);
669*7dd7cddfSDavid du Colombier 		im = tmp;
670*7dd7cddfSDavid du Colombier 	}
671*7dd7cddfSDavid du Colombier 	lsf = 0;
672*7dd7cddfSDavid du Colombier 	/* compact data to remove word-boundary padding */
673*7dd7cddfSDavid du Colombier 	bpl = bytesperline(im->r, im->depth);
674*7dd7cddfSDavid du Colombier 	n = bpl*Dy(im->r);
675*7dd7cddfSDavid du Colombier 	data = malloc(n);
676*7dd7cddfSDavid du Colombier 	if(data == nil){
677*7dd7cddfSDavid du Colombier 		fprint(2, "p9bitpost: malloc failed: %r\n");
678*7dd7cddfSDavid du Colombier 		exits("malloc");
679*7dd7cddfSDavid du Colombier 	}
680*7dd7cddfSDavid du Colombier 	for(i=0; i<Dy(im->r); i++){
681*7dd7cddfSDavid du Colombier 		/* memmove(data+bpl*i, byteaddr(im, Pt(im->r.min.x, im->r.min.y+i)), bpl); with inversion */
682*7dd7cddfSDavid du Colombier 		dst = data+bpl*i;
683*7dd7cddfSDavid du Colombier 		src = byteaddr(im, Pt(im->r.min.x, im->r.min.y+i));
684*7dd7cddfSDavid du Colombier 		for(j=0; j<bpl; j++)
685*7dd7cddfSDavid du Colombier 			*dst++ = 255 - *src++;
686*7dd7cddfSDavid du Colombier 	}
687*7dd7cddfSDavid du Colombier 	n4 = (n / 4) * 4;
688*7dd7cddfSDavid du Colombier 	for (i = 0; i < n4; i += 4){
689*7dd7cddfSDavid du Colombier 		cmap2ascii85(data+i, c85);
690*7dd7cddfSDavid du Colombier 		lsf += strlen((char *)c85);
691*7dd7cddfSDavid du Colombier 		Bprint(ioutb, "%s", c85);
692*7dd7cddfSDavid du Colombier 		if (lsf > 74) {
693*7dd7cddfSDavid du Colombier 			Bprint(ioutb, "\n");
694*7dd7cddfSDavid du Colombier 			lsf = 0;
695*7dd7cddfSDavid du Colombier 		}
696*7dd7cddfSDavid du Colombier 	}
697*7dd7cddfSDavid du Colombier 	nrest = n - n4;
698*7dd7cddfSDavid du Colombier 	if (nrest != 0) {
699*7dd7cddfSDavid du Colombier 		uchar foo[4];
700*7dd7cddfSDavid du Colombier 
701*7dd7cddfSDavid du Colombier 		for (i=0; i<nrest; i++)
702*7dd7cddfSDavid du Colombier 			foo[i] = data[n4+i];
703*7dd7cddfSDavid du Colombier 		for (i=nrest; i<4; i++)
704*7dd7cddfSDavid du Colombier 			foo[i] = '\0';
705*7dd7cddfSDavid du Colombier 		cmap2ascii85(foo, c85);
706*7dd7cddfSDavid du Colombier 		if (strcmp((char *)c85, "z") == 0 )
707*7dd7cddfSDavid du Colombier 			strcpy((char *)c85, "!!!!!");
708*7dd7cddfSDavid du Colombier 		Bprint(ioutb, "%.*s", nrest+1, c85);
709*7dd7cddfSDavid du Colombier 	}
710*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "\n~>");
711*7dd7cddfSDavid du Colombier 	Bprint(ioutb, "\n");
712*7dd7cddfSDavid du Colombier 	freememimage(tmp);
713*7dd7cddfSDavid du Colombier }
714*7dd7cddfSDavid du Colombier 
715*7dd7cddfSDavid du Colombier int
716*7dd7cddfSDavid du Colombier image2psfile(int fd, Memimage *im, int dpi) {
717*7dd7cddfSDavid du Colombier 	Rectangle r;
718*7dd7cddfSDavid du Colombier 	Rectangle bbox;
719*7dd7cddfSDavid du Colombier 	int e;
720*7dd7cddfSDavid du Colombier 	int paperlength = 792;
721*7dd7cddfSDavid du Colombier 	int paperwidth = 612;
722*7dd7cddfSDavid du Colombier 	int xmargin = 36;
723*7dd7cddfSDavid du Colombier 	int ymargin = 36;
724*7dd7cddfSDavid du Colombier 	double paperaspectratio;
725*7dd7cddfSDavid du Colombier 	double imageaspectratio;
726*7dd7cddfSDavid du Colombier 	Biobuf ioutb;
727*7dd7cddfSDavid du Colombier 	Memimage *tmp;
728*7dd7cddfSDavid du Colombier 
729*7dd7cddfSDavid du Colombier 	if(im->depth >= 8 && im->chan != CMAP8 && im->chan != GREY8){
730*7dd7cddfSDavid du Colombier 		/*
731*7dd7cddfSDavid du Colombier 		 * the postscript libraries can only handle [1248]-bit grey, 8-bit cmap,
732*7dd7cddfSDavid du Colombier 		 * and 24-bit color, so convert.
733*7dd7cddfSDavid du Colombier 		 */
734*7dd7cddfSDavid du Colombier 		tmp = allocmemimage(im->r, strtochan("b8g8r8"));
735*7dd7cddfSDavid du Colombier 		if(tmp == nil)
736*7dd7cddfSDavid du Colombier 			return 1;
737*7dd7cddfSDavid du Colombier 		memimagedraw(tmp, tmp->r, im, im->r.min, nil, ZP);
738*7dd7cddfSDavid du Colombier 		freememimage(im);
739*7dd7cddfSDavid du Colombier 		im = tmp;
740*7dd7cddfSDavid du Colombier 	}
741*7dd7cddfSDavid du Colombier 
742*7dd7cddfSDavid du Colombier 	Binit(&ioutb, fd, OWRITE);
743*7dd7cddfSDavid du Colombier  	r = im->r;
744*7dd7cddfSDavid du Colombier 	width = Dx(r);
745*7dd7cddfSDavid du Colombier 	height = Dy(r);
746*7dd7cddfSDavid du Colombier 	imageaspectratio = (double) width / (double) height;
747*7dd7cddfSDavid du Colombier 	if (landscape) {
748*7dd7cddfSDavid du Colombier 		paperaspectratio = ((double)paperlength - (ymargin * 2)) / ((double)paperwidth - (xmargin * 2));
749*7dd7cddfSDavid du Colombier 		if (dpi > 0) {
750*7dd7cddfSDavid du Colombier 			iwidth = width * 72 / dpi;
751*7dd7cddfSDavid du Colombier 			iheight = height * 72 / dpi;
752*7dd7cddfSDavid du Colombier 		} else if (imageaspectratio > paperaspectratio) {
753*7dd7cddfSDavid du Colombier 			iwidth = paperlength - (ymargin * 2);
754*7dd7cddfSDavid du Colombier 			iheight = iwidth / imageaspectratio;
755*7dd7cddfSDavid du Colombier 		} else {
756*7dd7cddfSDavid du Colombier 			iheight = paperwidth - (xmargin * 2);
757*7dd7cddfSDavid du Colombier 			iwidth  = iheight * imageaspectratio;
758*7dd7cddfSDavid du Colombier 		}
759*7dd7cddfSDavid du Colombier 		xstart = paperwidth - xmargin - (iheight * ymagnification);
760*7dd7cddfSDavid du Colombier 		ystart = paperlength - ymargin;
761*7dd7cddfSDavid du Colombier 		rotation = -90;
762*7dd7cddfSDavid du Colombier 	} else {
763*7dd7cddfSDavid du Colombier 		paperaspectratio = ((double)paperwidth - (xmargin * 2)) / ((double)paperlength - (ymargin * 2));
764*7dd7cddfSDavid du Colombier 		if (dpi > 0) {
765*7dd7cddfSDavid du Colombier 			iwidth = width * 72 / dpi;
766*7dd7cddfSDavid du Colombier 			iheight = height * 72 / dpi;
767*7dd7cddfSDavid du Colombier 		} else if (imageaspectratio > paperaspectratio) {
768*7dd7cddfSDavid du Colombier 			iwidth = paperwidth - (xmargin * 2);
769*7dd7cddfSDavid du Colombier 			iheight = iwidth / imageaspectratio;
770*7dd7cddfSDavid du Colombier 		} else {
771*7dd7cddfSDavid du Colombier 			iheight = paperlength - (ymargin * 2);
772*7dd7cddfSDavid du Colombier 			iwidth  = iheight * imageaspectratio;
773*7dd7cddfSDavid du Colombier 		}
774*7dd7cddfSDavid du Colombier 		xstart = xmargin;
775*7dd7cddfSDavid du Colombier 		ystart = paperlength - ymargin - (iheight * ymagnification);
776*7dd7cddfSDavid du Colombier 		rotation = 0;
777*7dd7cddfSDavid du Colombier 	}
778*7dd7cddfSDavid du Colombier 	bbox = Rect(xstart,ystart,xstart+iwidth,ystart+iheight);
779*7dd7cddfSDavid du Colombier 	e = preamble(&ioutb, bbox);
780*7dd7cddfSDavid du Colombier 	if(e != 0)
781*7dd7cddfSDavid du Colombier 		return e;
782*7dd7cddfSDavid du Colombier 	Bprint(&ioutb, "%%%%Page: 1\n%%%%BeginPageSetup\n");
783*7dd7cddfSDavid du Colombier 	Bprint(&ioutb, "/pgsave save def\n");
784*7dd7cddfSDavid du Colombier 	Bprint(&ioutb, "%%%%EndPageSetup\n");
785*7dd7cddfSDavid du Colombier 	bps = im->depth;
786*7dd7cddfSDavid du Colombier 	Bprint(&ioutb, "%d 0 %d %d %d %d %d %d %s doimage\n", iheight, iwidth, ystart, xstart, height, width, bps, im->flags&Fgrey ? "true" : "false");
787*7dd7cddfSDavid du Colombier  	imagebits(&ioutb, im);
788*7dd7cddfSDavid du Colombier 	Bprint(&ioutb, "pgsave restore\nshowpage\n");
789*7dd7cddfSDavid du Colombier 	e = trailer(&ioutb, 1);
790*7dd7cddfSDavid du Colombier 	if(e != 0)
791*7dd7cddfSDavid du Colombier 		return e;
792*7dd7cddfSDavid du Colombier 	Bterm(&ioutb);
793*7dd7cddfSDavid du Colombier 	return 0;
794*7dd7cddfSDavid du Colombier }
795*7dd7cddfSDavid du Colombier 
796*7dd7cddfSDavid du Colombier /* set local variables by string and pointer to its value
797*7dd7cddfSDavid du Colombier  * the variables are:
798*7dd7cddfSDavid du Colombier  *   int magnification
799*7dd7cddfSDavid du Colombier  *   int landscape
800*7dd7cddfSDavid du Colombier  *   char *Patch
801*7dd7cddfSDavid du Colombier  */
802*7dd7cddfSDavid du Colombier void
803*7dd7cddfSDavid du Colombier psopt(char *s, void *val)
804*7dd7cddfSDavid du Colombier {
805*7dd7cddfSDavid du Colombier 	if(s == nil)
806*7dd7cddfSDavid du Colombier 		return;
807*7dd7cddfSDavid du Colombier 	if(strcmp("xmagnification", s) == 0)
808*7dd7cddfSDavid du Colombier 		xmagnification = *((double *)val);
809*7dd7cddfSDavid du Colombier 	if(strcmp("ymagnification", s) == 0)
810*7dd7cddfSDavid du Colombier 		ymagnification = *((double *)val);
811*7dd7cddfSDavid du Colombier 	if(strcmp("landscape", s) == 0)
812*7dd7cddfSDavid du Colombier 		landscape = *((int *)val);
813*7dd7cddfSDavid du Colombier 	if(strcmp("Patch", s) == 0)
814*7dd7cddfSDavid du Colombier 		Patch = *((char **)val);
815*7dd7cddfSDavid du Colombier }
816