Commit Diff


commit - a6ad39aaaa36b8aadc5c35bfc803afbde32918c0
commit + 5f0fa185d0a978b45de5bf206193769596c056b5
blob - 164b1bd6ca461bb9c83d6c67da70e98105d2033c
blob + 2eeb404f66f12b81414a43617fbd77d9b88653c1
--- src/cmd/fontsrv/a.h
+++ src/cmd/fontsrv/a.h
@@ -4,19 +4,22 @@ int nxfont;
 
 enum {
 	SubfontSize = 32,
-	SubfontMask = (1<<16)/SubfontSize - 1,
+	MaxSubfont = (Runemax+1)/SubfontSize,
 };
 
 struct XFont
 {
 	char *name;
 	int loaded;
-	uchar range[(1<<16)/SubfontSize];	// range[i] == whether to have subfont i*SubfontSize to (i+1)*SubfontSize - 1.
-	int nrange;
+	uchar range[MaxSubfont]; // range[i] = fontfile starting at i*SubfontSize exists
+	ushort file[MaxSubfont];	// file[i] == fontfile i's lo rune / SubfontSize
+	int nfile;
 	int unit;
 	double height;
 	double originy;
 	void (*loadheight)(XFont*, int, int*, int*);
+	char *fonttext;
+	int nfonttext;
 
 	// fontconfig workarround, as FC_FULLNAME does not work for matching fonts.
 	char *fontfile;
blob - b4dadd90a0a2fc4954636a0fbdef626817593792
blob + 9829b5a89ae716625d1a4751089675bcc67d8be6
--- src/cmd/fontsrv/mac.c
+++ src/cmd/fontsrv/mac.c
@@ -200,9 +200,12 @@ load(XFont *f)
 	f->loadheight = fontheight;
 
 	// enable all Unicode ranges
+	if(nelem(f->file) > 0xffff)
+		sysfatal("too many subfiles"); // f->file holds ushorts
 	for(i=0; i<nelem(f->range); i++) {
 		f->range[i] = 1;
-		f->nrange++;
+		f->file[i] = i;
+		f->nfile++;
 	}
 }
 
@@ -233,7 +236,6 @@ mksubfont(XFont *f, char *name, int lo, int hi, int si
 	if(font == nil)
 		return nil;
 
-
 	bbox = CTFontGetBoundingBox(font);
 	x = (int)(bbox.size.width*2 + 0.99999999);
 
blob - ebab624975823d8d7fa561bec2597c9b75efd3ae
blob + b2189be98fbe3f33ecf24f6ad4eba56a9cd406f0
--- src/cmd/fontsrv/main.c
+++ src/cmd/fontsrv/main.c
@@ -52,7 +52,7 @@ enum
 #define QFONT(p) (((p) >> 4) & 0xFFFF)
 #define QSIZE(p) (((p) >> 20) & 0xFF)
 #define QANTIALIAS(p) (((p) >> 28) & 0x1)
-#define QRANGE(p) (((p) >> 29) & SubfontMask)
+#define QRANGE(p) (((p) >> 29) & 0xFFFFFF)
 static int sizes[] = { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 24, 28 };
 
 static vlong
@@ -102,7 +102,7 @@ dostat(vlong path, Qid *qid, Dir *dir)
 	case Qfontfile:
 		f = &xfont[QFONT(path)];
 		load(f);
-		length = 11+1+11+1+f->nrange*(6+1+6+1+9+1);
+		length = 11+1+11+1+f->nfile*(6+1+6+1+9+1);
 		name = "font";
 		break;
 
@@ -189,9 +189,9 @@ xwalk1(Fid *fid, char *name, Qid *qid)
 			goto NotFound;
 		p++;
 		n = strtoul(p, &p, 16);
-		if(p != name+5 || n%SubfontSize != 0 || strcmp(p, ".bit") != 0 || !f->range[(n/SubfontSize) & SubfontMask])
+		if(p < name+5 || p > name+5 && name[1] == '0' || n%SubfontSize != 0 || n/SubfontSize >= MaxSubfont || strcmp(p, ".bit") != 0 || !f->range[n/SubfontSize])
 			goto NotFound;
-		path += Qsubfontfile - Qsizedir + qpath(0, 0, 0, 0, (n/SubfontSize) & SubfontMask);
+		path += Qsubfontfile - Qsizedir + qpath(0, 0, 0, 0, n/SubfontSize);
 		break;
 	}
 Found:
