return node;
}
+#define LINE_DEF(Name, Field) \
+ { #Name, sizeof (#Name), offsetof(Svg_Line_Node, Field)}
+
+static const struct {
+ const char *tag;
+ int sz;
+ size_t offset;
+} line_tags[] = {
+ LINE_DEF(x1, x1),
+ LINE_DEF(y1, y1),
+ LINE_DEF(x2, x2),
+ LINE_DEF(y2, y2)
+};
+
+/* parse the attributes for a rect element.
+ * https://www.w3.org/TR/SVG/shapes.html#LineElement
+ */
+static Eina_Bool
+_attr_parse_line_node(void *data, const char *key, const char *value)
+{
+ Svg_Node *node = data;
+ Svg_Line_Node *line = & (node->node.line);
+ unsigned int i;
+ unsigned char *array;
+ int sz = strlen(key);
+
+ array = (unsigned char*) line;
+ for (i = 0; i < sizeof (line_tags) / sizeof(line_tags[0]); i++)
+ if (line_tags[i].sz - 1 == sz && !strncmp(line_tags[i].tag, key, sz))
+ {
+ *((double*) (array + line_tags[i].offset)) = _to_double(value);
+ return EINA_TRUE;
+ }
+
+ if (!strcmp(key, "id"))
+ {
+ node->id = _copy_id(value);
+ }
+ else if (!strcmp(key, "style"))
+ {
+ _attr_style_node(node, value);
+ }
+ else
+ {
+ _parse_style_attr(node, key, value);
+ }
+ return EINA_TRUE;
+}
+
+static Svg_Node *
+_create_line_node(Svg_Node *parent, const char *buf, unsigned buflen)
+{
+ Svg_Node *node = _create_node(parent, SVG_NODE_LINE);
+
+ eina_simple_xml_attributes_parse(buf, buflen,
+ _attr_parse_line_node, node);
+ return node;
+}
+
static Eina_Stringshare *
_id_from_href(const char *href)
{
to->node.rect.rx = from->node.rect.rx;
to->node.rect.ry = from->node.rect.ry;
break;
+ case SVG_NODE_LINE:
+ to->node.line.x1 = from->node.line.x1;
+ to->node.line.y1 = from->node.line.y1;
+ to->node.line.x2 = from->node.line.x2;
+ to->node.line.y2 = from->node.line.y2;
+ break;
case SVG_NODE_PATH:
to->node.path.path = eina_stringshare_add(from->node.path.path);
break;
TAG_DEF(polygon),
TAG_DEF(rect),
TAG_DEF(polyline),
+ TAG_DEF(line),
};
static const struct {
struct _Ector_Surface_Data
{
- void *key;
- void *surface;
+ void *key; // vg tree pointer
+ void *surface; // engine image
+ void *output;
};
struct _Ector_Surface_Cache
{
Eina_Hash *surface_hash;
Eina_List *lru_list;
- void *output;
};
/* General types - used for script type chceking */
void (*ector_begin) (void *data, void *context, Ector_Surface *ector, void *surface, int x, int y, Eina_Bool do_async);
void (*ector_renderer_draw) (void *data, void *context, void *surface, Ector_Renderer *r, Eina_Array *clips, Eina_Bool do_async);
void (*ector_end) (void *data, void *context, Ector_Surface *ector, void *surface, Eina_Bool do_async);
- void *(*ector_surface_create) (void *data, void *surface, int w, int h, Eina_Bool force);
+ void *(*ector_surface_create) (void *data, void *surface, int w, int h, Eina_Bool force);
void (*ector_surface_cache_set) (void *data, void *key, void *surface);
void *(*ector_surface_cache_get) (void *data, void *key);
};
#endif
// Svg Node
-typedef enum _Svg_Node_Type Svg_Node_Type;
-typedef enum _Svg_Length_Type Svg_Length_Type;
-
-typedef struct _Svg_Node Svg_Node;
-typedef struct _Svg_Doc_Node Svg_Doc_Node;
-typedef struct _Svg_G_Node Svg_G_Node;
-typedef struct _Svg_Defs_Node Svg_Defs_Node;
-typedef struct _Svg_Arc_Node Svg_Arc_Node;
-typedef struct _Svg_Circle_Node Svg_Circle_Node;
-typedef struct _Svg_Ellipse_Node Svg_Ellipse_Node;
-typedef struct _Svg_Polygon_Node Svg_Polygon_Node;
-typedef struct _Svg_Rect_Node Svg_Rect_Node;
-typedef struct _Svg_Path_Node Svg_Path_Node;
-typedef struct _Svg_Style_Property Svg_Style_Property;
+typedef enum _Svg_Node_Type Svg_Node_Type;
+typedef enum _Svg_Length_Type Svg_Length_Type;
+
+typedef struct _Svg_Node Svg_Node;
+typedef struct _Svg_Doc_Node Svg_Doc_Node;
+typedef struct _Svg_G_Node Svg_G_Node;
+typedef struct _Svg_Defs_Node Svg_Defs_Node;
+typedef struct _Svg_Arc_Node Svg_Arc_Node;
+typedef struct _Svg_Circle_Node Svg_Circle_Node;
+typedef struct _Svg_Ellipse_Node Svg_Ellipse_Node;
+typedef struct _Svg_Polygon_Node Svg_Polygon_Node;
+typedef struct _Svg_Rect_Node Svg_Rect_Node;
+typedef struct _Svg_Path_Node Svg_Path_Node;
+typedef struct _Svg_Style_Property Svg_Style_Property;
+typedef struct _Svg_Line_Node Svg_Line_Node;
typedef struct _Svg_Style_Stroke Svg_Style_Stroke;
typedef struct _Svg_Style_Fill Svg_Style_Fill;
double ry;
};
+struct _Svg_Line_Node
+{
+ double x1;
+ double y1;
+ double x2;
+ double y2;
+};
+
struct _Svg_Path_Node
{
Eina_Stringshare *path;
Svg_Polygon_Node polyline;
Svg_Rect_Node rect;
Svg_Path_Node path;
+ Svg_Line_Node line;
}node;
};
Eet_Data_Descriptor *_edje_edd_edje_path_node = NULL;
Eet_Data_Descriptor *_edje_edd_edje_polygon_node = NULL;
Eet_Data_Descriptor *_edje_edd_edje_vg_node = NULL;
+Eet_Data_Descriptor *_edje_edd_edje_line_node = NULL;
#define FREE_DESCRIPTOR(eed) \
if (eed) \
}
static inline Eet_Data_Descriptor*
+_eet_for_line_node(void)
+{
+ Eet_Data_Descriptor *eet;
+ Eet_Data_Descriptor_Class eetc;
+
+ EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eetc, Svg_Line_Node);
+ eet = eet_data_descriptor_stream_new(&eetc);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Line_Node, "x1", x1, EET_T_DOUBLE);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Line_Node, "y1", y1, EET_T_DOUBLE);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Line_Node, "x2", x2, EET_T_DOUBLE);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Line_Node, "y2", y2, EET_T_DOUBLE);
+ return eet;
+}
+
+static inline Eet_Data_Descriptor*
_eet_for_circle_node(void)
{
Eet_Data_Descriptor *eet;
{ SVG_NODE_POLYLINE, "polyline" },
{ SVG_NODE_RECT, "rect" },
{ SVG_NODE_PATH, "path" },
+ { SVG_NODE_LINE, "line" },
{ SVG_NODE_UNKNOWN, NULL }
};
_edje_edd_edje_circle_node = _eet_for_circle_node();
_edje_edd_edje_ellipse_node = _eet_for_ellipse_node();
_edje_edd_edje_rect_node = _eet_for_rect_node();
+ _edje_edd_edje_line_node = _eet_for_line_node();
_edje_edd_edje_path_node = _eet_for_path_node();
_edje_edd_edje_polygon_node = _eet_for_polygon_node();
_edje_edd_edje_style_property_node = _eet_for_style_property();
EET_DATA_DESCRIPTOR_ADD_MAPPING(eet_union, "circle", _edje_edd_edje_circle_node);
EET_DATA_DESCRIPTOR_ADD_MAPPING(eet_union, "ellipse", _edje_edd_edje_ellipse_node);
EET_DATA_DESCRIPTOR_ADD_MAPPING(eet_union, "rect", _edje_edd_edje_rect_node);
+ EET_DATA_DESCRIPTOR_ADD_MAPPING(eet_union, "line", _edje_edd_edje_line_node);
EET_DATA_DESCRIPTOR_ADD_MAPPING(eet_union, "path", _edje_edd_edje_path_node);
EET_DATA_DESCRIPTOR_ADD_MAPPING(eet_union, "polygon", _edje_edd_edje_polygon_node);
EET_DATA_DESCRIPTOR_ADD_MAPPING(eet_union, "polyline", _edje_edd_edje_polygon_node);
FREE_DESCRIPTOR(_edje_edd_edje_path_node);
FREE_DESCRIPTOR(_edje_edd_edje_polygon_node);
FREE_DESCRIPTOR(_edje_edd_edje_vg_node);
+ FREE_DESCRIPTOR(_edje_edd_edje_line_node);
}
evas_vg_shape_shape_append_rect(vg, node->node.rect.x, node->node.rect.y, node->node.rect.w, node->node.rect.h,
node->node.rect.rx, node->node.rect.ry);
break;
+ case SVG_NODE_LINE:
+ vg = evas_vg_shape_add(parent);
+ evas_vg_shape_shape_append_move_to(vg, node->node.line.x1, node->node.line.y1);
+ evas_vg_shape_shape_append_line_to(vg, node->node.line.x2, node->node.line.y2);
+ break;
default:
break;
}
eina_array_free(c);
}
-static void *
-eng_ector_surface_create(void *data, void *surface, int width, int height, Eina_Bool force EINA_UNUSED)
-{
- Evas_GL_Image *glim;
-
- if (!surface)
- {
- surface = eng_image_new_from_copied_data(data, width, height, NULL, EINA_TRUE, EVAS_COLORSPACE_ARGB8888);
- //Use this hint for ZERO COPY texture upload.
- eng_image_content_hint_set(data, surface, EVAS_IMAGE_CONTENT_HINT_DYNAMIC);
- }
- else
- {
- int cur_w , cur_h;
- glim = surface;
- eng_image_size_get(data, glim, &cur_w, &cur_h);
- if (width != cur_w || height != cur_h)
- {
- eng_image_free(data, surface);
- surface = eng_image_new_from_copied_data(data, width, height, NULL, EINA_TRUE, EVAS_COLORSPACE_ARGB8888);
- //Use this hint for ZERO COPY texture upload.
- eng_image_content_hint_set(data, surface, EVAS_IMAGE_CONTENT_HINT_DYNAMIC);
- }
- }
- return surface;
-}
-
static void
eng_ector_begin(void *data EINA_UNUSED, void *context EINA_UNUSED, Ector_Surface *ector,
void *surface, int x, int y, Eina_Bool do_async EINA_UNUSED)
}
}
+static void*
+eng_ector_surface_create(void *data, void *surface, int width, int height, Eina_Bool force EINA_UNUSED)
+{
+ Evas_GL_Image *glim;
+ int cur_w=0 , cur_h=0;
+
+ if (surface)
+ {
+ glim = surface;
+ eng_image_size_get(data, glim, &cur_w, &cur_h);
+ if ((width == cur_w) && (height == cur_h)) return surface;
+ eng_image_free(data, surface);
+ surface = NULL;
+ }
+
+ surface = eng_image_new_from_copied_data(data, width, height, NULL, EINA_TRUE, EVAS_COLORSPACE_ARGB8888);
+ //Use this hint for ZERO COPY texture upload.
+ eng_image_content_hint_set(data, surface, EVAS_IMAGE_CONTENT_HINT_DYNAMIC);
+ return surface;
+}
+
static Ector_Surface_Cache *surface_cache = NULL;
static void
-_ector_surface_cache_init(void *output)
+_ector_surface_cache_init(void)
{
if (!surface_cache)
{
surface_cache = calloc(1, sizeof(Ector_Surface_Cache));
- surface_cache->output = output;
surface_cache->surface_hash = eina_hash_int32_new(NULL);
}
}
// eina_hash_free(surface_cache->surface_hash);
// EINA_LIST_FREE(surface_cache->lru_list, data)
// {
-// eng_image_free(surface_cache->output, data->surface);
+// eng_image_free(data->output, data->surface);
// free(data);
// }
// free(surface_cache);
{
Ector_Surface_Data *surface_data = NULL;
int count;
- _ector_surface_cache_init(data);
- surface_data = calloc(1, sizeof(surface_data));
+ _ector_surface_cache_init();
+ surface_data = calloc(1, sizeof(Ector_Surface_Data));
surface_data->key = key;
surface_data->surface = surface;
+ surface_data->output = data;
eina_hash_add(surface_cache->surface_hash, &key, surface_data);
surface_cache->lru_list = eina_list_prepend(surface_cache->lru_list, surface_data);
count = eina_list_count(surface_cache->lru_list);
surface_data = eina_list_data_get(eina_list_last(surface_cache->lru_list));
eina_hash_del(surface_cache->surface_hash, &surface_data->key, surface_data);
surface_cache->lru_list = eina_list_remove_list(surface_cache->lru_list, eina_list_last(surface_cache->lru_list));
- eng_image_free(surface_cache->output, surface_data->surface);
+ eng_image_free(surface_data->output, surface_data->surface);
free(surface_data);
}
}
static void *
-eng_ector_surface_cache_get(void *data, void *key)
+eng_ector_surface_cache_get(void *data EINA_UNUSED, void *key)
{
- Ector_Surface_Data *surface_data = NULL;
+ Ector_Surface_Data *surface_data = NULL, *lru_data;
+ Eina_List *l;
- _ector_surface_cache_init(data);
+ _ector_surface_cache_init();
surface_data = eina_hash_find(surface_cache->surface_hash, &key);
- if (surface_data)
+ if (surface_data)
{
- surface_cache->lru_list = eina_list_remove(surface_cache->lru_list, surface_data);
- surface_cache->lru_list = eina_list_prepend(surface_cache->lru_list, surface_data);
+ EINA_LIST_FOREACH(surface_cache->lru_list, l, lru_data)
+ {
+ if (lru_data == surface_data)
+ {
+ surface_cache->lru_list = eina_list_demote_list(surface_cache->lru_list, l);
+ break;
+ }
+ }
return surface_data->surface;
}
return NULL;
}
-
static Evas_Func func, pfunc;
static int
{
RGBA_Image *im;
void *pixels = NULL;
+ int cur_w=0 , cur_h=0;
if (!force) return NULL;
- if (!surface)
- {
- surface = eng_image_new_from_copied_data(data, width, height, NULL, EINA_TRUE, EVAS_COLORSPACE_ARGB8888);
- im = surface;
- pixels = evas_cache_image_pixels(&im->cache_entry);
- memset(pixels, 0, (width * height * 4));
- }
- else
+ if (surface)
{
- int cur_w , cur_h;
im = surface;
eng_image_size_get(data, im, &cur_w, &cur_h);
- if (width != cur_w || height != cur_h)
+ if ((width != cur_w) || (height == cur_h))
{
eng_image_free(data, surface);
- surface = eng_image_new_from_copied_data(data, width, height, NULL, EINA_TRUE, EVAS_COLORSPACE_ARGB8888);
+ surface = NULL;
}
- }
+ }
+
+ if (!surface)
+ surface = eng_image_new_from_copied_data(data, width, height, NULL, EINA_TRUE, EVAS_COLORSPACE_ARGB8888);
+
+ im = surface;
+ pixels = evas_cache_image_pixels(&im->cache_entry);
+ memset(pixels, 0, (width * height * 4));
+
return surface;
}
static Ector_Surface_Cache *surface_cache = NULL;
static void
-_ector_surface_cache_init(void *output)
+_ector_surface_cache_init(void)
{
if (!surface_cache)
{
surface_cache = calloc(1, sizeof(Ector_Surface_Cache));
- surface_cache->output = output;
surface_cache->surface_hash = eina_hash_int32_new(NULL);
}
}
eina_hash_free(surface_cache->surface_hash);
EINA_LIST_FREE(surface_cache->lru_list, data)
{
- eng_image_free(surface_cache->output, data->surface);
+ eng_image_free(data->output, data->surface);
free(data);
}
free(surface_cache);
{
Ector_Surface_Data *surface_data = NULL;
int count;
- _ector_surface_cache_init(data);
- surface_data = calloc(1, sizeof(surface_data));
+ _ector_surface_cache_init();
+ surface_data = calloc(1, sizeof(Ector_Surface_Data));
surface_data->key = key;
surface_data->surface = surface;
+ surface_data->output = data;
eina_hash_add(surface_cache->surface_hash, &key, surface_data);
surface_cache->lru_list = eina_list_prepend(surface_cache->lru_list, surface_data);
count = eina_list_count(surface_cache->lru_list);
surface_data = eina_list_data_get(eina_list_last(surface_cache->lru_list));
eina_hash_del(surface_cache->surface_hash, &surface_data->key, surface_data);
surface_cache->lru_list = eina_list_remove_list(surface_cache->lru_list, eina_list_last(surface_cache->lru_list));
- eng_image_free(surface_cache->output, surface_data->surface);
+ eng_image_free(surface_data->output, surface_data->surface);
free(surface_data);
}
}
static void *
-eng_ector_surface_cache_get(void *data, void *key)
+eng_ector_surface_cache_get(void *data EINA_UNUSED, void *key)
{
- Ector_Surface_Data *surface_data = NULL;
+ Ector_Surface_Data *surface_data = NULL, *lru_data;
+ Eina_List *l;
- _ector_surface_cache_init(data);
+ _ector_surface_cache_init();
surface_data = eina_hash_find(surface_cache->surface_hash, &key);
- if (surface_data)
+ if (surface_data)
{
- surface_cache->lru_list = eina_list_remove(surface_cache->lru_list, surface_data);
- surface_cache->lru_list = eina_list_prepend(surface_cache->lru_list, surface_data);
+ EINA_LIST_FOREACH(surface_cache->lru_list, l, lru_data)
+ {
+ if (lru_data == surface_data)
+ {
+ surface_cache->lru_list = eina_list_demote_list(surface_cache->lru_list, l);
+ break;
+ }
+ }
return surface_data->surface;
}
return NULL;