vg_load_svg: Support dasharray attribute for stroke

Summary:
It supports stroke-dasharray, one of the stroke properties of svg.
https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dasharray

Test Plan:
[Test SVG]
<svg viewBox="0 0 30 10" xmlns="http://www.w3.org/2000/svg">
  <!-- No dashes nor gaps -->
  <line x1="0" y1="1" x2="30" y2="1" stroke="black" />

  <!-- Dashes and gaps of the same size -->
  <line x1="0" y1="3" x2="30" y2="3" stroke="black"
          stroke-dasharray="4" />

  <!-- Dashes and gaps of different sizes -->
  <line x1="0" y1="5" x2="30" y2="5" stroke="black"
          stroke-dasharray="4 1" />

  <!-- Dashes and gaps of various sizes with an odd number of values -->
  <line x1="0" y1="7" x2="30" y2="7" stroke="black"
          stroke-dasharray="4 1 2" />

  <!-- Dashes and gaps of various sizes with an even number of values -->
  <line x1="0" y1="9" x2="30" y2="9" stroke="black"
          stroke-dasharray="4 1 2 3" />
</svg>

Reviewers: Hermet, smohanty

Reviewed By: Hermet

Subscribers: kimcinoo, herb, cedric, #committers, #reviewers

Tags: #efl

Differential Revision: https://phab.enlightenment.org/D12146
This commit is contained in:
junsu choi 2020-09-15 12:11:49 +09:00 committed by Hermet Park
parent c412406487
commit 35f17a13fa
2 changed files with 32 additions and 5 deletions

View File

@ -259,8 +259,6 @@ static struct {
_PARSE_TAG(Efl_Gfx_Fill_Rule, fill_rule, fill_rule_tags, EFL_GFX_FILL_RULE_WINDING);
#if 0
// unused at the moment
/* parse the dash pattern used during stroking a path.
* Value: none | <dasharray> | inherit
* Initial: none
@ -269,7 +267,8 @@ _PARSE_TAG(Efl_Gfx_Fill_Rule, fill_rule, fill_rule_tags, EFL_GFX_FILL_RULE_WINDI
static inline void
_parse_dash_array(const char *str, Efl_Gfx_Dash** dash, int *length)
{
double tmp[30];
// It is assumed that the length of the dasharray string is 255 or less.
double tmp[255];
char *end = NULL;
int leni, gapi, count = 0, index = 0;
@ -291,20 +290,21 @@ _parse_dash_array(const char *str, Efl_Gfx_Dash** dash, int *length)
gapi = (2 * index + 1) % count;
(*dash)[index].length = tmp[leni];
(*dash)[index].gap = tmp[gapi];
index++;
}
}
else
{ // even case
*length = count/2;
*dash = calloc(*length, sizeof(Efl_Gfx_Dash));
while (index < count)
while (index < *length)
{
(*dash)[index].length = tmp[2 * index];
(*dash)[index].gap = tmp[2 * index + 1];
index++;
}
}
}
#endif
static Eina_Stringshare *
_id_from_url(const char *url)
@ -864,6 +864,13 @@ _handle_stroke_opacity_attr(Evas_SVG_Loader *loader EINA_UNUSED, Svg_Node* node,
node->style->stroke.opacity = _to_opacity(value);
}
static void
_handle_stroke_dasharray_attr(Evas_SVG_Loader *loader EINA_UNUSED, Svg_Node* node, const char *value)
{
node->style->stroke.flags |= SVG_STROKE_FLAGS_DASH;
_parse_dash_array(value, &node->style->stroke.dash, &node->style->stroke.dash_count);
}
static void
_handle_stroke_width_attr(Evas_SVG_Loader *loader, Svg_Node* node, const char *value)
{
@ -942,6 +949,7 @@ static const struct {
STYLE_DEF(stroke-linejoin, stroke_linejoin),
STYLE_DEF(stroke-linecap, stroke_linecap),
STYLE_DEF(stroke-opacity, stroke_opacity),
STYLE_DEF(stroke-dasharray, stroke_dasharray),
STYLE_DEF(transform, transform),
STYLE_DEF(display, display)
};
@ -2367,6 +2375,22 @@ _inherit_style(Svg_Style_Property *child, Svg_Style_Property *parent)
{
child->stroke.join = parent->stroke.join;
}
if (!(child->stroke.flags & SVG_STROKE_FLAGS_DASH))
{
int i = 0;
int count = parent->stroke.dash_count;
if (count > 0)
{
if (child->stroke.dash) free(child->stroke.dash);
child->stroke.dash = calloc(count, sizeof(Efl_Gfx_Dash));
child->stroke.dash_count = count;
for (i = 0; i < count; i++)
{
child->stroke.dash[i].length = parent->stroke.dash[i].length;
child->stroke.dash[i].gap = parent->stroke.dash[i].gap;
}
}
}
}
void

View File

@ -498,6 +498,7 @@ _node_style_free(Svg_Style_Property *style)
eina_stringshare_del(style->fill.paint.url);
_svg_style_gradient_free(style->stroke.paint.gradient);
eina_stringshare_del(style->stroke.paint.url);
if (style->stroke.dash) free(style->stroke.dash);
free(style);
}
@ -770,6 +771,8 @@ _apply_vg_property(Svg_Node *node, Efl_VG *vg, Efl_VG *parent, Vg_File_Data *vg_
efl_gfx_shape_stroke_cap_set(vg, style->stroke.cap);
efl_gfx_shape_stroke_join_set(vg, style->stroke.join);
efl_gfx_shape_stroke_scale_set(vg, style->stroke.scale);
if (style->stroke.dash && style->stroke.dash_count > 0)
efl_gfx_shape_stroke_dash_set(vg, style->stroke.dash, style->stroke.dash_count);
// if stroke property is NULL then do nothing
if (style->stroke.paint.none)