aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/edje/src/lib/edje_textblock_styles.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/edje/src/lib/edje_textblock_styles.c')
-rw-r--r--libraries/edje/src/lib/edje_textblock_styles.c424
1 files changed, 424 insertions, 0 deletions
diff --git a/libraries/edje/src/lib/edje_textblock_styles.c b/libraries/edje/src/lib/edje_textblock_styles.c
new file mode 100644
index 0000000..13a68ad
--- /dev/null
+++ b/libraries/edje/src/lib/edje_textblock_styles.c
@@ -0,0 +1,424 @@
1#include "edje_private.h"
2
3static int
4_edje_font_is_embedded(Edje_File *edf, char *font)
5{
6 if (!eina_hash_find(edf->fonts, font)) return 0;
7 return 1;
8}
9
10static void
11_edje_format_param_parse(char *item, char **key, char **val)
12{
13 char *p, *k, *v;
14
15 p = strchr(item, '=');
16 k = malloc(p - item + 1);
17 strncpy(k, item, p - item);
18 k[p - item] = 0;
19 *key = k;
20 p++;
21 v = strdup(p);
22 *val = v;
23}
24
25static char *
26_edje_format_parse(const char **s)
27{
28 char *item, *ds;
29 const char *p, *ss;
30 const char *s1 = NULL;
31 const char *s2 = NULL;
32
33 p = *s;
34 if ((!p) || (*p == 0)) return NULL;
35 for (;;)
36 {
37 if (!s1)
38 {
39 if (*p != ' ') s1 = p;
40 if (*p == 0) break;
41 }
42 else if (!s2)
43 {
44 if ((p > *s) && (p[-1] != '\\'))
45 {
46 if (*p == ' ') s2 = p;
47 }
48 if (*p == 0) s2 = p;
49 }
50 p++;
51 if (s1 && s2)
52 {
53 item = malloc(s2 - s1 + 1);
54 if (item)
55 {
56 for (ds = item, ss = s1; ss < s2; ss++, ds++)
57 {
58 if ((*ss == '\\') && (ss < (s2 - 1))) ss++;
59 *ds = *ss;
60 }
61 *ds = 0;
62 }
63 *s = s2;
64 return item;
65 }
66 }
67 *s = p;
68 return NULL;
69}
70
71static int
72_edje_format_is_param(char *item)
73{
74 if (strchr(item, '=')) return 1;
75 return 0;
76}
77
78static char *
79_edje_format_reparse(Edje_File *edf, const char *str, Edje_Style_Tag **tag_ret)
80{
81 Eina_Strbuf *txt, *tmp = NULL;
82 char *s2, *item, *ret;
83 const char *s;
84
85 txt = eina_strbuf_new();
86 s = str;
87 while ((item = _edje_format_parse(&s)))
88 {
89 if (_edje_format_is_param(item))
90 {
91 char *key = NULL, *val = NULL;
92
93 _edje_format_param_parse(item, &key, &val);
94 if (!strcmp(key, "font_source"))
95 {
96 /* dont allow font sources */
97 }
98 else if (!strcmp(key, "text_class"))
99 {
100 if (tag_ret)
101 (*tag_ret)->text_class = eina_stringshare_add(val);
102 }
103 else if (!strcmp(key, "font_size"))
104 {
105 if (tag_ret)
106 (*tag_ret)->font_size = atof(val);
107 }
108 else if (!strcmp(key, "font")) /* Fix fonts */
109 {
110 if (tag_ret)
111 {
112 if (_edje_font_is_embedded(edf, val))
113 {
114 if (!tmp)
115 tmp = eina_strbuf_new();
116 eina_strbuf_append(tmp, "edje/fonts/");
117 eina_strbuf_append(tmp, val);
118 (*tag_ret)->font = eina_stringshare_add(eina_strbuf_string_get(tmp));
119 eina_strbuf_reset(tmp);
120 }
121 else
122 {
123 (*tag_ret)->font = eina_stringshare_add(val);
124 }
125 }
126 }
127 else /* Otherwise add to tag buffer */
128 {
129 s2 = eina_str_escape(item);
130 if (s2)
131 {
132 if (eina_strbuf_length_get(txt)) eina_strbuf_append(txt, " ");
133 eina_strbuf_append(txt, s2);
134 free(s2);
135 }
136 }
137 free(key);
138 free(val);
139 }
140 else
141 {
142 if (eina_strbuf_length_get(txt)) eina_strbuf_append(txt, " ");
143 eina_strbuf_append(txt, item);
144 }
145 free(item);
146 }
147 if (tmp)
148 eina_strbuf_free(tmp);
149 ret = eina_strbuf_string_steal(txt);
150 eina_strbuf_free(txt);
151 return ret;
152}
153
154/* Update all evas_styles which are in an edje
155 *
156 * @param ed The edje containing styles which need to be updated
157 */
158void
159_edje_textblock_style_all_update(Edje *ed)
160{
161 Eina_List *l, *ll;
162 Edje_Style *stl;
163 Eina_Strbuf *txt = NULL;
164
165 if (!ed->file) return;
166
167 EINA_LIST_FOREACH(ed->file->styles, l, stl)
168 {
169 Edje_Style_Tag *tag;
170 Edje_Text_Class *tc;
171 int found = 0;
172 char *fontset = NULL, *fontsource = NULL;
173
174 /* Make sure the style is already defined */
175 if (!stl->style) break;
176
177 /* Make sure the style contains a text_class */
178 EINA_LIST_FOREACH(stl->tags, ll, tag)
179 if (tag->text_class) found = 1;
180
181 /* No text classes , goto next style */
182 if (!found) continue;
183 found = 0;
184 if (!txt)
185 txt = eina_strbuf_new();
186
187 if (_edje_fontset_append)
188 fontset = eina_str_escape(_edje_fontset_append);
189 fontsource = eina_str_escape(ed->file->path);
190
191 /* Build the style from each tag */
192 EINA_LIST_FOREACH(stl->tags, ll, tag)
193 {
194 if (!tag->key) continue;
195
196 /* Add Tag Key */
197 eina_strbuf_append(txt, tag->key);
198 eina_strbuf_append(txt, "='");
199
200 /* Configure fonts from text class if it exists */
201 if ((tc = _edje_text_class_find(ed, tag->text_class)))
202 {
203 /* Only update if not clearing, If clear leave it at zero */
204 if (tc->font) found = 1;
205 }
206
207 /* Add and Ha`ndle tag parsed data */
208 eina_strbuf_append(txt, tag->value);
209
210 if (!strcmp(tag->key, "DEFAULT"))
211 {
212 if (fontset)
213 {
214 eina_strbuf_append(txt, " ");
215 eina_strbuf_append(txt, "font_fallbacks=");
216 eina_strbuf_append(txt, fontset);
217 }
218 eina_strbuf_append(txt, " ");
219 eina_strbuf_append(txt, "font_source=");
220 eina_strbuf_append(txt, fontsource);
221 }
222 if (tag->font_size != 0)
223 {
224 char font_size[32];
225
226 if (found)
227 snprintf(font_size, sizeof(font_size), "%f", (double) _edje_text_size_calc(tag->font_size, tc));
228 else
229 snprintf(font_size, sizeof(font_size), "%f", tag->font_size);
230
231 eina_strbuf_append(txt, " ");
232 eina_strbuf_append(txt, "font_size=");
233 eina_strbuf_append(txt, font_size);
234 }
235 /* Add font name last to save evas from multiple loads */
236 if (tag->font)
237 {
238 const char *f;
239
240 eina_strbuf_append(txt, " ");
241 eina_strbuf_append(txt, "font=");
242
243 f = (found) ? tc->font : tag->font;
244 eina_strbuf_append_escaped(txt, f);
245 }
246 found = 0;
247
248 eina_strbuf_append(txt, "'");
249 }
250 if (fontset) free(fontset);
251 if (fontsource) free(fontsource);
252
253 /* Configure the style */
254 evas_textblock_style_set(stl->style, eina_strbuf_string_get(txt));
255 eina_strbuf_reset(txt);
256 }
257 if (txt)
258 eina_strbuf_free(txt);
259}
260
261void
262_edje_textblock_styles_add(Edje *ed)
263{
264 Eina_List *l, *ll;
265 Edje_Style *stl;
266
267 if (!ed->file) return;
268
269 EINA_LIST_FOREACH(ed->file->styles, l, stl)
270 {
271 Edje_Style_Tag *tag;
272
273 /* Make sure the style contains the text_class */
274 EINA_LIST_FOREACH(stl->tags, ll, tag)
275 {
276 if (!tag->text_class) continue;
277 _edje_text_class_member_add(ed, tag->text_class);
278 }
279 }
280}
281
282void
283_edje_textblock_styles_del(Edje *ed)
284{
285 Eina_List *l, *ll;
286 Edje_Style *stl;
287
288 if (!ed->file) return;
289
290 EINA_LIST_FOREACH(ed->file->styles, l, stl)
291 {
292 Edje_Style_Tag *tag;
293
294 /* Make sure the style contains the text_class */
295 EINA_LIST_FOREACH(stl->tags, ll, tag)
296 {
297 if (!tag->text_class) continue;
298 _edje_text_class_member_del(ed, tag->text_class);
299 }
300 }
301}
302
303/* When we get to here the edje file had been read into memory
304 * the name of the style is established as well as the name and
305 * data for the tags. This function will create the Evas_Style
306 * object for each style. The style is composed of a base style
307 * followed by a list of tags.
308 */
309void
310_edje_textblock_style_parse_and_fix(Edje_File *edf)
311{
312 Eina_Strbuf *txt = NULL;
313 Eina_List *l, *ll;
314 Edje_Style *stl;
315
316 EINA_LIST_FOREACH(edf->styles, l, stl)
317 {
318 Edje_Style_Tag *tag;
319 char *fontset = NULL, *fontsource = NULL, *ts;
320
321 if (stl->style) break;
322
323 if (!txt)
324 txt = eina_strbuf_new();
325
326 stl->style = evas_textblock_style_new();
327 evas_textblock_style_set(stl->style, NULL);
328
329 if (_edje_fontset_append)
330 fontset = eina_str_escape(_edje_fontset_append);
331 fontsource = eina_str_escape(edf->path);
332
333 /* Build the style from each tag */
334 EINA_LIST_FOREACH(stl->tags, ll, tag)
335 {
336 if (!tag->key) continue;
337
338 /* Add Tag Key */
339 eina_strbuf_append(txt, tag->key);
340 eina_strbuf_append(txt, "='");
341
342 ts = _edje_format_reparse(edf, tag->value, &(tag));
343
344 /* Add and Handle tag parsed data */
345 if (ts)
346 {
347 if (eet_dictionary_string_check(eet_dictionary_get(edf->ef), tag->value) == 0)
348 eina_stringshare_del(tag->value);
349 tag->value = eina_stringshare_add(ts);
350 eina_strbuf_append(txt, tag->value);
351 free(ts);
352 }
353
354 if (!strcmp(tag->key, "DEFAULT"))
355 {
356 if (fontset)
357 {
358 eina_strbuf_append(txt, " ");
359 eina_strbuf_append(txt, "font_fallbacks=");
360 eina_strbuf_append(txt, fontset);
361 }
362 eina_strbuf_append(txt, " ");
363 eina_strbuf_append(txt, "font_source=");
364 eina_strbuf_append(txt, fontsource);
365 }
366 if (tag->font_size > 0)
367 {
368 char font_size[32];
369
370 snprintf(font_size, sizeof(font_size), "%f", tag->font_size);
371 eina_strbuf_append(txt, " ");
372 eina_strbuf_append(txt, "font_size=");
373 eina_strbuf_append(txt, font_size);
374 }
375 /* Add font name last to save evas from multiple loads */
376 if (tag->font)
377 {
378 eina_strbuf_append(txt, " ");
379 eina_strbuf_append(txt, "font=");
380 eina_strbuf_append_escaped(txt, tag->font);
381 }
382 eina_strbuf_append(txt, "'");
383 }
384 if (fontset) free(fontset);
385 if (fontsource) free(fontsource);
386
387 /* Configure the style */
388 evas_textblock_style_set(stl->style, eina_strbuf_string_get(txt));
389 eina_strbuf_reset(txt);
390 }
391 if (txt)
392 eina_strbuf_free(txt);
393}
394
395void
396_edje_textblock_style_cleanup(Edje_File *edf)
397{
398 while (edf->styles)
399 {
400 Edje_Style *stl;
401
402 stl = edf->styles->data;
403 edf->styles = eina_list_remove_list(edf->styles, edf->styles);
404 while (stl->tags)
405 {
406 Edje_Style_Tag *tag;
407
408 tag = stl->tags->data;
409 stl->tags = eina_list_remove_list(stl->tags, stl->tags);
410 if (edf->free_strings)
411 {
412 if (tag->key) eina_stringshare_del(tag->key);
413/* FIXME: Find a proper way to handle it. */
414 if (tag->value) eina_stringshare_del(tag->value);
415 if (tag->text_class) eina_stringshare_del(tag->text_class);
416 if (tag->font) eina_stringshare_del(tag->font);
417 }
418 free(tag);
419 }
420 if (edf->free_strings && stl->name) eina_stringshare_del(stl->name);
421 if (stl->style) evas_textblock_style_free(stl->style);
422 free(stl);
423 }
424}