1
#include "edje_private.h"
4
void _edje_textblock_style_update(Edje *ed, Edje_Style *stl);
7
_edje_textblock_style_copy(Edje_Style *stl)
11
new_stl = calloc(1, sizeof(Edje_Style));
12
if (!new_stl) return NULL;
14
new_stl->style = evas_textblock_style_new();
15
evas_textblock_style_set(new_stl->style, NULL);
18
new_stl->tags = stl->tags;
19
new_stl->name = stl->name;
20
new_stl->cache = EINA_FALSE;
26
_edje_object_textblock_styles_cache_style_free(void *data)
28
Edje_Style *obj_stl = data;
32
if (obj_stl->style) evas_textblock_style_free(obj_stl->style);
37
_edje_object_textblock_styles_cache_add(Edje *ed, Edje_Style *stl)
39
Edje_Style *obj_stl = eina_hash_find(ed->styles, stl->name);
44
obj_stl = _edje_textblock_style_copy(stl);
48
if (!ed->styles) ed->styles = eina_hash_stringshared_new(_edje_object_textblock_styles_cache_style_free);
49
eina_hash_direct_add(ed->styles, obj_stl->name, obj_stl);
50
_edje_textblock_style_update(ed, obj_stl);
57
_edje_object_textblock_styles_cache_cleanup(Edje *ed)
59
if (!ed || !ed->styles) return;
60
eina_hash_free(ed->styles);
65
_edje_object_textblock_styles_cache_get(Edje *ed, const char *stl)
68
return eina_hash_find(ed->styles, stl);
72
_edje_font_is_embedded(Edje_File *edf, const char *font)
74
if (!eina_hash_find(edf->fonts, font)) return 0;
79
_edje_format_parse(const char **s)
82
const char *s1 = NULL;
83
const char *s2 = NULL;
84
Eina_Bool quote = EINA_FALSE;
87
if ((!p) || (*p == 0)) return NULL;
92
if (*p != ' ') s1 = p;
102
if ((p > *s) && (p[-1] != '\\') && (!quote))
104
if (*p == ' ') s2 = p;
109
if (s1 && s2 && (s2 > s1))
111
size_t len = s2 - s1;
112
char *ret = malloc(len + 1);
113
memcpy(ret, s1, len);
123
#define _IS_STRINGS_EQUAL(str1, len1, str2, len2) (((len1)==(len2)) && !strncmp(str1, str2, len1))
126
_edje_format_reparse(Edje_File *edf, const char *str, Edje_Style_Tag *tag_ret, Eina_Strbuf *result)
132
while ((item = _edje_format_parse(&s)))
134
const char *pos = strchr(item, '=');
137
size_t key_len = pos - item;
138
const char *key = item;
139
const char *val = pos + 1;
141
if (_IS_STRINGS_EQUAL(key, key_len, "font_source", 11))
145
else if (_IS_STRINGS_EQUAL(key, key_len, "text_class", 10))
148
eina_stringshare_replace(&(tag_ret->text_class), val);
156
else if (_IS_STRINGS_EQUAL(key, key_len, "color_class", 11))
159
eina_stringshare_replace(&(tag_ret->color_class), val);
167
else if (_IS_STRINGS_EQUAL(key, key_len, "font_size", 9))
170
tag_ret->font_size = atof(val);
172
else if (_IS_STRINGS_EQUAL(key, key_len, "font", 4))
176
if (_edje_font_is_embedded(edf, val))
179
snprintf(buffer, sizeof(buffer), "edje/fonts/%s", val);
180
eina_stringshare_replace(&tag_ret->font, buffer);
181
if (eina_strbuf_length_get(result)) eina_strbuf_append(result, " ");
182
eina_strbuf_append(result, "font=");
183
eina_strbuf_append(result, buffer);
188
tag_ret->font = eina_stringshare_add(val);
193
else if ((_IS_STRINGS_EQUAL(key, key_len, "color", 5)) ||
194
(_IS_STRINGS_EQUAL(key, key_len, "outline_color", 13)) ||
195
(_IS_STRINGS_EQUAL(key, key_len, "shadow_color", 12)) ||
196
(_IS_STRINGS_EQUAL(key, key_len, "underline_color", 15)) ||
197
(_IS_STRINGS_EQUAL(key, key_len, "underline2_color", 16)) ||
198
(_IS_STRINGS_EQUAL(key, key_len, "secondary_underline_color", 25)) ||
199
(_IS_STRINGS_EQUAL(key, key_len, "underline_dash_color", 20)) ||
200
(_IS_STRINGS_EQUAL(key, key_len, "underline_dashed_color", 22)) ||
201
(_IS_STRINGS_EQUAL(key, key_len, "glow_color", 10)) ||
202
(_IS_STRINGS_EQUAL(key, key_len, "glow2_color", 11)) ||
203
(_IS_STRINGS_EQUAL(key, key_len, "secondary_glow_color", 20)) ||
204
(_IS_STRINGS_EQUAL(key, key_len, "backing_color", 13)) ||
205
(_IS_STRINGS_EQUAL(key, key_len, "background_color", 16)) ||
206
(_IS_STRINGS_EQUAL(key, key_len, "strikethrough_color", 19)))
208
if (!strncmp(val, "cc:", 3))
210
if ((_IS_STRINGS_EQUAL(key, key_len, "color", 5)))
211
eina_stringshare_replace(&(tag_ret->color_class), val + 3);
212
else if ((_IS_STRINGS_EQUAL(key, key_len, "outline_color", 13)))
213
eina_stringshare_replace(&(tag_ret->outline_color_class), val + 3);
214
else if ((_IS_STRINGS_EQUAL(key, key_len, "shadow_color", 12)))
215
eina_stringshare_replace(&(tag_ret->shadow_color_class), val + 3);
216
else if ((_IS_STRINGS_EQUAL(key, key_len, "underline_color", 15)))
217
eina_stringshare_replace(&(tag_ret->underline_color_class), val + 3);
218
else if ((_IS_STRINGS_EQUAL(key, key_len, "underline2_color", 16)) ||
219
(_IS_STRINGS_EQUAL(key, key_len, "secondary_underline_color", 25)))
220
eina_stringshare_replace(&(tag_ret->underline2_color_class), val + 3);
221
else if ((_IS_STRINGS_EQUAL(key, key_len, "underline_dash_color", 20)) ||
222
(_IS_STRINGS_EQUAL(key, key_len, "underline_dashed_color", 22)))
223
eina_stringshare_replace(&(tag_ret->underline_dash_color_class), val + 3);
224
else if ((_IS_STRINGS_EQUAL(key, key_len, "glow_color", 10)))
225
eina_stringshare_replace(&(tag_ret->glow_color_class), val + 3);
226
else if ((_IS_STRINGS_EQUAL(key, key_len, "glow2_color", 11)) ||
227
(_IS_STRINGS_EQUAL(key, key_len, "secondary_glow_color", 20)))
228
eina_stringshare_replace(&(tag_ret->glow2_color_class), val + 3);
229
else if ((_IS_STRINGS_EQUAL(key, key_len, "backing_color", 13)) ||
230
(_IS_STRINGS_EQUAL(key, key_len, "background_color", 16)))
231
eina_stringshare_replace(&(tag_ret->backing_color_class), val + 3);
232
else if ((_IS_STRINGS_EQUAL(key, key_len, "strikethrough_color", 19)))
233
eina_stringshare_replace(&(tag_ret->strikethrough_color_class), val + 3);
249
s2 = eina_str_escape(item);
252
if (eina_strbuf_length_get(result)) eina_strbuf_append(result, " ");
253
eina_strbuf_append(result, s2);
259
if (eina_strbuf_length_get(result)) eina_strbuf_append(result, " ");
260
eina_strbuf_append(result, item);
267
_edje_textblock_tag_update(Eina_Strbuf *style, const char *key, const char *new_tag)
269
char *ptr = strstr(eina_strbuf_string_get(style), key);
275
ptr = strstr(ptr + 1, key);
280
char *tok = strdup(last);
282
while (*tok && !isspace(*tok))
290
eina_strbuf_replace_last(style, tok, new_tag);
295
eina_strbuf_append(style, " ");
296
eina_strbuf_append(style, new_tag);
301
_edje_textblock_font_tag_update(Eina_Strbuf *style, const char *new_value)
303
const char *font_key = "font=";
304
char new_font[256] = {0,};
305
snprintf(new_font, sizeof(new_font), "%s%s", font_key, new_value);
306
_edje_textblock_tag_update(style, font_key, new_font);
310
_edje_textblock_font_size_tag_update(Eina_Strbuf *style, double new_value)
312
const char *font_size_key = "font_size=";
313
char new_font_size[32] = {0,};
314
snprintf(new_font_size, sizeof(new_font_size), "%s%.1f", font_size_key, new_value);
315
_edje_textblock_tag_update(style, font_size_key, new_font_size);
326
_edje_textblock_style_update(Edje *ed, Edje_Style *stl)
329
Eina_Strbuf *txt = NULL;
332
Edje_Color_Class *cc;
333
char *fontset = _edje_fontset_append_escaped, *fontsource = NULL;
335
if (!ed->file) return;
338
if (!stl->style) return;
343
WRN("style_update() shouldn't be called for readonly style. performance regression : %s", stl->name);
350
WRN("style_update() shouldn't be called for cached style. performance regression : %s", stl->name);
355
txt = eina_strbuf_new();
358
fontsource = eina_str_escape(ed->file->path);
361
EINA_LIST_FOREACH(stl->tags, l, tag)
363
if (!tag->key) continue;
366
eina_strbuf_append(txt, tag->key);
367
eina_strbuf_append(txt, "='");
370
if (tag->text_class) tc = _edje_text_class_find(ed, tag->text_class);
374
eina_strbuf_append(txt, tag->value);
376
if (!strcmp(tag->key, "DEFAULT"))
380
eina_strbuf_append(txt, " font_fallbacks=");
381
eina_strbuf_append(txt, fontset);
385
eina_strbuf_append(txt, " font_source=");
386
eina_strbuf_append(txt, fontsource);
391
double new_size = _edje_text_size_calc(tag->font_size, tc);
392
if (!EINA_DBL_EQ(tag->font_size, new_size))
394
_edje_textblock_font_size_tag_update(txt, new_size);
403
f = _edje_text_font_get(tag->font, tc->font, &sfont);
404
_edje_textblock_font_tag_update(txt, f);
406
if (sfont) free(sfont);
408
if (tag->color_class)
410
if ((cc = _edje_color_class_recursive_find(ed, tag->color_class)))
411
eina_strbuf_append_printf(txt, " color=#%02x%02x%02x%02x", cc->r, cc->g, cc->b, cc->a);
413
if (tag->outline_color_class)
415
if ((cc = _edje_color_class_recursive_find(ed, tag->outline_color_class)))
416
eina_strbuf_append_printf(txt, " outline_color=#%02x%02x%02x%02x", cc->r, cc->g, cc->b, cc->a);
418
if (tag->shadow_color_class)
420
if ((cc = _edje_color_class_recursive_find(ed, tag->shadow_color_class)))
421
eina_strbuf_append_printf(txt, " shadow_color=#%02x%02x%02x%02x", cc->r, cc->g, cc->b, cc->a);
423
if (tag->underline_color_class)
425
if ((cc = _edje_color_class_recursive_find(ed, tag->underline_color_class)))
426
eina_strbuf_append_printf(txt, " underline_color=#%02x%02x%02x%02x", cc->r, cc->g, cc->b, cc->a);
428
if (tag->underline2_color_class)
430
if ((cc = _edje_color_class_recursive_find(ed, tag->underline2_color_class)))
431
eina_strbuf_append_printf(txt, " underline2_color=#%02x%02x%02x%02x", cc->r, cc->g, cc->b, cc->a);
433
if (tag->underline_dash_color_class)
435
if ((cc = _edje_color_class_recursive_find(ed, tag->underline_dash_color_class)))
436
eina_strbuf_append_printf(txt, " underline_dash_color=#%02x%02x%02x%02x", cc->r, cc->g, cc->b, cc->a);
438
if (tag->glow_color_class)
440
if ((cc = _edje_color_class_recursive_find(ed, tag->glow_color_class)))
441
eina_strbuf_append_printf(txt, " glow_color=#%02x%02x%02x%02x", cc->r, cc->g, cc->b, cc->a);
443
if (tag->glow2_color_class)
445
if ((cc = _edje_color_class_recursive_find(ed, tag->glow2_color_class)))
446
eina_strbuf_append_printf(txt, " glow2_color=#%02x%02x%02x%02x", cc->r, cc->g, cc->b, cc->a);
448
if (tag->backing_color_class)
450
if ((cc = _edje_color_class_recursive_find(ed, tag->backing_color_class)))
451
eina_strbuf_append_printf(txt, " backing_color=#%02x%02x%02x%02x", cc->r, cc->g, cc->b, cc->a);
453
if (tag->strikethrough_color_class)
455
if ((cc = _edje_color_class_recursive_find(ed, tag->strikethrough_color_class)))
456
eina_strbuf_append_printf(txt, " strikethrough_color=#%02x%02x%02x%02x", cc->r, cc->g, cc->b, cc->a);
459
eina_strbuf_append(txt, "'");
461
if (fontsource) free(fontsource);
464
stl->cache = EINA_TRUE;
465
evas_textblock_style_set(stl->style, eina_strbuf_string_get(txt));
466
if (txt) eina_strbuf_free(txt);
469
static inline Edje_Style *
470
_edje_textblock_style_search(Edje *ed, const char *style)
472
if (!style) return NULL;
474
return eina_hash_find(ed->file->style_hash, style);
478
_edje_textblock_style_observer_add(Edje_Style *stl, Efl_Observer* observer)
483
EINA_LIST_FOREACH(stl->tags, l, tag)
486
efl_observable_observer_add(_edje_text_class_member, tag->text_class, observer);
491
_edje_textblock_style_observer_del(Edje_Style *stl, Efl_Observer* observer)
496
EINA_LIST_FOREACH(stl->tags, l, tag)
499
efl_observable_observer_del(_edje_text_class_member, tag->text_class, observer);
504
_edje_textblock_style_add(Edje *ed, Edje_Style *stl)
508
if (stl->readonly) return;
510
_edje_textblock_style_observer_add(stl, ed->obj);
513
stl->cache = EINA_FALSE;
517
_edje_textblock_style_del(Edje *ed, Edje_Style *stl)
521
_edje_textblock_style_observer_del(stl, ed->obj);
525
_edje_textblock_styles_add(Edje *ed, Edje_Real_Part *ep)
527
Edje_Part *pt = ep->part;
528
Edje_Part_Description_Text *desc;
529
Edje_Style *stl = NULL;
533
if (pt->type != EDJE_PART_TYPE_TEXTBLOCK) return;
537
desc = (Edje_Part_Description_Text *)pt->default_desc;
538
style = edje_string_get(&desc->text.style);
539
stl = _edje_textblock_style_search(ed, style);
541
_edje_textblock_style_add(ed, stl);
544
for (i = 0; i < pt->other.desc_count; ++i)
546
desc = (Edje_Part_Description_Text *)pt->other.desc[i];
547
style = edje_string_get(&desc->text.style);
548
stl = _edje_textblock_style_search(ed, style);
550
_edje_textblock_style_add(ed, stl);
555
_edje_textblock_styles_del(Edje *ed, Edje_Part *pt)
557
Edje_Part_Description_Text *desc;
558
Edje_Style *stl = NULL;
562
if (pt->type != EDJE_PART_TYPE_TEXTBLOCK) return;
564
desc = (Edje_Part_Description_Text *)pt->default_desc;
565
style = edje_string_get(&desc->text.style);
567
stl = _edje_textblock_style_search(ed, style);
569
_edje_textblock_style_del(ed, stl);
571
for (i = 0; i < pt->other.desc_count; ++i)
573
desc = (Edje_Part_Description_Text *)pt->other.desc[i];
574
style = edje_string_get(&desc->text.style);
575
stl = _edje_textblock_style_search(ed, style);
577
_edje_textblock_style_del(ed, stl);
587
Evas_Textblock_Style *
588
_edje_textblock_style_get(Edje *ed, const char *style)
592
if (!style) return NULL;
595
stl = _edje_object_textblock_styles_cache_get(ed, style);
600
stl = _edje_textblock_style_search(ed, style);
603
if (!stl) return NULL;
606
if (stl->readonly) return stl->style;
610
_edje_textblock_style_update(ed, stl);
616
_edje_textblock_style_all_update_text_class(Edje *ed, const char *text_class, Eina_Bool is_object_level)
624
if (!ed->file) return;
625
if (!text_class) return;
630
EINA_LIST_FOREACH(edf->styles, l, stl)
634
if (stl->readonly) continue;
636
EINA_LIST_FOREACH(stl->tags, ll, tag)
638
if (!tag->text_class) continue;
640
if (!strcmp(tag->text_class, text_class))
644
obj_stl = _edje_object_textblock_styles_cache_get(ed, stl->name);
647
obj_stl->cache = EINA_FALSE;
650
_edje_object_textblock_styles_cache_add(ed, stl);
656
stl->cache = EINA_FALSE;
670
_edje_object_textblock_style_all_update_text_class(Edje *ed, const char *text_class)
672
_edje_textblock_style_all_update_text_class(ed, text_class, EINA_TRUE);
680
_edje_file_textblock_styles_all_update_text_class(Edje *ed, const char *text_class)
682
_edje_textblock_style_all_update_text_class(ed, text_class, EINA_FALSE);
692
_edje_file_textblock_style_parse_and_fix(Edje_File *edf)
696
char *fontset = _edje_fontset_append_escaped;
697
Eina_Strbuf *reparseBuffer = eina_strbuf_new();
698
Eina_Strbuf *styleBuffer = eina_strbuf_new();
699
char *fontsource = edf->fonts ? eina_str_escape(edf->path) : NULL;
701
EINA_LIST_FOREACH(edf->styles, l, stl)
705
if (stl->style) break;
707
stl->readonly = EINA_TRUE;
709
stl->style = evas_textblock_style_new();
710
evas_textblock_style_set(stl->style, NULL);
712
eina_strbuf_reset(styleBuffer);
714
EINA_LIST_FOREACH(stl->tags, ll, tag)
716
if (!tag->key) continue;
718
eina_strbuf_reset(reparseBuffer);
721
eina_strbuf_append(styleBuffer, tag->key);
722
eina_strbuf_append(styleBuffer, "='");
724
_edje_format_reparse(edf, tag->value, tag, reparseBuffer);
727
if (eina_strbuf_length_get(reparseBuffer))
729
if (edf->allocated_strings &&
730
eet_dictionary_string_check(eet_dictionary_get(edf->ef), tag->value) == 0)
731
eina_stringshare_del(tag->value);
732
tag->value = eina_stringshare_add(eina_strbuf_string_get(reparseBuffer));
733
eina_strbuf_append(styleBuffer, tag->value);
736
if (!strcmp(tag->key, "DEFAULT"))
740
eina_strbuf_append(styleBuffer, " font_fallbacks=");
741
eina_strbuf_append(styleBuffer, fontset);
745
eina_strbuf_append(styleBuffer, " font_source=");
746
eina_strbuf_append(styleBuffer, fontsource);
749
eina_strbuf_append(styleBuffer, "'");
751
if (tag->text_class) stl->readonly = EINA_FALSE;
752
else if (tag->color_class) stl->readonly = EINA_FALSE;
753
else if (tag->outline_color_class) stl->readonly = EINA_FALSE;
754
else if (tag->shadow_color_class) stl->readonly = EINA_FALSE;
755
else if (tag->underline_color_class) stl->readonly = EINA_FALSE;
756
else if (tag->underline2_color_class) stl->readonly = EINA_FALSE;
757
else if (tag->underline_dash_color_class) stl->readonly = EINA_FALSE;
758
else if (tag->glow_color_class) stl->readonly = EINA_FALSE;
759
else if (tag->glow2_color_class) stl->readonly = EINA_FALSE;
760
else if (tag->backing_color_class) stl->readonly = EINA_FALSE;
761
else if (tag->strikethrough_color_class) stl->readonly = EINA_FALSE;
765
evas_textblock_style_set(stl->style, eina_strbuf_string_get(styleBuffer));
768
if (fontsource) free(fontsource);
769
eina_strbuf_free(styleBuffer);
770
eina_strbuf_free(reparseBuffer);
774
_edje_file_textblock_style_cleanup(Edje_File *edf)
778
EINA_LIST_FREE(edf->styles, stl)
782
EINA_LIST_FREE(stl->tags, tag)
784
if (edf->allocated_strings &&
786
eet_dictionary_string_check(eet_dictionary_get(edf->ef), tag->value) == 0)
787
eina_stringshare_del(tag->value);
788
if (edf->free_strings)
790
#define STRSHRDEL(_x) if (tag->_x) eina_stringshare_del(tag->_x)
793
STRSHRDEL(text_class);
794
STRSHRDEL(color_class);
795
STRSHRDEL(outline_color_class);
796
STRSHRDEL(shadow_color_class);
797
STRSHRDEL(underline_color_class);
798
STRSHRDEL(underline2_color_class);
799
STRSHRDEL(underline_dash_color_class);
800
STRSHRDEL(glow_color_class);
801
STRSHRDEL(glow2_color_class);
802
STRSHRDEL(backing_color_class);
803
STRSHRDEL(strikethrough_color_class);
808
if (edf->free_strings && stl->name) eina_stringshare_del(stl->name);
809
if (stl->style) evas_textblock_style_free(stl->style);