From: Takashi Iwai Subject: Improve rendering of mgp-1.11b with XFT The patch adds better caches for XFT rendering. And it removes the unnecessary memory allocations/copies. ================================================================================ --- draw.c +++ draw.c @@ -4839,59 +4839,66 @@ return NULL; /* should not happen */ } +struct xft_font_cache { + char *name; + int size; + XftFont *font; + struct xft_font_cache *next; +}; + +static struct xft_font_cache *xft_fonts = NULL; + static XftFont * -xft_setfont(xfontarg, csize, registry) - char *xfontarg; +xft_setfont(xfont, csize, registry) + char *xfont; int csize; char *registry; { - char *xfont; - static XftFont *last_xftfont; - static char lastfont[100]; - static int lastsize = 0; XftFont *xftfont; - char *p, *p2; - char style[100]; + char *p; char font[100]; + char fontname[200]; + char *style = ""; int stlen; - - bzero(style, sizeof(style)); - bzero(font, sizeof(font)); - - xfont = strdup(xfontarg); - if (!xfont) - return NULL; - - if (!strcmp(xfont, lastfont) && lastsize == csize) { - free(xfont); - return last_xftfont; - } + struct xft_font_cache *cache; /* * if xfont contains "-", we believe this is a conventional xfont name * and try to convert it for xft */ if ((p = strchr(xfont, '-')) != NULL) { - *p++ = 0; - strlcpy(font, xfont, sizeof(font)); + stlen = p - xfont; + if (stlen >= sizeof(font)) + stlen = sizeof(font) - 1; + memcpy(font, xfont, stlen); + font[stlen] = 0; + p++; if (strncmp(p, "bold-i", 6) == 0) - strlcpy(style, "Bold Italic", sizeof(style)); + style = "Bold Italic"; else if (strncmp(p, "bold-", 5) == 0) - strlcpy(style, "Bold", sizeof(style)); + style = "Bold"; else if ((p = strchr(p, '-')) != NULL && p[1] == 'i') - strlcpy(style, "Italic", sizeof(style)); + style = "Italic"; } else if ((p = strchr(xfont, ':')) == NULL) strlcpy(font, xfont, sizeof(font)); else { - p2 = p +1; + style = p + 1; /* allow to use ":style=" syntax */ - if ((strstr(p2, "style=") != NULL) || (strstr(p2, "STYLE=") != NULL)) - p2 += 6; - *p = '\0'; - strlcpy(font, xfont, sizeof(font)); - strlcpy(style, p2, sizeof(style)); + if ((strstr(style, "style=") != NULL) || (strstr(style, "STYLE=") != NULL)) + style += 6; + stlen = p - xfont; + if (stlen >= sizeof(font)) + stlen = sizeof(font) - 1; + memcpy(font, xfont, stlen); + font[stlen] = 0; + } + snprintf(fontname, sizeof(fontname), "%s:%s", font, style); + for (cache = xft_fonts; cache; cache = cache->next) { + if (!strcmp(fontname, cache->name) && csize == cache->size) + return cache->font; } + if (style[0]) { xftfont = XftFontOpen(display, screen, XFT_FAMILY, XftTypeString, font, @@ -4905,18 +4912,29 @@ XFT_PIXEL_SIZE, XftTypeDouble, (float)csize, NULL); } if (xftfont == 0) { - free(xfont); return NULL; } - snprintf(lastfont, sizeof(lastfont), "%s:%s", font, style); + + cache = malloc(sizeof(*cache)); + if (! cache) { + XftFontClose(display, xftfont); + return NULL; + } + cache->name = strdup(fontname); + if (! cache->name) { + free(cache); + XftFontClose(display, xftfont); + return NULL; + } if (verbose) { - fprintf(stderr, "using xftfont [%s] size: %d\n", lastfont, + fprintf(stderr, "using xftfont [%s] size: %d\n", cache->name, csize); } - lastsize = csize; - last_xftfont = xftfont; - free(xfont); - return last_xftfont; + cache->size = csize; + cache->font = xftfont; + cache->next = xft_fonts; + xft_fonts = cache; + return cache->font; } #endif #ifdef USE_M17N