mirror of
https://github.com/9fans/plan9port.git
synced 2025-01-12 11:10:07 +00:00
libdraw: add 2*font syntax for scaled fonts
An experiment. Change-Id: I40660a211b8372701597d80f7e86917e94cccbaa Reviewed-on: https://plan9port-review.googlesource.com/1161 Reviewed-by: Russ Cox <rsc@swtch.com>
This commit is contained in:
parent
32dc15fa62
commit
77f23268f7
7 changed files with 77 additions and 5 deletions
|
@ -314,6 +314,7 @@ struct Font
|
||||||
int maxdepth; /* maximum depth of all loaded subfonts */
|
int maxdepth; /* maximum depth of all loaded subfonts */
|
||||||
int ncache; /* size of cache */
|
int ncache; /* size of cache */
|
||||||
int nsubf; /* size of subfont list */
|
int nsubf; /* size of subfont list */
|
||||||
|
int scale; /* pixel scaling to apply */
|
||||||
Cacheinfo *cache;
|
Cacheinfo *cache;
|
||||||
Cachesubf *subf;
|
Cachesubf *subf;
|
||||||
Cachefont **sub; /* as read from file */
|
Cachefont **sub; /* as read from file */
|
||||||
|
@ -482,7 +483,7 @@ extern int runestringnwidth(Font*, Rune*, int);
|
||||||
extern Point strsubfontwidth(Subfont*, char*);
|
extern Point strsubfontwidth(Subfont*, char*);
|
||||||
extern int loadchar(Font*, Rune, Cacheinfo*, int, int, char**);
|
extern int loadchar(Font*, Rune, Cacheinfo*, int, int, char**);
|
||||||
extern char* subfontname(char*, char*, int);
|
extern char* subfontname(char*, char*, int);
|
||||||
extern Subfont* _getsubfont(Display*, char*);
|
extern Subfont* _getsubfont(Display*, Font*, char*);
|
||||||
extern Subfont* getdefont(Display*);
|
extern Subfont* getdefont(Display*);
|
||||||
extern void lockdisplay(Display*);
|
extern void lockdisplay(Display*);
|
||||||
extern void unlockdisplay(Display*);
|
extern void unlockdisplay(Display*);
|
||||||
|
|
|
@ -25,6 +25,7 @@ buildfont(Display *d, char *buf, char *name)
|
||||||
if(fnt == 0)
|
if(fnt == 0)
|
||||||
return 0;
|
return 0;
|
||||||
memset(fnt, 0, sizeof(Font));
|
memset(fnt, 0, sizeof(Font));
|
||||||
|
fnt->scale = 1;
|
||||||
fnt->display = d;
|
fnt->display = d;
|
||||||
fnt->name = strdup(name);
|
fnt->name = strdup(name);
|
||||||
fnt->ncache = NFCACHE+NFLOOK;
|
fnt->ncache = NFCACHE+NFLOOK;
|
||||||
|
|
|
@ -8,8 +8,10 @@
|
||||||
|
|
||||||
int _fontpipe(char*);
|
int _fontpipe(char*);
|
||||||
|
|
||||||
|
static void scalesubfont(Subfont*, int);
|
||||||
|
|
||||||
Subfont*
|
Subfont*
|
||||||
_getsubfont(Display *d, char *name)
|
_getsubfont(Display *d, Font *ff, char *name)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
Subfont *f;
|
Subfont *f;
|
||||||
|
@ -36,5 +38,61 @@ _getsubfont(Display *d, char *name)
|
||||||
if(f == 0)
|
if(f == 0)
|
||||||
fprint(2, "getsubfont: can't read %s: %r\n", name);
|
fprint(2, "getsubfont: can't read %s: %r\n", name);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
if(ff->scale != 1 && ff->scale != 0)
|
||||||
|
scalesubfont(f, ff->scale);
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
scalesubfont(Subfont *f, int scale)
|
||||||
|
{
|
||||||
|
Image *i;
|
||||||
|
Rectangle r, r2;
|
||||||
|
int y, x, x2, j;
|
||||||
|
uchar *src, *dst;
|
||||||
|
int srcn, dstn, n, mask, v, pack;
|
||||||
|
|
||||||
|
r = f->bits->r;
|
||||||
|
r2 = r;
|
||||||
|
r2.min.x *= scale;
|
||||||
|
r2.min.y *= scale;
|
||||||
|
r2.max.x *= scale;
|
||||||
|
r2.max.y *= scale;
|
||||||
|
|
||||||
|
srcn = bytesperline(r, f->bits->depth);
|
||||||
|
src = malloc(srcn);
|
||||||
|
dstn = bytesperline(r2, f->bits->depth);
|
||||||
|
dst = malloc(dstn+1);
|
||||||
|
i = allocimage(f->bits->display, r2, f->bits->chan, 0, DBlack);
|
||||||
|
for(y=r.min.y; y < r.max.y; y++) {
|
||||||
|
n = unloadimage(f->bits, Rect(r.min.x, y, r.max.x, y+1), src, srcn);
|
||||||
|
if(n != srcn)
|
||||||
|
sysfatal("scalesubfont: bad unload: %d < %d: %r", n, srcn);
|
||||||
|
memset(dst, 0, dstn+1);
|
||||||
|
pack = 8 / f->bits->depth;
|
||||||
|
mask = (1<<f->bits->depth) - 1;
|
||||||
|
for(x=0; x<Dx(r); x++) {
|
||||||
|
v = ((src[x/pack] << ((x%pack)*f->bits->depth)) >> (8 - f->bits->depth)) & mask;
|
||||||
|
for(j=0; j<scale; j++) {
|
||||||
|
x2 = x*scale+j;
|
||||||
|
dst[x2/pack] |= v << (8 - f->bits->depth) >> ((x2%pack)*f->bits->depth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(dst[dstn] != 0)
|
||||||
|
sysfatal("overflow dst");
|
||||||
|
for(j=0; j<scale; j++)
|
||||||
|
loadimage(i, Rect(r2.min.x, y*scale+j, r2.max.x, y*scale+j+1), dst, dstn);
|
||||||
|
}
|
||||||
|
freeimage(f->bits);
|
||||||
|
f->bits = i;
|
||||||
|
f->height *= scale;
|
||||||
|
f->ascent *= scale;
|
||||||
|
|
||||||
|
for(j=0; j<f->n; j++) {
|
||||||
|
f->info[j].x *= scale;
|
||||||
|
f->info[j].top *= scale;
|
||||||
|
f->info[j].bottom *= scale;
|
||||||
|
f->info[j].left *= scale;
|
||||||
|
f->info[j].width *= scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ mkfont(Subfont *subfont, Rune min)
|
||||||
if(font == 0)
|
if(font == 0)
|
||||||
return 0;
|
return 0;
|
||||||
memset(font, 0, sizeof(Font));
|
memset(font, 0, sizeof(Font));
|
||||||
|
font->scale = 1;
|
||||||
font->display = subfont->bits->display;
|
font->display = subfont->bits->display;
|
||||||
font->name = strdup("<synthetic>");
|
font->name = strdup("<synthetic>");
|
||||||
font->ncache = NFCACHE+NFLOOK;
|
font->ncache = NFCACHE+NFLOOK;
|
||||||
|
|
|
@ -9,10 +9,15 @@ Font*
|
||||||
openfont(Display *d, char *name)
|
openfont(Display *d, char *name)
|
||||||
{
|
{
|
||||||
Font *fnt;
|
Font *fnt;
|
||||||
int fd, i, n;
|
int fd, i, n, scale;
|
||||||
char *buf, *nambuf;
|
char *buf, *nambuf;
|
||||||
|
|
||||||
nambuf = 0;
|
nambuf = 0;
|
||||||
|
scale = 1;
|
||||||
|
if('1' <= name[0] && name[0] <= '9' && name[1] == '*') {
|
||||||
|
scale = name[0] - '0';
|
||||||
|
name += 2;
|
||||||
|
}
|
||||||
fd = open(name, OREAD);
|
fd = open(name, OREAD);
|
||||||
|
|
||||||
if(fd < 0 && strncmp(name, "/lib/font/bit/", 14) == 0){
|
if(fd < 0 && strncmp(name, "/lib/font/bit/", 14) == 0){
|
||||||
|
@ -54,6 +59,12 @@ openfont(Display *d, char *name)
|
||||||
fnt = buildfont(d, buf, name);
|
fnt = buildfont(d, buf, name);
|
||||||
free(buf);
|
free(buf);
|
||||||
free(nambuf);
|
free(nambuf);
|
||||||
|
if(scale != 1) {
|
||||||
|
fnt->scale = scale;
|
||||||
|
fnt->height *= scale;
|
||||||
|
fnt->ascent *= scale;
|
||||||
|
fnt->width *= scale;
|
||||||
|
}
|
||||||
return fnt;
|
return fnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -130,7 +130,7 @@ _string(Image *dst, Point pt, Image *src, Point sp, Font *f, char *s, Rune *r, i
|
||||||
}
|
}
|
||||||
if(subfontname){
|
if(subfontname){
|
||||||
freesubfont(sf);
|
freesubfont(sf);
|
||||||
if((sf=_getsubfont(f->display, subfontname)) == 0){
|
if((sf=_getsubfont(f->display, f, subfontname)) == 0){
|
||||||
def = f->display ? f->display->defaultfont : nil;
|
def = f->display ? f->display->defaultfont : nil;
|
||||||
if(def && f!=def)
|
if(def && f!=def)
|
||||||
f = def;
|
f = def;
|
||||||
|
|
|
@ -48,7 +48,7 @@ _stringnwidth(Font *f, char *s, Rune *r, int len)
|
||||||
}
|
}
|
||||||
if(subfontname){
|
if(subfontname){
|
||||||
freesubfont(sf);
|
freesubfont(sf);
|
||||||
if((sf=_getsubfont(f->display, subfontname)) == 0){
|
if((sf=_getsubfont(f->display, f, subfontname)) == 0){
|
||||||
def = f->display ? f->display->defaultfont : nil;
|
def = f->display ? f->display->defaultfont : nil;
|
||||||
if(def && f!=def)
|
if(def && f!=def)
|
||||||
f = def;
|
f = def;
|
||||||
|
|
Loading…
Reference in a new issue