blob: 6838b77489db8ba1dcb5d3205f2c9f62710ca728 [file] [log] [blame]
wkja31db672004-04-21 01:15:41 +00001#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*/
17void
18gbproc(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
62void
63gb_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);
rsc536f9b82006-05-21 18:57:51 +000091 OUT(out, ob, 0);
wkja31db672004-04-21 01:15:41 +000092}
93
94void
95gb_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}