fontsrv: handle non-BMP runes on X11
Have to adjust algorithms to deal with much larger number of subfont files as well.
This commit is contained in:
parent
a6ad39aaaa
commit
5f0fa185d0
4 changed files with 45 additions and 44 deletions
|
|
@ -4,19 +4,22 @@ int nxfont;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
SubfontSize = 32,
|
SubfontSize = 32,
|
||||||
SubfontMask = (1<<16)/SubfontSize - 1,
|
MaxSubfont = (Runemax+1)/SubfontSize,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct XFont
|
struct XFont
|
||||||
{
|
{
|
||||||
char *name;
|
char *name;
|
||||||
int loaded;
|
int loaded;
|
||||||
uchar range[(1<<16)/SubfontSize]; // range[i] == whether to have subfont i*SubfontSize to (i+1)*SubfontSize - 1.
|
uchar range[MaxSubfont]; // range[i] = fontfile starting at i*SubfontSize exists
|
||||||
int nrange;
|
ushort file[MaxSubfont]; // file[i] == fontfile i's lo rune / SubfontSize
|
||||||
|
int nfile;
|
||||||
int unit;
|
int unit;
|
||||||
double height;
|
double height;
|
||||||
double originy;
|
double originy;
|
||||||
void (*loadheight)(XFont*, int, int*, int*);
|
void (*loadheight)(XFont*, int, int*, int*);
|
||||||
|
char *fonttext;
|
||||||
|
int nfonttext;
|
||||||
|
|
||||||
// fontconfig workarround, as FC_FULLNAME does not work for matching fonts.
|
// fontconfig workarround, as FC_FULLNAME does not work for matching fonts.
|
||||||
char *fontfile;
|
char *fontfile;
|
||||||
|
|
|
||||||
|
|
@ -200,9 +200,12 @@ load(XFont *f)
|
||||||
f->loadheight = fontheight;
|
f->loadheight = fontheight;
|
||||||
|
|
||||||
// enable all Unicode ranges
|
// 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++) {
|
for(i=0; i<nelem(f->range); i++) {
|
||||||
f->range[i] = 1;
|
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)
|
if(font == nil)
|
||||||
return nil;
|
return nil;
|
||||||
|
|
||||||
|
|
||||||
bbox = CTFontGetBoundingBox(font);
|
bbox = CTFontGetBoundingBox(font);
|
||||||
x = (int)(bbox.size.width*2 + 0.99999999);
|
x = (int)(bbox.size.width*2 + 0.99999999);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ enum
|
||||||
#define QFONT(p) (((p) >> 4) & 0xFFFF)
|
#define QFONT(p) (((p) >> 4) & 0xFFFF)
|
||||||
#define QSIZE(p) (((p) >> 20) & 0xFF)
|
#define QSIZE(p) (((p) >> 20) & 0xFF)
|
||||||
#define QANTIALIAS(p) (((p) >> 28) & 0x1)
|
#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 int sizes[] = { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 24, 28 };
|
||||||
|
|
||||||
static vlong
|
static vlong
|
||||||
|
|
@ -102,7 +102,7 @@ dostat(vlong path, Qid *qid, Dir *dir)
|
||||||
case Qfontfile:
|
case Qfontfile:
|
||||||
f = &xfont[QFONT(path)];
|
f = &xfont[QFONT(path)];
|
||||||
load(f);
|
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";
|
name = "font";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -189,9 +189,9 @@ xwalk1(Fid *fid, char *name, Qid *qid)
|
||||||
goto NotFound;
|
goto NotFound;
|
||||||
p++;
|
p++;
|
||||||
n = strtoul(p, &p, 16);
|
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;
|
goto NotFound;
|
||||||
path += Qsubfontfile - Qsizedir + qpath(0, 0, 0, 0, (n/SubfontSize) & SubfontMask);
|
path += Qsubfontfile - Qsizedir + qpath(0, 0, 0, 0, n/SubfontSize);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Found:
|
Found:
|
||||||
|
|
@ -229,7 +229,6 @@ sizegen(int i, Dir *d, void *v)
|
||||||
vlong path;
|
vlong path;
|
||||||
Fid *fid;
|
Fid *fid;
|
||||||
XFont *f;
|
XFont *f;
|
||||||
int j;
|
|
||||||
|
|
||||||
fid = v;
|
fid = v;
|
||||||
path = fid->qid.path;
|
path = fid->qid.path;
|
||||||
|
|
@ -240,15 +239,10 @@ sizegen(int i, Dir *d, void *v)
|
||||||
i--;
|
i--;
|
||||||
f = &xfont[QFONT(path)];
|
f = &xfont[QFONT(path)];
|
||||||
load(f);
|
load(f);
|
||||||
for(j=0; j<nelem(f->range); j++) {
|
if(i < f->nfile) {
|
||||||
if(f->range[j] == 0)
|
path += Qsubfontfile - Qsizedir;
|
||||||
continue;
|
path += qpath(0, 0, 0, 0, f->file[i]);
|
||||||
if(i == 0) {
|
goto Done;
|
||||||
path += Qsubfontfile - Qsizedir;
|
|
||||||
path += qpath(0, 0, 0, 0, j);
|
|
||||||
goto Done;
|
|
||||||
}
|
|
||||||
i--;
|
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
|
@ -315,23 +309,22 @@ xread(Req *r)
|
||||||
readstr(r, "font missing\n");
|
readstr(r, "font missing\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
height = 0;
|
if(f->fonttext == nil) {
|
||||||
ascent = 0;
|
height = 0;
|
||||||
if(f->unit > 0) {
|
ascent = 0;
|
||||||
height = f->height * (int)QSIZE(path)/f->unit + 0.99999999;
|
if(f->unit > 0) {
|
||||||
ascent = height - (int)(-f->originy * (int)QSIZE(path)/f->unit + 0.99999999);
|
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);
|
||||||
}
|
}
|
||||||
if(f->loadheight != nil)
|
readbuf(r, f->fonttext, f->nfonttext);
|
||||||
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);
|
|
||||||
}
|
|
||||||
data = fmtstrflush(&fmt);
|
|
||||||
readstr(r, data);
|
|
||||||
free(data);
|
|
||||||
break;
|
break;
|
||||||
case Qsubfontfile:
|
case Qsubfontfile:
|
||||||
f = &xfont[QFONT(path)];
|
f = &xfont[QFONT(path)];
|
||||||
|
|
|
||||||
|
|
@ -85,20 +85,23 @@ load(XFont *f)
|
||||||
|
|
||||||
int idx = charcode/SubfontSize;
|
int idx = charcode/SubfontSize;
|
||||||
|
|
||||||
if(charcode > 0xffff)
|
if(charcode > Runemax)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if(!f->range[idx]) {
|
if(!f->range[idx])
|
||||||
f->range[idx] = 1;
|
f->range[idx] = 1;
|
||||||
f->nrange++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// libdraw expects U+0000 to be present
|
|
||||||
if(!f->range[0]) {
|
|
||||||
f->range[0] = 1;
|
|
||||||
f->nrange++;
|
|
||||||
}
|
}
|
||||||
FT_Done_Face(face);
|
FT_Done_Face(face);
|
||||||
|
|
||||||
|
// libdraw expects U+0000 to be present
|
||||||
|
if(!f->range[0])
|
||||||
|
f->range[0] = 1;
|
||||||
|
|
||||||
|
// fix up file list
|
||||||
|
for(i=0; i<nelem(f->range); i++)
|
||||||
|
if(f->range[i])
|
||||||
|
f->file[f->nfile++] = i;
|
||||||
|
|
||||||
f->loaded = 1;
|
f->loaded = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue