From 39c11951763e1260c00d2584f2b8388a0c62267f Mon Sep 17 00:00:00 2001 From: Stafford Mitchell Horne Date: Tue, 28 Mar 2006 07:45:54 +0000 Subject: [PATCH] Add ability for text blocks to use text classes * Classes are defined at the tag level * Tags whithout classes inherit the parent class * text class defined by putting text_class= in tag style SVN revision: 21518 --- legacy/edje/src/lib/edje_calc.c | 4 +- legacy/edje/src/lib/edje_load.c | 13 +- legacy/edje/src/lib/edje_private.h | 12 +- legacy/edje/src/lib/edje_text.c | 5 +- legacy/edje/src/lib/edje_textblock_styles.c | 346 ++++++++++++++++---- legacy/edje/src/lib/edje_util.c | 15 +- 6 files changed, 307 insertions(+), 88 deletions(-) diff --git a/legacy/edje/src/lib/edje_calc.c b/legacy/edje/src/lib/edje_calc.c index b1a3008361..ccab2be437 100644 --- a/legacy/edje/src/lib/edje_calc.c +++ b/legacy/edje/src/lib/edje_calc.c @@ -513,6 +513,8 @@ _edje_part_recalc_single(Edje *ed, Evas_Coord tw, th; char buf[4096]; int inlined_font = 0; + + /* Update a object_text part */ if (chosen_desc->text.id_source >= 0) ep->text.source = ed->table_parts[chosen_desc->text.id_source % ed->table_parts_size]; @@ -612,7 +614,7 @@ _edje_part_recalc_single(Edje *ed, } if (inlined_font) evas_object_text_font_source_set(ep->object, ed->path); else evas_object_text_font_source_set(ep->object, NULL); - + if ((_edje_fontset_append) && (font)) { char *font2; diff --git a/legacy/edje/src/lib/edje_load.c b/legacy/edje/src/lib/edje_load.c index 9fe89ea664..070c7ea254 100644 --- a/legacy/edje/src/lib/edje_load.c +++ b/legacy/edje/src/lib/edje_load.c @@ -46,7 +46,10 @@ edje_object_file_set(Evas_Object *obj, const char *file, const char *part) ed->load_error = EDJE_LOAD_ERROR_NONE; _edje_file_add(ed); - + + _edje_textblock_styles_add(ed); + _edje_textblock_style_all_update(ed); + if (ed->collection) { Evas_List *l; @@ -60,7 +63,8 @@ edje_object_file_set(Evas_Object *obj, const char *file, const char *part) /* Register any color classes in this parts descriptions. */ ep = l->data; - if ((ep->default_desc) && (ep->default_desc->color_class)) _edje_color_class_member_add(ed, ep->default_desc->color_class); + if ((ep->default_desc) && (ep->default_desc->color_class)) + _edje_color_class_member_add(ed, ep->default_desc->color_class); for (hist = ep->other_desc; hist; hist = hist->next) { Edje_Part_Description *desc; @@ -147,13 +151,13 @@ edje_object_file_set(Evas_Object *obj, const char *file, const char *part) { printf("EDJE ERROR: no default part description!\n"); } - _edje_text_part_on_add(ed, rp); if (ep->type == EDJE_PART_TYPE_RECTANGLE) rp->object = evas_object_rectangle_add(ed->evas); else if (ep->type == EDJE_PART_TYPE_IMAGE) rp->object = evas_object_image_add(ed->evas); else if (ep->type == EDJE_PART_TYPE_TEXT) { + _edje_text_part_on_add(ed, rp); rp->object = evas_object_text_add(ed->evas); evas_object_text_font_source_set(rp->object, ed->path); } @@ -489,7 +493,8 @@ _edje_file_del(Edje *ed) if ((ed->file) && (ed->collection)) { Evas_List *l; - + + _edje_textblock_styles_del(ed); for (l = ed->collection->parts; l; l = l->next) { Edje_Part *ep; diff --git a/legacy/edje/src/lib/edje_private.h b/legacy/edje/src/lib/edje_private.h index ba2a0f67b6..18d7403d59 100644 --- a/legacy/edje/src/lib/edje_private.h +++ b/legacy/edje/src/lib/edje_private.h @@ -213,8 +213,11 @@ struct _Edje_Style struct _Edje_Style_Tag { - char *key; - char *value; + const char *key; + const char *value; + const char *font; + double font_size; + const char *text_class; }; /*----------*/ @@ -249,7 +252,7 @@ struct _Edje_Image_Directory_Entry { char *entry; /* the nominal name of the image - if any */ int source_type; /* alternate source mode. 0 = none */ - int source_param; /* extar params on encoding */ + int source_param; /* extra params on encoding */ int id; /* the id no. of the image */ }; @@ -946,6 +949,9 @@ void _edje_message_queue_process (void); void _edje_message_queue_clear (void); void _edje_message_del (Edje *ed); +void _edje_textblock_styles_add(Edje *ed); +void _edje_textblock_styles_del(Edje *ed); +void _edje_textblock_style_all_update(Edje *ed); void _edje_textblock_style_parse_and_fix(Edje_File *edf); void _edje_textblock_style_cleanup(Edje_File *edf); Edje_File *_edje_cache_file_coll_open(const char *file, const char *coll, int *error_ret, Edje_Part_Collection **edc_ret); diff --git a/legacy/edje/src/lib/edje_text.c b/legacy/edje/src/lib/edje_text.c index c7c957d1d2..38fc266827 100644 --- a/legacy/edje/src/lib/edje_text.c +++ b/legacy/edje/src/lib/edje_text.c @@ -27,13 +27,14 @@ _edje_text_part_on_add(Edje *ed, Edje_Real_Part *ep) if ((pt->default_desc) && (pt->default_desc->text.text_class)) _edje_text_class_member_add(ed, pt->default_desc->text.text_class); - /* If any other classes exit add them */ + /* If any other classes exist add them */ for (tmp = pt->other_desc; tmp; tmp = tmp->next) { Edje_Part_Description *desc; desc = tmp->data; - if ((desc) && (desc->text.text_class)) _edje_text_class_member_add(ed, desc->text.text_class); + if ((desc) && (desc->text.text_class)) + _edje_text_class_member_add(ed, desc->text.text_class); } } diff --git a/legacy/edje/src/lib/edje_textblock_styles.c b/legacy/edje/src/lib/edje_textblock_styles.c index c59777ae62..d2e1bedfd0 100644 --- a/legacy/edje/src/lib/edje_textblock_styles.c +++ b/legacy/edje/src/lib/edje_textblock_styles.c @@ -39,10 +39,14 @@ _edje_str_deescape(char *str) } #endif +/* Put a \ before and Space( ), \ or ' in a string. + * A newly allocated string is returned. + */ static char * -_edje_str_escape(char *str) +_edje_str_escape(const char *str) { - char *s2, *s, *d; + char *s2, *d; + const char *s; s2 = malloc((strlen(str) * 2) + 1); if (!s2) return NULL; @@ -76,11 +80,14 @@ _edje_format_param_parse(char *item, char **key, char **val) } static char * -_edje_format_parse(char **s) +_edje_format_parse(const char **s) { - char *p, *item, *ss, *ds; - char *s1 = NULL, *s2 = NULL; - + char *item, *ds; + const char *p; + const char *ss; + const char *s1 = NULL; + const char *s2 = NULL; + p = *s; if ((!p) || (*p == 0)) return NULL; for (;;) @@ -128,7 +135,7 @@ _edje_format_is_param(char *item) } static char * -_edje_strbuf_append(char *s, char *s2, int *len, int *alloc) +_edje_strbuf_append(char *s, const char *s2, int *len, int *alloc) { int l2; int tlen; @@ -153,11 +160,12 @@ _edje_strbuf_append(char *s, char *s2, int *len, int *alloc) } static char * -_edje_format_reparse(Edje_File *edf, char *str) +_edje_format_reparse(Edje_File *edf, const char *str, Edje_Style_Tag **tag_ret) { - char *s, *s2; + char *s2; char *item; char *newstr = NULL; + const char *s; int newlen = 0, newalloc = 0; s = str; @@ -172,32 +180,38 @@ _edje_format_reparse(Edje_File *edf, char *str) { /* dont allow font sources */ } - else if (!strcmp(key, "font")) + else if (!strcmp(key, "text_class")) + { + if (tag_ret) + (*tag_ret)->text_class = evas_stringshare_add(val); + } + else if (!strcmp(key, "font_size")) { - if (_edje_font_is_embedded(edf, val)) + if (tag_ret) + (*tag_ret)->font_size = atof(val); + } + else if (!strcmp(key, "font")) /* Fix fonts */ + { + if (tag_ret) { - if (newstr) newstr = _edje_strbuf_append(newstr, " ", &newlen, &newalloc); - newstr = _edje_strbuf_append(newstr, key, &newlen, &newalloc); - newstr = _edje_strbuf_append(newstr, "=fonts/", &newlen, &newalloc); - s2 = _edje_str_escape(val); - if (s2) + if (_edje_font_is_embedded(edf, val)) { - newstr = _edje_strbuf_append(newstr, s2, &newlen, &newalloc); - free(s2); + char *tmpstr = NULL; + int tmplen = 0; + int tmpalloc = 0; + + tmpstr = _edje_strbuf_append(tmpstr, "fonts/", &tmplen, &tmpalloc); + tmpstr = _edje_strbuf_append(tmpstr, val, &tmplen, &tmpalloc); + (*tag_ret)->font = evas_stringshare_add(tmpstr); + free(tmpstr); } - } - else - { - s2 = _edje_str_escape(item); - if (s2) - { - if (newstr) newstr = _edje_strbuf_append(newstr, " ", &newlen, &newalloc); - newstr = _edje_strbuf_append(newstr, s2, &newlen, &newalloc); - free(s2); + else + { + (*tag_ret)->font = evas_stringshare_add(val); } } } - else + else /* Otherwise add to tag buffer */ { s2 = _edje_str_escape(item); if (s2) @@ -220,6 +234,170 @@ _edje_format_reparse(Edje_File *edf, char *str) return newstr; } +/* Update all evas_styles which are in an edje + * + * @param ed The edje containing styles which need to be updated + */ +void +_edje_textblock_style_all_update(Edje *ed) +{ + Evas_List *l, *ll; + + if (!ed->file) return; + + for (l = ed->file->styles; l; l = l->next) + { + Edje_Style *stl; + Edje_Style_Tag *tag; + Edje_Text_Class *tc; + char *buf = NULL; + int bufalloc = 0; + int buflen = 0; + int found = 0; + char *fontset = NULL, *fontsource = NULL; + + stl = l->data; + /* Make sure the style is already defined */ + if (!stl->style) break; + + /* Make sure the style contains a text_class */ + for (ll = stl->tags; ll; ll = ll->next) + { + tag = ll->data; + if (tag->text_class) + found = 1; + } + + /* No text classes , goto next style */ + if (!found) continue; + found = 0; + + if (_edje_fontset_append) + fontset = _edje_str_escape(_edje_fontset_append); + fontsource = _edje_str_escape(ed->file->path); + + /* Build the style from each tag */ + for (ll = stl->tags; ll; ll = ll->next) + { + tag = ll->data; + if (!tag->key) continue; + + /* Add Tag Key */ + buf = _edje_strbuf_append(buf, tag->key, &buflen, &bufalloc); + buf = _edje_strbuf_append(buf, "='", &buflen, &bufalloc); + + /* Configure fonts from text class if it exists */ + if ((tc = _edje_text_class_find(ed, tag->text_class))) + { + /* Only update if not clearing, If clear leave it at zero */ + if (tc->font) found = 1; + } + + /* Add and Ha`ndle tag parsed data */ + buf = _edje_strbuf_append(buf, tag->value, &buflen, &bufalloc); + + /* Add font properties */ + if (tag->font) + { + buf = _edje_strbuf_append(buf, " ", &buflen, &bufalloc); + buf = _edje_strbuf_append(buf, "font=", &buflen, &bufalloc); + if (found) + buf = _edje_strbuf_append(buf, tc->font, &buflen, &bufalloc); + else + buf = _edje_strbuf_append(buf, tag->font, &buflen, &bufalloc); + } + if (tag->font_size > 0) + { + char font_size[32]; + + if (found) + snprintf(font_size, sizeof(font_size), "%f", tc->size); + else + snprintf(font_size, sizeof(font_size), "%f", tag->font_size); + + buf = _edje_strbuf_append(buf, " ", &buflen, &bufalloc); + buf = _edje_strbuf_append(buf, "font_size=", &buflen, &bufalloc); + buf = _edje_strbuf_append(buf, font_size, &buflen, &bufalloc); + } + found = 0; + + if (!strcmp(tag->key, "DEFAULT")) + { + if (fontset) + { + buf = _edje_strbuf_append(buf, " ", &buflen, &bufalloc); + buf = _edje_strbuf_append(buf, "font_fallbacks=", &buflen, &bufalloc); + buf = _edje_strbuf_append(buf, fontset, &buflen, &bufalloc); + } + buf = _edje_strbuf_append(buf, " ", &buflen, &bufalloc); + buf = _edje_strbuf_append(buf, "font_source=", &buflen, &bufalloc); + buf = _edje_strbuf_append(buf, fontsource, &buflen, &bufalloc); + } + buf = _edje_strbuf_append(buf, "'", &buflen, &bufalloc); + } + if (fontset) free(fontset); + if (fontsource) free(fontsource); + + /* Configure the style */ + evas_textblock_style_set(stl->style, buf); + free(buf); + } +} + +void +_edje_textblock_styles_add(Edje *ed) +{ + Evas_List *l, *ll; + + if (!ed->file) return; + + for (l = ed->file->styles; l; l = l->next) + { + Edje_Style *stl; + Edje_Style_Tag *tag; + + stl = l->data; + + /* Make sure the style contains the text_class */ + for (ll = stl->tags; ll; ll = ll->next) + { + tag = ll->data; + if (!tag->text_class) continue; + _edje_text_class_member_add(ed, tag->text_class); + } + } +} + +void +_edje_textblock_styles_del(Edje *ed) +{ + Evas_List *l, *ll; + + if (!ed->file) return; + + for (l = ed->file->styles; l; l = l->next) + { + Edje_Style *stl; + Edje_Style_Tag *tag; + + stl = l->data; + + /* Make sure the style contains the text_class */ + for (ll = stl->tags; ll; ll = ll->next) + { + tag = ll->data; + if (!tag->text_class) continue; + _edje_text_class_member_del(ed, tag->text_class); + } + } +} + +/* When we get to here the edje file had been read into memory + * the name of the style is established as well as the name and + * data for the tags. This function will create the Evas_Style + * object for each style. The style is composed of a base style + * followed by a list of tags. + */ void _edje_textblock_style_parse_and_fix(Edje_File *edf) { @@ -230,77 +408,99 @@ _edje_textblock_style_parse_and_fix(Edje_File *edf) Edje_Style *stl; Edje_Style_Tag *tag; char *buf = NULL; - int len = 0; - int def_done; + int bufalloc = 0; + int buflen = 0; + int def_done = 0; char *fontset = NULL, *fontsource = NULL, *ts; + const char *default_font = NULL; + const char *default_text_class = NULL; + double default_font_size = 0.0; stl = l->data; if (stl->style) break; + stl->style = evas_textblock_style_new(); - evas_textblock_style_set(stl->style, (const char *)buf); - def_done = 0; - /* FIXME: i think we have no choice by to parse the style line, - * look for font= tags and IF that font is in the .edj then prepend - * a "fonts/" to it to it's found - */ + evas_textblock_style_set(stl->style, buf); + if (_edje_fontset_append) fontset = _edje_str_escape(_edje_fontset_append); fontsource = _edje_str_escape(edf->path); - + + /* Build the style from each tag */ for (ll = stl->tags; ll; ll = ll->next) { tag = ll->data; if (!tag->key) continue; - len += strlen(tag->key); - len += 1; - len += 1; - ts = _edje_format_reparse(edf, tag->value); + /* Add Tag Key */ + buf = _edje_strbuf_append(buf, tag->key, &buflen, &bufalloc); + buf = _edje_strbuf_append(buf, "='", &buflen, &bufalloc); + + ts = _edje_format_reparse(edf, tag->value, &(tag)); + + /* Handle the returned tag data */ + if ((!def_done) && (!strcmp(tag->key, "DEFAULT"))) + { /* establish base font properties */ + default_font_size = tag->font_size; + default_font = tag->font; + default_text_class = tag->text_class; + } + else + { /* Try to inherit font properties from base style */ + if (tag->font_size == 0.0) + tag->font_size = default_font_size; + if (tag->font == NULL && default_font != NULL) + tag->font = evas_stringshare_add(default_font); + if (tag->text_class == NULL && default_text_class != NULL) + tag->text_class = evas_stringshare_add(default_text_class); + } + + /* Add and Handle tag parsed data */ if (ts) { - len += strlen(ts); - free(ts); - len += 1; - } - } - - if (fontset) - { - len += 1 + strlen("font_fallbacks=") + strlen(fontset); - } - len += 1 + strlen("font_source=") + strlen(edf->path); - buf = malloc(len + 1); - buf[0] = 0; - for (ll = stl->tags; ll; ll = ll->next) - { - tag = ll->data; - if (!tag->key) continue; - strcat(buf, tag->key); - strcat(buf, "='"); - ts = _edje_format_reparse(edf, tag->value); - if (ts) - { - strcat(buf, ts); + evas_stringshare_del(tag->value); + tag->value = evas_stringshare_add(ts); + buf = _edje_strbuf_append(buf, tag->value, &buflen, &bufalloc); free(ts); } + + /* Add font properties */ + if (tag->font) + { + buf = _edje_strbuf_append(buf, " ", &buflen, &bufalloc); + buf = _edje_strbuf_append(buf, "font=", &buflen, &bufalloc); + buf = _edje_strbuf_append(buf, tag->font, &buflen, &bufalloc); + } + if (tag->font_size > 0) + { + char font_size[32]; + + snprintf(font_size, sizeof(font_size), "%f", tag->font_size); + buf = _edje_strbuf_append(buf, " ", &buflen, &bufalloc); + buf = _edje_strbuf_append(buf, "font_size=", &buflen, &bufalloc); + buf = _edje_strbuf_append(buf, font_size, &buflen, &bufalloc); + } + if ((!def_done) && (!strcmp(tag->key, "DEFAULT"))) { if (fontset) { - strcat(buf, " "); - strcat(buf, "font_fallbacks="); - strcat(buf, fontset); + buf = _edje_strbuf_append(buf, " ", &buflen, &bufalloc); + buf = _edje_strbuf_append(buf, "font_fallbacks=", &buflen, &bufalloc); + buf = _edje_strbuf_append(buf, fontset, &buflen, &bufalloc); } - strcat(buf, " "); - strcat(buf, "font_source="); - strcat(buf, fontsource); + buf = _edje_strbuf_append(buf, " ", &buflen, &bufalloc); + buf = _edje_strbuf_append(buf, "font_source=", &buflen, &bufalloc); + buf = _edje_strbuf_append(buf, fontsource, &buflen, &bufalloc); def_done = 1; } - strcat(buf, "'"); + buf = _edje_strbuf_append(buf, "'", &buflen, &bufalloc); } if (fontset) free(fontset); if (fontsource) free(fontsource); - evas_textblock_style_set(stl->style, (const char *)buf); + + /* Configure the style */ + evas_textblock_style_set(stl->style, buf); free(buf); } } @@ -322,6 +522,8 @@ _edje_textblock_style_cleanup(Edje_File *edf) stl->tags = evas_list_remove_list(stl->tags, stl->tags); if (tag->key) evas_stringshare_del(tag->key); if (tag->value) evas_stringshare_del(tag->value); + if (tag->text_class) evas_stringshare_del(tag->text_class); + if (tag->font) evas_stringshare_del(tag->font); free(tag); } if (stl->name) evas_stringshare_del(stl->name); diff --git a/legacy/edje/src/lib/edje_util.c b/legacy/edje/src/lib/edje_util.c index 26294b6fbe..585a9f1eaa 100644 --- a/legacy/edje/src/lib/edje_util.c +++ b/legacy/edje/src/lib/edje_util.c @@ -4,11 +4,11 @@ #include "Edje.h" #include "edje_private.h" -Evas_Hash *_edje_color_class_hash = NULL; -Evas_Hash *_edje_color_class_member_hash = NULL; +static Evas_Hash *_edje_color_class_hash = NULL; +static Evas_Hash *_edje_color_class_member_hash = NULL; -Evas_Hash *_edje_text_class_hash = NULL; -Evas_Hash *_edje_text_class_member_hash = NULL; +static Evas_Hash *_edje_text_class_hash = NULL; +static Evas_Hash *_edje_text_class_member_hash = NULL; char *_edje_fontset_append = NULL; @@ -417,7 +417,8 @@ edje_object_color_class_del(Evas_Object *obj, const char *color_class) * @param font The font name * @param size The font size * - * This sets the Edje text class ?! + * This sets updates all edje members which belong to this text class + * with the new font attributes. */ EAPI void edje_text_class_set(const char *text_class, const char *font, Evas_Font_Size size) @@ -426,7 +427,6 @@ edje_text_class_set(const char *text_class, const char *font, Evas_Font_Size siz Edje_Text_Class *tc; if (!text_class) return; - if (size < 0) size = 0; if (!font) font = ""; @@ -478,6 +478,7 @@ edje_text_class_set(const char *text_class, const char *font, Evas_Font_Size siz ed = members->data; ed->dirty = 1; + _edje_textblock_style_all_update(ed); _edje_recalc(ed); members = members->next; } @@ -500,6 +501,7 @@ edje_object_text_class_set(Evas_Object *obj, const char *text_class, const char ed = _edje_fetch(obj); if ((!ed) || (!text_class)) return; + if (size < 0.0) size = 0.0; /* for each text_class in the edje */ @@ -548,6 +550,7 @@ edje_object_text_class_set(Evas_Object *obj, const char *text_class, const char /* Add to edje's text class list */ ed->text_classes = evas_list_append(ed->text_classes, tc); ed->dirty = 1; + _edje_textblock_style_all_update(ed); _edje_recalc(ed); }