it* My version of sent Err codevoid.de 70 i Err codevoid.de 70 hgit clone git://git.codevoid.de/sent-sdk.git URL:git://git.codevoid.de/sent-sdk.git codevoid.de 70 1Log /git/sent-sdk/log.gph codevoid.de 70 1Files /git/sent-sdk/files.gph codevoid.de 70 1Refs /git/sent-sdk/refs.gph codevoid.de 70 1README /git/sent-sdk/file/README.md.gph codevoid.de 70 1LICENSE /git/sent-sdk/file/LICENSE.gph codevoid.de 70 i--- Err codevoid.de 70 1commit 4993b300f38e6f29a8b0478bd01fb362aacf809d /git/sent-sdk/commit/4993b300f38e6f29a8b0478bd01fb362aacf809d.gph codevoid.de 70 1parent 85d25716b07498fd9786045f77478abc253fd036 /git/sent-sdk/commit/85d25716b07498fd9786045f77478abc253fd036.gph codevoid.de 70 hAuthor: Markus Teich URL:mailto:markus.teich@stusta.mhn.de codevoid.de 70 iDate: Tue, 21 Apr 2015 22:57:52 +0200 Err codevoid.de 70 i Err codevoid.de 70 idrw: fixup font handling Err codevoid.de 70 i Err codevoid.de 70 iDiffstat: Err codevoid.de 70 i M drw.c | 120 +++++++++++++++++-------------- Err codevoid.de 70 i M drw.h | 17 +++++++++-------- Err codevoid.de 70 i Err codevoid.de 70 i2 files changed, 75 insertions(+), 62 deletions(-) Err codevoid.de 70 i--- Err codevoid.de 70 1diff --git a/drw.c b/drw.c /git/sent-sdk/file/drw.c.gph codevoid.de 70 it@@ -11,6 +11,8 @@ Err codevoid.de 70 i #define UTF_INVALID 0xFFFD Err codevoid.de 70 i #define UTF_SIZ 4 Err codevoid.de 70 i Err codevoid.de 70 i+static void drw_xfont_free(Fnt *font); Err codevoid.de 70 i+ Err codevoid.de 70 i static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0}; Err codevoid.de 70 i static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}; Err codevoid.de 70 i static const long utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000}; Err codevoid.de 70 it@@ -68,7 +70,6 @@ drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h Err codevoid.de 70 i drw->h = h; Err codevoid.de 70 i drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen)); Err codevoid.de 70 i drw->gc = XCreateGC(dpy, root, 0, NULL); Err codevoid.de 70 i- drw->fontcount = 0; Err codevoid.de 70 i XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter); Err codevoid.de 70 i return drw; Err codevoid.de 70 i } Err codevoid.de 70 it@@ -86,17 +87,14 @@ drw_resize(Drw *drw, unsigned int w, unsigned int h) { Err codevoid.de 70 i Err codevoid.de 70 i void Err codevoid.de 70 i drw_free(Drw *drw) { Err codevoid.de 70 i- size_t i; Err codevoid.de 70 i- for (i = 0; i < drw->fontcount; i++) { Err codevoid.de 70 i- drw_font_free(drw->fonts[i]); Err codevoid.de 70 i- } Err codevoid.de 70 i+ drw_fontset_free(drw->fonts); Err codevoid.de 70 i XFreePixmap(drw->dpy, drw->drawable); Err codevoid.de 70 i XFreeGC(drw->dpy, drw->gc); Err codevoid.de 70 i free(drw); Err codevoid.de 70 i } Err codevoid.de 70 i Err codevoid.de 70 i /* This function is an implementation detail. Library users should use Err codevoid.de 70 i- * drw_font_create instead. Err codevoid.de 70 i+ * drw_fontset_create instead. Err codevoid.de 70 i */ Err codevoid.de 70 i static Fnt * Err codevoid.de 70 i drw_font_xcreate(Drw *drw, const char *fontname, FcPattern *fontpattern) { Err codevoid.de 70 it@@ -116,7 +114,7 @@ drw_font_xcreate(Drw *drw, const char *fontname, FcPattern *fontpattern) { Err codevoid.de 70 i * missing-character-rectangles being drawn, at least with some fonts. Err codevoid.de 70 i */ Err codevoid.de 70 i if (!(font->xfont = XftFontOpenName(drw->dpy, drw->screen, fontname)) || Err codevoid.de 70 i- !(font->pattern = FcNameParse((FcChar8 *) fontname))) { Err codevoid.de 70 i+ !(font->pattern = FcNameParse((const FcChar8 *) fontname))) { Err codevoid.de 70 i if (font->xfont) { Err codevoid.de 70 i XftFontClose(drw->dpy, font->xfont); Err codevoid.de 70 i font->xfont = NULL; Err codevoid.de 70 it@@ -143,26 +141,8 @@ drw_font_xcreate(Drw *drw, const char *fontname, FcPattern *fontpattern) { Err codevoid.de 70 i return font; Err codevoid.de 70 i } Err codevoid.de 70 i Err codevoid.de 70 i-Fnt* Err codevoid.de 70 i-drw_font_create(Drw *drw, const char *fontname) { Err codevoid.de 70 i- return drw_font_xcreate(drw, fontname, NULL); Err codevoid.de 70 i-} Err codevoid.de 70 i- Err codevoid.de 70 i void Err codevoid.de 70 i-drw_load_fonts(Drw* drw, const char *fonts[], size_t fontcount) { Err codevoid.de 70 i- size_t i; Err codevoid.de 70 i- Fnt *font; Err codevoid.de 70 i- for (i = 0; i < fontcount; i++) { Err codevoid.de 70 i- if (drw->fontcount >= DRW_FONT_CACHE_SIZE) { Err codevoid.de 70 i- die("Font cache exhausted.\n"); Err codevoid.de 70 i- } else if ((font = drw_font_xcreate(drw, fonts[i], NULL))) { Err codevoid.de 70 i- drw->fonts[drw->fontcount++] = font; Err codevoid.de 70 i- } Err codevoid.de 70 i- } Err codevoid.de 70 i-} Err codevoid.de 70 i- Err codevoid.de 70 i-void Err codevoid.de 70 i-drw_font_free(Fnt *font) { Err codevoid.de 70 i+drw_xfont_free(Fnt *font) { Err codevoid.de 70 i if(!font) Err codevoid.de 70 i return; Err codevoid.de 70 i if(font->pattern) Err codevoid.de 70 it@@ -171,6 +151,30 @@ drw_font_free(Fnt *font) { Err codevoid.de 70 i free(font); Err codevoid.de 70 i } Err codevoid.de 70 i Err codevoid.de 70 i+Fnt* Err codevoid.de 70 i+drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount) { Err codevoid.de 70 i+ Fnt *ret = NULL; Err codevoid.de 70 i+ Fnt *cur = NULL; Err codevoid.de 70 i+ ssize_t i; Err codevoid.de 70 i+ for (i = fontcount - 1; i >= 0; i--) { Err codevoid.de 70 i+ if ((cur = drw_font_xcreate(drw, fonts[i], NULL))) { Err codevoid.de 70 i+ cur->next = ret; Err codevoid.de 70 i+ ret = cur; Err codevoid.de 70 i+ } Err codevoid.de 70 i+ } Err codevoid.de 70 i+ return ret; Err codevoid.de 70 i+} Err codevoid.de 70 i+ Err codevoid.de 70 i+void Err codevoid.de 70 i+drw_fontset_free(Fnt *font) { Err codevoid.de 70 i+ Fnt *nf = font; Err codevoid.de 70 i+ Err codevoid.de 70 i+ while ((font = nf)) { Err codevoid.de 70 i+ nf = font->next; Err codevoid.de 70 i+ drw_xfont_free(font); Err codevoid.de 70 i+ } Err codevoid.de 70 i+} Err codevoid.de 70 i+ Err codevoid.de 70 i Scm * Err codevoid.de 70 i drw_scm_create(Drw *drw, const char *fgname, const char *bgname) { Err codevoid.de 70 i Scm *scm; Err codevoid.de 70 it@@ -198,6 +202,12 @@ drw_scm_free(Scm *scm) { Err codevoid.de 70 i } Err codevoid.de 70 i Err codevoid.de 70 i void Err codevoid.de 70 i+drw_setfontset(Drw *drw, Fnt *set) { Err codevoid.de 70 i+ if (drw) Err codevoid.de 70 i+ drw->fonts = set; Err codevoid.de 70 i+} Err codevoid.de 70 i+ Err codevoid.de 70 i+void Err codevoid.de 70 i drw_setscheme(Drw *drw, Scm *scm) { Err codevoid.de 70 i if (drw && scm) Err codevoid.de 70 i drw->scheme = scm; Err codevoid.de 70 it@@ -223,7 +233,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex Err codevoid.de 70 i Colormap cmap; Err codevoid.de 70 i Visual *vis; Err codevoid.de 70 i XftDraw *d; Err codevoid.de 70 i- Fnt *curfont, *nextfont; Err codevoid.de 70 i+ Fnt *usedfont, *curfont, *nextfont; Err codevoid.de 70 i size_t i, len; Err codevoid.de 70 i int utf8strlen, utf8charlen, render; Err codevoid.de 70 i long utf8codepoint = 0; Err codevoid.de 70 it@@ -245,7 +255,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex Err codevoid.de 70 i XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); Err codevoid.de 70 i } Err codevoid.de 70 i Err codevoid.de 70 i- if (!text || !drw->fontcount) { Err codevoid.de 70 i+ if (!text || !drw->fonts) { Err codevoid.de 70 i return 0; Err codevoid.de 70 i } else if (render) { Err codevoid.de 70 i cmap = DefaultColormap(drw->dpy, drw->screen); Err codevoid.de 70 it@@ -253,27 +263,27 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex Err codevoid.de 70 i d = XftDrawCreate(drw->dpy, drw->drawable, vis, cmap); Err codevoid.de 70 i } Err codevoid.de 70 i Err codevoid.de 70 i- curfont = drw->fonts[0]; Err codevoid.de 70 i+ usedfont = drw->fonts; Err codevoid.de 70 i while (1) { Err codevoid.de 70 i utf8strlen = 0; Err codevoid.de 70 i utf8str = text; Err codevoid.de 70 i nextfont = NULL; Err codevoid.de 70 i while (*text) { Err codevoid.de 70 i utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ); Err codevoid.de 70 i- for (i = 0; i < drw->fontcount; i++) { Err codevoid.de 70 i- charexists = charexists || XftCharExists(drw->dpy, drw->fonts[i]->xfont, utf8codepoint); Err codevoid.de 70 i+ for (curfont = drw->fonts; curfont; curfont = curfont->next) { Err codevoid.de 70 i+ charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint); Err codevoid.de 70 i if (charexists) { Err codevoid.de 70 i- if (drw->fonts[i] == curfont) { Err codevoid.de 70 i+ if (curfont == usedfont) { Err codevoid.de 70 i utf8strlen += utf8charlen; Err codevoid.de 70 i text += utf8charlen; Err codevoid.de 70 i } else { Err codevoid.de 70 i- nextfont = drw->fonts[i]; Err codevoid.de 70 i+ nextfont = curfont; Err codevoid.de 70 i } Err codevoid.de 70 i break; Err codevoid.de 70 i } Err codevoid.de 70 i } Err codevoid.de 70 i Err codevoid.de 70 i- if (!charexists || (nextfont && nextfont != curfont)) { Err codevoid.de 70 i+ if (!charexists || nextfont) { Err codevoid.de 70 i break; Err codevoid.de 70 i } else { Err codevoid.de 70 i charexists = 0; Err codevoid.de 70 it@@ -281,10 +291,10 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex Err codevoid.de 70 i } Err codevoid.de 70 i Err codevoid.de 70 i if (utf8strlen) { Err codevoid.de 70 i- drw_font_getexts(curfont, utf8str, utf8strlen, &ew, NULL); Err codevoid.de 70 i+ drw_font_getexts(usedfont, utf8str, utf8strlen, &ew, NULL); Err codevoid.de 70 i /* shorten text if necessary */ Err codevoid.de 70 i- for(len = MIN(utf8strlen, (sizeof buf) - 1); len && (ew > w - drw->fonts[0]->h || w < drw->fonts[0]->h); len--) Err codevoid.de 70 i- drw_font_getexts(curfont, utf8str, len, &ew, NULL); Err codevoid.de 70 i+ for(len = MIN(utf8strlen, (sizeof buf) - 1); len && (ew > w - drw->fonts->h || w < drw->fonts->h); len--) Err codevoid.de 70 i+ drw_font_getexts(usedfont, utf8str, len, &ew, NULL); Err codevoid.de 70 i Err codevoid.de 70 i if (len) { Err codevoid.de 70 i memcpy(buf, utf8str, len); Err codevoid.de 70 it@@ -293,10 +303,10 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex Err codevoid.de 70 i for(i = len; i && i > len - 3; buf[--i] = '.'); Err codevoid.de 70 i Err codevoid.de 70 i if (render) { Err codevoid.de 70 i- th = curfont->ascent + curfont->descent; Err codevoid.de 70 i- ty = y + (h / 2) - (th / 2) + curfont->ascent; Err codevoid.de 70 i+ th = usedfont->ascent + usedfont->descent; Err codevoid.de 70 i+ ty = y + (h / 2) - (th / 2) + usedfont->ascent; Err codevoid.de 70 i tx = x + (h / 2); Err codevoid.de 70 i- XftDrawStringUtf8(d, invert ? &drw->scheme->bg.rgb : &drw->scheme->fg.rgb, curfont->xfont, tx, ty, (XftChar8 *)buf, len); Err codevoid.de 70 i+ XftDrawStringUtf8(d, invert ? &drw->scheme->bg.rgb : &drw->scheme->fg.rgb, usedfont->xfont, tx, ty, (XftChar8 *)buf, len); Err codevoid.de 70 i } Err codevoid.de 70 i Err codevoid.de 70 i x += ew; Err codevoid.de 70 it@@ -308,28 +318,24 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex Err codevoid.de 70 i break; Err codevoid.de 70 i } else if (nextfont) { Err codevoid.de 70 i charexists = 0; Err codevoid.de 70 i- curfont = nextfont; Err codevoid.de 70 i+ usedfont = nextfont; Err codevoid.de 70 i } else { Err codevoid.de 70 i /* Regardless of whether or not a fallback font is found, the Err codevoid.de 70 i * character must be drawn. Err codevoid.de 70 i */ Err codevoid.de 70 i charexists = 1; Err codevoid.de 70 i Err codevoid.de 70 i- if (drw->fontcount >= DRW_FONT_CACHE_SIZE) { Err codevoid.de 70 i- continue; Err codevoid.de 70 i- } Err codevoid.de 70 i- Err codevoid.de 70 i fccharset = FcCharSetCreate(); Err codevoid.de 70 i FcCharSetAddChar(fccharset, utf8codepoint); Err codevoid.de 70 i Err codevoid.de 70 i- if (!drw->fonts[0]->pattern) { Err codevoid.de 70 i+ if (!drw->fonts->pattern) { Err codevoid.de 70 i /* Refer to the comment in drw_font_xcreate for more Err codevoid.de 70 i * information. Err codevoid.de 70 i */ Err codevoid.de 70 i die("The first font in the cache must be loaded from a font string.\n"); Err codevoid.de 70 i } Err codevoid.de 70 i Err codevoid.de 70 i- fcpattern = FcPatternDuplicate(drw->fonts[0]->pattern); Err codevoid.de 70 i+ fcpattern = FcPatternDuplicate(drw->fonts->pattern); Err codevoid.de 70 i FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset); Err codevoid.de 70 i FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue); Err codevoid.de 70 i Err codevoid.de 70 it@@ -341,14 +347,14 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex Err codevoid.de 70 i FcPatternDestroy(fcpattern); Err codevoid.de 70 i Err codevoid.de 70 i if (match) { Err codevoid.de 70 i- curfont = drw_font_xcreate(drw, NULL, match); Err codevoid.de 70 i- if (curfont && XftCharExists(drw->dpy, curfont->xfont, utf8codepoint)) { Err codevoid.de 70 i- drw->fonts[drw->fontcount++] = curfont; Err codevoid.de 70 i+ usedfont = drw_font_xcreate(drw, NULL, match); Err codevoid.de 70 i+ if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) { Err codevoid.de 70 i+ for (curfont = drw->fonts; curfont->next; curfont = curfont->next) Err codevoid.de 70 i+ ; /* just find the end of the linked list */ Err codevoid.de 70 i+ curfont->next = usedfont; Err codevoid.de 70 i } else { Err codevoid.de 70 i- if (curfont) { Err codevoid.de 70 i- drw_font_free(curfont); Err codevoid.de 70 i- } Err codevoid.de 70 i- curfont = drw->fonts[0]; Err codevoid.de 70 i+ drw_xfont_free(usedfont); Err codevoid.de 70 i+ usedfont = drw->fonts; Err codevoid.de 70 i } Err codevoid.de 70 i } Err codevoid.de 70 i } Err codevoid.de 70 it@@ -369,6 +375,12 @@ drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h) { Err codevoid.de 70 i XSync(drw->dpy, False); Err codevoid.de 70 i } Err codevoid.de 70 i Err codevoid.de 70 i+unsigned int Err codevoid.de 70 i+drw_fontset_getwidth(Drw *drw, const char *text) { Err codevoid.de 70 i+ if (!drw || !drw->fonts || !text) Err codevoid.de 70 i+ return 0; Err codevoid.de 70 i+ return drw_text(drw, 0, 0, 0, 0, text, 0) + drw->fonts->h; Err codevoid.de 70 i+} Err codevoid.de 70 i Err codevoid.de 70 i void Err codevoid.de 70 i drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h) { Err codevoid.de 70 1diff --git a/drw.h b/drw.h /git/sent-sdk/file/drw.h.gph codevoid.de 70 it@@ -5,14 +5,16 @@ typedef struct { Err codevoid.de 70 i Cursor cursor; Err codevoid.de 70 i } Cur; Err codevoid.de 70 i Err codevoid.de 70 i-typedef struct { Err codevoid.de 70 i+typedef struct Fnt Fnt; Err codevoid.de 70 i+struct Fnt { Err codevoid.de 70 i Display *dpy; Err codevoid.de 70 i int ascent; Err codevoid.de 70 i int descent; Err codevoid.de 70 i unsigned int h; Err codevoid.de 70 i XftFont *xfont; Err codevoid.de 70 i FcPattern *pattern; Err codevoid.de 70 i-} Fnt; Err codevoid.de 70 i+ Fnt *next; Err codevoid.de 70 i+}; Err codevoid.de 70 i Err codevoid.de 70 i typedef struct { Err codevoid.de 70 i struct { Err codevoid.de 70 it@@ -29,8 +31,7 @@ typedef struct { Err codevoid.de 70 i Drawable drawable; Err codevoid.de 70 i GC gc; Err codevoid.de 70 i Scm *scheme; Err codevoid.de 70 i- size_t fontcount; Err codevoid.de 70 i- Fnt *fonts[DRW_FONT_CACHE_SIZE]; Err codevoid.de 70 i+ Fnt *fonts; Err codevoid.de 70 i } Drw; Err codevoid.de 70 i Err codevoid.de 70 i /* Drawable abstraction */ Err codevoid.de 70 it@@ -39,9 +40,9 @@ void drw_resize(Drw *drw, unsigned int w, unsigned int h); Err codevoid.de 70 i void drw_free(Drw *drw); Err codevoid.de 70 i Err codevoid.de 70 i /* Fnt abstraction */ Err codevoid.de 70 i-Fnt *drw_font_create(Drw *drw, const char *fontname); Err codevoid.de 70 i-void drw_load_fonts(Drw* drw, const char *fonts[], size_t fontcount); Err codevoid.de 70 i-void drw_font_free(Fnt *font); Err codevoid.de 70 i+Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount); Err codevoid.de 70 i+void drw_fontset_free(Fnt* set); Err codevoid.de 70 i+unsigned int drw_fontset_getwidth(Drw *drw, const char *text); Err codevoid.de 70 i void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h); Err codevoid.de 70 i Err codevoid.de 70 i /* Colorscheme abstraction */ Err codevoid.de 70 it@@ -53,7 +54,7 @@ Cur *drw_cur_create(Drw *drw, int shape); Err codevoid.de 70 i void drw_cur_free(Drw *drw, Cur *cursor); Err codevoid.de 70 i Err codevoid.de 70 i /* Drawing context manipulation */ Err codevoid.de 70 i-void drw_setfont(Drw *drw, Fnt *font); Err codevoid.de 70 i+void drw_setfontset(Drw *drw, Fnt *set); Err codevoid.de 70 i void drw_setscheme(Drw *drw, Scm *scm); Err codevoid.de 70 i Err codevoid.de 70 i /* Drawing functions */ Err codevoid.de 70 .