aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/tcs/conv_gb.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/tcs/conv_gb.c')
-rw-r--r--src/cmd/tcs/conv_gb.c134
1 files changed, 134 insertions, 0 deletions
diff --git a/src/cmd/tcs/conv_gb.c b/src/cmd/tcs/conv_gb.c
new file mode 100644
index 00000000..70835257
--- /dev/null
+++ b/src/cmd/tcs/conv_gb.c
@@ -0,0 +1,134 @@
+#ifdef PLAN9
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#else
+#include <stdio.h>
+#include <unistd.h>
+#include "plan9.h"
+#endif
+#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)
+ 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);
+ if(!clean)
+ emit(BADMAP);
+ state = state0;
+ return;
+ }
+ ch = tabgb[n];
+ if(ch < 0){
+ nerrors++;
+ if(squawk)
+ EPR "%s: unknown gb %ld (from 0x%x,0x%lx) near byte %ld in %s\n", argv0, n, lastc, cold, input_loc, file);
+ if(!clean)
+ emit(BADMAP);
+ } else
+ emit(ch);
+ state = state0;
+ }
+}
+
+void
+gb_in(int fd, long *notused, struct convert *out)
+{
+ Rune ob[N];
+ Rune *r, *re;
+ uchar ibuf[N];
+ int n, i;
+ long nin;
+
+ USED(notused);
+ 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);
+}
+
+void
+gb_out(Rune *base, int n, long *notused)
+{
+ char *p;
+ int i;
+ Rune r;
+ static int first = 1;
+
+ USED(notused);
+ 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(tab[r] != -1){
+ r = tab[r];
+ *p++ = 0xA0 + (r/100);
+ *p++ = 0xA0 + (r%100);
+ continue;
+ }
+ if(squawk)
+ EPR "%s: rune 0x%x not in output cs\n", argv0, r);
+ nerrors++;
+ if(clean)
+ continue;
+ *p++ = BYTEBADMAP;
+ }
+ }
+ noutput += p-obuf;
+ if(p > obuf)
+ write(1, obuf, p-obuf);
+}