conv_gb.c (2228B)
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 }