@@ -229,7 +229,6 @@ sizegen(int i, Dir *d, void *v)
 	vlong path;
 	Fid *fid;
 	XFont *f;
-	int j;
 
 	fid = v;
 	path = fid->qid.path;
@@ -240,15 +239,10 @@ sizegen(int i, Dir *d, void *v)
 	i--;
 	f = &xfont[QFONT(path)];
 	load(f);
-	for(j=0; j<nelem(f->range); j++) {
-		if(f->range[j] == 0)
-			continue;
-		if(i == 0) {
-			path += Qsubfontfile - Qsizedir;
-			path += qpath(0, 0, 0, 0, j);
-			goto Done;
-		}
-		i--;
+	if(i < f->nfile) {
+		path += Qsubfontfile - Qsizedir;
+		path += qpath(0, 0, 0, 0, f->file[i]);
+		goto Done;
 	}
 	return -1;
 
@@ -315,23 +309,22 @@ xread(Req *r)
 			readstr(r, "font missing\n");
 			break;
 		}
-		height = 0;
-		ascent = 0;
-		if(f->unit > 0) {
-			height = f->height * (int)QSIZE(path)/f->unit + 0.99999999;
-			ascent = height - (int)(-f->originy * (int)QSIZE(path)/f->unit + 0.99999999);
-		}
-		if(f->loadheight != nil)
-			f->loadheight(f, QSIZE(path), &height, &ascent);
-		fmtprint(&fmt, "%11d %11d\n", height, ascent);
-		for(i=0; i<nelem(f->range); i++) {
-			if(f->range[i] == 0)
-				continue;
-			fmtprint(&fmt, "0x%04x 0x%04x x%04x.bit\n", i*SubfontSize, ((i+1)*SubfontSize) - 1, i*SubfontSize);
+		if(f->fonttext == nil) {
+			height = 0;
+			ascent = 0;
+			if(f->unit > 0) {
+				height = f->height * (int)QSIZE(path)/f->unit + 0.99999999;
+				ascent = height - (int)(-f->originy * (int)QSIZE(path)/f->unit + 0.99999999);
+			}
+			if(f->loadheight != nil)
+				f->loadheight(f, QSIZE(path), &height, &ascent);
+			fmtprint(&fmt, "%11d %11d\n", height, ascent);
+			for(i=0; i<f->nfile; i++)
+				fmtprint(&fmt, "0x%04x 0x%04x x%04x.bit\n", f->file[i]*SubfontSize, ((f->file[i]+1)*SubfontSize) - 1, f->file[i]*SubfontSize);
+			f->fonttext = fmtstrflush(&fmt);
+			f->nfonttext = strlen(f->fonttext);
 		}
-		data = fmtstrflush(&fmt);
-		readstr(r, data);
-		free(data);
+		readbuf(r, f->fonttext, f->nfonttext);
 		break;
 	case Qsubfontfile:
 		f = &xfont[QFONT(path)];
blob - 0f6b97bbf4b0fb4f2e2e9b8d7630aa041320b312
blob + c78ad03667f1cc7f97a4d8de509b689d7b6006d1
--- src/cmd/fontsrv/x11.c
+++ src/cmd/fontsrv/x11.c
@@ -85,20 +85,23 @@ load(XFont *f)
 
 		int idx = charcode/SubfontSize;
 
-		if(charcode > 0xffff)
+		if(charcode > Runemax)
 			break;
 
-		if(!f->range[idx]) {
+		if(!f->range[idx])
 			f->range[idx] = 1;
-			f->nrange++;
-		}
 	}
+	FT_Done_Face(face);
+
 	// libdraw expects U+0000 to be present
-	if(!f->range[0]) {
+	if(!f->range[0])
 		f->range[0] = 1;
-		f->nrange++;
-	}
-	FT_Done_Face(face);
+
+	// fix up file list
+	for(i=0; i<nelem(f->range); i++)
+		if(f->range[i])
+			f->file[f->nfile++] = i;
+
 	f->loaded = 1;
 }