svg: ported svg change from opensource 17/87017/2
authorSubhransu Mohanty <sub.mohanty@samsung.com>
Tue, 6 Sep 2016 04:29:43 +0000 (13:29 +0900)
committerSubhransu Mohanty <sub.mohanty@samsung.com>
Tue, 6 Sep 2016 04:32:30 +0000 (13:32 +0900)
Change-Id: I74f048e42bac243b7da99f805800556b17b5923d

src/bin/edje/edje_svg_loader.c
src/lib/evas/include/evas_private.h
src/lib/evas/vg/evas_vg_common.h
src/lib/evas/vg/evas_vg_eet_handler.c
src/modules/evas/engines/gl_generic/evas_engine.c
src/modules/evas/engines/software_generic/evas_engine.c

index 3e24e2a..d3b0ef4 100644 (file)
@@ -1247,6 +1247,65 @@ _create_rect_node(Svg_Node *parent, const char *buf, unsigned buflen)
    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)
 {
@@ -1368,6 +1427,12 @@ _copy_attribute(Svg_Node *to, Svg_Node *from)
            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;
@@ -1450,6 +1515,7 @@ static const struct {
   TAG_DEF(polygon),
   TAG_DEF(rect),
   TAG_DEF(polyline),
+  TAG_DEF(line),
 };
 
 static const struct {
index c05cd4a..f6d2a4f 100755 (executable)
@@ -533,15 +533,15 @@ typedef struct _Ector_Surface_Data  Ector_Surface_Data;
 
 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 */
@@ -1479,7 +1479,7 @@ struct _Evas_Func
    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);
 };
index b6f8c7a..d9ddf0b 100644 (file)
 #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;
@@ -152,6 +153,14 @@ struct _Svg_Rect_Node
    double ry;
 };
 
+struct _Svg_Line_Node
+{
+   double x1;
+   double y1;
+   double x2;
+   double y2;
+};
+
 struct _Svg_Path_Node
 {
    Eina_Stringshare *path;
@@ -281,6 +290,7 @@ struct _Svg_Node
         Svg_Polygon_Node polyline;
         Svg_Rect_Node rect;
         Svg_Path_Node path;
+        Svg_Line_Node line;
      }node;
 };
 
index 6216a78..30a8d6c 100644 (file)
@@ -16,6 +16,7 @@ Eet_Data_Descriptor *_edje_edd_edje_arc_node = NULL;
 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)                              \
@@ -42,6 +43,21 @@ _eet_for_rect_node(void)
 }
 
 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;
@@ -306,6 +322,7 @@ struct
    { SVG_NODE_POLYLINE, "polyline" },
    { SVG_NODE_RECT, "rect" },
    { SVG_NODE_PATH, "path" },
+   { SVG_NODE_LINE, "line" },
    { SVG_NODE_UNKNOWN, NULL }
 };
 
@@ -373,6 +390,7 @@ _evas_vg_svg_node_eet(void)
    _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();
@@ -386,6 +404,7 @@ _evas_vg_svg_node_eet(void)
    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);
@@ -420,6 +439,7 @@ _evas_vg_svg_node_eet_destroy(void)
    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);
 }
 
 
@@ -613,6 +633,11 @@ _create_vg_node(Svg_Node *node, Efl_VG *parent)
            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;
      }
index d7a845c..592109f 100644 (file)
@@ -2470,33 +2470,6 @@ eng_ector_renderer_draw(void *data, void *context, void *surface, Ector_Renderer
    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)
@@ -2553,15 +2526,35 @@ eng_ector_end(void *data EINA_UNUSED, void *context EINA_UNUSED, Ector_Surface *
      }
 }
 
+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);
      }
 }
@@ -2576,7 +2569,7 @@ _ector_surface_cache_init(void *output)
 //         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);
@@ -2589,10 +2582,11 @@ eng_ector_surface_cache_set(void *data, void *key, void *surface)
 {
    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);
@@ -2601,28 +2595,34 @@ eng_ector_surface_cache_set(void *data, void *key, void *surface)
       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
index c244bec..52e7268 100644 (file)
@@ -3894,39 +3894,39 @@ eng_ector_surface_create(void *data, void *surface, int width, int height, Eina_
 {
    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);
      }
 }
@@ -3941,7 +3941,7 @@ _ector_surface_cache_dump(void)
         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);
@@ -3954,10 +3954,11 @@ eng_ector_surface_cache_set(void *data, void *key, void *surface)
 {
    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);
@@ -3966,22 +3967,29 @@ eng_ector_surface_cache_set(void *data, void *key, void *surface)
       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;