ref: 53fe82ee861967f0c02dbec7901660470da79098
dir: /sys/src/cmd/tcs/conv_gb.c/
#include <u.h> #include <libc.h> #include <bio.h> #include "hdr.h" #include "conv.h" #include "gb.h" /* a state machine for interpreting gb. */ void gbproc(int c, Rune **r, long input_loc) { static enum { state0, state1 } state = state0; static int lastc; long n, ch, cold = c; switch(state) { case state0: /* idle state */ if(c < 0) return; if(c >= 0xA1){ lastc = c; state = state1; return; } emit(c); return; case state1: /* seen a font spec */ if(c >= 0xA1) n = (lastc-0xA0)*100 + (c-0xA0); else { nerrors++; if(squawk) warn("bad gb glyph %d (from 0x%x,0x%lx) near byte %ld in %s", c-0xA0, lastc, cold, input_loc, file); if(!clean) emit(BADMAP); state = state0; return; } ch = tabgb[n]; if(ch < 0){ nerrors++; if(squawk) warn("unknown gb %ld (from 0x%x,0x%lx) near byte %ld in %s", n, lastc, cold, input_loc, file); if(!clean) emit(BADMAP); } else emit(ch); state = state0; } } void gb_in(int fd, long *, struct convert *out) { Rune ob[N]; Rune *r, *re; uchar ibuf[N]; int n, i; long nin; r = ob; re = ob+N-3; nin = 0; while((n = read(fd, ibuf, sizeof ibuf)) > 0){ for(i = 0; i < n; i++){ gbproc(ibuf[i], &r, nin++); if(r >= re){ OUT(out, ob, r-ob); r = ob; } } if(r > ob){ OUT(out, ob, r-ob); r = ob; } } gbproc(-1, &r, nin); if(r > ob) OUT(out, ob, r-ob); OUT(out, ob, 0); } void gb_out(Rune *base, int n, long *) { char *p; int i; Rune r; static int first = 1; if(first){ first = 0; for(i = 0; i < NRUNE; i++) tab[i] = -1; for(i = 0; i < GBMAX; i++) if(tabgb[i] != -1) tab[tabgb[i]] = i; } nrunes += n; p = obuf; for(i = 0; i < n; i++){ r = base[i]; if(r < 128) *p++ = r; else { if(r < NRUNE && tab[r] != -1){ r = tab[r]; *p++ = 0xA0 + (r/100); *p++ = 0xA0 + (r%100); continue; } if(squawk) warn("rune 0x%x not in output cs", r); nerrors++; if(clean) continue; *p++ = BYTEBADMAP; } } noutput += p-obuf; if(p > obuf) write(1, obuf, p-obuf); }