aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/tcs/font
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/tcs/font')
-rw-r--r--src/cmd/tcs/font/bbits.c89
-rw-r--r--src/cmd/tcs/font/bmap.c34
-rw-r--r--src/cmd/tcs/font/font.c34
-rw-r--r--src/cmd/tcs/font/gbits.c137
-rw-r--r--src/cmd/tcs/font/gmap.c34
-rw-r--r--src/cmd/tcs/font/hdr.h11
-rw-r--r--src/cmd/tcs/font/kbits.c93
-rw-r--r--src/cmd/tcs/font/kmap.c34
-rw-r--r--src/cmd/tcs/font/main.c87
-rw-r--r--src/cmd/tcs/font/merge.c127
-rw-r--r--src/cmd/tcs/font/mkfile103
-rw-r--r--src/cmd/tcs/font/qbits.c93
12 files changed, 876 insertions, 0 deletions
diff --git a/src/cmd/tcs/font/bbits.c b/src/cmd/tcs/font/bbits.c
new file mode 100644
index 00000000..71c9b004
--- /dev/null
+++ b/src/cmd/tcs/font/bbits.c
@@ -0,0 +1,89 @@
+#include <u.h>
+#include <libc.h>
+#include <libg.h>
+#include <bio.h>
+#include "hdr.h"
+
+enum {
+ Charsperfont = 157,
+ Void1b = (0xC6-0xA2)*Charsperfont+0x3f,
+ Void1e = (0xC9-0xA2)*Charsperfont - 1 ,
+};
+
+Bitmap *
+breadbits(char *file, int n, long *chars, int size, uchar *bits, int **doneptr)
+{
+ Bitmap *bm;
+ Biobuf *bf;
+ int i, j, byt;
+ int nch;
+ long c;
+ uchar *b, *nbits;
+ int *done;
+ static uchar missing[32] = {0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x08, 0x00, 0x04, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40, 0x00, 0x20, 0x00, 0x10, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ uchar buf[32];
+
+ bf = Bopen(file, OREAD);
+ if(bf == 0){
+ fprint(2, "%s: %s: %r\n", argv0, file);
+ exits("bitfile open error");
+ }
+ done = (int *)malloc(n*sizeof(done[0]));
+ if(done == 0){
+ fprint(2, "%s: malloc error (%d bytes)\n", argv0, n);
+ exits("malloc error");
+ }
+ *doneptr = done;
+ byt = size/8;
+ nch = 0;
+ for(i = 0; i < n; i++){
+ done[i] = 1;
+ nch++;
+ c = chars[i];
+ if((c >= Void1b) && (c <= Void1e)){
+ done[i] = 0;
+ nch--;
+ continue;
+ }
+ /* magic via presotto for calculating the seek */
+ j = c;
+ if(c >= 2*Charsperfont)
+ j += 294; /* baffling hole between A3 and A4 */
+ if(c > Void1e)
+ j -= 3*Charsperfont - 0x3F;
+ j *= byt*size; /* bytes per char */
+ j += 256; /* 256 front matter */
+ Bseek(bf, j, 0);
+ Bread(bf, buf, sizeof(missing));
+ if(memcmp(buf, missing, sizeof(missing)) == 0){
+ done[i] = 0;
+ nch--;
+ continue;
+ }
+ Bseek(bf, j, 0);
+ b = bits + i*byt;
+ for(j = 0; j < size; j++){ /* rows */
+ Bread(bf, b, byt);
+ b += n*byt;
+ }
+ }
+ nbits = (uchar *)malloc(nch*byt*size);
+ if(nbits == 0){
+ fprint(2, "%s: malloc error (%d bytes)\n", argv0, nch*byt);
+ exits("malloc error");
+ }
+ c = 0;
+ for(i = 0; i < n; i++)
+ if(done[i]){
+ for(j = 0; j < size; j++)
+ memmove(nbits+c*byt+j*nch*byt, bits+i*byt+j*n*byt, byt);
+ c++;
+ }
+ bm = balloc((Rectangle){(Point){0, 0}, (Point){nch*size, size}}, 0);
+ if(bm == 0){
+ fprint(2, "%s: balloc failure\n", argv0);
+ exits("balloc failure");
+ }
+ wrbitmap(bm, 0, size, nbits);
+ return(bm);
+}
diff --git a/src/cmd/tcs/font/bmap.c b/src/cmd/tcs/font/bmap.c
new file mode 100644
index 00000000..7861d658
--- /dev/null
+++ b/src/cmd/tcs/font/bmap.c
@@ -0,0 +1,34 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <libg.h>
+#include "hdr.h"
+#include "../big5.h"
+
+/*
+ map: put big5 for runes from..to into chars
+*/
+
+void
+bmap(int from, int to, long *chars)
+{
+ long *l, *ll;
+ int k, k1, n;
+
+ for(n = from; n <= to; n++)
+ chars[n-from] = 0;
+ for(l = tabbig5, ll = tabbig5+BIG5MAX; l < ll; l++)
+ if((*l >= from) && (*l <= to))
+ chars[*l-from] = l-tabbig5;
+ k = 0;
+ k1 = 0; /* not necessary; just shuts ken up */
+ for(n = from; n <= to; n++)
+ if(chars[n-from] == 0){
+ k++;
+ k1 = n;
+ }
+ if(k){
+ fprint(2, "%s: %d/%d chars found (missing include 0x%x=%d)\n", argv0, (to-from+1-k), to-from+1, k1, k1);
+ /*exits("map problem");/**/
+ }
+}
diff --git a/src/cmd/tcs/font/font.c b/src/cmd/tcs/font/font.c
new file mode 100644
index 00000000..75e25128
--- /dev/null
+++ b/src/cmd/tcs/font/font.c
@@ -0,0 +1,34 @@
+#include <u.h>
+#include <libc.h>
+#include <libg.h>
+#include <bio.h>
+#include "hdr.h"
+
+Subfont *
+bf(int n, int size, Bitmap *b, int *done)
+{
+ Fontchar *fc;
+ int i, j;
+ Subfont *f;
+
+ fc = (Fontchar *)malloc(sizeof(Fontchar)*(n+1));
+ if(fc == 0){
+ fprint(2, "%s: fontchar malloc(%d) failure\n", argv0, sizeof(Fontchar)*(n+1));
+ exits("fontchar malloc failure");
+ }
+ j = 0;
+ for(i = 0; i <= n; i++){
+ fc[i] = (Fontchar){j, 0, size, 0, size};
+ if(done[i])
+ j += size;
+ else
+ fc[i].width = 0;
+ }
+ fc[n] = (Fontchar){j, 0, size, 0, size};
+ f = subfalloc(n, size, size*7/8, fc, b, ~0, ~0);
+ if(f == 0){
+ fprint(2, "%s: falloc failure\n", argv0);
+ exits("falloc failure");
+ }
+ return(f);
+}
diff --git a/src/cmd/tcs/font/gbits.c b/src/cmd/tcs/font/gbits.c
new file mode 100644
index 00000000..6173907d
--- /dev/null
+++ b/src/cmd/tcs/font/gbits.c
@@ -0,0 +1,137 @@
+#include <u.h>
+#include <libc.h>
+#include <libg.h>
+#include <bio.h>
+#include "hdr.h"
+
+/*
+ this file reads bdf fonts. it is mapping dependent in that the ENCODING
+ field is font dependent.
+*/
+
+static char *field(Biobuf *, char *);
+
+Bitmap *
+greadbits(char *file, int n, long *chars, int size, uchar *bits, int **doneptr)
+{
+ Bitmap *bm;
+ Biobuf *bf;
+ char *p, *s;
+ long kmin, kmax;
+ int i, j, byt;
+ int nch;
+ long c;
+ uchar *b;
+ int *done;
+ uchar *nbits;
+ char buf[1024]; /* big enough for one char! */
+ static int dig[256] = {
+ ['0'] 0, ['1'] 1, ['2'] 2, ['3'] 3, ['4'] 4, ['5'] 5, ['6'] 6, ['7'] 7,
+ ['8'] 8, ['9'] 9, ['a'] 10, ['b'] 11, ['c'] 12, ['d'] 13, ['e'] 14, ['f'] 15,
+ };
+
+ bf = Bopen(file, OREAD);
+ if(bf == 0){
+ fprint(2, "%s: %s: %r\n", argv0, file);
+ exits("bitfile open error");
+ }
+ done = (int *)malloc(n*sizeof(done[0]));
+ if(done == 0){
+ fprint(2, "%s: malloc error (%d bytes)\n", argv0, n);
+ exits("malloc error");
+ }
+ *doneptr = done;
+ memset(done, 0, n*sizeof(done[0]));
+ kmin = 65536;
+ kmax = 0;
+ for(i = 0; i < n; i++){
+ c = chars[i];
+ if(kmin > c)
+ kmin = c;
+ if(kmax < c)
+ kmax = c;
+ }
+ nch = 0;
+ byt = size/8;
+ for(;;){
+ while(s = Brdline(bf, '\n')){
+ if(strncmp(s, "STARTCHAR", 9) == 0)
+ break;
+ }
+ if(s == 0)
+ break;
+ s = field(bf, "ENCODING");
+ c = strtol(s, (char **)0, 10);
+ c = (c/256 - 0xA0)*100 + (c%256 - 0xA0);
+ field(bf, "BITMAP");
+ p = buf;
+ for(i = 0; i < size; i++){ /* rows */
+ if((s = Brdline(bf, '\n')) == 0){
+ exits("bad bdf");
+ }
+ memcpy(p, s, 2*byt);
+ p += 2*byt;
+ }
+ field(bf, "ENDCHAR");
+ if((c < kmin) || (c > kmax))
+ continue;
+ for(i = 0; i < n; i++)
+ if(c == chars[i]){
+ nch++;
+ done[i] = 1;
+ p = buf;
+ b = bits + i*byt;
+ for(i = 0; i < size; i++){ /* rows */
+ for(j = 0; j < byt; j++){
+ *b++ = (dig[*p]<<4) | dig[p[1]];
+ p += 2;
+ }
+ b += (n-1)*byt;
+ }
+ break;
+ }
+ }
+ nbits = (uchar *)malloc(nch*byt*size);
+ if(nbits == 0){
+ fprint(2, "%s: malloc error (%d bytes)\n", argv0, nch*byt);
+ exits("malloc error");
+ }
+ c = 0;
+ for(i = 0; i < n; i++)
+ if(done[i]){
+ for(j = 0; j < size; j++)
+ memmove(nbits+c*byt+j*nch*byt, bits+i*byt+j*n*byt, byt);
+ c++;
+ }
+ bm = balloc((Rectangle){(Point){0, 0}, (Point){nch*size, size}}, 0);
+ if(bm == 0){
+ fprint(2, "%s: balloc failure\n", argv0);
+ exits("balloc failure");
+ }
+ wrbitmap(bm, 0, size, nbits);
+ for(i = 0; i < n; i++)
+ if(done[i] == 0){
+ /*fprint(2, "char 0x%x (%d) not found\n", chars[i], chars[i]);/**/
+ }
+ return(bm);
+}
+
+static char *
+field(Biobuf *bf, char *name)
+{
+ char *s;
+ int n;
+
+ n = strlen(name);
+ while(s = Brdline(bf, '\n')){
+ if(strncmp(s, name, n) == 0)
+ return(s+n);
+ if(strncmp(s, "ENDCHAR", 7) == 0){
+ fprint(2, "%s: char missing %s field\n", argv0, name);
+ exits("bad bdf");
+ }
+ }
+ fprint(2, "%s: char missing %s field; unexpected EOF\n", argv0, name);
+ exits("bad bdf");
+ return(0);
+}
diff --git a/src/cmd/tcs/font/gmap.c b/src/cmd/tcs/font/gmap.c
new file mode 100644
index 00000000..50f4e5c1
--- /dev/null
+++ b/src/cmd/tcs/font/gmap.c
@@ -0,0 +1,34 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <libg.h>
+#include "hdr.h"
+#include "../gb.h"
+
+/*
+ map: put gb for runes from..to into chars
+*/
+
+void
+gmap(int from, int to, long *chars)
+{
+ long *l, *ll;
+ int k, k1, n;
+
+ for(n = from; n <= to; n++)
+ chars[n-from] = 0;
+ for(l = tabgb, ll = tabgb+GBMAX; l < ll; l++)
+ if((*l >= from) && (*l <= to))
+ chars[*l-from] = l-tabgb;
+ k = 0;
+ k1 = 0; /* not necessary; just shuts ken up */
+ for(n = from; n <= to; n++)
+ if(chars[n-from] == 0){
+ k++;
+ k1 = n;
+ }
+ if(k){
+ fprint(2, "%s: %d/%d chars found (missing include 0x%x=%d)\n", argv0, (to-from+1-k), to-from+1, k1, k1);
+ /*exits("map problem");/**/
+ }
+}
diff --git a/src/cmd/tcs/font/hdr.h b/src/cmd/tcs/font/hdr.h
new file mode 100644
index 00000000..e401dc0b
--- /dev/null
+++ b/src/cmd/tcs/font/hdr.h
@@ -0,0 +1,11 @@
+typedef Bitmap *readbitsfn(char *, int, long *, int, uchar *, int **);
+typedef void mapfn(int, int, long *);
+
+extern Bitmap *kreadbits(char *file, int nc, long *chars, int size, uchar *bits, int **);
+extern void kmap(int from, int to, long *chars);
+extern Bitmap *breadbits(char *file, int nc, long *chars, int size, uchar *bits, int **);
+extern void bmap(int from, int to, long *chars);
+extern Bitmap *greadbits(char *file, int nc, long *chars, int size, uchar *bits, int **);
+extern void gmap(int from, int to, long *chars);
+extern Bitmap *qreadbits(char *file, int nc, long *chars, int size, uchar *bits, int **);
+extern Subfont *bf(int n, int size, Bitmap *b, int *);
diff --git a/src/cmd/tcs/font/kbits.c b/src/cmd/tcs/font/kbits.c
new file mode 100644
index 00000000..325edc33
--- /dev/null
+++ b/src/cmd/tcs/font/kbits.c
@@ -0,0 +1,93 @@
+#include <u.h>
+#include <libc.h>
+#include <libg.h>
+#include <bio.h>
+#include "hdr.h"
+
+Bitmap *
+kreadbits(char *file, int n, long *chars, int size, uchar *bits, int **doneptr)
+{
+ Bitmap *bm;
+ Biobuf *bf;
+ char *p;
+ long kmin, kmax;
+ int i, j, byt;
+ int nch;
+ long c;
+ uchar *b;
+ int *done;
+ uchar *nbits;
+ static int dig[256] = {
+ ['0'] 0, ['1'] 1, ['2'] 2, ['3'] 3, ['4'] 4, ['5'] 5, ['6'] 6, ['7'] 7,
+ ['8'] 8, ['9'] 9, ['a'] 10, ['b'] 11, ['c'] 12, ['d'] 13, ['e'] 14, ['f'] 15,
+ };
+
+ bf = Bopen(file, OREAD);
+ if(bf == 0){
+ fprint(2, "%s: %s: %r\n", argv0, file);
+ exits("bitfile open error");
+ }
+ done = (int *)malloc(n*sizeof(done[0]));
+ if(done == 0){
+ fprint(2, "%s: malloc error (%d bytes)\n", argv0, n);
+ exits("malloc error");
+ }
+ *doneptr = done;
+ memset(done, 0, n*sizeof(done[0]));
+ kmin = 65536;
+ kmax = 0;
+ for(i = 0; i < n; i++){
+ c = chars[i];
+ if(kmin > c)
+ kmin = c;
+ if(kmax < c)
+ kmax = c;
+ }
+ nch = 0;
+ byt = size/8;
+ Brdline(bf, '\n'); /* header line 1 */
+ Brdline(bf, '\n'); /* header line 2 */
+ while(p = (char *)Brdline(bf, '\n')){
+ c = strtol(p+17, (char **)0, 10);
+ if((c < kmin) || (c > kmax))
+ continue;
+ for(i = 0; i < n; i++)
+ if(c == chars[i]){
+ nch++;
+ done[i] = 1;
+ p += 25;
+ b = bits + i*byt;
+ for(i = 0; i < size; i++){ /* rows */
+ for(j = 0; j < byt; j++){
+ *b++ = (dig[*p]<<4) | dig[p[1]];
+ p += 2;
+ }
+ b += (n-1)*byt;
+ }
+ break;
+ }
+ }
+ nbits = (uchar *)malloc(nch*byt*size);
+ if(nbits == 0){
+ fprint(2, "%s: malloc error (%d bytes)\n", argv0, nch*byt);
+ exits("malloc error");
+ }
+ c = 0;
+ for(i = 0; i < n; i++)
+ if(done[i]){
+ for(j = 0; j < size; j++)
+ memmove(nbits+c*byt+j*nch*byt, bits+i*byt+j*n*byt, byt);
+ c++;
+ }
+ bm = balloc((Rectangle){(Point){0, 0}, (Point){nch*size, size}}, 0);
+ if(bm == 0){
+ fprint(2, "%s: balloc failure\n", argv0);
+ exits("balloc failure");
+ }
+ wrbitmap(bm, 0, size, nbits);
+ for(i = 0; i < n; i++)
+ if(done[i] == 0){
+ /*fprint(2, "char 0x%x (%d) not found\n", chars[i], chars[i]);/**/
+ }
+ return(bm);
+}
diff --git a/src/cmd/tcs/font/kmap.c b/src/cmd/tcs/font/kmap.c
new file mode 100644
index 00000000..3266ed41
--- /dev/null
+++ b/src/cmd/tcs/font/kmap.c
@@ -0,0 +1,34 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <libg.h>
+#include "hdr.h"
+#include "../kuten208.h"
+
+/*
+ map: put kuten for runes from..to into chars
+*/
+
+void
+kmap(int from, int to, long *chars)
+{
+ long *l, *ll;
+ int k, k1, n;
+
+ for(n = from; n <= to; n++)
+ chars[n-from] = 0;
+ for(l = tabkuten208, ll = tabkuten208+KUTEN208MAX; l < ll; l++)
+ if((*l >= from) && (*l <= to))
+ chars[*l-from] = l-tabkuten208;
+ k = 0;
+ k1 = 0; /* not necessary; just shuts ken up */
+ for(n = from; n <= to; n++)
+ if(chars[n-from] == 0){
+ k++;
+ k1 = n;
+ }
+ if(k){
+ fprint(2, "%s: %d/%d chars found (missing include 0x%x=%d)\n", argv0, (to-from+1-k), to-from+1, k1, k1);
+ /*exits("map problem");/**/
+ }
+}
diff --git a/src/cmd/tcs/font/main.c b/src/cmd/tcs/font/main.c
new file mode 100644
index 00000000..acc3ea3f
--- /dev/null
+++ b/src/cmd/tcs/font/main.c
@@ -0,0 +1,87 @@
+#include <u.h>
+#include <libc.h>
+#include <libg.h>
+#include <bio.h>
+#include "hdr.h"
+
+/*
+ produces the bitmap for the designated han characters
+*/
+
+static void usage(void);
+enum { Jis = 0, Big5, Gb_bdf, Gb_qw };
+enum { Size24 = 0, Size16 };
+struct {
+ char *names[2];
+ mapfn *mfn;
+ readbitsfn *bfn;
+} source[] = {
+ [Jis] { "../han/jis.bits", "../han/jis16.bits", kmap, kreadbits },
+ [Big5] { "no 24 bit file", "../han/big5.16.bits", bmap, breadbits },
+ [Gb_bdf] { "no 24 bit file", "../han/cclib16fs.bdf", gmap, greadbits },
+ [Gb_qw] { "no 24 bit file", "no 16bit file", gmap, qreadbits },
+};
+
+void
+main(int argc, char **argv)
+{
+ int from, to;
+ int size = 24;
+ int src = Jis;
+ char *file = 0;
+ long nc, nb;
+ int x;
+ uchar *bits;
+ long *chars;
+ int raw = 0;
+ Bitmap *b, *b1;
+ Subfont *f;
+ int *found;
+
+ ARGBEGIN{
+ case 'f': file = ARGF(); break;
+ case 'r': raw = 1; break;
+ case '5': src = Big5; break;
+ case 's': size = 16; break;
+ case 'g': src = Gb_bdf; break;
+ case 'q': src = Gb_qw; break;
+ default: usage();
+ }ARGEND
+ if(file == 0)
+ file = source[src].names[(size==24)? Size24:Size16];
+ if(argc != 2)
+ usage();
+ from = strtol(argv[0], (char **)0, 0);
+ to = strtol(argv[1], (char **)0, 0);
+ binit(0, 0, "fontgen");
+ nc = to-from+1;
+ nb = size*size/8; /* bytes per char */
+ nb *= nc;
+ bits = (uchar *)malloc(nb);
+ chars = (long *)malloc(sizeof(long)*nc);
+ found = (int *)malloc(sizeof(found[0])*nc);
+ if(bits == 0 || chars == 0){
+ fprint(2, "%s: couldn't malloc %d bytes for %d chars\n", argv0, nb, nc);
+ exits("out of memory");
+ }
+ if(raw){
+ for(x = from; x <= to; x++)
+ chars[x-from] = x;
+ } else
+ source[src].mfn(from, to, chars);
+ memset(bits, 0, nb);
+ b = source[src].bfn(file, nc, chars, size, bits, &found);
+ b1 = balloc(b->r, b->ldepth);
+ bitblt(b1, b1->r.min, b, b->r, S);
+ f = bf(nc, size, b1, found);
+ wrbitmapfile(1, b);
+ wrsubfontfile(1, f);/**/
+ exits(0);
+}
+
+static void
+usage(void)
+{
+ fprint(2, "Usage: %s [-s] from to\n", argv0);
+ exits("usage");
+}
diff --git a/src/cmd/tcs/font/merge.c b/src/cmd/tcs/font/merge.c
new file mode 100644
index 00000000..35a5db39
--- /dev/null
+++ b/src/cmd/tcs/font/merge.c
@@ -0,0 +1,127 @@
+#include <u.h>
+#include <libc.h>
+#include <libg.h>
+#include <bio.h>
+
+static void usage(void);
+static void snarf(char *, int);
+static void choose(Fontchar *, Bitmap *, int, int, int);
+struct {
+ char *name;
+ Bitmap *bm;
+ Subfont *sf;
+} ft[1024];
+int nf;
+
+void
+main(int argc, char **argv)
+{
+ int i, errs;
+ Fontchar *fc;
+ Bitmap *b;
+ int nc, ht, as;
+ Subfont *f;
+
+ binit(0, 0, "font merge");
+ if(argc < 1)
+ usage();
+ nf = argc-1;
+ for(i = 0; i < nf; i++)
+ snarf(argv[i+1], i);
+ nc = ft[0].sf->n;
+ ht = ft[0].sf->height;
+ as = ft[0].sf->ascent;
+ errs = 0;
+ for(i = 0; i < nf; i++){
+ if(nc < ft[i].sf->n) nc = ft[i].sf->n;
+ if(ht != ft[1].sf->height){
+ fprint(2, "%s: %s.height=%d (!= %s.height=%d)\n", argv[0],
+ ft[i].name, ft[i].sf->height, ft[0].name, ht);
+ errs = 1;
+ }
+ if(as != ft[1].sf->ascent){
+ fprint(2, "%s: %s.ascent=%d (!= %s.ascent=%d)\n", argv[0],
+ ft[i].name, ft[i].sf->ascent, ft[0].name, ht);
+ errs = 1;
+ }
+ }
+ if(errs)
+ exits("param mismatch");
+ fc = (Fontchar *)malloc(nc*sizeof(Fontchar));
+ b = balloc(Rect(0, 0, nc*64, ht), ft[0].bm->ldepth);
+ if(b == 0 || fc == 0){
+ fprint(2, "%s: couldn't malloc %d chars\n", argv0, nc);
+ exits("out of memory");
+ }
+ bitblt(b, b->r.min, b, b->r, Zero);
+ choose(fc, b, nc, ht, as);
+ wrbitmapfile(1, b);
+bitblt(&screen, screen.r.min, b, b->r, S); bflush();sleep(5000);
+ f = subfalloc(nc, ht, as, fc, b, ~0, ~0);
+ wrsubfontfile(1, f);
+ exits(0);
+}
+
+static void
+usage(void)
+{
+ fprint(2, "Usage: %s file ...\n", argv0);
+ exits("usage");
+}
+
+static void
+snarf(char *name, int i)
+{
+ int fd;
+ Bitmap *b;
+
+ ft[i].name = name;
+ if((fd = open(name, OREAD)) < 0){
+ perror(name);
+ exits("font read");
+ }
+ if((b = rdbitmapfile(fd)) == 0){
+ fprint(2, "rdbitmapfile failed\n");
+ exits("font read");
+ }
+ if((ft[i].bm = balloc(b->r, b->ldepth)) == 0){
+ fprint(2, "ballocsnarf failed\n");
+ exits("font read");
+ }
+ bitblt(ft[i].bm, b->r.min, b, b->r, S);
+ if((ft[i].sf = rdsubfontfile(fd, b)) == 0){
+ fprint(2, "rdsubfontfile failed\n");
+ exits("font read");
+ }
+ close(fd);
+}
+
+static void
+choose(Fontchar *f, Bitmap *b, int nc, int ht, int as)
+{
+ int j;
+ Fontchar *info;
+ int lastx = 0;
+ int w, n;
+
+ for(n = 0; n < nc; n++, f++){
+ f->x = lastx;
+ for(j = 0; j < nf; j++){
+ if(n >= ft[j].sf->n)
+ continue;
+ info = ft[j].sf->info;
+ if(info[n+1].x != info[n].x)
+ goto found;
+ }
+ continue;
+ found:
+ f->left = info[n].left;
+ f->top = info[n].top;
+ f->bottom = info[n].bottom;
+ f->width = info[n].width;
+ w = info[n+1].x - info[n].x;
+ bitblt(b, Pt(0, lastx), ft[j].bm, Rect(0, info[n].x, ht, info[n+1].x), S);
+ lastx += w;
+ }
+ f->x = lastx;
+}
diff --git a/src/cmd/tcs/font/mkfile b/src/cmd/tcs/font/mkfile
new file mode 100644
index 00000000..0184be9b
--- /dev/null
+++ b/src/cmd/tcs/font/mkfile
@@ -0,0 +1,103 @@
+<$PLAN9/src/mkhdr
+NPROC=3
+
+OBJ=main.$O font.$O \
+ kmap.$O kbits.$O kuten208.$O \
+ bmap.$O bbits.$O big5.$O \
+ gmap.$O gbits.$O qbits.$O gb.$O
+
+$O.out: $OBJ
+ $LD $prereq -lbio -lg
+
+%.$O: %.c
+ $CC -w $stem.c
+
+$O: hdr.h
+
+kuten208.$O: ../kuten208.c
+ $CC -I.. -w ../kuten208.c
+big5.$O: ../big5.c
+ $CC -I.. -w ../big5.c
+gb.$O: ../gb.c
+ $CC -I.. -w ../gb.c
+
+kuten208.$O kmap.$O: ../kuten208.h
+big5.$O bmap.$O: ../big5.h
+gb.$O gmap.$O: ../gb.h
+
+clean:V:
+ rm -f [$OS].out *.[$OS] y.tab.? rc.*
+
+poot:V: merge
+ merge /lib/font/bit/gb/*.7000.24 > /dev/null
+
+merge: merge.c
+ $CC -w merge.c && vl -o merge merge.$O && rm merge.$O
+
+fonts:V: v.out rc.jis rc.big5
+ jis.rc
+ big5.rc
+
+rc.jis:VQD:
+ awk 'BEGIN {
+ fontsize = 512 # set this to chars/subfont
+ dest = "/lib/font/bit/jis"
+ print "#!/bin/rc"
+ printf "v.out -s 0x3000 0x303f > %s/jis3000.16\n", dest
+ printf "v.out -s 0x30a1 0x30fe > %s/katakana.16\n", dest
+ printf "v.out -s 0x3041 0x309e > %s/hiragana.16\n", dest
+ printf "v.out 0x3000 0x303f > %s/jis3000.24\n", dest
+ printf "v.out 0x30a1 0x30fe > %s/katakana.24\n", dest
+ printf "v.out 0x3041 0x309e > %s/hiragana.24\n", dest
+ for(i = 19968; i < 40865; i += fontsize)
+ printf "v.out -s 0x%x 0x%x > %s/jis%x.16\n", i, i+fontsize-1, dest, i
+ for(i = 19968; i < 40865; i += fontsize)
+ printf "v.out 0x%x 0x%x > %s/jis%x.24\n", i, i+fontsize-1, dest, i
+ exit
+ }' > $target
+ chmod 775 $target
+
+rc.big5:VQD:
+ awk 'BEGIN {
+ fontsize = 512 # set this to chars/subfont
+ dest = "/lib/font/bit/big5"
+ print "#!/bin/rc"
+ for(i = 19968; i < 40869; i += fontsize)
+ printf "v.out -5 -s 0x%x 0x%x > %s/%x.16\n", i, i+fontsize-1, dest, i
+ exit
+ }' > $target
+ chmod 775 $target
+
+rc.gb:VQD:
+ fn g{
+ x=$1
+ y=$2
+ z=$3
+ awk 'BEGIN {
+ fontsize = 512 # set this to chars/subfont
+ dest = "/lib/font/bit/gb/'$"x'."
+ opt = "'$"y'"
+ sz = "'$"z'"
+ print "#!/bin/rc"
+ printf "v.out %s 0x3000 0x303f > %s3000.%s\n", opt, dest, sz
+ printf "v.out %s 0x30a1 0x30fe > %skatakana.%s\n", opt, dest, sz
+ printf "v.out %s 0x3041 0x309e > %shiragana.%s\n", opt, dest, sz
+ printf "v.out %s 0x3100 0x312f > %sbopomofo.%s\n", opt, dest, sz
+ printf "v.out %s 0x3200 0x32ff > %s3200.%s\n", opt, dest, sz
+ for(i = 19968; i < 40869; i += fontsize)
+ printf "v.out %s 0x%x 0x%x > %s%x.%s\n", opt, i, i+fontsize-1, dest, i, sz
+ exit
+ }'
+ }
+ {
+ g TradSong '-q -f ../han/cfan24.ccf' 24
+ g FangSong '-q -f ../han/cfang24.ccf' 24
+ g Hei '-q -f ../han/chei24.ccf' 24
+ g Kai '-q -f ../han/ckai24.ccf' 24
+ g Song '-q -f ../han/csong24.ccf' 24
+ g Song '-g -s -f ../han/cclib16st.bdf' 16
+ g FangSong '-g -s -f ../han/cclib16fs.bdf' 16
+ } > $target
+ chmod 775 $target
+
+<$PLAN9/src/mkmany
diff --git a/src/cmd/tcs/font/qbits.c b/src/cmd/tcs/font/qbits.c
new file mode 100644
index 00000000..58cbd925
--- /dev/null
+++ b/src/cmd/tcs/font/qbits.c
@@ -0,0 +1,93 @@
+#include <u.h>
+#include <libc.h>
+#include <libg.h>
+#include <bio.h>
+#include "hdr.h"
+
+/* quwei encoding for gb */
+
+Bitmap *
+qreadbits(char *file, int n, long *chars, int size, uchar *bits, int **doneptr)
+{
+ Bitmap *bm;
+ Biobuf *bf;
+ char *p;
+ long kmin, kmax;
+ int i, j, byt;
+ int nch;
+ long c;
+ uchar *b;
+ int *done;
+ uchar *nbits;
+ static int dig[256] = {
+ ['0'] 0, ['1'] 1, ['2'] 2, ['3'] 3, ['4'] 4, ['5'] 5, ['6'] 6, ['7'] 7,
+ ['8'] 8, ['9'] 9, ['a'] 10, ['b'] 11, ['c'] 12, ['d'] 13, ['e'] 14, ['f'] 15,
+ };
+
+ bf = Bopen(file, OREAD);
+ if(bf == 0){
+ fprint(2, "%s: %s: %r\n", argv0, file);
+ exits("bitfile open error");
+ }
+ done = (int *)malloc(n*sizeof(done[0]));
+ if(done == 0){
+ fprint(2, "%s: malloc error (%d bytes)\n", argv0, n);
+ exits("malloc error");
+ }
+ *doneptr = done;
+ memset(done, 0, n*sizeof(done[0]));
+ kmin = 65536;
+ kmax = 0;
+ for(i = 0; i < n; i++){
+ c = chars[i];
+ if(kmin > c)
+ kmin = c;
+ if(kmax < c)
+ kmax = c;
+ }
+ nch = 0;
+ byt = size/8;
+ while(p = (char *)Brdline(bf, '\n')){
+ c = (p[0]-'0')*1000 + (p[1]-'0')*100 + (p[2]-'0')*10 + (p[3]-'0');
+ if((c < kmin) || (c > kmax))
+ continue;
+ for(i = 0; i < n; i++)
+ if(c == chars[i]){
+ nch++;
+ done[i] = 1;
+ p += 5;
+ b = bits + i*byt;
+ for(i = 0; i < size; i++){ /* rows */
+ for(j = 0; j < byt; j++){
+ *b++ = (dig[*p]<<4) | dig[p[1]];
+ p += 2;
+ }
+ b += (n-1)*byt;
+ }
+ break;
+ }
+ }
+ nbits = (uchar *)malloc(nch*byt*size);
+ if(nbits == 0){
+ fprint(2, "%s: malloc error (%d bytes)\n", argv0, nch*byt);
+ exits("malloc error");
+ }
+ c = 0;
+ for(i = 0; i < n; i++)
+ if(done[i]){
+ for(j = 0; j < size; j++)
+ memmove(nbits+c*byt+j*nch*byt, bits+i*byt+j*n*byt, byt);
+ c++;
+ }
+ bm = balloc((Rectangle){(Point){0, 0}, (Point){nch*size, size}}, 0);
+ if(bm == 0){
+ fprint(2, "%s: balloc failure\n", argv0);
+ exits("balloc failure");
+ }
+ wrbitmap(bm, 0, size, nbits);
+ for(i = 0; i < n; i++)
+ if(done[i] == 0){
+ /*fprint(2, "char 0x%x (%d) not found\n", chars[i], chars[i]);/**/
+ }
+ return(bm);
+}