diff options
author | Burt P <pburt0@gmail.com> | 2019-07-03 18:01:27 -0500 |
---|---|---|
committer | Leandro Pereira <leandro@hardinfo.org> | 2019-07-04 22:40:34 -0700 |
commit | 37811a2157a962f15010c9f11bf0b708f6123cd8 (patch) | |
tree | c1cac4a5651d453ccf04eb61060430aa7c7eb1f4 | |
parent | 26deb733649d4ff2bbdf6506d8ccd58c134d218b (diff) |
shell/report: icon cache using css
Only include one copy of each icon in the source, by using
css class rather than img with src for each instance.
Signed-off-by: Burt P <pburt0@gmail.com>
-rw-r--r-- | includes/report.h | 3 | ||||
-rw-r--r-- | shell/report.c | 96 |
2 files changed, 70 insertions, 29 deletions
diff --git a/includes/report.h b/includes/report.h index cd7034da..f2f279f6 100644 --- a/includes/report.h +++ b/includes/report.h @@ -63,7 +63,8 @@ struct _ReportContext { gboolean show_column_headers; guint columns, parent_columns; GHashTable *column_titles; - GHashTable *icons; + GHashTable *icon_refs; + GHashTable *icon_data; }; struct _ReportDialog { diff --git a/shell/report.c b/shell/report.c index 27ed053b..429d0746 100644 --- a/shell/report.c +++ b/shell/report.c @@ -87,26 +87,45 @@ gint report_get_visible_columns(ReportContext *ctx) return columns; } -gchar *make_icon_html(const gchar *file, const gchar *alt_text) { - if (!file) +gchar *icon_name_css_id(const gchar *file) { + gchar *safe = g_strdup_printf("icon-%s", file); + gchar *p = safe; + while(*p) { + if (!isalnum(*p)) + *p = '-'; + p++; + } + return safe; +} + +gchar *make_icon_css(const gchar *file) { + if (!file || *file == 0) return; + gchar *ret = NULL; gchar *path = g_build_filename(params.path_data, "pixmaps", file, NULL); gchar *contents = NULL; gsize length = 0; - //printf("make_icon_html(%s, %s): %d bytes\n", file, alt_text, (int)length); if ( g_file_get_contents(path, &contents, &length, NULL) ) { + gchar *css_class = icon_name_css_id(file); const char ctype[] = "image/png"; gchar *b64data = g_base64_encode(contents, length); - gchar *ret = g_strdup_printf( - "<img src=\"data:%s;base64,%s\" alt=\"%s\">", - ctype, b64data, - alt_text ? alt_text : ""); + ret = g_strdup_printf( + ".%s\n" + "{ background: url(data:%s;base64,%s) no-repeat;\n" + " background-size: cover; }\n", + css_class ? css_class : "", + ctype, b64data ); g_free(b64data); - g_free(contents); - g_free(path); - return ret; + g_free(css_class); } - return ""; + g_free(contents); + g_free(path); + return ret ? ret : g_strdup(""); +} + +void cache_icon(ReportContext *ctx, const gchar *file) { + if (!g_hash_table_lookup(ctx->icon_data, file) ) + g_hash_table_insert(ctx->icon_data, g_strdup(file), make_icon_css(file)); } void report_context_configure(ReportContext * ctx, GKeyFile * keyfile) @@ -114,11 +133,11 @@ void report_context_configure(ReportContext * ctx, GKeyFile * keyfile) gchar **keys; const gchar *group = "$ShellParam$"; - if (ctx->icons) { - g_hash_table_remove_all(ctx->icons); - ctx->icons = NULL; + if (ctx->icon_refs) { + g_hash_table_remove_all(ctx->icon_refs); + ctx->icon_refs = NULL; } - ctx->icons = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); //g_free + ctx->icon_refs = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); keys = g_key_file_get_keys(keyfile, group, NULL, NULL); if (keys) { @@ -166,9 +185,8 @@ void report_context_configure(ReportContext * ctx, GKeyFile * keyfile) gchar *ikey = g_utf8_strchr(key, -1, '$'); gchar *tag = key_mi_tag(ikey); gchar *icon = g_key_file_get_value(keyfile, group, key, NULL); - gchar *icon_html = make_icon_html(icon, tag); - g_hash_table_insert(ctx->icons, tag, icon_html); - g_free(icon); + cache_icon(ctx, icon); + g_hash_table_insert(ctx->icon_refs, tag, icon); } } @@ -400,16 +418,27 @@ static void report_html_header(ReportContext * ctx) " .value { font: 80%% sans-serif; color: #505050 }\n" " .hilight { font: bold 110%% sans-serif; color: #000000; background: #ffff66 }\n" " table.details { margin-left: 50px; }\n" - " td.icon { width: 2.4em; }\n" - " .icon img { width: 1.2em; padding-left: 1.2em; }\n" + " td.icon { width: 1.2em; padding-left: 1.2em; }\n" + " td.icon img { width: 1.2em; }\n" + " td.icon div { display: block; box-sizing: border-box; -moz-box-sizing: border-box;\n" + " width: 1.2em; height: 1.2em; background-position: right; }\n" "</style>\n" "</head><body>\n", VERSION); } static void report_html_footer(ReportContext * ctx) { - ctx->output = h_strconcat(ctx->output, - "</table></html>", NULL); + ctx->output = h_strconcat(ctx->output, "</table>", NULL); + ctx->output = h_strconcat(ctx->output, "<style>\n", NULL); + GList *l = NULL, *keys = g_hash_table_get_keys(ctx->icon_data); + for(l = keys; l; l = l->next) { + gchar *data = g_hash_table_lookup(ctx->icon_data, (gchar*)l->data); + if (data) + ctx->output = h_strconcat(ctx->output, data, NULL); + } + g_list_free(keys); + ctx->output = h_strconcat(ctx->output, "</style>\n", NULL); + ctx->output = h_strconcat(ctx->output, "</html>", NULL); } static void report_html_title(ReportContext * ctx, gchar * text) @@ -458,9 +487,15 @@ report_html_key_value(ReportContext * ctx, gchar * key, gchar * value) gboolean highlight = key_is_highlighted(key); gchar *tag = key_mi_tag(key); - const gchar *icon_html = tag ? g_hash_table_lookup(ctx->icons, tag) : NULL; + gchar *icon = tag ? (gchar*)g_hash_table_lookup(ctx->icon_refs, tag) : NULL; g_free(tag); - if (!icon_html) icon_html = ""; + /* icon from the table is const, so can be re-used without free */ + if (icon) { + gchar *icon_class = icon_name_css_id(icon); + icon = g_strdup_printf("<div class=\"%s\"></div>", icon_class); + g_free(icon_class); + } else + icon = g_strdup(""); gchar *name = (gchar*)key_get_name(key); @@ -469,12 +504,12 @@ report_html_key_value(ReportContext * ctx, gchar * key, gchar * value) "<td class=\"value\">%s</td></tr>\n", ctx->output, highlight ? " class=\"hilight\"" : "", - icon_html, name, value); + icon, name, value); } else { values = g_strsplit(value, "|", columns); mc = g_strv_length(values) - 1; - ctx->output = h_strdup_cprintf("\n<tr%s>\n<td class=\"icon\">%s</td><td class=\"field\">%s</td>", ctx->output, highlight ? " class=\"hilight\"" : "", icon_html, name); + ctx->output = h_strdup_cprintf("\n<tr%s>\n<td class=\"icon\">%s</td><td class=\"field\">%s</td>", ctx->output, highlight ? " class=\"hilight\"" : "", icon, name); for (i = mc; i >= 0; i--) { ctx->output = h_strdup_cprintf("<td class=\"value\">%s</td>", @@ -486,6 +521,7 @@ report_html_key_value(ReportContext * ctx, gchar * key, gchar * value) g_strfreev(values); } + g_free(icon); } static void report_text_header(ReportContext * ctx) @@ -720,6 +756,8 @@ ReportContext *report_context_html_new() g_free, g_free); ctx->first_table = TRUE; + ctx->icon_data = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); + return ctx; } @@ -776,8 +814,10 @@ ReportContext *report_context_shell_new() void report_context_free(ReportContext * ctx) { g_hash_table_destroy(ctx->column_titles); - if(ctx->icons) - g_hash_table_destroy(ctx->icons); + if(ctx->icon_refs) + g_hash_table_destroy(ctx->icon_refs); + if(ctx->icon_data) + g_hash_table_destroy(ctx->icon_data); g_free(ctx->output); g_free(ctx); } |