add emoji font.

fix: 97ae9b1709
This commit is contained in:
Hojun-Cho 2025-12-28 19:50:38 +09:00
parent 72063f84b7
commit 874b941439
8 changed files with 67 additions and 20 deletions

2
dat.h
View File

@ -17,7 +17,7 @@ enum
Fontsz = 32, Fontsz = 32,
Fontbase = 4, Fontbase = 4,
Nglyphs = 65536, Nglyphs = 0x20000,
}; };
enum enum

72
font.c
View File

@ -10,9 +10,12 @@ struct Glyph
int w, h, ox, oy; int w, h, ox, oy;
}; };
static stbtt_fontinfo font; enum { Maxfonts = 4 };
static uchar *fontdata;
static float scale; static stbtt_fontinfo fonts[Maxfonts];
static uchar *fontdata[Maxfonts];
static float scale[Maxfonts];
static int nfonts;
static Glyph cache[Nglyphs]; static Glyph cache[Nglyphs];
static u32int blendtab[2][256]; static u32int blendtab[2][256];
@ -28,25 +31,64 @@ blend(u32int bg, int a)
return (r << 16) | (g << 8) | b; return (r << 16) | (g << 8) | b;
} }
void static void
fontinit(char *path) loadfont(char *path)
{ {
int fd, a; int fd;
long sz, n; long sz, n;
if(nfonts >= Maxfonts)
die("too many fonts");
fd = open(path, OREAD); fd = open(path, OREAD);
if(fd < 0) if(fd < 0)
die("can't open font: %s", path); die("can't open font: %s", path);
sz = seek(fd, 0, 2); sz = seek(fd, 0, 2);
seek(fd, 0, 0); seek(fd, 0, 0);
fontdata = emalloc(sz); fontdata[nfonts] = emalloc(sz);
n = readn(fd, fontdata, sz); n = readn(fd, fontdata[nfonts], sz);
close(fd); close(fd);
if(n != sz) if(n != sz)
die("can't read font: %s", path); die("can't read font: %s", path);
if(!stbtt_InitFont(&font, fontdata, stbtt_GetFontOffsetForIndex(fontdata, 0))) if(!stbtt_InitFont(&fonts[nfonts], fontdata[nfonts], stbtt_GetFontOffsetForIndex(fontdata[nfonts], 0)))
die("can't init font: %s", path); die("can't init font: %s", path);
scale = stbtt_ScaleForPixelHeight(&font, Fontsz); scale[nfonts] = stbtt_ScaleForPixelHeight(&fonts[nfonts], Fontsz);
nfonts++;
}
static int
isfont(char *name)
{
char *p;
p = strrchr(name, '.');
if(p == nil)
return 0;
return strcmp(p, ".ttf") == 0 || strcmp(p, ".otf") == 0;
}
void
fontinit(char *dir)
{
int fd, n, i, a;
Dir *d;
char path[256];
fd = open(dir, OREAD);
if(fd < 0)
die("can't open font dir: %s", dir);
n = dirreadall(fd, &d);
close(fd);
if(n < 0)
die("can't read font dir: %s", dir);
for(i = 0; i < n; i++){
if(isfont(d[i].name)){
snprint(path, sizeof path, "%s/%s", dir, d[i].name);
loadfont(path);
}
}
free(d);
if(nfonts == 0)
die("no fonts in %s", dir);
for(a = 0; a < 256; a++){ for(a = 0; a < 256; a++){
blendtab[0][a] = blend(Colbg, a); blendtab[0][a] = blend(Colbg, a);
blendtab[1][a] = blend(Colsel, a); blendtab[1][a] = blend(Colsel, a);
@ -57,14 +99,20 @@ void
putfont(u32int *buf, int w, int h, int px, int py, Rune r) putfont(u32int *buf, int w, int h, int px, int py, Rune r)
{ {
Glyph *g; Glyph *g;
int i, j, x, y, a, sel; int i, j, x, y, a, sel, f;
u32int *p; u32int *p;
if(r >= Nglyphs) if(r >= Nglyphs)
return; return;
g = &cache[r]; g = &cache[r];
if(g->bmp == nil){ if(g->bmp == nil){
g->bmp = stbtt_GetCodepointBitmap(&font, scale, scale, r, &g->w, &g->h, &g->ox, &g->oy); for(f = 0; f < nfonts; f++){
if(stbtt_FindGlyphIndex(&fonts[f], r) == 0)
continue;
g->bmp = stbtt_GetCodepointBitmap(&fonts[f], scale[f], scale[f], r, &g->w, &g->h, &g->ox, &g->oy);
if(g->bmp != nil)
break;
}
if(g->bmp == nil) if(g->bmp == nil)
return; return;
} }

BIN
font/NotoEmoji-Regular.ttf Normal file

Binary file not shown.

BIN
font/NotoSans-Regular.ttf Normal file

Binary file not shown.

View File

@ -1 +0,0 @@
NotoSansMonoCJKsc-Regular.otf

6
main.c
View File

@ -5,7 +5,7 @@ Channel *drawc;
Channel *keyc; Channel *keyc;
Channel *dictreqc; Channel *dictreqc;
Channel *dictresc; Channel *dictresc;
char *fontpath; char *fontdir;
int int
threadmaybackground(void) threadmaybackground(void)
@ -16,7 +16,7 @@ threadmaybackground(void)
void void
usage(void) usage(void)
{ {
fprint(2, "usage: strans mapdir fontpath\n"); fprint(2, "usage: strans mapdir fontdir\n");
threadexitsall("usage"); threadexitsall("usage");
} }
@ -60,7 +60,7 @@ threadmain(int argc, char **argv)
if(argc != 3) if(argc != 3)
usage(); usage();
fontpath = argv[2]; fontdir = argv[2];
drawc = chancreate(sizeof(Drawcmd), 0); drawc = chancreate(sizeof(Drawcmd), 0);
keyc = chancreate(sizeof(Keyreq), 0); keyc = chancreate(sizeof(Keyreq), 0);
dictreqc = chancreate(sizeof(Dictreq), 4); dictreqc = chancreate(sizeof(Dictreq), 4);

2
run.sh
View File

@ -4,6 +4,6 @@ pkill strans
pkill strans-xim pkill strans-xim
sleep 1 sleep 1
./strans map font/font.otf & ./strans map font &
sleep 1 sleep 1
xim/strans-xim & xim/strans-xim &

4
win.c
View File

@ -6,7 +6,7 @@ enum {
Asciitofull = 0xFEE0, Asciitofull = 0xFEE0,
}; };
extern char *fontpath; extern char *fontdir;
static xcb_connection_t *conn; static xcb_connection_t *conn;
static xcb_screen_t *scr; static xcb_screen_t *scr;
@ -52,7 +52,7 @@ wininit(void)
gc = xcb_generate_id(conn); gc = xcb_generate_id(conn);
xcb_create_gc(conn, gc, win, 0, nil); xcb_create_gc(conn, gc, win, 0, nil);
img = emalloc(Imgw * Imgh * sizeof(img[0])); img = emalloc(Imgw * Imgh * sizeof(img[0]));
fontinit(fontpath); fontinit(fontdir);
} }
static void static void