Imported Upstream version 1.7.1
[platform/upstream/edje.git] / src / bin / edje_convert.c
1 #include "edje_private.h"
2
3 #include "edje_cc.h"
4 #include "edje_convert.h"
5
6 static const Edje_File *_current_edje_file = NULL;
7
8 const Edje_File *
9 _edje_file_get(void)
10 {
11    return _current_edje_file;
12 }
13
14 void
15 _edje_file_set(const Edje_File *edf)
16 {
17    _current_edje_file = edf;
18 }
19
20 static Eina_Bool
21 _edje_file_convert_external(Edje_File *edf, Old_Edje_File *oedf)
22 {
23    Edje_External_Directory_Entry *ede;
24    unsigned int max;
25    unsigned int i = 0;
26
27    edf->external_dir = calloc(1, sizeof (Edje_External_Directory));
28    if (!edf->external_dir) return EINA_FALSE;
29    if (!oedf->external_dir) return EINA_TRUE;
30
31    max = eina_list_count(oedf->external_dir->entries);
32    edf->external_dir->entries = calloc(1, sizeof (Edje_External_Directory_Entry) * max);
33    edf->external_dir->entries_count = max;
34
35    if (!edf->external_dir->entries && max)
36      return EINA_FALSE;
37
38    EINA_LIST_FREE(oedf->external_dir->entries, ede)
39      {
40         edf->external_dir->entries[i++].entry = ede->entry;
41         free(ede);
42      }
43
44    free(oedf->external_dir);
45    oedf->external_dir = NULL;
46
47    return EINA_TRUE;
48 }
49
50 static Eina_Bool
51 _edje_file_convert_images(Edje_File *edf, Old_Edje_File *oedf)
52 {
53    Edje_Image_Directory_Entry *de;
54    Edje_Image_Directory_Set *ds;
55    Eina_List *l;
56    int max;
57
58    edf->image_dir = calloc(1, sizeof (Edje_Image_Directory));
59    if (!edf->image_dir) return EINA_FALSE;
60    if (!oedf->image_dir) return EINA_TRUE;
61
62    max = -1;
63    EINA_LIST_FOREACH(oedf->image_dir->entries, l, de)
64      if (max < de->id)
65        max = de->id;
66
67    edf->image_dir->entries = calloc(1, sizeof (Edje_Image_Directory_Entry) * (max + 1));
68    edf->image_dir->entries_count = max + 1;
69
70    if (!edf->image_dir->entries && edf->image_dir->entries_count)
71      return EINA_FALSE;
72
73    EINA_LIST_FREE(oedf->image_dir->entries, de)
74      {
75         memcpy(edf->image_dir->entries + de->id,
76                de,
77                sizeof (Edje_Image_Directory_Entry));
78         free(de);
79      }
80
81    max = -1;
82    EINA_LIST_FOREACH(oedf->image_dir->sets, l, ds)
83      if (max < ds->id)
84        max = ds->id;
85
86    edf->image_dir->sets = calloc(1, sizeof (Edje_Image_Directory_Set) * (max + 1));
87    edf->image_dir->sets_count = max + 1;
88
89    if (!edf->image_dir->sets && edf->image_dir->sets_count)
90      {
91         free(edf->image_dir->entries);
92         edf->image_dir->entries = NULL;
93         return EINA_FALSE;
94      }
95
96    EINA_LIST_FREE(oedf->image_dir->sets, ds)
97      {
98         memcpy(edf->image_dir->sets + ds->id,
99                ds,
100                sizeof (Edje_Image_Directory_Set));
101         free(ds);
102      }
103
104    return EINA_TRUE;
105 }
106
107 Edje_File *
108 _edje_file_convert(Eet_File *ef, Old_Edje_File *oedf)
109 {
110    Edje_Part_Collection_Directory_Entry *ce;
111    Edje_Font_Directory_Entry *fnt;
112    Edje_File *edf;
113    Eina_List *l;
114    Old_Edje_Data *ed;
115
116    if (oedf->version < 2) return NULL;
117
118    edf = calloc(1, sizeof (Edje_File));
119    if (!edf) return NULL;
120
121    edf->free_strings = 0;
122
123    edf->fonts = eina_hash_string_small_new(free);
124    edf->collection = eina_hash_string_small_new(free);
125    edf->data = eina_hash_string_small_new(free);
126
127    if (!edf->fonts || !edf->collection || !edf->data)
128      goto on_error;
129
130    EINA_LIST_FREE(oedf->data, ed)
131      {
132         Edje_String *es;
133
134         es = calloc(1, sizeof (Edje_String));
135         if (!es) continue;
136
137         es->str = ed->value;
138
139         eina_hash_direct_add(edf->data, ed->key, es);
140         free(ed);
141      }
142
143    EINA_LIST_FOREACH(oedf->collection_dir->entries, l, ce)
144      if (ce->entry)
145        eina_hash_direct_add(edf->collection, ce->entry, ce);
146      else
147        error_and_abort(ef, "Collection %i: name missing.\n", ce->id);
148
149    if (oedf->font_dir)
150      EINA_LIST_FOREACH(oedf->font_dir->entries, l, fnt)
151         eina_hash_direct_add(edf->fonts, fnt->entry, fnt);
152
153    if (!_edje_file_convert_images(edf, oedf))
154      goto on_error;
155
156    if (!_edje_file_convert_external(edf, oedf))
157      goto on_error;
158
159    edf->styles = oedf->styles;
160    edf->color_classes = oedf->color_classes;
161    edf->version = EDJE_FILE_VERSION;
162    edf->feature_ver = oedf->feature_ver;
163    edf->compiler = oedf->compiler;
164
165    edf->dangling = EINA_FALSE;
166    edf->warning = EINA_FALSE;
167
168    /* Below you will find all memory structure that could be cleaned when under
169       memory pressure */
170    edf->collection_cache = NULL;
171    edf->collection_patterns = NULL;
172
173    return edf;
174
175  on_error:
176    eina_hash_free(edf->fonts);
177    eina_hash_free(edf->collection);
178    eina_hash_free(edf->data);
179    free(edf->image_dir);
180    free(edf->external_dir);
181    free(edf);
182    return NULL;
183 }
184
185 static void
186 _edje_collection_program_add(Edje_Program ***array,
187                              unsigned int *count,
188                              Edje_Program *add)
189 {
190    Edje_Program **tmp;
191
192    tmp = realloc(*array, sizeof (Edje_Program*) * (*count + 1));
193    if (!tmp) return ;
194
195    tmp[(*count)++] = add;
196    *array = tmp;
197 }
198
199 Edje_Part_Collection *
200 _edje_collection_convert(Eet_File *ef, Edje_Part_Collection_Directory_Entry *ce, Old_Edje_Part_Collection *oedc)
201 {
202    Edje_Part_Collection *edc;
203    Old_Edje_Part *part;
204    Edje_Program *pg;
205    Old_Edje_Data *di;
206    Eina_List *l;
207    char *buffer;
208    unsigned int k;
209
210    oedc->part = ce->entry;
211
212    /* Count each type part and their respective state */
213    EINA_LIST_FOREACH(oedc->parts, l, part)
214      {
215         int *count;
216         int dummy = 0;
217
218
219         switch (part->type)
220           {
221 #define CSP(Tp, Ce)                                             \
222              case EDJE_PART_TYPE_##Tp :                         \
223                 count = &Ce->count.Tp;                          \
224                 break;
225
226              CSP(RECTANGLE, ce);
227              CSP(TEXT, ce);
228              CSP(IMAGE, ce);
229              CSP(SWALLOW, ce);
230              CSP(TEXTBLOCK, ce);
231              CSP(GROUP, ce);
232              CSP(BOX, ce);
233              CSP(TABLE, ce);
234              CSP(EXTERNAL, ce);
235            default:
236               count = &dummy;
237               break;
238           }
239
240         *count += eina_list_count(part->other_desc) + 1;
241      }
242    ce->count.part = eina_list_count(oedc->parts);
243
244 #define CONVERT_EMN(Tp, Sz, Ce)                                         \
245    buffer = alloca(strlen(ce->entry) + strlen(#Tp) + 2);                \
246    sprintf(buffer, "%s/%s", ce->entry, #Tp);                            \
247    Ce->mp.Tp = eina_mempool_add("one_big", buffer, NULL, sizeof (Sz), Ce->count.Tp);
248
249    CONVERT_EMN(RECTANGLE, Edje_Part_Description_Common, ce);
250    CONVERT_EMN(TEXT, Edje_Part_Description_Text, ce);
251    CONVERT_EMN(IMAGE, Edje_Part_Description_Image, ce);
252    CONVERT_EMN(SWALLOW, Edje_Part_Description_Common, ce);
253    CONVERT_EMN(TEXTBLOCK, Edje_Part_Description_Text, ce);
254    CONVERT_EMN(GROUP, Edje_Part_Description_Common, ce);
255    CONVERT_EMN(BOX, Edje_Part_Description_Box, ce);
256    CONVERT_EMN(TABLE, Edje_Part_Description_Table, ce);
257    CONVERT_EMN(EXTERNAL, Edje_Part_Description_External, ce);
258    CONVERT_EMN(part, Edje_Part, ce);
259
260    /* Change structure layout */
261    edc = calloc(1, sizeof (Edje_Part_Collection));
262    if (!edc) error_and_abort(ef, "Not enough memory");
263    ce->ref = edc;
264
265    EINA_LIST_FREE(oedc->programs, pg)
266      {
267         if (!pg->signal && !pg->source)
268           _edje_collection_program_add(&edc->programs.nocmp,
269                                        &edc->programs.nocmp_count,
270                                        pg);
271         else if (pg->signal && !strpbrk(pg->signal, "*?[\\")
272                  && pg->source && !strpbrk(pg->source, "*?[\\"))
273           _edje_collection_program_add(&edc->programs.strcmp,
274                                        &edc->programs.strcmp_count,
275                                        pg);
276         else if (pg->signal && edje_program_is_strncmp(pg->signal)
277                  && pg->source && edje_program_is_strncmp(pg->source))
278           _edje_collection_program_add(&edc->programs.strncmp,
279                                        &edc->programs.strncmp_count,
280                                        pg);
281         else if (pg->signal && edje_program_is_strrncmp(pg->signal)
282                  && pg->source && edje_program_is_strrncmp(pg->source))
283           _edje_collection_program_add(&edc->programs.strrncmp,
284                                        &edc->programs.strrncmp_count,
285                                        pg);
286         else
287           _edje_collection_program_add(&edc->programs.fnmatch,
288                                        &edc->programs.fnmatch_count,
289                                        pg);
290      }
291
292    edc->data = eina_hash_string_small_new(NULL);
293    EINA_LIST_FREE(oedc->data, di)
294      {
295         Edje_String *es;
296
297         es = calloc(1, sizeof (Edje_String));
298         if (!es) continue ;
299
300         es->str = di->value;
301
302         eina_hash_direct_add(edc->data, di->key, es);
303         free(di);
304      }
305
306    edc->parts_count = eina_list_count(oedc->parts);
307    edc->parts = calloc(edc->parts_count, sizeof (Edje_Part *));
308    if (edc->parts_count && !edc->parts)
309      error_and_abort(ef, "Not enough memory");
310    k = 0;
311
312    EINA_LIST_FREE(oedc->parts, part)
313      {
314         Old_Edje_Part_Description *oepd;
315         Edje_Pack_Element *elm;
316         Edje_Part *replacement;
317         unsigned int i;
318
319         replacement = eina_mempool_malloc(ce->mp.part, sizeof (Edje_Part));
320         if (!replacement)
321           error_and_abort(ef, "Not enough memory");
322
323         replacement->name = part->name;
324         replacement->default_desc = _edje_description_convert(part->type, ce, part->default_desc);
325
326         replacement->other.desc_count = eina_list_count(part->other_desc);
327         replacement->other.desc = calloc(replacement->other.desc_count, sizeof (Edje_Part_Description_Common*));
328
329         i = 0;
330         EINA_LIST_FREE(part->other_desc, oepd)
331           replacement->other.desc[i++] = _edje_description_convert(part->type, ce, oepd);
332
333         replacement->source = part->source;
334         replacement->source2 = part->source2;
335         replacement->source3 = part->source3;
336         replacement->source4 = part->source4;
337         replacement->source5 = part->source5;
338         replacement->source6 = part->source6;
339         replacement->id = part->id;
340         replacement->clip_to_id = part->clip_to_id;
341         replacement->dragable = part->dragable;
342         replacement->items_count = eina_list_count(part->items);
343         replacement->items = calloc(replacement->items_count, sizeof (Edje_Pack_Element*));
344
345         i = 0;
346         EINA_LIST_FREE(part->items, elm)
347           replacement->items[i++] = elm;
348
349         replacement->type = part->type;
350         replacement->effect = part->effect;
351         replacement->mouse_events = part->mouse_events;
352         replacement->repeat_events = part->repeat_events;
353         replacement->ignore_flags = part->ignore_flags;
354         replacement->scale = part->scale;
355         replacement->precise_is_inside = part->precise_is_inside;
356         replacement->use_alternate_font_metrics = part->use_alternate_font_metrics;
357         replacement->pointer_mode = part->pointer_mode;
358         replacement->entry_mode = part->entry_mode;
359         replacement->select_mode = part->select_mode;
360         replacement->multiline = part->multiline;
361         replacement->api = part->api;
362
363         edc->parts[k++] = replacement;
364
365         free(part);
366      }
367
368    edc->id = oedc->id;
369    edc->alias = oedc->alias;
370    edc->prop.min = oedc->prop.min;
371    edc->prop.max = oedc->prop.max;
372    edc->script = oedc->script;
373    edc->part = oedc->part;
374    edc->script_only = oedc->script_only;
375    edc->lua_script_only = oedc->lua_script_only;
376    edc->checked = oedc->checked;
377
378    free(oedc);
379
380    return edc;
381 }
382
383 Edje_Part_Description_Common*
384 _edje_description_convert(int type,
385                           Edje_Part_Collection_Directory_Entry *ce,
386                           Old_Edje_Part_Description *oed)
387 {
388    Edje_Part_Description_Common *result = NULL;
389
390    switch (type)
391      {
392       case EDJE_PART_TYPE_RECTANGLE:
393          result = eina_mempool_malloc(ce->mp.RECTANGLE,
394                                       sizeof (Edje_Part_Description_Common));
395          break;
396       case EDJE_PART_TYPE_SWALLOW:
397          result = eina_mempool_malloc(ce->mp.SWALLOW,
398                                       sizeof (Edje_Part_Description_Common));
399          break;
400       case EDJE_PART_TYPE_GROUP:
401          result = eina_mempool_malloc(ce->mp.GROUP,
402                                       sizeof (Edje_Part_Description_Common));
403          break;
404
405       case EDJE_PART_TYPE_IMAGE:
406         {
407            Edje_Part_Description_Image *img;
408            Edje_Part_Image_Id *id;
409            unsigned int i = 0;
410
411            img = eina_mempool_malloc(ce->mp.IMAGE, sizeof (Edje_Part_Description_Image));
412
413            img->image.tweens_count = eina_list_count(oed->image.tween_list);
414            img->image.tweens = calloc(img->image.tweens_count,
415                                       sizeof (Edje_Part_Image_Id*));
416            if (img->image.tweens_count > 0 && !img->image.tweens)
417              {
418                 eina_mempool_free(ce->mp.IMAGE, img);
419                 return NULL;
420              }
421
422            EINA_LIST_FREE(oed->image.tween_list, id)
423              img->image.tweens[i++] = id;
424
425            img->image.id = oed->image.id;
426            img->image.scale_hint = oed->image.scale_hint;
427            img->image.set = oed->image.set;
428
429            img->image.border = oed->image.border;
430            img->image.fill = oed->image.fill;
431
432            result = &img->common;
433            break;
434         }
435
436 #define CONVERT_ALLOC_POOL(Short, Type, Name)                           \
437          case EDJE_PART_TYPE_##Short:                                   \
438            {                                                            \
439               Edje_Part_Description_##Type *Name;                       \
440                                                                         \
441               Name = eina_mempool_malloc(ce->mp.Short, sizeof (Edje_Part_Description_##Type)); \
442               Name->Name = oed->Name;                                   \
443               result = &Name->common;                                   \
444               break;                                                    \
445            }
446
447          CONVERT_ALLOC_POOL(TEXT, Text, text);
448          CONVERT_ALLOC_POOL(TEXTBLOCK, Text, text);
449          CONVERT_ALLOC_POOL(BOX, Box, box);
450          CONVERT_ALLOC_POOL(TABLE, Table, table);
451          CONVERT_ALLOC_POOL(EXTERNAL, External, external_params);
452      }
453
454    if (result)
455      *result = oed->common;
456
457    free(oed);
458    return result;
459 }