Tried to enable font tag size/face support and discovered that this made loading sites slow since same fonts were queried, dropped and requeried many times from X server. So here is a patch which makes Dw_style not drop any fonts from fonts_table hashmap until Dw_style_cleanup_fonts is called (from Html_close, when page rendering is finished) and enables support for font tags size and face attributes. diff -pru -x CVS -x configure -x 'aclocal*' -x 'Makefile*' -x config.h.in cvs/dillo/src/dw_style.c dillo/src/dw_style.c --- cvs/dillo/src/dw_style.c 2003-01-05 17:04:56.000000000 +0200 +++ dillo/src/dw_style.c 2003-04-13 14:26:12.000000000 +0300 @@ -24,8 +24,7 @@ #define EQUIV(a, b) (((a) && (b)) || (!(a) && !(b))) #define Dw_style_font_ref(font) ((font)->ref_count++) -#define Dw_style_font_unref(font) if (--((font)->ref_count) == 0) \ - Dw_style_font_remove (font) +#define Dw_style_font_unref(font) (--(font)->ref_count) #define Dw_style_color_ref(color) ((color)->ref_count++) #define Dw_style_color_unref(color) if (--((color)->ref_count) == 0) \ @@ -82,6 +81,8 @@ static void Dw_style_count_fonts (gpoint count[1] += font->ref_count; } + + /* * Called by a_Dw_style_freeall. */ @@ -142,6 +143,25 @@ void a_Dw_style_freeall (void) g_hash_table_destroy (colors_table); } +static gboolean Dw_style_cleanup_fonts (gpointer key, + gpointer value, + gpointer user_data) +{ + DwStyleFont *font = (DwStyleFont*) key; + + if (font->ref_count <= 0) { + Dw_style_font_remove (font); + return TRUE; + } + return FALSE; +} + +/* Collects garbage from fonts cache... */ +void a_Dw_style_fonts_cleanup (void) +{ +// fprintf(stderr, "a_Dw_style_fonts_cleanup called\n"); + g_hash_table_foreach_remove (fonts_table, Dw_style_cleanup_fonts, NULL); +} /* ---------------------------------------------------------------------- * @@ -340,6 +360,9 @@ static DwStyleFont* Dw_style_font_new_in if ((font = g_hash_table_lookup (fonts_table, font_attrs))) { return font; } else { +/*fprintf(stderr, "*** load new font... %d b%d i%d '%s'\n", + (int) font_attrs->size, (int) font_attrs->bold, + (int) font_attrs->italic, font_attrs->name);*/ font = g_new (DwStyleFont, 1); font->size = font_attrs->size; font->bold = font_attrs->bold; @@ -349,6 +372,9 @@ static DwStyleFont* Dw_style_font_new_in Dw_style_font_realize (font, try_all); if (font->font) { +/*fprintf(stderr, "*** new font: %d b%d i%d '%s'\n", + (int) font->size, (int) font->bold, + (int) font->italic, font->name);*/ g_hash_table_insert (fonts_table, font, font); return font; } else { @@ -424,7 +450,10 @@ DwStyleFont* a_Dw_style_font_new_from_li */ static void Dw_style_font_remove (DwStyleFont *font) { - g_hash_table_remove (fonts_table, font); +/*fprintf(stderr, "*** remove font... %d b%d i%d '%s'\n", + (int) font->size, (int) font->bold, + (int) font->italic, font->name);*/ +// g_hash_table_remove (fonts_table, font); g_free (font->name); gdk_font_unref (font->font); g_free (font); diff -pru -x CVS -x configure -x 'aclocal*' -x 'Makefile*' -x config.h.in cvs/di llo/src/dw_style.h dillo/src/dw_style.h --- cvs/dillo/src/dw_style.h 2002-12-29 18:09:52.000000000 +0200 +++ dillo/src/dw_style.h 2003-04-13 14:26:12.000000000 +0300 @@ -122,6 +122,7 @@ DwStyle* a_Dw_style_new GdkWindow *window); DwStyleFont* a_Dw_style_font_new (DwStyleFont *font_attrs); DwStyleFont* a_Dw_style_font_new_from_list (DwStyleFont *font_attrs); +void a_Dw_style_fonts_cleanup (void); DwStyleColor* a_Dw_style_color_new (gint color_val, GdkWindow *window); DwStyleShadedColor* a_Dw_style_shaded_color_new (gint color_val, +#define SUPPORT_FONTS 1 + +#if SUPPORT_FONTS +static const char *strcasestr(const char *haystack, const char *needle) +{ + int needle_len; + + for (needle_len = strlen(needle); *haystack; ++haystack) + if ((*haystack|' ') == (*needle|' ') && + !g_strncasecmp(haystack, needle, needle_len)) return haystack; + return NULL; +} +#endif static void Html_tag_open_font(DilloHtml *html, char *tag, gint tagsize) { #if 1 DwStyle style_attrs, *old_style; - /*DwStyleFont font;*/ +#if SUPPORT_FONTS + DwStyleFont font; + gint level, setsize = 0; +#endif const char *attrbuf; gint32 color; @@ -1792,10 +1817,26 @@ static void Html_tag_open_font(DilloHtml } } -#if 0 - if ((attrbuf = Html_get_attr(html, tag, tagsize, "face"))) { +#if SUPPORT_FONTS + if ((attrbuf = Html_get_attr(html, tag, tagsize, "size"))) { + level = strtol(attrbuf, NULL, 10); + if (level < 0 || *attrbuf == '+') + level += Html_fontsize_to_level(style_attrs.font->size); + setsize = Html_level_to_fontsize(level); + } + + if ((attrbuf = Html_get_attr(html, tag, tagsize, "face")) && + strcasestr(attrbuf, style_attrs.font->name)) + attrbuf = NULL; + + if (attrbuf || (setsize > 0 && setsize != style_attrs.font->size)) { font = *( style_attrs.font ); - font.name = attrbuf; +/* fprintf(stderr, "font '%s'->'%s', %d->%d\n", + font.name, attrbuf, font.size, setsize);*/ + if (attrbuf) + font.name = (char*) attrbuf; + if (setsize > 0) + font.size = setsize; style_attrs.font = a_Dw_style_font_new_from_list (&font); } #endif @@ -4183,6 +4289,9 @@ static void Html_close(DilloHtml *html, a_Progressbar_update(html->bw->progress, NULL, 0); g_free(html); + + /* free unused entries from font cache */ + a_Dw_style_fonts_cleanup(); }