Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#ifdef	PLAN9
2
#include	<u.h>
3
#include	<libc.h>
4
#include	<bio.h>
5
#else
6
#include	<stdio.h>
7
#include	<unistd.h>
8
#include	"plan9.h"
9
#endif
10
#include	"hdr.h"
11
#include	"conv.h"
12
#include	"gb.h"
13
 
14
/*
15
	a state machine for interpreting gb.
16
*/
17
void
18
gbproc(int c, Rune **r, long input_loc)
19
{
20
	static enum { state0, state1 } state = state0;
21
	static int lastc;
22
	long n, ch, cold = c;
23
 
24
	switch(state)
25
	{
26
	case state0:	/* idle state */
27
		if(c < 0)
28
			return;
29
		if(c >= 0xA1){
30
			lastc = c;
31
			state = state1;
32
			return;
33
		}
34
		emit(c);
35
		return;
36
 
37
	case state1:	/* seen a font spec */
38
		if(c >= 0xA1)
39
			n = (lastc-0xA0)*100 + (c-0xA0);
40
		else {
41
			nerrors++;
42
			if(squawk)
43
				EPR "%s: bad gb glyph %d (from 0x%x,0x%lx) near byte %ld in %s\n", argv0, c-0xA0, lastc, cold, input_loc, file);
44
			if(!clean)
45
				emit(BADMAP);
46
			state = state0;
47
			return;
48
		}
49
		ch = tabgb[n];
50
		if(ch < 0){
51
			nerrors++;
52
			if(squawk)
53
				EPR "%s: unknown gb %ld (from 0x%x,0x%lx) near byte %ld in %s\n", argv0, n, lastc, cold, input_loc, file);
54
			if(!clean)
55
				emit(BADMAP);
56
		} else
57
			emit(ch);
58
		state = state0;
59
	}
60
}
61
 
62
void
63
gb_in(int fd, long *notused, struct convert *out)
64
{
65
	Rune ob[N];
66
	Rune *r, *re;
67
	uchar ibuf[N];
68
	int n, i;
69
	long nin;
70
 
71
	USED(notused);
72
	r = ob;
73
	re = ob+N-3;
74
	nin = 0;
75
	while((n = read(fd, ibuf, sizeof ibuf)) > 0){
76
		for(i = 0; i < n; i++){
77
			gbproc(ibuf[i], &r, nin++);
78
			if(r >= re){
79
				OUT(out, ob, r-ob);
80
				r = ob;
81
			}
82
		}
83
		if(r > ob){
84
			OUT(out, ob, r-ob);
85
			r = ob;
86
		}
87
	}
88
	gbproc(-1, &r, nin);
89
	if(r > ob)
90
		OUT(out, ob, r-ob);
91
	OUT(out, ob, 0);
92
}
93
 
94
void
95
gb_out(Rune *base, int n, long *notused)
96
{
97
	char *p;
98
	int i;
99
	Rune r;
100
	static int first = 1;
101
 
102
	USED(notused);
103
	if(first){
104
		first = 0;
105
		for(i = 0; i < NRUNE; i++)
106
			tab[i] = -1;
107
		for(i = 0; i < GBMAX; i++)
108
			if(tabgb[i] != -1)
109
				tab[tabgb[i]] = i;
110
	}
111
	nrunes += n;
112
	p = obuf;
113
	for(i = 0; i < n; i++){
114
		r = base[i];
115
		if(r < 128)
116
			*p++ = r;
117
		else {
118
			if(tab[r] != -1){
119
				r = tab[r];
120
				*p++ = 0xA0 + (r/100);
121
				*p++ = 0xA0 + (r%100);
122
				continue;
123
			}
124
			if(squawk)
125
				EPR "%s: rune 0x%x not in output cs\n", argv0, r);
126
			nerrors++;
127
			if(clean)
128
				continue;
129
			*p++ = BYTEBADMAP;
130
		}
131
	}
132
	noutput += p-obuf;
133
	if(p > obuf)
134
		write(1, obuf, p-obuf);
135
}