Commit 41581021 authored by Tebjan Halm's avatar Tebjan Halm
Browse files

Merge remote-tracking branch 'origin/master'

parents 79c12b63 220cac7f
......@@ -5,6 +5,7 @@ using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using Svg.DataTypes;
namespace Svg.FilterEffects
{
......@@ -17,6 +18,28 @@ namespace Svg.FilterEffects
private Bitmap sourceGraphic;
private Bitmap sourceAlpha;
/// <summary>
/// Gets or sets the position where the left point of the filter.
/// </summary>
[SvgAttribute("x")]
public SvgUnit X
{
get { return this.Attributes.GetAttribute<SvgUnit>("x"); }
set { this.Attributes["x"] = value; }
}
/// <summary>
/// Gets or sets the position where the top point of the filter.
/// </summary>
[SvgAttribute("y")]
public SvgUnit Y
{
get { return this.Attributes.GetAttribute<SvgUnit>("y"); }
set { this.Attributes["y"] = value; }
}
/// <summary>
/// Gets or sets the width of the resulting filter graphic.
/// </summary>
......@@ -37,6 +60,19 @@ namespace Svg.FilterEffects
set { this.Attributes["height"] = value; }
}
/// <summary>
/// Gets or sets the color-interpolation-filters of the resulting filter graphic.
/// NOT currently mapped through to bitmap
/// </summary>
[SvgAttribute("color-interpolation-filters")]
public SvgColourInterpolation ColorInterpolationFilters
{
get { return this.Attributes.GetAttribute<SvgColourInterpolation>("color-interpolation-filters"); }
set { this.Attributes["color-interpolation-filters"] = value; }
}
internal Dictionary<string, Func<SvgVisualElement, SvgRenderer, Bitmap>> Buffer { get; private set; }
/// <summary>
......@@ -53,7 +89,7 @@ namespace Svg.FilterEffects
/// <param name="renderer">The <see cref="SvgRenderer"/> object to render to.</param>
protected override void Render(SvgRenderer renderer)
{
// Do nothing
base.RenderChildren(renderer);
}
/// <summary>
......@@ -164,5 +200,23 @@ namespace Svg.FilterEffects
return this.sourceAlpha;
}
#endregion
public override SvgElement DeepCopy()
{
return DeepCopy<SvgFilter>();
}
public override SvgElement DeepCopy<T>()
{
var newObj = base.DeepCopy<T>() as SvgFilter;
newObj.Height = this.Height;
newObj.Width = this.Width;
newObj.X = this.X;
newObj.Y = this.Y;
newObj.ColorInterpolationFilters = this.ColorInterpolationFilters;
return newObj;
}
}
}
\ No newline at end of file
using System;
using System.Drawing;
using System.Collections.Generic;
using Svg.Filter_Effects.feColourMatrix;
namespace Svg.FilterEffects
{
/// <summary>
/// Note: this is not used in calculations to bitmap - used only to allow for svg xml output
/// </summary>
[SvgElement("feColorMatrix")]
public class SvgColourMatrix : SvgFilterPrimitive
{
/// <summary>
/// matrix | saturate | hueRotate | luminanceToAlpha
/// Indicates the type of matrix operation. The keyword 'matrix' indicates that a full 5x4 matrix of values will be provided. The other keywords represent convenience shortcuts to allow commonly used color operations to be performed without specifying a complete matrix. If attribute type is not specified, then the effect is as if a value of matrix were specified.
/// Note: this is not used in calculations to bitmap - used only to allow for svg xml output
/// </summary>
[SvgAttribute("type")]
public SvgColourMatrixType Type { get; set; }
/// <summary>
/// list of <number>s
/// The contents of values depends on the value of attribute type:
/// Note: this is not used in calculations to bitmap - used only to allow for svg xml output
/// </summary>
[SvgAttribute("values")]
public string Values { get; set; }
public override Bitmap Process()
{
return null;
}
public override SvgElement DeepCopy()
{
return DeepCopy<SvgColourMatrix>();
}
public override SvgElement DeepCopy<T>()
{
var newObj = base.DeepCopy<T>() as SvgColourMatrix;
newObj.Type = this.Type;
newObj.Values = this.Values;
return newObj;
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Svg.Filter_Effects.feColourMatrix
{
public enum SvgColourMatrixType
{
matrix,
saturate,
hueRotate,
luminanceToAlpha
}
}
......@@ -12,40 +12,43 @@ namespace Svg.FilterEffects
}
[SvgElement("feGaussianBlur")]
public class SvgGaussianBlur
public class SvgGaussianBlur : SvgFilterPrimitive
{
private int _radius;
private int _stdDeviation;
private BlurType _blurType;
private int[] _kernel;
private int _kernelSum;
private int[,] _multable;
private BlurType _blurType;
public SvgGaussianBlur()
: this(1, BlurType.Both)
{
}
public SvgGaussianBlur(int radius)
: this(radius, BlurType.Both)
public SvgGaussianBlur(int stdDeviation)
: this(stdDeviation, BlurType.Both)
{
}
public SvgGaussianBlur(int radius, BlurType blurType)
public SvgGaussianBlur(int stdDeviation, BlurType blurType) : base()
{
_radius = radius;
_stdDeviation = stdDeviation;
_blurType = blurType;
PreCalculate();
}
private void PreCalculate()
{
int sz = _radius * 2 + 1;
int sz = _stdDeviation * 2 + 1;
_kernel = new int[sz];
_multable = new int[sz, 256];
for (int i = 1; i <= _radius; i++)
for (int i = 1; i <= _stdDeviation; i++)
{
int szi = _radius - i;
int szj = _radius + i;
int szi = _stdDeviation - i;
int szj = _stdDeviation + i;
_kernel[szj] = _kernel[szi] = (szi + 1) * (szi + 1);
_kernelSum += (_kernel[szj] + _kernel[szi]);
for (int j = 0; j < 256; j++)
......@@ -53,11 +56,11 @@ namespace Svg.FilterEffects
_multable[szj, j] = _multable[szi, j] = _kernel[szj] * j;
}
}
_kernel[_radius] = (_radius + 1) * (_radius + 1);
_kernelSum += _kernel[_radius];
_kernel[_stdDeviation] = (_stdDeviation + 1) * (_stdDeviation + 1);
_kernelSum += _kernel[_stdDeviation];
for (int j = 0; j < 256; j++)
{
_multable[_radius, j] = _kernel[_radius] * j;
_multable[_stdDeviation, j] = _kernel[_stdDeviation] * j;
}
}
......@@ -101,7 +104,7 @@ namespace Svg.FilterEffects
for (int i = 0; i < pixelCount; i++)
{
bsum = gsum = rsum = asum = 0;
read = i - _radius;
read = i - _stdDeviation;
for (int z = 0; z < _kernel.Length; z++)
{
if (read < start)
......@@ -153,7 +156,7 @@ namespace Svg.FilterEffects
index = 0;
for (int i = 0; i < src.Height; i++)
{
int y = i - _radius;
int y = i - _stdDeviation;
start = y * src.Width;
for (int j = 0; j < src.Width; j++)
{
......@@ -216,20 +219,25 @@ namespace Svg.FilterEffects
}
}
public int Radius
/// <summary>
/// Gets or sets the radius of the blur (only allows for one value - not the two specified in the SVG Spec)
/// </summary>
[SvgAttribute("stdDeviation")]
public int StdDeviation
{
get { return _radius; }
get { return _stdDeviation; }
set
{
if (value < 1)
{
throw new InvalidOperationException("Radius must be greater then 0");
}
_radius = value;
_stdDeviation = value;
PreCalculate();
}
}
public BlurType BlurType
{
get { return _blurType; }
......@@ -238,5 +246,29 @@ namespace Svg.FilterEffects
_blurType = value;
}
}
public override Bitmap Process()
{
//Todo
return null;
}
public override SvgElement DeepCopy()
{
return DeepCopy<SvgGaussianBlur>();
}
public override SvgElement DeepCopy<T>()
{
var newObj = base.DeepCopy<T>() as SvgGaussianBlur;
newObj.StdDeviation = this.StdDeviation;
newObj.BlurType = this.BlurType;
return newObj;
}
}
}
\ No newline at end of file
......@@ -8,6 +8,8 @@ using System.Drawing.Imaging;
namespace Svg.FilterEffects
{
[SvgElement("feMerge")]
public class SvgMerge : SvgFilterPrimitive
{
public StringCollection MergeResults { get; private set; }
......@@ -19,6 +21,8 @@ namespace Svg.FilterEffects
public override Bitmap Process()
{
//Todo
//Bitmap merged = new Bitmap((int)this.Owner.Width.Value, (int)this.Owner.Height.Value);
//Graphics mergedGraphics = Graphics.FromImage(merged);
......@@ -34,5 +38,12 @@ namespace Svg.FilterEffects
return null;
}
public override SvgElement DeepCopy()
{
throw new NotImplementedException();
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
namespace Svg.FilterEffects
{
[SvgElement("feMergeNode")]
public class SvgMergeNode : SvgFilterPrimitive
{
public override Bitmap Process()
{
//Todo
return null;
}
public override SvgElement DeepCopy()
{
throw new NotImplementedException();
}
}
}
\ No newline at end of file
using System;
using System.Drawing;
using System.Collections.Generic;
using Svg.Filter_Effects.feColourMatrix;
namespace Svg.FilterEffects
{
/// <summary>
/// Note: this is not used in calculations to bitmap - used only to allow for svg xml output
/// </summary>
[SvgElement("feOffset")]
public class SvgOffset : SvgFilterPrimitive
{
/// <summary>
/// The amount to offset the input graphic along the x-axis. The offset amount is expressed in the coordinate system established by attribute ‘primitiveUnits’ on the ‘filter’ element.
/// If the attribute is not specified, then the effect is as if a value of 0 were specified.
/// Note: this is not used in calculations to bitmap - used only to allow for svg xml output
/// </summary>
[SvgAttribute("dx")]
public SvgUnit Dx { get; set; }
/// <summary>
/// The amount to offset the input graphic along the y-axis. The offset amount is expressed in the coordinate system established by attribute ‘primitiveUnits’ on the ‘filter’ element.
/// If the attribute is not specified, then the effect is as if a value of 0 were specified.
/// Note: this is not used in calculations to bitmap - used only to allow for svg xml output
/// </summary>
[SvgAttribute("dy")]
public string Dy { get; set; }
public override Bitmap Process()
{
return null;
}
public override SvgElement DeepCopy()
{
return DeepCopy<SvgOffset>();
}
public override SvgElement DeepCopy<T>()
{
var newObj = base.DeepCopy<T>() as SvgOffset;
newObj.Dx = this.Dx;
newObj.Dy = this.Dy;
return newObj;
}
}
}
\ No newline at end of file
......@@ -45,5 +45,21 @@ namespace Svg
// Return the hex value
return String.Format("#{0}", c.ToArgb().ToString("x").Substring(2));
}
public override SvgElement DeepCopy()
{
return DeepCopy<SvgColourServer>();
}
public override SvgElement DeepCopy<T>()
{
var newObj = base.DeepCopy<T>() as SvgColourServer;
newObj.Colour = this.Colour;
return newObj;
}
}
}
......@@ -179,5 +179,17 @@ namespace Svg
_stops.AddRange(this.InheritGradient.Stops);
}
}
public override SvgElement DeepCopy<T>()
{
var newObj = base.DeepCopy<T>() as SvgGradientServer;
newObj.SpreadMethod = this.SpreadMethod;
newObj.GradientUnits = this.GradientUnits;
newObj.InheritGradient = this.InheritGradient;
return newObj;
}
}
}
\ No newline at end of file
......@@ -71,5 +71,21 @@ namespace Svg
this._colour = colour;
this._opacity = 1.0f;
}
public override SvgElement DeepCopy()
{
return DeepCopy<SvgGradientStop>();
}
public override SvgElement DeepCopy<T>()
{
var newObj = base.DeepCopy<T>() as SvgGradientStop;
newObj.Offset = this.Offset;
newObj.Colour = this.Colour;
newObj.Opacity = this.Opacity;
return newObj;
}
}
}
\ No newline at end of file
......@@ -115,5 +115,24 @@ namespace Svg
gradient.WrapMode = WrapMode.TileFlipX;
return gradient;
}
public override SvgElement DeepCopy()
{
return DeepCopy<SvgLinearGradientServer>();
}
public override SvgElement DeepCopy<T>()
{
var newObj = base.DeepCopy<T>() as SvgLinearGradientServer;
newObj.X1 = this.X1;
newObj.Y1 = this.Y1;
newObj.X2 = this.X2;
newObj.Y2 = this.Y2;
return newObj;
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Xml;
using System.Xml.Serialization;
using System.Drawing.Drawing2D;
namespace Svg
{
[SvgElement("marker")]
public class SvgMarker : SvgVisualElement, ISvgViewPort
{
private SvgOrient _svgOrient = new SvgOrient();
[SvgAttribute("refX")]
public virtual SvgUnit RefX
{
get { return this.Attributes.GetAttribute<SvgUnit>("refX"); }
set { this.Attributes["refX"] = value; }
}
[SvgAttribute("refY")]
public virtual SvgUnit RefY
{
get { return this.Attributes.GetAttribute<SvgUnit>("refY"); }
set { this.Attributes["refY"] = value; }
}
[SvgAttribute("orient")]
public virtual SvgOrient Orient
{
get { return _svgOrient; }
set { _svgOrient = value; }
}
[SvgAttribute("overflow")]
public virtual SvgOverflow Overflow
{
get { return this.Attributes.GetAttribute<SvgOverflow>("overflow"); }
set { this.Attributes["overflow"] = value; }
}
[SvgAttribute("viewBox")]
public virtual SvgViewBox ViewBox
{
get { return this.Attributes.GetAttribute<SvgViewBox>("viewBox"); }
set { this.Attributes["viewBox"] = value; }
}
[SvgAttribute("preserveAspectRatio")]
public virtual SvgAspectRatio AspectRatio
{
get { return this.Attributes.GetAttribute<SvgAspectRatio>("preserveAspectRatio"); }
set { this.Attributes["preserveAspectRatio"] = value; }
}
public override System.Drawing.Drawing2D.GraphicsPath Path
{
get
{
var path = this.Children.FirstOrDefault(x => x is SvgPath);
if (path != null)
return (path as SvgPath).Path;
return null;
}
}
public override System.Drawing.RectangleF Bounds
{
get
{
var path = this.Path;
if (path != null)
return path.GetBounds();
return new System.Drawing.RectangleF();
}
}
//protected internal override void RenderStroke(SvgRenderer renderer)
//{
// this.PushTransforms(renderer);
// SvgElement parent = element._parent;
// element._parent = this;
// element.RenderElement(renderer);
// element._parent = parent;
// this.PopTransforms(renderer);
//}
public override SvgElement DeepCopy()
{
return DeepCopy<SvgMarker>();
}
public override SvgElement DeepCopy<T>()
{
var newObj = base.DeepCopy<T>() as SvgMarker;
newObj.RefX = this.RefX;
newObj.RefY = this.RefY;
newObj.Orient = this.Orient;
newObj.ViewBox = this.ViewBox;
newObj.Overflow = this.Overflow;
newObj.AspectRatio = this.AspectRatio;
return newObj;
}
}
}
\ No newline at end of file
......@@ -51,5 +51,8 @@ namespace Svg
{
return String.Format("url(#{0})", this.ID);
}
}
}
\ No newline at end of file
......@@ -21,6 +21,14 @@ namespace Svg
private SvgUnit _y;
private SvgViewBox _viewBox;
[SvgAttribute("overflow")]
public SvgOverflow Overflow
{
get { return this.Attributes.GetAttribute<SvgOverflow>("overflow"); }
set { this.Attributes["overflow"] = value; }
}
/// <summary>
/// Specifies a supplemental transformation which is applied on top of any
/// transformations necessary to create a new pattern coordinate system.
......@@ -149,5 +157,28 @@ namespace Svg
return textureBrush;
}
public override SvgElement DeepCopy()
{
return DeepCopy<SvgPatternServer>();
}
public override SvgElement DeepCopy<T>()
{
var newObj = base.DeepCopy<T>() as SvgPatternServer;
newObj.Overflow = this.Overflow;
newObj.ViewBox = this.ViewBox;
newObj.AspectRatio = this.AspectRatio;
newObj.X = this.X;
newObj.Y = this.Y;
newObj.Width = this.Width;
newObj.Height = this.Height;
return newObj;
}
}
}
\ No newline at end of file
......@@ -78,5 +78,24 @@ namespace Svg
return null;
}
public override SvgElement DeepCopy()
{
return DeepCopy<SvgRadialGradientServer>();
}
public override SvgElement DeepCopy<T>()
{
var newObj = base.DeepCopy<T>() as SvgRadialGradientServer;
newObj.CenterX = this.CenterX;
newObj.CenterY = this.CenterY;
newObj.Radius = this.Radius;
newObj.FocalX = this.FocalX;
newObj.FocalY = this.FocalY;
return newObj;
}
}
}
\ No newline at end of file
......@@ -46,6 +46,29 @@ namespace Svg
set { this._pathLength = value; }
}
/// <summary>
/// Gets or sets the marker (end cap) of the path.
/// </summary>
[SvgAttribute("marker-end")]
public Uri MarkerEnd
{
get { return this.Attributes.GetAttribute<Uri>("marker-end"); }
set { this.Attributes["marker-end"] = value; }
}
/// <summary>
/// Gets or sets the marker (start cap) of the path.
/// </summary>
[SvgAttribute("marker-start")]
public Uri MarkerStart
{
get { return this.Attributes.GetAttribute<Uri>("marker-start"); }
set { this.Attributes["marker-start"] = value; }
}
/// <summary>
/// Gets the <see cref="GraphicsPath"/> for this element.
/// </summary>
......@@ -98,5 +121,70 @@ namespace Svg
this._pathData = new SvgPathSegmentList();
this._pathData._owner = this;
}
/// <summary>
/// Renders the stroke of the <see cref="SvgVisualElement"/> to the specified <see cref="SvgRenderer"/>
/// </summary>
/// <param name="renderer">The <see cref="SvgRenderer"/> object to render to.</param>
protected internal override void RenderStroke(SvgRenderer renderer)
{
if (this.Stroke != null)
{
float strokeWidth = this.StrokeWidth.ToDeviceValue(this);
using (var pen = new Pen(this.Stroke.GetBrush(this, this.StrokeOpacity), strokeWidth))
{
if (this.StrokeDashArray != null && this.StrokeDashArray.Count > 0)
{
/* divide by stroke width - GDI behaviour that I don't quite understand yet.*/
pen.DashPattern = this.StrokeDashArray.ConvertAll(u => u.Value / ((strokeWidth <= 0) ? 1 : strokeWidth)).ToArray();
}
//hardcoded transformation matrix. I am not sure why this is not in proportion or rotated correctly (something to do with how the endcaps are determined in GDI)
var transMatrix = new Matrix();
transMatrix.Rotate(-90f);
transMatrix.Scale(.6f, .6f);
if (this.MarkerStart != null)
{
var marker = this.OwnerDocument.GetElementById<SvgMarker>(this.MarkerStart.ToString());
var markerPath = marker.Path.Clone() as GraphicsPath;
markerPath.Transform(transMatrix);
pen.CustomStartCap = new CustomLineCap(markerPath, null);
}
if (this.MarkerEnd != null)
{
var marker = this.OwnerDocument.GetElementById<SvgMarker>(this.MarkerEnd.ToString());
var markerPath = marker.Path.Clone() as GraphicsPath;
markerPath.Transform(transMatrix);
pen.CustomEndCap = new CustomLineCap(markerPath, null);
}
renderer.DrawPath(pen, this.Path);
}
}
}
public override SvgElement DeepCopy()
{
return DeepCopy<SvgPath>();
}
public override SvgElement DeepCopy<T>()
{
var newObj = base.DeepCopy<T>() as SvgPath;
foreach (var pathData in this.PathData)
newObj.PathData.Add(pathData.Clone());
newObj.PathLength = this.PathLength;
newObj.MarkerStart = this.MarkerStart;
newObj.MarkerEnd = this.MarkerEnd;
return newObj;
}
}
}
\ No newline at end of file
......@@ -217,7 +217,7 @@ namespace Svg
for (var i = 0; i < path.Length; i++)
{
string command;
if (char.IsLetter(path[i]))
if (char.IsLetter(path[i]) && path[i] != 'e') //e is used in scientific notiation. but not svg path
{
command = path.Substring(commandStart, i - commandStart).Trim();
commandStart = i;
......@@ -247,8 +247,9 @@ namespace Svg
private static IEnumerable<float> ParseCoordinates(string coords)
{
// TODO: Handle "1-1" (new PointF(1, -1);
var parts = coords.Remove(0, 1).Replace("-", " -").Split(new[] { ',', ' ', '\r', '\n' },
StringSplitOptions.RemoveEmptyEntries);
// var parts = coords.Remove(0, 1).Replace("-", " -").Split(new[] { ',', ' ', '\r', '\n' },StringSplitOptions.RemoveEmptyEntries);
//gareth: removed replacing '-' with ' -' - was screwing up scientific notiation
var parts = coords.Remove(0, 1).Split(new[] { ',', ' ', '\r', '\n' },StringSplitOptions.RemoveEmptyEntries);
for (var i = 0; i < parts.Length; i++)
{
......
......@@ -34,5 +34,10 @@ namespace Svg.Pathing
}
public abstract void AddToPath(GraphicsPath graphicsPath);
public SvgPathSegment Clone()
{
return this.MemberwiseClone() as SvgPathSegment;
}
}
}
......@@ -48,7 +48,7 @@
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugType>Full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\vvvv\public\common\src\thirdparty\</OutputPath>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG;REFLECTION</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
......@@ -59,7 +59,7 @@
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>PdbOnly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\..\vvvv\public\common\src\thirdparty\</OutputPath>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
......@@ -81,6 +81,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Basic Shapes\SvgImage.cs" />
<Compile Include="Basic Shapes\SvgVisualElement.cs" />
<Compile Include="Basic Shapes\SvgCircle.cs" />
<Compile Include="Basic Shapes\SvgEllipse.cs" />
......@@ -91,18 +92,28 @@
<Compile Include="Clipping and Masking\SvgClipRule.cs" />
<Compile Include="Clipping and Masking\SvgClipPath.cs" />
<Compile Include="Clipping and Masking\SvgMask.cs" />
<Compile Include="DataTypes\SvgOrient.cs" />
<Compile Include="DataTypes\ISvgViewPort.cs" />
<Compile Include="DataTypes\SvgAspectRatio.cs" />
<Compile Include="DataTypes\SvgColourInterpolation.cs" />
<Compile Include="DataTypes\SvgElementStyle.cs" />
<Compile Include="DataTypes\SvgCoordinateUnits.cs" />
<Compile Include="DataTypes\SvgFontWeight.cs" />
<Compile Include="DataTypes\SvgOverflow.cs" />
<Compile Include="DataTypes\SvgUnitCollection.cs" />
<Compile Include="DataTypes\SvgViewBox.cs" />
<Compile Include="Document Structure\SvgDocumentMetadata.cs" />
<Compile Include="Painting\SvgMarker.cs" />
<Compile Include="Document Structure\SvgDefinitionList.cs" />
<Compile Include="Document Structure\SvgDescription.cs" />
<Compile Include="Document Structure\SvgGroup.cs" />
<Compile Include="Document Structure\SvgFragment.cs" />
<Compile Include="Document Structure\SvgGroup.cs" />
<Compile Include="Document Structure\SvgUse.cs" />
<Compile Include="Filter Effects\feColourMatrix\SvgColourMatrix.cs" />
<Compile Include="Filter Effects\feColourMatrix\SvgColourMatrixType.cs" />
<Compile Include="Filter Effects\feGaussianBlur\RawBitmap.cs" />
<Compile Include="Filter Effects\feMerge\SvgMergeNode.cs" />
<Compile Include="Filter Effects\feOffset\SvgOffset.cs" />
<Compile Include="Filter Effects\ISvgFilterable.cs" />
<Compile Include="Filter Effects\SvgFilter.cs" />
<Compile Include="Filter Effects\SvgFilterPrimitive.cs" />
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
......@@ -11,7 +12,18 @@ namespace Svg
[AttributeUsage(AttributeTargets.Property)]
public class SvgAttributeAttribute : System.Attribute
{
private const string SVG_NAMESPACE = "http://www.w3.org/2000/svg";
/// <summary>
/// Gets a <see cref="string"/> containing the XLink namespace (http://www.w3.org/1999/xlink).
/// </summary>
public const string SVG_NAMESPACE = "http://www.w3.org/2000/svg";
public const string XLinkPrefix = "xlink";
public const string XLinkNamespace = "http://www.w3.org/1999/xlink";
public static readonly List<KeyValuePair<string, string>> Namespaces = new List<KeyValuePair<string, string>>()
{
new KeyValuePair<string, string>("", SVG_NAMESPACE),
new KeyValuePair<string, string>(XLinkPrefix, XLinkNamespace)
};
private string _name;
private string _namespace;
......@@ -36,6 +48,20 @@ namespace Svg
return String.Compare(indicator.Name, this.Name) == 0;
}
/// <summary>
/// Gets the name of the SVG attribute.
/// </summary>
public string NamespaceAndName
{
get
{
if (_namespace == SVG_NAMESPACE)
return _name;
return Namespaces.First(x => x.Value == _namespace).Key + ":" + _name;
}
}
/// <summary>
/// Gets the name of the SVG attribute.
/// </summary>
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment