Skip to content

Commit 4f97bdd

Browse files
committed
Workaround for quoted FuncIRIs.
Improve performance when accessing internal properties of SvgElement.
1 parent 06dd7ef commit 4f97bdd

File tree

4 files changed

+37
-33
lines changed

4 files changed

+37
-33
lines changed

SvgFileType/Extensions/SvgDocumentExtensions.cs

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33

44
using System;
55
using System.Drawing;
6-
using System.IO;
7-
using System.Text;
86
using Svg;
97
using SvgFileTypePlugin.Import;
108

@@ -38,7 +36,7 @@ public static IDisposable UseSetRasterDimensions(this SvgDocument svg, SvgImport
3836
svg.Width = rasterSize.Width;
3937
svg.Height = rasterSize.Height;
4038
svg.ViewBox = new SvgViewBox(0, 0, originalSize.Width, originalSize.Height);
41-
SvgPreserveAspectRatio aspectRatio = config.PreserveAspectRatio
39+
SvgPreserveAspectRatio aspectRatio = config.PreserveAspectRatio
4240
? SvgPreserveAspectRatio.xMinYMin
4341
: SvgPreserveAspectRatio.none;
4442
svg.AspectRatio = new SvgAspectRatio(aspectRatio);
@@ -51,23 +49,4 @@ public static IDisposable UseSetRasterDimensions(this SvgDocument svg, SvgImport
5149
svg.ViewBox = originalViewbox;
5250
});
5351
}
54-
55-
public static string GetXML2(this SvgDocument svg)
56-
{
57-
ArgumentNullException.ThrowIfNull(svg);
58-
59-
// This issue has been resolved for resvg but,
60-
// apparently, Direct2D renderer is also affected.
61-
// https://github.com/RazrFalcon/resvg/issues/235
62-
return svg.GetXML().Replace(""", string.Empty);
63-
}
64-
65-
public static Stream AsStream(this SvgDocument svg, bool removeQuotes = false)
66-
{
67-
ArgumentNullException.ThrowIfNull(svg);
68-
69-
string xml = removeQuotes ? svg.GetXML2() : svg.GetXML();
70-
byte[] bytes = Encoding.UTF8.GetBytes(xml);
71-
return new MemoryStream(bytes);
72-
}
7352
}

SvgFileType/Extensions/SvgElementExtensions.cs

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,35 @@
22
// Use of this source code is governed by GNU General Public License (GPL-2.0) that can be found in the COPYING file.
33

44
using System;
5+
using System.IO;
56
using System.Reflection;
7+
using System.Text;
68
using Svg;
79

810
namespace SvgFileTypePlugin.Extensions;
911

1012
internal static class SvgElementExtensions
1113
{
12-
private static readonly MethodInfo? ElementNameGetter = GetGetMethod("ElementName");
13-
private static readonly MethodInfo? AttributesGetter = GetGetMethod("Attributes");
14+
private delegate SvgAttributeCollection AttributesGetterDelegate(SvgElement element);
15+
private delegate string? ElementNameGetterDelegate(SvgElement element);
16+
17+
private static readonly AttributesGetterDelegate GetElementAttributes = CreateGetterDelegate<AttributesGetterDelegate>("Attributes");
18+
private static readonly ElementNameGetterDelegate GetElementName = CreateGetterDelegate<ElementNameGetterDelegate>("ElementName");
1419

1520
public static string GetName(this SvgElement element)
1621
{
1722
ArgumentNullException.ThrowIfNull(element);
1823

19-
return element.GetType().GetCustomAttribute<SvgElementAttribute>()?.ElementName
20-
?? ElementNameGetter?.Invoke(element, null) as string
24+
return element.GetType().GetCustomAttribute<SvgElementAttribute>()?.ElementName
25+
?? GetElementName(element)
2126
?? element.GetType().Name;
2227
}
2328

24-
public static SvgAttributeCollection? GetAttributes(this SvgElement element)
29+
public static SvgAttributeCollection GetAttributes(this SvgElement element)
2530
{
2631
ArgumentNullException.ThrowIfNull(element);
2732

28-
return (SvgAttributeCollection?)AttributesGetter?.Invoke(element, null);
33+
return GetElementAttributes(element);
2934
}
3035

3136
public static void RemoveInvisibleAndNonTextElements(this SvgElement element)
@@ -42,8 +47,28 @@ public static void RemoveInvisibleAndNonTextElements(this SvgElement element)
4247
}
4348
}
4449

45-
private static MethodInfo? GetGetMethod(string propertyName)
50+
public static string GetXML_QuotedFuncIRIHack(this SvgElement svg)
51+
{
52+
ArgumentNullException.ThrowIfNull(svg);
53+
54+
return svg.GetXML().Replace("&quot;", string.Empty);
55+
}
56+
57+
public static Stream GetXMLAsStream(this SvgElement svg)
58+
{
59+
ArgumentNullException.ThrowIfNull(svg);
60+
61+
string xml = svg.GetXML_QuotedFuncIRIHack();
62+
byte[] bytes = Encoding.UTF8.GetBytes(xml);
63+
return new MemoryStream(bytes);
64+
}
65+
66+
private static T CreateGetterDelegate<T>(string propertyName) where T : Delegate
4667
{
47-
return typeof(SvgElement).GetProperty(propertyName, BindingFlags.NonPublic | BindingFlags.Instance)?.GetGetMethod(true);
68+
MethodInfo getter = typeof(SvgElement)
69+
?.GetProperty(propertyName, BindingFlags.NonPublic | BindingFlags.Instance)
70+
?.GetGetMethod(true)
71+
?? throw new MissingMemberException(nameof(SvgElement), propertyName);
72+
return getter.CreateDelegate<T>();
4873
}
4974
}

SvgFileType/Import/Direct2DSvgRenderer.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ protected override Document GetFlatDocument(string svgdata, SvgImportConfig conf
4242
using IBitmap<ColorBgra32> sbitmap = surface.CreateSharedBitmap();
4343
using IBitmap<ColorPbgra32> pbitmap = sbitmap.CreatePremultipliedAdapter(PremultipliedAdapterOptions.UnPremultiplyOnDispose);
4444
using IDeviceContext dc = d2d.CreateBitmapDeviceContext(pbitmap);
45-
using Stream stream = svgdoc.AsStream(removeQuotes: true);
45+
using Stream stream = svgdoc.GetXMLAsStream();
4646
using ISvgDocument svg = dc.CreateSvgDocument(stream, viewport);
4747
using DrawingScope _1 = dc.UseBeginDraw();
4848
dc.Clear();
@@ -190,7 +190,7 @@ private void RenderSvgDocument(SvgElement element, IDeviceContext dc)
190190
else
191191
{
192192
SvgDocument clone = element.OwnerDocument.RemoveInvisibleAndNonTextElements();
193-
using Stream stream = clone.AsStream(removeQuotes: true);
193+
using Stream stream = clone.GetXMLAsStream();
194194
using ISvgDocument partial = dc.CreateSvgDocument(stream, dc.Size);
195195
using DrawingScope _ = dc.UseBeginDraw();
196196
dc.Clear();

SvgFileType/Import/ResvgSvgRenderer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ private void RenderSvgDocument(SvgElement element, Surface surface, ResvgOptions
139139
else
140140
{
141141
SvgDocument clone = element.OwnerDocument.RemoveInvisibleAndNonTextElements();
142-
using (Resvg resvg = Resvg.FromData(clone.GetXML(), options))
142+
using (Resvg resvg = Resvg.FromData(clone.GetXML_QuotedFuncIRIHack(), options))
143143
resvg.Render(surface.Scan0.Pointer, surface.Width, surface.Height);
144144
surface.ConvertFromPrgba();
145145
}

0 commit comments

Comments
 (0)