Improve format parsing performance by using preloaded stringshares to do pointer

comparisons rather than strcmp and avoid extra malloc/free overhead. May be a
slight slow down on short simple text, but a significant improvement on longer
and more complex formatting.


SVN revision: 27268
This commit is contained in:
ningerso 2006-11-28 16:14:11 +00:00 committed by ningerso
parent 97970e262f
commit 0a734352bd
1 changed files with 123 additions and 37 deletions

View File

@ -746,7 +746,7 @@ _hex_string_get(char ch)
} }
static void static void
_format_color_parse(char *str, unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a) _format_color_parse(const char *str, unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a)
{ {
int slen; int slen;
@ -793,12 +793,92 @@ _format_color_parse(char *str, unsigned char *r, unsigned char *g, unsigned char
*b = (*b * *a) / 255; *b = (*b * *a) / 255;
} }
static const char *fontstr;
static const char *font_fallbacksstr;
static const char *font_sizestr;
static const char *font_sourcestr;
static const char *colorstr;
static const char *underline_colorstr;
static const char *underline2_colorstr;
static const char *outline_colorstr;
static const char *shadow_colorstr;
static const char *glow_colorstr;
static const char *glow2_colorstr;
static const char *backing_colorstr;
static const char *strikethrough_colorstr;
static const char *alignstr;
static const char *valignstr;
static const char *wrapstr;
static const char *left_marginstr;
static const char *right_marginstr;
static const char *underlinestr;
static const char *strikethroughstr;
static const char *backingstr;
static const char *stylestr;
static const char *tabstopsstr;
static void static void
_format_command(Evas_Object *obj, Evas_Object_Textblock_Format *fmt, char *cmd, char *param) _format_command_init()
{
fontstr = evas_stringshare_add("font");
font_fallbacksstr = evas_stringshare_add("font_fallbacks");
font_sizestr = evas_stringshare_add("font_size");
font_sourcestr = evas_stringshare_add("font_source");
colorstr = evas_stringshare_add("color");
underline_colorstr = evas_stringshare_add("underline_color");
underline2_colorstr = evas_stringshare_add("underline2_color");
outline_colorstr = evas_stringshare_add("outline_color");
shadow_colorstr = evas_stringshare_add("shadow_color");
glow_colorstr = evas_stringshare_add("glow_color");
glow2_colorstr = evas_stringshare_add("glow2_color");
backing_colorstr = evas_stringshare_add("backing_color");
strikethrough_colorstr = evas_stringshare_add("strikethrough_color");
alignstr = evas_stringshare_add("align");
valignstr = evas_stringshare_add("valign");
wrapstr = evas_stringshare_add("wrap");
left_marginstr = evas_stringshare_add("left_margin");
right_marginstr = evas_stringshare_add("right_margin");
underlinestr = evas_stringshare_add("underline");
strikethroughstr = evas_stringshare_add("strikethrough");
backingstr = evas_stringshare_add("backing");
stylestr = evas_stringshare_add("style");
tabstopsstr = evas_stringshare_add("tabstops");
}
static void
_format_command_shutdown()
{
evas_stringshare_del(fontstr);
evas_stringshare_del(font_fallbacksstr);
evas_stringshare_del(font_sizestr);
evas_stringshare_del(font_sourcestr);
evas_stringshare_del(colorstr);
evas_stringshare_del(underline_colorstr);
evas_stringshare_del(underline2_colorstr);
evas_stringshare_del(outline_colorstr);
evas_stringshare_del(shadow_colorstr);
evas_stringshare_del(glow_colorstr);
evas_stringshare_del(glow2_colorstr);
evas_stringshare_del(backing_colorstr);
evas_stringshare_del(strikethrough_colorstr);
evas_stringshare_del(alignstr);
evas_stringshare_del(valignstr);
evas_stringshare_del(wrapstr);
evas_stringshare_del(left_marginstr);
evas_stringshare_del(right_marginstr);
evas_stringshare_del(underlinestr);
evas_stringshare_del(strikethroughstr);
evas_stringshare_del(backingstr);
evas_stringshare_del(stylestr);
evas_stringshare_del(tabstopsstr);
}
static void
_format_command(Evas_Object *obj, Evas_Object_Textblock_Format *fmt, const char *cmd, const char *param)
{ {
int new_font = 0; int new_font = 0;
if (!strcmp(cmd, "font")) if (cmd == fontstr)
{ {
if ((!fmt->font.name) || if ((!fmt->font.name) ||
((fmt->font.name) && (strcmp(fmt->font.name, param)))) ((fmt->font.name) && (strcmp(fmt->font.name, param))))
@ -808,7 +888,7 @@ _format_command(Evas_Object *obj, Evas_Object_Textblock_Format *fmt, char *cmd,
new_font = 1; new_font = 1;
} }
} }
else if (!strcmp(cmd, "font_fallbacks")) else if (cmd == font_fallbacksstr)
{ {
if ((!fmt->font.fallbacks) || if ((!fmt->font.fallbacks) ||
((fmt->font.fallbacks) && (strcmp(fmt->font.fallbacks, param)))) ((fmt->font.fallbacks) && (strcmp(fmt->font.fallbacks, param))))
@ -821,7 +901,7 @@ _format_command(Evas_Object *obj, Evas_Object_Textblock_Format *fmt, char *cmd,
new_font = 1; new_font = 1;
} }
} }
else if (!strcmp(cmd, "font_size")) else if (cmd == font_sizestr)
{ {
int v; int v;
@ -832,7 +912,7 @@ _format_command(Evas_Object *obj, Evas_Object_Textblock_Format *fmt, char *cmd,
new_font = 1; new_font = 1;
} }
} }
else if (!strcmp(cmd, "font_source")) else if (cmd == font_sourcestr)
{ {
if ((!fmt->font.source) || if ((!fmt->font.source) ||
((fmt->font.source) && (strcmp(fmt->font.source, param)))) ((fmt->font.source) && (strcmp(fmt->font.source, param))))
@ -842,43 +922,43 @@ _format_command(Evas_Object *obj, Evas_Object_Textblock_Format *fmt, char *cmd,
new_font = 1; new_font = 1;
} }
} }
else if (!strcmp(cmd, "color")) else if (cmd == colorstr)
_format_color_parse(param, _format_color_parse(param,
&(fmt->color.normal.r), &(fmt->color.normal.g), &(fmt->color.normal.r), &(fmt->color.normal.g),
&(fmt->color.normal.b), &(fmt->color.normal.a)); &(fmt->color.normal.b), &(fmt->color.normal.a));
else if (!strcmp(cmd, "underline_color")) else if (cmd == underline_colorstr)
_format_color_parse(param, _format_color_parse(param,
&(fmt->color.underline.r), &(fmt->color.underline.g), &(fmt->color.underline.r), &(fmt->color.underline.g),
&(fmt->color.underline.b), &(fmt->color.underline.a)); &(fmt->color.underline.b), &(fmt->color.underline.a));
else if (!strcmp(cmd, "underline2_color")) else if (cmd == underline2_colorstr)
_format_color_parse(param, _format_color_parse(param,
&(fmt->color.underline2.r), &(fmt->color.underline2.g), &(fmt->color.underline2.r), &(fmt->color.underline2.g),
&(fmt->color.underline2.b), &(fmt->color.underline2.a)); &(fmt->color.underline2.b), &(fmt->color.underline2.a));
else if (!strcmp(cmd, "outline_color")) else if (cmd == outline_colorstr)
_format_color_parse(param, _format_color_parse(param,
&(fmt->color.outline.r), &(fmt->color.outline.g), &(fmt->color.outline.r), &(fmt->color.outline.g),
&(fmt->color.outline.b), &(fmt->color.outline.a)); &(fmt->color.outline.b), &(fmt->color.outline.a));
else if (!strcmp(cmd, "shadow_color")) else if (cmd == shadow_colorstr)
_format_color_parse(param, _format_color_parse(param,
&(fmt->color.shadow.r), &(fmt->color.shadow.g), &(fmt->color.shadow.r), &(fmt->color.shadow.g),
&(fmt->color.shadow.b), &(fmt->color.shadow.a)); &(fmt->color.shadow.b), &(fmt->color.shadow.a));
else if (!strcmp(cmd, "glow_color")) else if (cmd == glow_colorstr)
_format_color_parse(param, _format_color_parse(param,
&(fmt->color.glow.r), &(fmt->color.glow.g), &(fmt->color.glow.r), &(fmt->color.glow.g),
&(fmt->color.glow.b), &(fmt->color.glow.a)); &(fmt->color.glow.b), &(fmt->color.glow.a));
else if (!strcmp(cmd, "glow2_color")) else if (cmd == glow2_colorstr)
_format_color_parse(param, _format_color_parse(param,
&(fmt->color.glow2.r), &(fmt->color.glow2.g), &(fmt->color.glow2.r), &(fmt->color.glow2.g),
&(fmt->color.glow2.b), &(fmt->color.glow2.a)); &(fmt->color.glow2.b), &(fmt->color.glow2.a));
else if (!strcmp(cmd, "backing_color")) else if (cmd == backing_colorstr)
_format_color_parse(param, _format_color_parse(param,
&(fmt->color.backing.r), &(fmt->color.backing.g), &(fmt->color.backing.r), &(fmt->color.backing.g),
&(fmt->color.backing.b), &(fmt->color.backing.a)); &(fmt->color.backing.b), &(fmt->color.backing.a));
else if (!strcmp(cmd, "strikethrough_color")) else if (cmd == strikethrough_colorstr)
_format_color_parse(param, _format_color_parse(param,
&(fmt->color.strikethrough.r), &(fmt->color.strikethrough.g), &(fmt->color.strikethrough.r), &(fmt->color.strikethrough.g),
&(fmt->color.strikethrough.b), &(fmt->color.strikethrough.a)); &(fmt->color.strikethrough.b), &(fmt->color.strikethrough.a));
else if (!strcmp(cmd, "align")) else if (cmd == alignstr)
{ {
if (!strcmp(param, "middle")) fmt->halign = 0.5; if (!strcmp(param, "middle")) fmt->halign = 0.5;
else if (!strcmp(param, "center")) fmt->halign = 0.5; else if (!strcmp(param, "center")) fmt->halign = 0.5;
@ -903,7 +983,7 @@ _format_command(Evas_Object *obj, Evas_Object_Textblock_Format *fmt, char *cmd,
else if (fmt->halign > 1.0) fmt->halign = 1.0; else if (fmt->halign > 1.0) fmt->halign = 1.0;
} }
} }
else if (!strcmp(cmd, "valign")) else if (cmd == valignstr)
{ {
if (!strcmp(param, "top")) fmt->valign = 0.0; if (!strcmp(param, "top")) fmt->valign = 0.0;
else if (!strcmp(param, "middle")) fmt->valign = 0.5; else if (!strcmp(param, "middle")) fmt->valign = 0.5;
@ -930,7 +1010,7 @@ _format_command(Evas_Object *obj, Evas_Object_Textblock_Format *fmt, char *cmd,
else if (fmt->valign > 1.0) fmt->valign = 1.0; else if (fmt->valign > 1.0) fmt->valign = 1.0;
} }
} }
else if (!strcmp(cmd, "wrap")) else if (cmd == wrapstr)
{ {
if (!strcmp(param, "word")) if (!strcmp(param, "word"))
{ {
@ -948,7 +1028,7 @@ _format_command(Evas_Object *obj, Evas_Object_Textblock_Format *fmt, char *cmd,
fmt->wrap_char = 0; fmt->wrap_char = 0;
} }
} }
else if (!strcmp(cmd, "left_margin")) else if (cmd == left_marginstr)
{ {
if (!strcmp(param, "reset")) if (!strcmp(param, "reset"))
fmt->margin.l = 0; fmt->margin.l = 0;
@ -963,7 +1043,7 @@ _format_command(Evas_Object *obj, Evas_Object_Textblock_Format *fmt, char *cmd,
if (fmt->margin.l < 0) fmt->margin.l = 0; if (fmt->margin.l < 0) fmt->margin.l = 0;
} }
} }
else if (!strcmp(cmd, "right_margin")) else if (cmd == right_marginstr)
{ {
if (!strcmp(param, "reset")) if (!strcmp(param, "reset"))
fmt->margin.r = 0; fmt->margin.r = 0;
@ -978,7 +1058,7 @@ _format_command(Evas_Object *obj, Evas_Object_Textblock_Format *fmt, char *cmd,
if (fmt->margin.r < 0) fmt->margin.r = 0; if (fmt->margin.r < 0) fmt->margin.r = 0;
} }
} }
else if (!strcmp(cmd, "underline")) else if (cmd == underlinestr)
{ {
if (!strcmp(param, "off")) if (!strcmp(param, "off"))
{ {
@ -997,21 +1077,21 @@ _format_command(Evas_Object *obj, Evas_Object_Textblock_Format *fmt, char *cmd,
fmt->underline2 = 1; fmt->underline2 = 1;
} }
} }
else if (!strcmp(cmd, "strikethrough")) else if (cmd == strikethroughstr)
{ {
if (!strcmp(param, "off")) if (!strcmp(param, "off"))
fmt->strikethrough = 0; fmt->strikethrough = 0;
else if (!strcmp(param, "on")) else if (!strcmp(param, "on"))
fmt->strikethrough = 1; fmt->strikethrough = 1;
} }
else if (!strcmp(cmd, "backing")) else if (cmd == backingstr)
{ {
if (!strcmp(param, "off")) if (!strcmp(param, "off"))
fmt->backing = 0; fmt->backing = 0;
else if (!strcmp(param, "on")) else if (!strcmp(param, "on"))
fmt->backing = 1; fmt->backing = 1;
} }
else if (!strcmp(cmd, "style")) else if (cmd == stylestr)
{ {
if (!strcmp(param, "off")) fmt->style = EVAS_TEXT_STYLE_PLAIN; if (!strcmp(param, "off")) fmt->style = EVAS_TEXT_STYLE_PLAIN;
else if (!strcmp(param, "none")) fmt->style = EVAS_TEXT_STYLE_PLAIN; else if (!strcmp(param, "none")) fmt->style = EVAS_TEXT_STYLE_PLAIN;
@ -1027,7 +1107,7 @@ _format_command(Evas_Object *obj, Evas_Object_Textblock_Format *fmt, char *cmd,
else if (!strcmp(param, "far_soft_shadow")) fmt->style = EVAS_TEXT_STYLE_FAR_SOFT_SHADOW; else if (!strcmp(param, "far_soft_shadow")) fmt->style = EVAS_TEXT_STYLE_FAR_SOFT_SHADOW;
else fmt->style = EVAS_TEXT_STYLE_PLAIN; else fmt->style = EVAS_TEXT_STYLE_PLAIN;
} }
else if (!strcmp(cmd, "tabstops")) else if (cmd == tabstopsstr)
{ {
fmt->tabstops = atoi(param); fmt->tabstops = atoi(param);
if (fmt->tabstops < 1) fmt->tabstops = 1; if (fmt->tabstops < 1) fmt->tabstops = 1;
@ -1064,18 +1144,18 @@ _format_is_param(char *item)
} }
static void static void
_format_param_parse(char *item, char **key, char **val) _format_param_parse(char *item, const char **key, const char **val)
{ {
char *p; char *p;
char *k, *v; const char *k, *v;
p = strchr(item, '='); p = strchr(item, '=');
k = malloc(p - item + 1); *p = '\0';
strncpy(k, item, p - item); k = evas_stringshare_add(item);
k[p - item] = 0;
*key = k; *key = k;
*p = '=';
p++; p++;
v = strdup(p); v = evas_stringshare_add(p);
*val = v; *val = v;
} }
@ -1139,12 +1219,12 @@ _format_fill(Evas_Object *obj, Evas_Object_Textblock_Format *fmt, char *str)
{ {
if (_format_is_param(item)) if (_format_is_param(item))
{ {
char *key = NULL, *val = NULL; const char *key = NULL, *val = NULL;
_format_param_parse(item, &key, &val); _format_param_parse(item, &key, &val);
_format_command(obj, fmt, key, val); _format_command(obj, fmt, key, val);
free(key); evas_stringshare_del(key);
free(val); evas_stringshare_del(val);
} }
else else
{ {
@ -1279,12 +1359,12 @@ _layout_format_pop(Ctxt *c, Evas_Object_Textblock_Format *fmt)
static void static void
_layout_format_value_handle(Ctxt *c, Evas_Object_Textblock_Format *fmt, char *item) _layout_format_value_handle(Ctxt *c, Evas_Object_Textblock_Format *fmt, char *item)
{ {
char *key = NULL, *val = NULL; const char *key = NULL, *val = NULL;
_format_param_parse(item, &key, &val); _format_param_parse(item, &key, &val);
if ((key) && (val)) _format_command(c->obj, fmt, key, val); if ((key) && (val)) _format_command(c->obj, fmt, key, val);
if (key) free(key); if (key) evas_stringshare_del(key);
if (val) free(val); if (val) evas_stringshare_del(val);
c->align = fmt->halign; c->align = fmt->halign;
c->marginl = fmt->margin.l; c->marginl = fmt->margin.l;
c->marginr = fmt->margin.r; c->marginr = fmt->margin.r;
@ -1873,6 +1953,8 @@ _layout(Evas_Object *obj, int calc_only, int w, int h, int *w_ret, int *h_ret)
c->line_no = 0; c->line_no = 0;
c->align = 0.0; c->align = 0.0;
_format_command_init();
/* setup default base style */ /* setup default base style */
if ((c->o->style) && (c->o->style->default_tag)) if ((c->o->style) && (c->o->style->default_tag))
{ {
@ -1881,6 +1963,7 @@ _layout(Evas_Object *obj, int calc_only, int w, int h, int *w_ret, int *h_ret)
} }
if (!fmt) if (!fmt)
{ {
_format_command_shutdown();
if (w_ret) *w_ret = 0; if (w_ret) *w_ret = 0;
if (h_ret) *h_ret = 0; if (h_ret) *h_ret = 0;
return; return;
@ -2021,14 +2104,17 @@ _layout(Evas_Object *obj, int calc_only, int w, int h, int *w_ret, int *h_ret)
o->style_pad.b = style_pad_b; o->style_pad.b = style_pad_b;
_layout(obj, calc_only, w, h, w_ret, h_ret); _layout(obj, calc_only, w, h, w_ret, h_ret);
_lines_clear(obj, lines); _lines_clear(obj, lines);
_format_command_shutdown();
return; return;
} }
if (!calc_only) if (!calc_only)
{ {
o->lines = c->lines; o->lines = c->lines;
_format_command_shutdown();
return; return;
} }
if (c->lines) _lines_clear(obj, c->lines); if (c->lines) _lines_clear(obj, c->lines);
_format_command_shutdown();
} }
static void static void