mirror of
https://github.com/0intro/wmii
synced 2024-11-22 05:42:05 +03:00
Better font metrics support.
This commit is contained in:
parent
6659d28663
commit
e31731e8bc
@ -293,6 +293,8 @@ main(int argc, char *argv[]) {
|
||||
loadcolor(&cnorm, readctl("normcolors "));
|
||||
loadcolor(&csel, readctl("focuscolors "));
|
||||
font = loadfont(readctl("font "));
|
||||
sscanf(readctl("fontpad "), "%d %d %d %d", &font->pad.min.x, &font->pad.max.x,
|
||||
&font->pad.min.x, &font->pad.max.y);
|
||||
if(!font)
|
||||
fatal("Can't load font %q", readctl("font "));
|
||||
|
||||
|
@ -130,15 +130,15 @@ next:
|
||||
|
||||
static void
|
||||
_menu_draw(bool draw) {
|
||||
Rectangle r, rd, rp, r2;
|
||||
Rectangle r, rd, rp, r2, extent;
|
||||
CTuple *c;
|
||||
Item *i;
|
||||
int inputw, itemoff, end, pad, n;
|
||||
int inputw, itemoff, end, pad, n, offset;
|
||||
|
||||
r = barwin->r;
|
||||
r = rectsetorigin(r, ZP);
|
||||
|
||||
pad = (font->height & ~1);
|
||||
pad = (font->height & ~1) + font->pad.min.x + font->pad.max.x;
|
||||
|
||||
rd = r;
|
||||
rp = ZR; // SET(rp)
|
||||
@ -208,7 +208,8 @@ _menu_draw(bool draw) {
|
||||
r2.max.x = promptw + inputw;
|
||||
drawstring(ibuf, font, r2, West, input.string, cnorm.fg);
|
||||
|
||||
r2.min.x = promptw + textwidth_l(font, input.string, input.pos - input.string) + pad/2 - 1;
|
||||
extent = textextents_l(font, input.string, input.pos - input.string, &offset);
|
||||
r2.min.x = promptw + offset + font->pad.min.x - extent.min.x + pad/2 - 1;
|
||||
r2.max.x = r2.min.x + 2;
|
||||
r2.min.y++;
|
||||
r2.max.y--;
|
||||
@ -236,7 +237,7 @@ menu_show(void) {
|
||||
ltwidth = textwidth(font, "<");
|
||||
|
||||
pad = (font->height & ~1)/2;
|
||||
height = font->height + 2;
|
||||
height = labelh(font);
|
||||
|
||||
r = scr.rect;
|
||||
if(ontop)
|
||||
|
@ -140,7 +140,7 @@ bar_draw(WMScreen *s) {
|
||||
foreach_bar(s, b) {
|
||||
b->r.min = ZP;
|
||||
b->r.max.y = Dy(s->brect);
|
||||
b->r.max.x = def.font->height & ~1;
|
||||
b->r.max.x = (def.font->height & ~1) + def.font->pad.min.x + def.font->pad.max.x;
|
||||
if(b->text && strlen(b->text))
|
||||
b->r.max.x += textwidth(def.font, b->text);
|
||||
width += Dx(b->r);
|
||||
|
@ -466,8 +466,8 @@ frame_draw(Frame *f) {
|
||||
|
||||
/* grabbox */
|
||||
r.min = Pt(2, 2);
|
||||
r.max.x = r.min.x + def.font->height - 3;
|
||||
r.max.y -= 2;
|
||||
r.max.x = r.min.x + Dy(r);
|
||||
f->grabbox = r;
|
||||
|
||||
if(c->urgent)
|
||||
|
@ -35,6 +35,7 @@ enum {
|
||||
LEXEC,
|
||||
LFOCUSCOLORS,
|
||||
LFONT,
|
||||
LFONTPAD,
|
||||
LGRABMOD,
|
||||
LGROW,
|
||||
LINCMODE,
|
||||
@ -69,6 +70,7 @@ char *symtab[] = {
|
||||
"exec",
|
||||
"focuscolors",
|
||||
"font",
|
||||
"fontpad",
|
||||
"grabmod",
|
||||
"grow",
|
||||
"incmode",
|
||||
@ -265,6 +267,16 @@ getbase(const char **s, long *sign) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool
|
||||
getint(const char *s, int *ret) {
|
||||
long l;
|
||||
bool res;
|
||||
|
||||
res = getlong(s, &l);
|
||||
*ret = l;
|
||||
return res;
|
||||
}
|
||||
|
||||
bool
|
||||
getlong(const char *s, long *ret) {
|
||||
const char *end;
|
||||
@ -537,6 +549,18 @@ message_root(void *p, IxpMsg *m) {
|
||||
ret = "can't load font";
|
||||
view_update(selview);
|
||||
break;
|
||||
case LFONTPAD:
|
||||
if(!getint(msg_getword(m), &def.font->pad.min.x) ||
|
||||
!getint(msg_getword(m), &def.font->pad.max.x) ||
|
||||
!getint(msg_getword(m), &def.font->pad.max.y) ||
|
||||
!getint(msg_getword(m), &def.font->pad.min.y))
|
||||
ret = "invalid rectangle";
|
||||
else {
|
||||
for(n=0; n < nscreens; n++)
|
||||
bar_resize(screens[n]);
|
||||
view_update(selview);
|
||||
}
|
||||
break;
|
||||
case LGRABMOD:
|
||||
s = msg_getword(m);
|
||||
if(!parsekey(s, &i, nil) || i == 0)
|
||||
@ -598,6 +622,8 @@ readctl_root(void) {
|
||||
}
|
||||
bufprint("focuscolors %s\n", def.focuscolor.colstr);
|
||||
bufprint("font %s\n", def.font->name);
|
||||
bufprint("fontpad %d %d %d %d\n", def.font->pad.min.x, def.font->pad.max.x,
|
||||
def.font->pad.max.y, def.font->pad.min.y);
|
||||
bufprint("grabmod %s\n", def.grabmod);
|
||||
bufprint("incmode %s\n", incmodetab[def.incmode]);
|
||||
bufprint("normcolors %s\n", def.normcolor.colstr);
|
||||
|
@ -537,8 +537,9 @@ uint
|
||||
drawstring(Image *dst, Font *font,
|
||||
Rectangle r, Align align,
|
||||
char *text, ulong col) {
|
||||
Rectangle tr;
|
||||
char *buf;
|
||||
uint x, y, w, h, len;
|
||||
uint x, y, width, height, len;
|
||||
int shortened;
|
||||
|
||||
shortened = 0;
|
||||
@ -547,14 +548,22 @@ drawstring(Image *dst, Font *font,
|
||||
buf = emalloc(len+1);
|
||||
memcpy(buf, text, len+1);
|
||||
|
||||
h = font->ascent + font->descent;
|
||||
y = r.min.y + Dy(r) / 2 - h / 2 + font->ascent;
|
||||
r.max.y -= font->pad.min.y;
|
||||
r.min.y += font->pad.max.y;
|
||||
|
||||
height = font->ascent + font->descent;
|
||||
y = r.min.y + Dy(r) / 2 - height / 2 + font->ascent;
|
||||
|
||||
width = Dx(r) - font->pad.min.x - font->pad.max.x - (font->height & ~1);
|
||||
|
||||
r.min.x += font->pad.min.x;
|
||||
r.max.x -= font->pad.max.x;
|
||||
|
||||
/* shorten text if necessary */
|
||||
w = 0;
|
||||
tr = ZR;
|
||||
while(len > 0) {
|
||||
w = textwidth_l(font, buf, len + min(shortened, 3));
|
||||
if(w <= Dx(r) - (font->height & ~1))
|
||||
tr = textextents_l(font, buf, len + min(shortened, 3), nil);
|
||||
if(Dx(tr) <= width)
|
||||
break;
|
||||
while(len > 0 && (buf[--len]&0xC0) == 0x80)
|
||||
buf[len] = '.';
|
||||
@ -562,7 +571,7 @@ drawstring(Image *dst, Font *font,
|
||||
shortened++;
|
||||
}
|
||||
|
||||
if(len == 0 || w > Dx(r))
|
||||
if(len == 0 || Dx(tr) > width)
|
||||
goto done;
|
||||
|
||||
/* mark shortened info in the string */
|
||||
@ -571,13 +580,13 @@ drawstring(Image *dst, Font *font,
|
||||
|
||||
switch (align) {
|
||||
case East:
|
||||
x = r.max.x - (w + (font->height / 2));
|
||||
x = r.max.x - (tr.max.x + (font->height / 2));
|
||||
break;
|
||||
case Center:
|
||||
x = r.min.x + (Dx(r) - w) / 2;
|
||||
x = r.min.x + (Dx(r) - Dx(tr)) / 2 - tr.min.x;
|
||||
break;
|
||||
default:
|
||||
x = r.min.x + (font->height / 2);
|
||||
x = r.min.x + (font->height / 2) - tr.min.x;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -605,7 +614,7 @@ drawstring(Image *dst, Font *font,
|
||||
|
||||
done:
|
||||
free(buf);
|
||||
return w;
|
||||
return Dx(tr);
|
||||
}
|
||||
|
||||
void
|
||||
@ -745,26 +754,44 @@ freefont(Font *f) {
|
||||
free(f);
|
||||
}
|
||||
|
||||
uint
|
||||
textwidth_l(Font *font, char *text, uint len) {
|
||||
Rectangle
|
||||
textextents_l(Font *font, char *text, uint len, int *offset) {
|
||||
Rectangle rect;
|
||||
XRectangle r;
|
||||
XGlyphInfo i;
|
||||
int unused;
|
||||
|
||||
if(!offset)
|
||||
offset = &unused;
|
||||
|
||||
switch(font->type) {
|
||||
case FFontSet:
|
||||
Xutf8TextExtents(font->font.set, text, len, nil, &r);
|
||||
return r.width;
|
||||
*offset = Xutf8TextExtents(font->font.set, text, len, &r, nil);
|
||||
return Rect(r.x, -r.y - r.height, r.x + r.width, -r.y);
|
||||
case FXft:
|
||||
XftTextExtentsUtf8(display, font->font.xft, (uchar*)text, len, &i);
|
||||
return i.width;
|
||||
*offset = i.xOff;
|
||||
return Rect(-i.x, i.y - i.height, -i.x + i.width, i.y);
|
||||
case FX11:
|
||||
return XTextWidth(font->font.x11, text, len);
|
||||
rect = ZR;
|
||||
rect.max.x = XTextWidth(font->font.x11, text, len);
|
||||
rect.max.y = font->ascent;
|
||||
*offset = rect.max.x;
|
||||
return rect;
|
||||
default:
|
||||
die("Invalid font type");
|
||||
return 0; /* shut up ken */
|
||||
return ZR; /* shut up ken */
|
||||
}
|
||||
}
|
||||
|
||||
uint
|
||||
textwidth_l(Font *font, char *text, uint len) {
|
||||
Rectangle r;
|
||||
|
||||
r = textextents_l(font, text, len, nil);
|
||||
return Dx(r);
|
||||
}
|
||||
|
||||
uint
|
||||
textwidth(Font *font, char *text) {
|
||||
return textwidth_l(font, text, strlen(text));
|
||||
@ -772,7 +799,7 @@ textwidth(Font *font, char *text) {
|
||||
|
||||
uint
|
||||
labelh(Font *font) {
|
||||
return font->height + 2;
|
||||
return font->height + font->descent + font->pad.min.y + font->pad.max.y;
|
||||
}
|
||||
|
||||
/* Misc */
|
||||
|
@ -367,6 +367,7 @@ struct exectab {
|
||||
{0, }
|
||||
}, utiltab[] = {
|
||||
{"namespace", xnamespace},
|
||||
{"ns", xnamespace},
|
||||
{"setsid", xsetsid},
|
||||
{0, }
|
||||
};
|
||||
|
@ -91,6 +91,7 @@ struct Font {
|
||||
XFontSet set;
|
||||
XftFont* xft;
|
||||
} font;
|
||||
Rectangle pad;
|
||||
int ascent;
|
||||
int descent;
|
||||
uint height;
|
||||
@ -261,6 +262,7 @@ Point subpt(Point, Point);
|
||||
void sync(void);
|
||||
uint textwidth(Font*, char*);
|
||||
uint textwidth_l(Font*, char*, uint len);
|
||||
Rectangle textextents_l(Font*, char*, uint, int*);
|
||||
int traperrors(bool);
|
||||
Point translate(Window*, Window*, Point);
|
||||
void ungrabkeyboard(void);
|
||||
|
Loading…
Reference in New Issue
Block a user