aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/fontsrv
diff options
context:
space:
mode:
authorRuss Cox <rsc@swtch.com>2020-05-26 11:36:59 -0400
committerRuss Cox <rsc@swtch.com>2020-05-29 20:58:37 -0400
commit5f0fa185d0a978b45de5bf206193769596c056b5 (patch)
tree98c8c32d74ccf5bdc787b8c527de0cc2d5597bd1 /src/cmd/fontsrv
parenta6ad39aaaa36b8aadc5c35bfc803afbde32918c0 (diff)
downloadplan9port-5f0fa185d0a978b45de5bf206193769596c056b5.tar.gz
plan9port-5f0fa185d0a978b45de5bf206193769596c056b5.tar.bz2
plan9port-5f0fa185d0a978b45de5bf206193769596c056b5.zip
fontsrv: handle non-BMP runes on X11
Have to adjust algorithms to deal with much larger number of subfont files as well.
Diffstat (limited to 'src/cmd/fontsrv')
-rw-r--r--src/cmd/fontsrv/a.h9
-rw-r--r--src/cmd/fontsrv/mac.c6
-rw-r--r--src/cmd/fontsrv/main.c53
-rw-r--r--src/cmd/fontsrv/x11.c19
4 files changed, 44 insertions, 43 deletions
diff --git a/src/cmd/fontsrv/a.h b/src/cmd/fontsrv/a.h
index 164b1bd6..2eeb404f 100644
--- a/src/cmd/fontsrv/a.h
+++ b/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;
diff --git a/src/cmd/fontsrv/mac.c b/src/cmd/fontsrv/mac.c
index b4dadd90..9829b5a8 100644
--- a/src/cmd/fontsrv/mac.c
+++ b/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 size, int antialias)
if(font == nil)
return nil;
-
bbox = CTFontGetBoundingBox(font);
x = (int)(bbox.size.width*2 + 0.99999999);
diff --git a/src/cmd/fontsrv/main.c b/src/cmd/fontsrv/main.c
index ebab6249..b2189be9 100644
--- a/src/cmd/fontsrv/main.c
+++ b/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)];
diff --git a/src/cmd/fontsrv/x11.c b/src/cmd/fontsrv/x11.c
index 0f6b97bb..c78ad036 100644
--- a/src/cmd/fontsrv/x11.c
+++ b/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;
}