char *authors = NULL;
char *license = NULL;
Eina_List *licenses = NULL;
+Eina_Array *requires;
static const char *progname = NULL;
edje_file->efl_version.major = 1;
edje_file->efl_version.minor = 18;
edje_file->base_scale = FROM_INT(1);
+ requires = eina_array_new(10);
#ifdef HAVE_SYS_RESOURCE_H
{
extern int had_quote;
extern unsigned int max_open_files;
+extern Eina_Array *requires;
/* TIZEN_ONLY(150320)********************Ninepatch patch for Samsung************************************/
Eina_Bool is_ninepatch_image(const char* name);
static void check_has_anchors(void);
static void st_id(void);
+static void st_requires(void);
static void st_efl_version(void);
static void st_externals_external(void);
New_Statement_Handler statement_handlers[] =
{
{"id", st_id},
+ {"requires", st_requires},
{"efl_version", st_efl_version},
{"externals.external", st_externals_external},
IMAGE_STATEMENTS("")
static void
st_id(void)
{
+ Eina_Array_Iterator it;
+ unsigned int i;
+ char *str, *id;
+
+ check_arg_count(1);
+ id = parse_str(0);
+
+ EINA_ARRAY_ITER_NEXT(requires, i, str, it)
+ if (eina_streq(str, id))
+ error_and_abort(NULL, "Cannot use same id for file as one of its required files!");
+ free((void*)edje_file->id);
+ edje_file->id = id;
+}
+
+/** @edcsubsection{toplevel_requires,
+ * requires} */
+
+/**
+ @page edcref
+
+ @property
+ requires
+ @parameters
+ [name]
+ @effect
+ Specifying this property informs edje not to close the
+ file with the corresponding id property for as long as this
+ file is open. Multiple requires properties can be individually specified.
+ @since 1.21
+ @endproperty
+ */
+static void
+st_requires(void)
+{
+ char *str;
check_arg_count(1);
- free(edje_file->id);
- edje_file->id = parse_str(0);
+ str = parse_str(0);
+ if (eina_streq(str, edje_file->id))
+ error_and_abort(NULL, "Cannot require the current file!");
+ eina_array_push(requires, str);
}
/** @edcsubsection{toplevel_externals,
@property
image
@parameters
- [image file] [compression method] (compression level)
+ [image file] [compression method] (compression level)(edje file id)
@effect
Used to include each image file. The full path to the directory holding
the images can be defined later with edje_cc's "-id" option.
@li LOSSY_ETC1 [0-100]: ETC1 lossy texture compression with quality from 0 to 100.
@li LOSSY_ETC2 [0-100]: ETC2 lossy texture compression with quality from 0 to 100 (supports alpha).
@li USER: Do not embed the file, refer to the external file instead.
+ @li EXTERNAL: The file exists in the edje file with the specified id.
Defaults: compression level for lossy methods is 90.
@endproperty
"LOSSY_ETC1", 3,
"LOSSY_ETC2", 4,
"USER", 5,
+ "EXTERNAL", 6,
NULL);
if (v == 0)
{
img->source_type = EDJE_IMAGE_SOURCE_TYPE_USER;
img->source_param = 0;
}
+ else if (v == 6)
+ {
+ img->source_type = EDJE_IMAGE_SOURCE_TYPE_EXTERNAL;
+ img->source_param = 0;
+ img->external_id = parse_str(2);
+ }
if ((img->source_type < EDJE_IMAGE_SOURCE_TYPE_INLINE_LOSSY) ||
- (img->source_type > EDJE_IMAGE_SOURCE_TYPE_INLINE_LOSSY_ETC2))
+ (img->source_type == EDJE_IMAGE_SOURCE_TYPE_USER))
check_arg_count(2);
- else
+ else if (img->source_type != EDJE_IMAGE_SOURCE_TYPE_EXTERNAL)
{
if (check_range_arg_count(2, 3) > 2)
img->source_param = parse_int_range(2, 0, 100);
else
img->source_param = 90;
}
+ if (!edje_file->image_id_hash)
+ edje_file->image_id_hash = eina_hash_string_superfast_new(free);
+ {
+ Edje_Image_Hash *eih = mem_alloc(SZ(Edje_Image_Hash));
+ eih->id = img->id;
+ eina_hash_add(edje_file->image_id_hash, tmp, eih);
+ }
}
static void
@property
image
@parameters
- [image file] [compression method] (compression level)
+ [image file] [compression method] (compression level)(edje file id)
@effect
Used to include each image file. The full path to the directory holding
the images can be defined later with edje_cc's "-id" option.
@li LOSSY_ETC1 [0-100]: ETC1 lossy texture compression with quality from 0 to 100.
@li LOSSY_ETC2 [0-100]: ETC2 lossy texture compression with quality from 0 to 100 (supports alpha).
@li USER: Do not embed the file, refer to the external file instead.
+ @li EXTERNAL: The file exists in the edje file with the specified id.
Defaults: compression level for lossy methods is 90.
@endproperty
/************************************************************************************/
img = &edje_file->image_dir->entries[cur_image_entry];
- if ((img->source_type == EDJE_IMAGE_SOURCE_TYPE_USER) || !img->entry)
+ if ((img->source_type >= EDJE_IMAGE_SOURCE_TYPE_USER) || !img->entry)
continue;
if (img->source_type == EDJE_IMAGE_SOURCE_TYPE_INLINE_LOSSY_ETC1 ||
}
}
- if (img->source_type != EDJE_IMAGE_SOURCE_TYPE_USER)
+ if (img->source_type < EDJE_IMAGE_SOURCE_TYPE_USER)
{
ext = strrchr(img->entry, '.');
if (ext && (!strcasecmp(ext, ".svg") || !strcasecmp(ext, ".svgz")))
EFL_VERSION_MAJOR, EFL_VERSION_MINOR);
}
+ if (eina_array_count(requires))
+ {
+ int i = 0;
+
+ edje_file->requires_count = eina_array_count(requires);
+ edje_file->requires = mem_alloc(edje_file->requires_count * sizeof(void*));
+ do
+ {
+ edje_file->requires[i] = eina_array_pop(requires);
+ i++;
+ } while (eina_array_count(requires));
+ eina_array_free(requires);
+ }
+
check_groups(ef);
ecore_thread_max_set(ecore_thread_max_get() * 2);
if ((de->entry) && (!strcmp(de->entry, image->name)))
{
- if (de->source_type == EDJE_IMAGE_SOURCE_TYPE_USER)
+ if (de->source_type >= EDJE_IMAGE_SOURCE_TYPE_USER)
*(image->dest) = -de->id - 1;
else
*(image->dest) = de->id;
if ((ei->source_type > EDJE_IMAGE_SOURCE_TYPE_NONE) &&
(ei->source_type < EDJE_IMAGE_SOURCE_TYPE_LAST) &&
(ei->source_type != EDJE_IMAGE_SOURCE_TYPE_USER) &&
+ (ei->source_type != EDJE_IMAGE_SOURCE_TYPE_EXTERNAL) &&
(ei->entry))
{
Ecore_Evas *ee;
#include "edje_private.h"
Eina_Hash *_edje_file_hash = NULL;
+Eina_Hash *_edje_id_hash = NULL;
+static Eina_Hash *_edje_requires_pending;
static int _edje_file_cache_size = 16;
static Eina_List *_edje_file_cache = NULL;
if (sc->name)
eina_hash_direct_add(edf->size_hash, sc->name, sc);
+ if (edf->requires_count)
+ {
+ unsigned int i;
+ Edje_File *required_edf;
+ char **requires = (char**)edf->requires;
+
+ /* EET_DATA_DESCRIPTOR_ADD_VAR_ARRAY_STRING returns an mmapped blob, not stringshares */
+ edf->requires = malloc(edf->requires_count * sizeof(char*));
+ for (i = 0; i < edf->requires_count; i++)
+ {
+ char *str = (char*)requires[i];
+
+ edf->requires[i] = eina_stringshare_add(str);
+ required_edf = eina_hash_find(_edje_id_hash, edf->requires[i]);
+ if (required_edf)
+ {
+ required_edf->references++;
+ continue;
+ }
+ ERR("edje file '%s' REQUIRES file '%s' which is not loaded", edf->path, edf->requires[i]);
+ if (!_edje_requires_pending)
+ _edje_requires_pending = eina_hash_stringshared_new(NULL);
+ eina_hash_list_append(_edje_requires_pending, edf->requires[i], edf);
+ }
+ free(requires);
+ }
+ if (_edje_requires_pending && edf->id)
+ {
+ l = eina_hash_set(_edje_requires_pending, edf->id, NULL);
+
+ edf->references += eina_list_count(l);
+ eina_list_free(l);
+
+ if (!eina_hash_population(_edje_requires_pending))
+ {
+ eina_hash_free(_edje_requires_pending);
+ _edje_requires_pending = NULL;
+ }
+ }
+
return edf;
}
Edje_Part_Collection *edc;
Edje_Part *ep;
+ if (!_edje_id_hash)
+ _edje_id_hash = eina_hash_stringshared_new(NULL);
if (!_edje_file_hash)
{
_edje_file_hash = eina_hash_pointer_new(NULL);
if (!edf) return NULL;
eina_hash_direct_add(_edje_file_hash, &edf->f, edf);
+ if (edf->id)
+ eina_hash_list_append(_edje_id_hash, edf->id, edf);
/* return edf; */
open:
edf->references--;
if (edf->references != 0) return;
+ if (edf->requires_count)
+ {
+ unsigned int i;
+
+ for (i = 0; i < edf->requires_count; i++)
+ {
+ Edje_File *required_edf = eina_hash_find(_edje_id_hash, edf->requires[i]);
+
+ if (required_edf)
+ _edje_cache_file_unref(edf);
+ else if (_edje_requires_pending)
+ {
+ eina_hash_list_remove(_edje_requires_pending, edf->requires[i], edf);
+ if (!eina_hash_population(_edje_requires_pending))
+ {
+ eina_hash_free(_edje_requires_pending);
+ _edje_requires_pending = NULL;
+ }
+ }
+ }
+ }
+
if (edf->dangling)
{
_edje_file_free(edf);
return;
}
+ if (edf->id)
+ eina_hash_list_remove(_edje_id_hash, edf->id, edf);
+ if (!eina_hash_population(_edje_id_hash))
+ {
+ eina_hash_free(_edje_id_hash);
+ _edje_id_hash = NULL;
+ }
eina_hash_del(_edje_file_hash, &edf->f, edf);
if (!eina_hash_population(_edje_file_hash))
{
}
static void
+_edje_real_part_image_error_check(Edje_Real_Part *ep)
+{
+ switch (evas_object_image_load_error_get(ep->object))
+ {
+ case EVAS_LOAD_ERROR_GENERIC:
+ ERR("Error type: EVAS_LOAD_ERROR_GENERIC");
+ break;
+
+ case EVAS_LOAD_ERROR_DOES_NOT_EXIST:
+ ERR("Error type: EVAS_LOAD_ERROR_DOES_NOT_EXIST");
+ break;
+
+ case EVAS_LOAD_ERROR_PERMISSION_DENIED:
+ ERR("Error type: EVAS_LOAD_ERROR_PERMISSION_DENIED");
+ break;
+
+ case EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED:
+ ERR("Error type: EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED");
+ break;
+
+ case EVAS_LOAD_ERROR_CORRUPT_FILE:
+ ERR("Error type: EVAS_LOAD_ERROR_CORRUPT_FILE");
+ break;
+
+ case EVAS_LOAD_ERROR_UNKNOWN_FORMAT:
+ ERR("Error type: EVAS_LOAD_ERROR_UNKNOWN_FORMAT");
+ break;
+
+ default:
+ ERR("Error type: ???");
+ break;
+ }
+}
+
+static Eina_Bool
+_edje_real_part_image_internal_set(Edje_File *edf, Edje_Real_Part *ep, int image_id)
+{
+ char buf[1024] = "edje/images/";
+
+ /* Replace snprint("edje/images/%i") == memcpy + itoa */
+ eina_convert_itoa(image_id, buf + 12); /* No need to check length as 2³² need only 10 characteres. */
+
+ evas_object_image_mmap_set(ep->object, edf->f, buf);
+ if (evas_object_image_load_error_get(ep->object) != EVAS_LOAD_ERROR_NONE)
+ {
+ ERR("Error loading image collection \"%s\" from "
+ "file \"%s\". Missing EET Evas loader module?",
+ buf, edf->path);
+ _edje_real_part_image_error_check(ep);
+ return EINA_FALSE;
+ }
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_edje_real_part_image_external_set(Edje_File *edf, Edje_Real_Part *ep, int image_id)
+{
+ Edje_Image_Directory_Entry *ie;
+
+ if (!edf->image_dir) return EINA_FALSE;
+ ie = edf->image_dir->entries + (-image_id) - 1;
+ if ((ie) &&
+ (ie->source_type == EDJE_IMAGE_SOURCE_TYPE_USER) &&
+ (ie->entry))
+ {
+ evas_object_image_file_set(ep->object, ie->entry, NULL);
+ _edje_real_part_image_error_check(ep);
+ return EINA_TRUE;
+ }
+ else if ((ie) &&
+ (ie->source_type == EDJE_IMAGE_SOURCE_TYPE_EXTERNAL) &&
+ (ie->entry))
+ {
+ Edje_File *edff;
+ Eina_List *l, *ll;
+
+ l = eina_hash_find(_edje_id_hash, ie->external_id);
+ EINA_LIST_FOREACH(l, ll, edff)
+ {
+ Edje_Image_Hash *eih = eina_hash_find(edff->image_id_hash, ie->entry);
+
+ if (!eih) continue;
+ if (eih->id < 0)
+ return _edje_real_part_image_external_set(edff, ep, eih->id);
+ else
+ _edje_real_part_image_internal_set(edff, ep, eih->id);
+ return EINA_TRUE;
+ }
+ return EINA_FALSE;
+ }
+ return EINA_FALSE;
+}
+
+static void
_edje_real_part_image_set(Edje *ed, Edje_Real_Part *ep, Edje_Real_Part_Set **set, FLOAT_T pos)
{
int image_id;
if (set) *set = ep->param1.set;
if (image_id < 0)
{
- Edje_Image_Directory_Entry *ie;
-
- if (!ed->file->image_dir) ie = NULL;
- else ie = ed->file->image_dir->entries + (-image_id) - 1;
- if ((ie) &&
- (ie->source_type == EDJE_IMAGE_SOURCE_TYPE_USER) &&
- (ie->entry))
- {
- evas_object_image_file_set(ep->object, ie->entry, NULL);
- }
+ _edje_real_part_image_external_set(ed->file, ep, image_id);
}
else
{
}
if (image_id < 0)
{
- ERR("Part \"%s\" description, "
- "\"%s\" %3.3f with image %i index has a missing image id in a set of %i !!!",
- ep->part->name,
- ep->param1.description->state.name,
- ep->param1.description->state.value,
- image_num,
- image_count);
+ if (!_edje_real_part_image_external_set(ed->file, ep, image_id))
+ ERR("Part \"%s\" description, "
+ "\"%s\" %3.3f with image %i index has a missing image id in a set of %i !!!",
+ ep->part->name,
+ ep->param1.description->state.name,
+ ep->param1.description->state.value,
+ image_num,
+ image_count);
}
else
{
- char buf[1024] = "edje/images/";
-
- /* Replace snprint("edje/images/%i") == memcpy + itoa */
- eina_convert_itoa(image_id, buf + 12); /* No need to check length as 2³² need only 10 characteres. */
-
- evas_object_image_mmap_set(ep->object, ed->file->f, buf);
- if (evas_object_image_load_error_get(ep->object) != EVAS_LOAD_ERROR_NONE)
- {
- ERR("Error loading image collection \"%s\" from "
- "file \"%s\". Missing EET Evas loader module?",
- buf, ed->file->path);
- switch (evas_object_image_load_error_get(ep->object))
- {
- case EVAS_LOAD_ERROR_GENERIC:
- ERR("Error type: EVAS_LOAD_ERROR_GENERIC");
- break;
-
- case EVAS_LOAD_ERROR_DOES_NOT_EXIST:
- ERR("Error type: EVAS_LOAD_ERROR_DOES_NOT_EXIST");
- break;
-
- case EVAS_LOAD_ERROR_PERMISSION_DENIED:
- ERR("Error type: EVAS_LOAD_ERROR_PERMISSION_DENIED");
- break;
-
- case EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED:
- ERR("Error type: EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED");
- break;
-
- case EVAS_LOAD_ERROR_CORRUPT_FILE:
- ERR("Error type: EVAS_LOAD_ERROR_CORRUPT_FILE");
- break;
-
- case EVAS_LOAD_ERROR_UNKNOWN_FORMAT:
- ERR("Error type: EVAS_LOAD_ERROR_UNKNOWN_FORMAT");
- break;
-
- default:
- ERR("Error type: ???");
- break;
- }
- }
+ _edje_real_part_image_internal_set(ed->file, ep, image_id);
}
}
}
Eet_Data_Descriptor *_edje_edd_edje_external_directory = NULL;
Eet_Data_Descriptor *_edje_edd_edje_external_directory_entry = NULL;
Eet_Data_Descriptor *_edje_edd_edje_font_directory_entry = NULL;
+Eet_Data_Descriptor *_edje_edd_edje_image_id_hash = NULL;
Eet_Data_Descriptor *_edje_edd_edje_image_directory = NULL;
Eet_Data_Descriptor *_edje_edd_edje_image_directory_entry = NULL;
Eet_Data_Descriptor *_edje_edd_edje_image_directory_set = NULL;
FREED(_edje_edd_edje_external_directory);
FREED(_edje_edd_edje_external_directory_entry);
FREED(_edje_edd_edje_font_directory_entry);
+ FREED(_edje_edd_edje_image_id_hash);
FREED(_edje_edd_edje_image_directory);
FREED(_edje_edd_edje_image_directory_entry);
FREED(_edje_edd_edje_image_directory_set);
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_font_directory_entry, Edje_Font_Directory_Entry, "entry", entry, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_font_directory_entry, Edje_Font_Directory_Entry, "file", file, EET_T_STRING);
+ /* image hash */
+ EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Edje_Image_Hash);
+ _edje_edd_edje_image_id_hash = eet_data_descriptor_file_new(&eddc);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_image_id_hash, Edje_Image_Hash, "id", id, EET_T_INT);
+
/* image directory */
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Edje_Image_Directory_Entry);
_edje_edd_edje_image_directory_entry =
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_image_directory_entry, Edje_Image_Directory_Entry, "source_type", source_type, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_image_directory_entry, Edje_Image_Directory_Entry, "source_param", source_param, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_image_directory_entry, Edje_Image_Directory_Entry, "id", id, EET_T_INT);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_image_directory_entry, Edje_Image_Directory_Entry, "external_id", external_id, EET_T_STRING);
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Edje_Image_Directory_Set_Entry);
_edje_edd_edje_image_directory_set_entry =
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_file, Edje_File, "efl_version.minor", efl_version.minor, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_file, Edje_File, "base_scale", base_scale, EDJE_T_FLOAT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_file, Edje_File, "id", id, EET_T_STRING);
+ EET_DATA_DESCRIPTOR_ADD_VAR_ARRAY_STRING(_edje_edd_edje_file, Edje_File, "requires", requires);
EET_DATA_DESCRIPTOR_ADD_SUB(_edje_edd_edje_file, Edje_File, "external_dir", external_dir, _edje_edd_edje_external_directory);
EET_DATA_DESCRIPTOR_ADD_SUB(_edje_edd_edje_file, Edje_File, "image_dir", image_dir, _edje_edd_edje_image_directory);
EET_DATA_DESCRIPTOR_ADD_SUB(_edje_edd_edje_file, Edje_File, "model_dir", model_dir, _edje_edd_edje_model_directory);
EET_DATA_DESCRIPTOR_ADD_HASH(_edje_edd_edje_file, Edje_File, "data", data, _edje_edd_edje_string);
EET_DATA_DESCRIPTOR_ADD_HASH(_edje_edd_edje_file, Edje_File, "fonts", fonts, _edje_edd_edje_font_directory_entry);
EET_DATA_DESCRIPTOR_ADD_HASH(_edje_edd_edje_file, Edje_File, "collection", collection, _edje_edd_edje_part_collection_directory_entry);
+ EET_DATA_DESCRIPTOR_ADD_HASH(_edje_edd_edje_file, Edje_File, "image_id_hash", image_id_hash, _edje_edd_edje_image_id_hash);
/* parts & limit & programs - loaded induvidually */
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Edje_Limit);
HASH_FREE(edf->fonts);
HASH_FREE(edf->collection);
HASH_FREE(edf->data);
+ HASH_FREE(edf->image_id_hash);
+
+ if (edf->requires_count)
+ {
+ unsigned int i;
+
+ for (i = 0; i < edf->requires_count; i++)
+ eina_stringshare_del(edf->requires[i]);
+ free(edf->requires);
+ }
if (edf->image_dir)
{
#define EDJE_IMAGE_SOURCE_TYPE_INLINE_LOSSY_ETC1 3
#define EDJE_IMAGE_SOURCE_TYPE_INLINE_LOSSY_ETC2 4
#define EDJE_IMAGE_SOURCE_TYPE_USER 5
-#define EDJE_IMAGE_SOURCE_TYPE_LAST 6
+#define EDJE_IMAGE_SOURCE_TYPE_EXTERNAL 6
+#define EDJE_IMAGE_SOURCE_TYPE_LAST 7
#define EDJE_SOUND_SOURCE_TYPE_NONE 0
#define EDJE_SOUND_SOURCE_TYPE_INLINE_RAW 1
int rel_to;
};
+typedef struct Edje_Image_Hash
+{
+ int id;
+} Edje_Image_Hash;
+
struct _Edje_File
{
const char *path;
Edje_Mo_Directory *mo_dir;
Edje_Gfx_Filter_Directory *filter_dir;
+ Eina_Hash *image_id_hash;
+ Eina_Stringshare **requires;
+ unsigned int requires_count;
+
Eina_List *styles;
// TIZEN_ONLY(20150110): Add plugin keyword.
#ifdef EDJE_TIZEN_PLUGIN
const char *entry; /* the nominal name of the image - if any */
int source_type; /* alternate source mode. 0 = none */
int source_param; /* extra params on encoding */
+ Eina_Stringshare *external_id;
int id; /* the id no. of the image */
};
extern Eina_Cow *_edje_calc_params_physics_cow;
extern Eina_Hash *_edje_file_hash;
+extern Eina_Hash *_edje_id_hash;
extern const char *_edje_language;
extern const char *_edje_cache_path;