static inline char *
_copy_id(const char* str)
{
+ if (str == NULL) return NULL;
+
return strdup(str);
}
_handle_fill_attr(Svg_Node* node, const char *value)
{
Svg_Style_Property *style = node->style;
+ style->fill.flags |= SVG_FILL_FLAGS_PAINT;
_handle_paint_attr(&style->fill.paint, value);
}
_handle_stroke_attr(Svg_Node* node, const char *value)
{
Svg_Style_Property *style = node->style;
+ style->stroke.flags |= SVG_STROKE_FLAGS_PAINT;
_handle_paint_attr(&style->stroke.paint, value);
}
static void
_handle_stroke_opacity_attr(Svg_Node* node, const char *value)
{
+ node->style->stroke.flags |= SVG_STROKE_FLAGS_OPACITY;
node->style->stroke.opacity = _to_opacity(value);
}
static void
_handle_stroke_width_attr(Svg_Node* node, const char *value)
{
+ node->style->stroke.flags |= SVG_STROKE_FLAGS_WIDTH;
node->style->stroke.width = _to_double(value);
}
static void
_handle_stroke_linecap_attr(Svg_Node* node, const char *value)
{
+ node->style->stroke.flags |= SVG_STROKE_FLAGS_CAP;
node->style->stroke.cap = _to_line_cap(value);
}
static void
_handle_stroke_linejoin_attr(Svg_Node* node, const char *value)
{
+ node->style->stroke.flags |= SVG_STROKE_FLAGS_JOIN;
node->style->stroke.join = _to_line_join(value);
}
static void
_handle_fill_rule_attr(Svg_Node* node, const char *value)
{
+ node->style->fill.flags |= SVG_FILL_FLAGS_FILL_RULE;
node->style->fill.fill_rule = _to_fill_rule(value);
}
static void
_handle_fill_opacity_attr(Svg_Node* node, const char *value)
{
+ node->style->fill.flags |= SVG_FILL_FLAGS_OPACITY;
node->style->fill.opacity = _to_opacity(value);
}
{
node->id = _copy_id(value);
}
+ else
+ {
+ _parse_style_attr(node, key, value);
+ }
return EINA_TRUE;
}
return EINA_TRUE;
}
+static void
+_inherit_style(Svg_Style_Property *child, Svg_Style_Property *parent)
+{
+ if (parent == NULL)
+ return;
+ // inherit the property of parent if not present in child.
+ // fill
+ if (!(child->fill.flags & SVG_FILL_FLAGS_PAINT))
+ {
+ child->fill.paint.r = parent->fill.paint.r;
+ child->fill.paint.g = parent->fill.paint.g;
+ child->fill.paint.b = parent->fill.paint.b;
+ child->fill.paint.none = parent->fill.paint.none;
+ child->fill.paint.cur_color = parent->fill.paint.cur_color;
+ child->fill.paint.url = _copy_id(parent->fill.paint.url);
+ }
+ if (!(child->fill.flags & SVG_FILL_FLAGS_OPACITY))
+ {
+ child->fill.opacity = parent->fill.opacity;
+ }
+ if (!(child->fill.flags & SVG_FILL_FLAGS_FILL_RULE))
+ {
+ child->fill.fill_rule = parent->fill.fill_rule;
+ }
+ // stroke
+ if (!(child->stroke.flags & SVG_STROKE_FLAGS_PAINT))
+ {
+ child->stroke.paint.r = parent->stroke.paint.r;
+ child->stroke.paint.g = parent->stroke.paint.g;
+ child->stroke.paint.b = parent->stroke.paint.b;
+ child->stroke.paint.none = parent->stroke.paint.none;
+ child->stroke.paint.cur_color = parent->stroke.paint.cur_color;
+ child->stroke.paint.url = _copy_id(parent->stroke.paint.url);
+ }
+ if (!(child->stroke.flags & SVG_STROKE_FLAGS_OPACITY))
+ {
+ child->stroke.opacity = parent->stroke.opacity;
+ }
+ if (!(child->stroke.flags & SVG_STROKE_FLAGS_WIDTH))
+ {
+ child->stroke.width = parent->stroke.width;
+ }
+ if (!(child->stroke.flags & SVG_STROKE_FLAGS_CAP))
+ {
+ child->stroke.cap = parent->stroke.cap;
+ }
+ if (!(child->stroke.flags & SVG_STROKE_FLAGS_JOIN))
+ {
+ child->stroke.join = parent->stroke.join;
+ }
+}
+
+void
+_update_style(Svg_Node *node, Svg_Style_Property *parent_style)
+{
+ Eina_List *l;
+ Svg_Node *child;
+
+ _inherit_style(node->style, parent_style);
+
+ EINA_LIST_FOREACH(node->child, l, child)
+ {
+ _update_style(child, node->style);
+ }
+}
+
EAPI Svg_Node *
_svg_load(Eina_File *f, const char *key EINA_UNUSED)
{
eina_array_free(loader.stack);
eina_file_map_free(f, (void*) content);
}
+
+ if (loader.doc)
+ _update_style(loader.doc, NULL);
+
return loader.doc;
}
EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "g", g, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "b", b, EET_T_INT);
// for fill
+ EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "fill.flags", fill.flags, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_SUB(eet, Svg_Style_Property, "fill.gradient", fill.gradient, eet_gradient);
EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "fill.paint.r", fill.paint.r, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "fill.paint.g", fill.paint.g, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "fill.fill_rule", fill.fill_rule, EET_T_INT);
// for stroke
+ EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "stroke.flags", stroke.flags, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_SUB(eet, Svg_Style_Property, "stroke.gradient", stroke.gradient, eet_gradient);
EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "stroke.paint.r", stroke.paint.r, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "stroke.paint.g", stroke.paint.g, EET_T_INT);
typedef struct _Svg_Path_Node Svg_Path_Node;
typedef struct _Svg_Style_Property Svg_Style_Property;
-typedef struct _Svg_Style_Stroke Svg_Style_Stroke;
-typedef struct _Svg_Style_Fill Svg_Style_Fill;
+typedef struct _Svg_Style_Stroke Svg_Style_Stroke;
+typedef struct _Svg_Style_Fill Svg_Style_Fill;
+typedef enum _Svg_Fill_Flags Svg_Fill_Flags;
+typedef enum _Svg_Stroke_Flags Svg_Stroke_Flags;
+
typedef enum _Svg_Gradient_Type Svg_Gradient_Type;
typedef struct _Svg_Style_Gradient Svg_Style_Gradient;
char *url;
};
+enum _Svg_Fill_Flags
+{
+ SVG_FILL_FLAGS_PAINT = 0x1,
+ SVG_FILL_FLAGS_OPACITY = 0x2,
+ SVG_FILL_FLAGS_GRADIENT = 0x4,
+ SVG_FILL_FLAGS_FILL_RULE = 0x8
+};
+
+enum _Svg_Stroke_Flags
+{
+ SVG_STROKE_FLAGS_PAINT = 0x1,
+ SVG_STROKE_FLAGS_OPACITY = 0x2,
+ SVG_STROKE_FLAGS_GRADIENT = 0x4,
+ SVG_STROKE_FLAGS_SCALE = 0x8,
+ SVG_STROKE_FLAGS_WIDTH = 0x10,
+ SVG_STROKE_FLAGS_CAP = 0x20,
+ SVG_STROKE_FLAGS_JOIN = 0x40,
+ SVG_STROKE_FLAGS_DASH = 0x80,
+};
+
struct _Svg_Style_Fill
{
+ Svg_Fill_Flags flags;
Svg_Paint paint;
int opacity;
Svg_Style_Gradient *gradient;
struct _Svg_Style_Stroke
{
+ Svg_Stroke_Flags flags;
Svg_Paint paint;
int opacity;
Svg_Style_Gradient *gradient;