Skip to content

Commit

Permalink
Fixes #980 - SVG: Improved USE element support & some fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
daniel-luberda committed May 29, 2018
1 parent 96f998a commit 53072d6
Showing 1 changed file with 44 additions and 38 deletions.
82 changes: 44 additions & 38 deletions source/FFImageLoading.Svg.Shared/SkSvg.cs
Original file line number Diff line number Diff line change
Expand Up @@ -331,9 +331,25 @@ private void ReadElement(XElement e, SKCanvas canvas, SKPaint stroke, SKPaint fi
var elementPath = ReadElement(e);
if (elementPath == null)
break;


if (mask != null)
{
canvas.SaveLayer(new SKPaint());
foreach (var gElement in mask.Element.Elements())
{
ReadElement(gElement, canvas, mask.Fill.Clone(), mask.Fill.Clone());
}
using (var paint = fill.Clone())
{
paint.BlendMode = SKBlendMode.SrcIn;
canvas.DrawPath(elementPath, paint);
}
canvas.Restore();
return;
}

string fillId = e.Attribute("fill")?.Value;
object addFill = null;
object addFill = null;
if (!string.IsNullOrWhiteSpace(fillId) && fills.TryGetValue(fillId, out addFill))
{
var x = ReadNumber(e.Attribute("x"));
Expand Down Expand Up @@ -405,28 +421,11 @@ private void ReadElement(XElement e, SKCanvas canvas, SKPaint stroke, SKPaint fi
gradientPaint.TryDispose();
}
}
else if (fill != null)
canvas.DrawPath(elementPath, fill);
if (stroke != null)
canvas.DrawPath(elementPath, stroke);

if (mask != null)
{
canvas.SaveLayer(new SKPaint());
foreach (var gElement in mask.Element.Elements())
{
ReadElement(gElement, canvas, mask.Fill.Clone(), mask.Fill.Clone());
}
using (var paint = fill.Clone())
{
paint.BlendMode = SKBlendMode.SrcIn;
canvas.DrawPath(elementPath, paint);
}
canvas.Restore();
}
else
{
if (fill != null)
canvas.DrawPath(elementPath, fill);
if (stroke != null)
canvas.DrawPath(elementPath, stroke);
}
break;
}
case "g":
Expand Down Expand Up @@ -478,18 +477,22 @@ private void ReadElement(XElement e, SKCanvas canvas, SKPaint stroke, SKPaint fi
var href = ReadHref(e);
if (href != null)
{
// TODO: copy/process other attributes

var x = ReadNumber(e.Attribute("x"));
var y = ReadNumber(e.Attribute("y"));
var useTransform = SKMatrix.MakeTranslation(x, y);
// create a deep copy as we will copy attributes
href = new XElement(href);
var attributes = e.Attributes();
foreach (var attribute in attributes)
{
var name = attribute.Name.LocalName;

canvas.Save();
canvas.Concat(ref useTransform);
if (!name.Contains("href", StringComparison.OrdinalIgnoreCase)
&& !name.Equals("id", StringComparison.OrdinalIgnoreCase)
&& !name.Equals("transform", StringComparison.OrdinalIgnoreCase))
{
href.SetAttributeValue(attribute.Name, attribute.Value);
}
}

ReadElement(href, canvas, stroke?.Clone(), fill?.Clone());

canvas.Restore();
}
}
break;
Expand Down Expand Up @@ -1140,19 +1143,18 @@ private void ReadPaints(Dictionary<string, string> style, ref SKPaint strokePain
var urlM = urlRe.Match(fill);
if (urlM.Success)
{
var id = urlM.Groups[1].Value.Trim();

var id = urlM.Groups[1].Value.Trim();
if (defs.TryGetValue(id, out XElement defE))
{
switch (defE.Name.LocalName)
switch (defE.Name.LocalName.ToLower())
{
case "linearGradient":
case "lineargradient":
fillPaint.Color = SKColors.Transparent;
if (!fills.ContainsKey(fill))
fills.Add(fill, ReadLinearGradient(defE));
read = true;
break;
case "radialGradient":
case "radialgradient":
fillPaint.Color = SKColors.Transparent;
if (!fills.ContainsKey(fill))
fills.Add(fill, ReadRadialGradient(defE));
Expand Down Expand Up @@ -1197,7 +1199,6 @@ private SKPaint CreatePaint(bool stroke = false)
{
IsAntialias = true,
IsStroke = stroke,
Color = SKColors.Black
};

if (stroke)
Expand All @@ -1206,6 +1207,11 @@ private SKPaint CreatePaint(bool stroke = false)
strokePaint.StrokeMiter = 4f;
strokePaint.StrokeJoin = SKStrokeJoin.Miter;
strokePaint.StrokeCap = SKStrokeCap.Butt;
strokePaint.Color = SKColors.Transparent;
}
else
{
strokePaint.Color = SKColors.Black;
}

return strokePaint;
Expand Down

0 comments on commit 53072d6

Please sign in to comment.