Introduction
Introduction Statistics Contact Development Disclaimer Help
drw: fixup font handling - sent - simple plaintext presentation tool
git clone git://git.suckless.org/sent
Log
Files
Refs
README
LICENSE
---
commit 4993b300f38e6f29a8b0478bd01fb362aacf809d
parent 85d25716b07498fd9786045f77478abc253fd036
Author: Markus Teich <[email protected]>
Date: Tue, 21 Apr 2015 22:57:52 +0200
drw: fixup font handling
Diffstat:
M drw.c | 120 +++++++++++++++++------------…
M drw.h | 17 +++++++++--------
2 files changed, 75 insertions(+), 62 deletions(-)
---
diff --git a/drw.c b/drw.c
@@ -11,6 +11,8 @@
#define UTF_INVALID 0xFFFD
#define UTF_SIZ 4
+static void drw_xfont_free(Fnt *font);
+
static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF…
static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF…
static const long utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x100…
@@ -68,7 +70,6 @@ drw_create(Display *dpy, int screen, Window root, unsigned in…
drw->h = h;
drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, scree…
drw->gc = XCreateGC(dpy, root, 0, NULL);
- drw->fontcount = 0;
XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
return drw;
}
@@ -86,17 +87,14 @@ drw_resize(Drw *drw, unsigned int w, unsigned int h) {
void
drw_free(Drw *drw) {
- size_t i;
- for (i = 0; i < drw->fontcount; i++) {
- drw_font_free(drw->fonts[i]);
- }
+ drw_fontset_free(drw->fonts);
XFreePixmap(drw->dpy, drw->drawable);
XFreeGC(drw->dpy, drw->gc);
free(drw);
}
/* This function is an implementation detail. Library users should use
- * drw_font_create instead.
+ * drw_fontset_create instead.
*/
static Fnt *
drw_font_xcreate(Drw *drw, const char *fontname, FcPattern *fontpattern) {
@@ -116,7 +114,7 @@ drw_font_xcreate(Drw *drw, const char *fontname, FcPattern …
* missing-character-rectangles being drawn, at least with som…
*/
if (!(font->xfont = XftFontOpenName(drw->dpy, drw->screen, fon…
- !(font->pattern = FcNameParse((FcChar8 *) fontname))) {
+ !(font->pattern = FcNameParse((const FcChar8 *) fontname))…
if (font->xfont) {
XftFontClose(drw->dpy, font->xfont);
font->xfont = NULL;
@@ -143,26 +141,8 @@ drw_font_xcreate(Drw *drw, const char *fontname, FcPattern…
return font;
}
-Fnt*
-drw_font_create(Drw *drw, const char *fontname) {
- return drw_font_xcreate(drw, fontname, NULL);
-}
-
void
-drw_load_fonts(Drw* drw, const char *fonts[], size_t fontcount) {
- size_t i;
- Fnt *font;
- for (i = 0; i < fontcount; i++) {
- if (drw->fontcount >= DRW_FONT_CACHE_SIZE) {
- die("Font cache exhausted.\n");
- } else if ((font = drw_font_xcreate(drw, fonts[i], NULL))) {
- drw->fonts[drw->fontcount++] = font;
- }
- }
-}
-
-void
-drw_font_free(Fnt *font) {
+drw_xfont_free(Fnt *font) {
if(!font)
return;
if(font->pattern)
@@ -171,6 +151,30 @@ drw_font_free(Fnt *font) {
free(font);
}
+Fnt*
+drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount) {
+ Fnt *ret = NULL;
+ Fnt *cur = NULL;
+ ssize_t i;
+ for (i = fontcount - 1; i >= 0; i--) {
+ if ((cur = drw_font_xcreate(drw, fonts[i], NULL))) {
+ cur->next = ret;
+ ret = cur;
+ }
+ }
+ return ret;
+}
+
+void
+drw_fontset_free(Fnt *font) {
+ Fnt *nf = font;
+
+ while ((font = nf)) {
+ nf = font->next;
+ drw_xfont_free(font);
+ }
+}
+
Scm *
drw_scm_create(Drw *drw, const char *fgname, const char *bgname) {
Scm *scm;
@@ -198,6 +202,12 @@ drw_scm_free(Scm *scm) {
}
void
+drw_setfontset(Drw *drw, Fnt *set) {
+ if (drw)
+ drw->fonts = set;
+}
+
+void
drw_setscheme(Drw *drw, Scm *scm) {
if (drw && scm)
drw->scheme = scm;
@@ -223,7 +233,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned i…
Colormap cmap;
Visual *vis;
XftDraw *d;
- Fnt *curfont, *nextfont;
+ Fnt *usedfont, *curfont, *nextfont;
size_t i, len;
int utf8strlen, utf8charlen, render;
long utf8codepoint = 0;
@@ -245,7 +255,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned i…
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
}
- if (!text || !drw->fontcount) {
+ if (!text || !drw->fonts) {
return 0;
} else if (render) {
cmap = DefaultColormap(drw->dpy, drw->screen);
@@ -253,27 +263,27 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned…
d = XftDrawCreate(drw->dpy, drw->drawable, vis, cmap);
}
- curfont = drw->fonts[0];
+ usedfont = drw->fonts;
while (1) {
utf8strlen = 0;
utf8str = text;
nextfont = NULL;
while (*text) {
utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ…
- for (i = 0; i < drw->fontcount; i++) {
- charexists = charexists || XftCharExists(drw->…
+ for (curfont = drw->fonts; curfont; curfont = curfont-…
+ charexists = charexists || XftCharExists(drw->…
if (charexists) {
- if (drw->fonts[i] == curfont) {
+ if (curfont == usedfont) {
utf8strlen += utf8charlen;
text += utf8charlen;
} else {
- nextfont = drw->fonts[i];
+ nextfont = curfont;
}
break;
}
}
- if (!charexists || (nextfont && nextfont != curfont)) {
+ if (!charexists || nextfont) {
break;
} else {
charexists = 0;
@@ -281,10 +291,10 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned…
}
if (utf8strlen) {
- drw_font_getexts(curfont, utf8str, utf8strlen, &ew, NU…
+ drw_font_getexts(usedfont, utf8str, utf8strlen, &ew, N…
/* shorten text if necessary */
- for(len = MIN(utf8strlen, (sizeof buf) - 1); len && (e…
- drw_font_getexts(curfont, utf8str, len, &ew, N…
+ for(len = MIN(utf8strlen, (sizeof buf) - 1); len && (e…
+ drw_font_getexts(usedfont, utf8str, len, &ew, …
if (len) {
memcpy(buf, utf8str, len);
@@ -293,10 +303,10 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned…
for(i = len; i && i > len - 3; buf[--i…
if (render) {
- th = curfont->ascent + curfont->descen…
- ty = y + (h / 2) - (th / 2) + curfont-…
+ th = usedfont->ascent + usedfont->desc…
+ ty = y + (h / 2) - (th / 2) + usedfont…
tx = x + (h / 2);
- XftDrawStringUtf8(d, invert ? &drw->sc…
+ XftDrawStringUtf8(d, invert ? &drw->sc…
}
x += ew;
@@ -308,28 +318,24 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned…
break;
} else if (nextfont) {
charexists = 0;
- curfont = nextfont;
+ usedfont = nextfont;
} else {
/* Regardless of whether or not a fallback font is fou…
* character must be drawn.
*/
charexists = 1;
- if (drw->fontcount >= DRW_FONT_CACHE_SIZE) {
- continue;
- }
-
fccharset = FcCharSetCreate();
FcCharSetAddChar(fccharset, utf8codepoint);
- if (!drw->fonts[0]->pattern) {
+ if (!drw->fonts->pattern) {
/* Refer to the comment in drw_font_xcreate fo…
* information.
*/
die("The first font in the cache must be loade…
}
- fcpattern = FcPatternDuplicate(drw->fonts[0]->pattern);
+ fcpattern = FcPatternDuplicate(drw->fonts->pattern);
FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset);
FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue);
@@ -341,14 +347,14 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned…
FcPatternDestroy(fcpattern);
if (match) {
- curfont = drw_font_xcreate(drw, NULL, match);
- if (curfont && XftCharExists(drw->dpy, curfont…
- drw->fonts[drw->fontcount++] = curfont;
+ usedfont = drw_font_xcreate(drw, NULL, match);
+ if (usedfont && XftCharExists(drw->dpy, usedfo…
+ for (curfont = drw->fonts; curfont->ne…
+ ; /* just find the end of the …
+ curfont->next = usedfont;
} else {
- if (curfont) {
- drw_font_free(curfont);
- }
- curfont = drw->fonts[0];
+ drw_xfont_free(usedfont);
+ usedfont = drw->fonts;
}
}
}
@@ -369,6 +375,12 @@ drw_map(Drw *drw, Window win, int x, int y, unsigned int w…
XSync(drw->dpy, False);
}
+unsigned int
+drw_fontset_getwidth(Drw *drw, const char *text) {
+ if (!drw || !drw->fonts || !text)
+ return 0;
+ return drw_text(drw, 0, 0, 0, 0, text, 0) + drw->fonts->h;
+}
void
drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *…
diff --git a/drw.h b/drw.h
@@ -5,14 +5,16 @@ typedef struct {
Cursor cursor;
} Cur;
-typedef struct {
+typedef struct Fnt Fnt;
+struct Fnt {
Display *dpy;
int ascent;
int descent;
unsigned int h;
XftFont *xfont;
FcPattern *pattern;
-} Fnt;
+ Fnt *next;
+};
typedef struct {
struct {
@@ -29,8 +31,7 @@ typedef struct {
Drawable drawable;
GC gc;
Scm *scheme;
- size_t fontcount;
- Fnt *fonts[DRW_FONT_CACHE_SIZE];
+ Fnt *fonts;
} Drw;
/* Drawable abstraction */
@@ -39,9 +40,9 @@ void drw_resize(Drw *drw, unsigned int w, unsigned int h);
void drw_free(Drw *drw);
/* Fnt abstraction */
-Fnt *drw_font_create(Drw *drw, const char *fontname);
-void drw_load_fonts(Drw* drw, const char *fonts[], size_t fontcount);
-void drw_font_free(Fnt *font);
+Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount);
+void drw_fontset_free(Fnt* set);
+unsigned int drw_fontset_getwidth(Drw *drw, const char *text);
void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned …
/* Colorscheme abstraction */
@@ -53,7 +54,7 @@ Cur *drw_cur_create(Drw *drw, int shape);
void drw_cur_free(Drw *drw, Cur *cursor);
/* Drawing context manipulation */
-void drw_setfont(Drw *drw, Fnt *font);
+void drw_setfontset(Drw *drw, Fnt *set);
void drw_setscheme(Drw *drw, Scm *scm);
/* Drawing functions */
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.