Commit c88ad05d authored by davescriven's avatar davescriven
Browse files

All current source code

parent 01b73c95
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Xml;
using System.Web.UI.WebControls;
using System.ComponentModel;
namespace Svg
{
/// <summary>
/// An SVG element to render circles to the document.
/// </summary>
public class SvgCircle : SvgGraphicsElement
{
private GraphicsPath _path;
private SvgUnit _cx;
private SvgUnit _cy;
private SvgUnit _radius;
/// <summary>
/// Gets the center point of the circle.
/// </summary>
/// <value>The center.</value>
public SvgPoint Center
{
get { return new SvgPoint(this.CenterX, this.CenterY); }
}
/// <summary>
/// Gets or sets the center X co-ordinate.
/// </summary>
/// <value>The center X.</value>
[SvgAttribute("cx")]
public SvgUnit CenterX
{
get { return this._cx; }
set
{
this._cx = value;
this.IsPathDirty = true;
}
}
/// <summary>
/// Gets or sets the center Y co-ordinate.
/// </summary>
/// <value>The center Y.</value>
[SvgAttribute("cy")]
public SvgUnit CenterY
{
get { return this._cy; }
set
{
this._cy = value;
this.IsPathDirty = true;
}
}
/// <summary>
/// Gets or sets the radius of the circle.
/// </summary>
/// <value>The radius.</value>
[SvgAttribute("r")]
public SvgUnit Radius
{
get { return this._radius; }
set
{
this._radius = value;
this.IsPathDirty = true;
}
}
/// <summary>
/// Gets the name of the element.
/// </summary>
/// <value></value>
protected override string ElementName
{
get { return "circle"; }
}
/// <summary>
/// Gets the bounds of the circle.
/// </summary>
/// <value>The bounds.</value>
public override RectangleF Bounds
{
get { return this.Path.GetBounds(); }
}
/// <summary>
/// Gets a value indicating whether the circle requires anti-aliasing when being rendered.
/// </summary>
/// <value>
/// <c>true</c> if the circle requires anti-aliasing; otherwise, <c>false</c>.
/// </value>
protected override bool RequiresSmoothRendering
{
get { return true; }
}
public override GraphicsPath Path
{
get
{
if (this._path == null || this.IsPathDirty)
{
_path = new GraphicsPath();
_path.StartFigure();
_path.AddEllipse(this.Center.ToDeviceValue().X - this.Radius.ToDeviceValue(), this.Center.ToDeviceValue().Y - this.Radius.ToDeviceValue(), 2 * this.Radius.ToDeviceValue(), 2 * this.Radius.ToDeviceValue());
_path.CloseFigure();
this.IsPathDirty = false;
}
return _path;
}
}
/// <summary>
/// Renders the circle to the specified <see cref="Graphics"/> object.
/// </summary>
/// <param name="graphics">The graphics object.</param>
protected override void Render(Graphics graphics)
{
// Don't draw if there is no radius set
if (this.Radius.Value > 0.0f)
{
base.Render(graphics);
}
}
/// <summary>
/// Initializes a new instance of the <see cref="SvgCircle"/> class.
/// </summary>
public SvgCircle()
{
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Xml;
using System.ComponentModel;
namespace Svg
{
public class SvgEllipse : SvgGraphicsElement
{
private SvgUnit _radiusX;
private SvgUnit _radiusY;
private SvgUnit _centerX;
private SvgUnit _centerY;
private GraphicsPath _path;
[SvgAttribute("cx")]
public virtual SvgUnit CenterX
{
get { return this._centerX; }
set
{
this._centerX = value;
this.IsPathDirty = true;
}
}
[SvgAttribute("cy")]
public virtual SvgUnit CenterY
{
get { return this._centerY; }
set
{
this._centerY = value;
this.IsPathDirty = true;
}
}
[SvgAttribute("rx")]
public virtual SvgUnit RadiusX
{
get { return this._radiusX; }
set { this._radiusX = value; this.IsPathDirty = true; }
}
[SvgAttribute("ry")]
public virtual SvgUnit RadiusY
{
get { return this._radiusY; }
set { this._radiusY = value; this.IsPathDirty = true; }
}
/// <summary>
/// Gets or sets a value to determine if anti-aliasing should occur when the element is being rendered.
/// </summary>
/// <value></value>
protected override bool RequiresSmoothRendering
{
get { return true; }
}
/// <summary>
/// Gets the bounds of the element.
/// </summary>
/// <value>The bounds.</value>
public override RectangleF Bounds
{
get { return this.Path.GetBounds(); }
}
/// <summary>
/// Gets the <see cref="GraphicsPath"/> for this element.
/// </summary>
/// <value></value>
public override GraphicsPath Path
{
get
{
if (this._path == null || this.IsPathDirty)
{
PointF center = new PointF(this._centerX.ToDeviceValue(this), this._centerY.ToDeviceValue(this, true));
PointF radius = new PointF(this._radiusX.ToDeviceValue(this), this._radiusY.ToDeviceValue(this, true));
this._path = new GraphicsPath();
_path.StartFigure();
_path.AddEllipse(center.X - radius.X, center.Y - radius.Y, 2 * radius.X, 2 * radius.Y);
_path.CloseFigure();
this.IsPathDirty = false;
}
return _path;
}
}
/// <summary>
/// Renders the <see cref="SvgElement"/> and contents to the specified <see cref="Graphics"/> object.
/// </summary>
/// <param name="graphics">The <see cref="Graphics"/> object to render to.</param>
protected override void Render(Graphics graphics)
{
if (this._radiusX.Value > 0.0f && this._radiusY.Value > 0.0f)
{
base.Render(graphics);
}
}
/// <summary>
/// Initializes a new instance of the <see cref="SvgEllipse"/> class.
/// </summary>
public SvgEllipse()
{
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Xml.Serialization;
using System.ComponentModel;
using System.Diagnostics;
namespace Svg
{
/// <summary>
/// The class that all SVG elements should derive from when they are to be rendered.
/// </summary>
public abstract partial class SvgGraphicsElement : SvgElement, ISvgStylable
{
private bool _dirty;
private bool _requiresSmoothRendering;
/// <summary>
/// Gets the <see cref="GraphicsPath"/> for this element.
/// </summary>
public abstract GraphicsPath Path { get; }
/// <summary>
/// Gets the bounds of the element.
/// </summary>
/// <value>The bounds.</value>
public abstract RectangleF Bounds { get; }
/// <summary>
/// Gets or sets a value indicating whether this element's <see cref="Path"/> is dirty.
/// </summary>
/// <value>
/// <c>true</c> if the path is dirty; otherwise, <c>false</c>.
/// </value>
protected virtual bool IsPathDirty
{
get { return this._dirty; }
set { this._dirty = value; }
}
/// <summary>
/// Gets or sets a value to determine if anti-aliasing should occur when the element is being rendered.
/// </summary>
protected virtual bool RequiresSmoothRendering
{
get { return this._requiresSmoothRendering; }
}
/// <summary>
/// Initializes a new instance of the <see cref="SvgGraphicsElement"/> class.
/// </summary>
public SvgGraphicsElement()
{
this._dirty = true;
this._requiresSmoothRendering = false;
}
/// <summary>
/// Renders the <see cref="SvgElement"/> and contents to the specified <see cref="Graphics"/> object.
/// </summary>
/// <param name="graphics">The <see cref="Graphics"/> object to render to.</param>
protected override void Render(Graphics graphics)
{
if (this.Path != null && this.Visible)
{
this.PushTransforms(graphics);
// If this element needs smoothing enabled turn anti aliasing on
if (this.RequiresSmoothRendering)
{
graphics.SmoothingMode = SmoothingMode.AntiAlias;
}
// Fill first so that the stroke can overlay
if (!SvgPaintServer.IsNullOrEmpty(this.Fill))
{
using (Brush brush = this.Fill.GetBrush(this, this.FillOpacity))
{
if (brush != null)
{
graphics.FillPath(brush, this.Path);
}
}
}
// Stroke is the last thing to do
if (!SvgPaintServer.IsNullOrEmpty(this.Stroke))
{
float strokeWidth = this.StrokeWidth.ToDeviceValue(this);
using (Pen pen = new Pen(this.Stroke.GetBrush(this, this.StrokeOpacity), strokeWidth))
{
if (pen != null)
{
graphics.DrawPath(pen, this.Path);
}
}
}
// Reset the smoothing mode
if (this.RequiresSmoothRendering && graphics.SmoothingMode == SmoothingMode.AntiAlias)
{
graphics.SmoothingMode = SmoothingMode.Default;
}
this.PopTransforms(graphics);
}
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Text;
namespace Svg
{
public abstract partial class SvgGraphicsElement
{
private static readonly object _mouseOverKey = new object();
private static readonly object _mouseOutKey = new object();
private static readonly object _focusKey = new object();
private static readonly object _activeKey = new object();
private static readonly object _clickKey = new object();
public event EventHandler MouseOver
{
add { this.Events.AddHandler(_mouseOverKey, value); }
remove { this.Events.RemoveHandler(_mouseOverKey, value); }
}
public event EventHandler MouseOut
{
add { this.Events.AddHandler(_mouseOutKey, value); }
remove { this.Events.RemoveHandler(_mouseOutKey, value); }
}
public event EventHandler Focus
{
add { this.Events.AddHandler(_focusKey, value); }
remove { this.Events.RemoveHandler(_focusKey, value); }
}
public event EventHandler Active
{
add { this.Events.AddHandler(_activeKey, value); }
remove { this.Events.RemoveHandler(_activeKey, value); }
}
public event EventHandler Click
{
add { this.Events.AddHandler(_clickKey, value); }
remove { this.Events.RemoveHandler(_clickKey, value); }
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.ComponentModel;
namespace Svg
{
public abstract partial class SvgGraphicsElement
{
private static float FixOpacityValue(float value)
{
const float max = 1.0f;
const float min = 0.0f;
return Math.Min(Math.Max(value, min), max);
}
/// <summary>
/// Gets or sets a value to determine whether the element will be rendered.
/// </summary>
[SvgAttribute("visibility")]
public virtual bool Visible
{
get { return (this.Attributes["Visible"] == null) ? true : (bool)this.Attributes["Visible"]; }
set { this.Attributes["Visible"] = value; }
}
[SvgAttribute("fill")]
public virtual SvgPaintServer Fill
{
get { return (this.Attributes["Fill"] == null) ? SvgPaintServer.None : (SvgPaintServer)this.Attributes["Fill"]; }
set { this.Attributes["Fill"] = value; }
}
[SvgAttribute("stroke")]
public virtual SvgPaintServer Stroke
{
get { return (this.Attributes["Stroke"] == null) ? SvgPaintServer.None : (SvgPaintServer)this.Attributes["Stroke"]; }
set { this.Attributes["Stroke"] = value; }
}
[SvgAttribute("fill-rule")]
public virtual SvgFillRule FillRule
{
get { return (this.Attributes["FillRule"] == null) ? SvgFillRule.NonZero : (SvgFillRule)this.Attributes["FillRule"]; }
set { this.Attributes["FillRule"] = value; }
}
[SvgAttribute("fill-opacity")]
public virtual float FillOpacity
{
get { return (this.Attributes["FillOpacity"] == null) ? this.Opacity : (float)this.Attributes["FillOpacity"]; }
set { this.Attributes["FillOpacity"] = FixOpacityValue(value); }
}
[SvgAttribute("stroke-width")]
public virtual SvgUnit StrokeWidth
{
get { return (this.Attributes["StrokeWidth"] == null) ? new SvgUnit(1.0f) : (SvgUnit)this.Attributes["StrokeWidth"]; }
set { this.Attributes["StrokeWidth"] = value; }
}
[SvgAttribute("stroke-linecap")]
public virtual SvgStrokeLineCap StrokeLineCap
{
get { return (this.Attributes["StrokeLineCap"] == null) ? SvgStrokeLineCap.Butt : (SvgStrokeLineCap)this.Attributes["StrokeLineCap"]; }
set { this.Attributes["StrokeLineCap"] = value; }
}
[SvgAttribute("stroke-linejoin")]
public virtual SvgStrokeLineJoin StrokeLineJoin
{
get { return (this.Attributes["StrokeLineJoin"] == null) ? SvgStrokeLineJoin.Miter : (SvgStrokeLineJoin)this.Attributes["StrokeLineJoin"]; }
set { this.Attributes["StrokeLineJoin"] = value; }
}
[SvgAttribute("stroke-miterlimit")]
public virtual float StrokeMiterLimit
{
get { return (this.Attributes["StrokeMiterLimit"] == null) ? 4.0f : (float)this.Attributes["StrokeMiterLimit"]; }
set { this.Attributes["StrokeMiterLimit"] = value; }
}
[SvgAttribute("stroke-dasharray")]
public virtual SvgUnit[] StrokeDashArray
{
get { return (this.Attributes["StrokeDashArray"] == null) ? null : (SvgUnit[])this.Attributes["StrokeDashArray"]; }
set { this.Attributes["StrokeDashArray"] = value; }
}
[SvgAttribute("stroke-dashoffset")]
public virtual SvgUnit StrokeDashOffset
{
get { return (this.Attributes["StrokeDashOffset"] == null) ? SvgUnit.Empty : (SvgUnit)this.Attributes["StrokeDashOffset"]; }
set { this.Attributes["StrokeDashOffset"] = value; }
}
[SvgAttribute("stroke-opacity")]
public virtual float StrokeOpacity
{
get { return (this.Attributes["StrokeOpacity"] == null) ? this.Opacity : (float)this.Attributes["StrokeOpacity"]; }
set { this.Attributes["StrokeOpacity"] = FixOpacityValue(value); }
}
/// <summary>
/// Gets or sets the opacity of the element. 1.0 is fully opaque; 0.0 is transparent.
/// </summary>
[SvgAttribute("opacity")]
public virtual float Opacity
{
get { return (this.Attributes["Opacity"] == null) ? 1.0f : (float)this.Attributes["Opacity"]; }
set { this.Attributes["Opacity"] = FixOpacityValue(value); }
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace Svg
{
public class SvgLine : SvgGraphicsElement
{
private SvgUnit _startX;
private SvgUnit _startY;
private SvgUnit _endX;
private SvgUnit _endY;
private GraphicsPath _path;
[SvgAttribute("x1")]
public SvgUnit StartX
{
get { return this._startX; }
set { this._startX = value; this.IsPathDirty = true; }
}
[SvgAttribute("y1")]
public SvgUnit StartY
{
get { return this._startY; }
set { this._startY = value; this.IsPathDirty = true; }
}
[SvgAttribute("x2")]
public SvgUnit EndX
{
get { return this._endX; }
set { this._endX = value; this.IsPathDirty = true; }
}
[SvgAttribute("y2")]
public SvgUnit EndY
{
get { return this._endY; }
set { this._endY = value; this.IsPathDirty = true; }
}
public override SvgPaintServer Fill
{
get { return null; /* Line can't have a fill */ }
set
{
// Do nothing
}
}
public SvgLine()
{
}
public override System.Drawing.Drawing2D.GraphicsPath Path
{
get
{
if (this._path == null || this.IsPathDirty)
{
PointF start = new PointF(this.StartX.ToDeviceValue(this), this.StartY.ToDeviceValue(this, true));
PointF end = new PointF(this.EndX.ToDeviceValue(this), this.EndY.ToDeviceValue(this, true));
this._path = new GraphicsPath();
this._path.AddLine(start, end);
this.IsPathDirty = false;
}
return this._path;
}
}
public override System.Drawing.RectangleF Bounds
{
get { return this.Path.GetBounds(); }
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Diagnostics;
using Svg.Pathing;
namespace Svg
{
/// <summary>
/// SvgPolygon defines a closed shape consisting of a set of connected straight line segments.
/// </summary>
public class SvgPolygon : SvgGraphicsElement
{
protected GraphicsPath _path;
protected SvgUnitCollection _points;
/// <summary>
/// The points that make up the SvgPolygon
/// </summary>
[SvgAttribute("points")]
public SvgUnitCollection Points
{
get { return this._points; }
set { this._points = value; this.IsPathDirty = true; }
}
protected override bool RequiresSmoothRendering
{
get { return true; }
}
public override GraphicsPath Path
{
get
{
if (this._path == null || this.IsPathDirty)
{
this._path = new GraphicsPath();
this._path.StartFigure();
try
{
for (int i = 0; i < this._points.Count; i+=2)
{
PointF endPoint = new PointF(this._points[i].ToDeviceValue(this), this._points[i+1].ToDeviceValue(this));
// TODO: Remove unrequired first line
if (_path.PointCount == 0)
{
_path.AddLine(endPoint, endPoint);
}
else
{
_path.AddLine(_path.GetLastPoint(), endPoint);
}
}
}
catch
{
Trace.TraceError("Error parsing points");
}
this._path.CloseFigure();
this.IsPathDirty = false;
}
return this._path;
}
}
public override RectangleF Bounds
{
get { return this.Path.GetBounds(); }
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Diagnostics;
namespace Svg
{
/// <summary>
/// SvgPolyline defines a set of connected straight line segments. Typically, SvgPolyline defines open shapes.
/// </summary>
public class SvgPolyline : SvgPolygon
{
public override SvgPaintServer Fill
{
get { return null; /* Line can't have a fill */ }
set
{
// Do nothing
}
}
public override GraphicsPath Path
{
get
{
if (this._path == null || this.IsPathDirty)
{
this._path = new GraphicsPath();
try
{
for (int i = 0; i < this._points.Count; i += 2)
{
PointF endPoint = new PointF(this._points[i].ToDeviceValue(this), this._points[i + 1].ToDeviceValue(this));
// TODO: Remove unrequired first line
if (_path.PointCount == 0)
{
_path.AddLine(endPoint, endPoint);
}
else
{
_path.AddLine(_path.GetLastPoint(), endPoint);
}
}
}
catch
{
Trace.TraceError("Error rendering points.");
}
this.IsPathDirty = false;
}
return this._path;
}
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Xml;
using System.ComponentModel;
namespace Svg
{
[Serializable()]
public class SvgRectangle : SvgGraphicsElement
{
private SvgUnit _width;
private SvgUnit _height;
private SvgUnit _x;
private SvgUnit _y;
private SvgUnit _cornerRadiusX;
private SvgUnit _cornerRadiusY;
private GraphicsPath _path;
public SvgPoint Location
{
get { return new SvgPoint(this.X, this.Y); }
}
[SvgAttribute("x")]
public SvgUnit X
{
get { return this._x; }
set { this._x = value; this.IsPathDirty = true; }
}
[SvgAttribute("y")]
public SvgUnit Y
{
get { return this._y; }
set { this._y = value; this.IsPathDirty = true; }
}
[SvgAttribute("width")]
public SvgUnit Width
{
get { return this._width; }
set { this._width = value; this.IsPathDirty = true; }
}
[SvgAttribute("height")]
public SvgUnit Height
{
get { return this._height; }
set { this._height = value; this.IsPathDirty = true; }
}
[SvgAttribute("rx")]
public SvgUnit CornerRadiusX
{
get
{
// If ry has been set and rx hasn't, use it's value
if (this._cornerRadiusX.Value == 0.0f && this._cornerRadiusY.Value > 0.0f)
return this._cornerRadiusY;
return this._cornerRadiusX;
}
set { this._cornerRadiusX = value; this.IsPathDirty = true; }
}
[SvgAttribute("ry")]
public SvgUnit CornerRadiusY
{
get
{
// If rx has been set and ry hasn't, use it's value
if (this._cornerRadiusY.Value == 0.0f && this._cornerRadiusX.Value > 0.0f)
return this._cornerRadiusX;
return this._cornerRadiusY;
}
set
{
this._cornerRadiusY = value;
this.IsPathDirty = true;
}
}
protected override bool RequiresSmoothRendering
{
get { return (this.CornerRadiusX.Value > 0 || this.CornerRadiusY.Value > 0); }
}
public override RectangleF Bounds
{
get { return this.Path.GetBounds(); }
}
public override GraphicsPath Path
{
get
{
if (this._path == null || this.IsPathDirty)
{
// If the corners aren't to be rounded just create a rectangle
if (this.CornerRadiusX.Value == 0.0f && this.CornerRadiusY.Value == 0.0f)
{
RectangleF rectangle = new RectangleF(this.Location.ToDeviceValue(), new SizeF(this.Width.ToDeviceValue(), this.Height.ToDeviceValue()));
_path = new GraphicsPath();
_path.StartFigure();
_path.AddRectangle(rectangle);
_path.CloseFigure();
}
else
{
_path = new GraphicsPath();
RectangleF arcBounds = new RectangleF();
PointF lineStart = new PointF();
PointF lineEnd = new PointF();
float width = this.Width.ToDeviceValue();
float height = this.Height.ToDeviceValue();
float rx = this.CornerRadiusX.ToDeviceValue();
float ry = this.CornerRadiusY.ToDeviceValue();
PointF location = this.Location.ToDeviceValue();
// Start
_path.StartFigure();
// Add first arc
arcBounds.Location = location;
arcBounds.Width = rx;
arcBounds.Height = ry;
_path.AddArc(arcBounds, 180, 90);
// Add first line
lineStart.X = location.X+rx;
lineStart.Y = location.Y;
lineEnd.X = location.X + width - rx;
lineEnd.Y = lineStart.Y;
_path.AddLine(lineStart, lineEnd);
// Add second arc
arcBounds.Location = new PointF(location.X + width - rx, location.Y);
_path.AddArc(arcBounds, 270, 90);
// Add second line
lineStart.X = location.X + width;
lineStart.Y = location.Y + ry;
lineEnd.X = lineStart.X;
lineEnd.Y = location.Y + height - ry;
_path.AddLine(lineStart, lineEnd);
// Add third arc
arcBounds.Location = new PointF(location.X + width - rx, location.Y + height - ry);
_path.AddArc(arcBounds, 0, 90);
// Add third line
lineStart.X = location.X + width - rx;
lineStart.Y = location.Y + height;
lineEnd.X = location.X + rx;
lineEnd.Y = lineStart.Y;
_path.AddLine(lineStart, lineEnd);
// Add third arc
arcBounds.Location = new PointF(location.X, location.Y + height - ry);
_path.AddArc(arcBounds, 90, 90);
// Add fourth line
lineStart.X = location.X;
lineStart.Y = location.Y + height - ry;
lineEnd.X = lineStart.X;
lineEnd.Y = location.Y + ry;
_path.AddLine(lineStart, lineEnd);
// Close
_path.CloseFigure();
}
this.IsPathDirty = false;
}
return _path;
}
}
protected override void Render(Graphics graphics)
{
if (this.Width.Value > 0.0f && this.Height.Value > 0.0f)
base.Render(graphics);
}
public SvgRectangle()
{
this._width = new SvgUnit(0.0f);
this._height = new SvgUnit(0.0f);
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace Svg
{
public interface ISvgClipable
{
SvgClipPath ClipPath { get; set; }
void SetClip(Graphics graphics);
void ResetClip(Graphics graphics);
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace Svg
{
public sealed class SvgClipPath : SvgElement
{
private SvgCoordinateSystem _clipPathUnits;
private bool _pathDirty;
private Region _region;
[SvgAttribute("clipPathUnits")]
public SvgCoordinateSystem ClipPathUnits
{
get { return this._clipPathUnits; }
set { this._clipPathUnits = value; }
}
public SvgClipPath()
{
this._clipPathUnits = SvgCoordinateSystem.UserSpaceOnUse;
}
public override string ElementName
{
get { return "clipPath"; }
}
public override object Clone()
{
SvgClipPath path = new SvgClipPath();
path._clipPathUnits = this._clipPathUnits;
return path;
}
public Region GetClipRegion()
{
if (_region == null || _pathDirty)
{
_region = new Region();
foreach (SvgElement element in this.Children)
ComplementRegion(_region, element);
_pathDirty = false;
}
return _region;
}
private void ComplementRegion(Region region, SvgElement element)
{
SvgGraphicsElement graphicsElement = element as SvgGraphicsElement;
if (graphicsElement != null)
region.Complement(graphicsElement.Path);
foreach (SvgElement child in element.Children)
ComplementRegion(region, element);
}
protected override void AddedElement(SvgElement child, int index)
{
base.AddedElement(child, index);
this._pathDirty = true;
}
protected override void RemovedElement(SvgElement child)
{
base.RemovedElement(child);
this._pathDirty = true;
}
protected override void Render(System.Drawing.Graphics graphics)
{
// Do nothing
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace Svg
{
public class SvgMask : SvgElement
{
public override object Clone()
{
throw new Exception("The method or operation is not implemented.");
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Svg
{
/// <summary>
/// Provides properties and methods to be implemented by view port elements.
/// </summary>
public interface ISvgViewPort
{
/// <summary>
/// Gets or sets the viewport of the element.
/// </summary>
SvgViewBox ViewBox { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Svg
{
public class SvgElementStyle
{
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.ComponentModel;
namespace Svg
{
public struct SvgPoint
{
private SvgUnit x;
private SvgUnit y;
public SvgUnit X
{
get { return this.x; }
set { this.x = value; }
}
public SvgUnit Y
{
get { return this.y; }
set { this.y = value; }
}
public PointF ToDeviceValue()
{
return new PointF(this.X.ToDeviceValue(), this.Y.ToDeviceValue());
}
public bool IsEmpty()
{
return (this.X.Value == 0.0f && this.Y.Value == 0.0f);
}
public override bool Equals(object obj)
{
if (obj == null)
return false;
if (!(obj.GetType() == typeof(SvgPoint)))
return false;
SvgPoint point = (SvgPoint)obj;
return (point.X.Equals(this.X) && point.Y.Equals(this.Y));
}
public SvgPoint(string x, string y)
{
TypeConverter converter = TypeDescriptor.GetConverter(typeof(SvgUnit));
this.x = (SvgUnit)converter.ConvertFrom(x);
this.y = (SvgUnit)converter.ConvertFrom(y);
}
public SvgPoint(SvgUnit x, SvgUnit y)
{
this.x = x;
this.y = y;
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Web.UI.WebControls;
namespace Svg
{
/// <summary>
/// Represents a unit in an Scalable Vector Graphics document.
/// </summary>
[TypeConverter(typeof(SvgUnitConverter))]
public struct SvgUnit
{
private SvgUnitType _type;
private float _value;
private bool _isEmpty;
private float? _deviceValue;
public static readonly SvgUnit Empty = new SvgUnit(0.0f);
/// <summary>
/// Gets a value to determine whether the unit is empty.
/// </summary>
public bool IsEmpty
{
get { return this._isEmpty; }
}
/// <summary>
/// Gets the value of the unit.
/// </summary>
public float Value
{
get { return this._value; }
}
public SvgUnitType Type
{
get { return this._type; }
}
public float ToDeviceValue()
{
return this.ToDeviceValue(null);
}
public float ToDeviceValue(ISvgStylable styleOwner)
{
return this.ToDeviceValue(styleOwner, false);
}
public float ToDeviceValue(ISvgStylable styleOwner, bool vertical)
{
// If it's already been calculated
if (this._deviceValue.HasValue)
{
return this._deviceValue.Value;
}
if (this._value == 0.0f)
{
this._deviceValue = 0.0f;
return this._deviceValue.Value;
}
// http://www.w3.org/TR/CSS21/syndata.html#values
// http://www.w3.org/TR/SVG11/coords.html#Units
const float cmInInch = 2.54f;
int ppi = SvgDocument.PPI;
switch (this.Type)
{
case SvgUnitType.Centimeter:
_deviceValue = (float)((this.Value / cmInInch) * ppi);
break;
case SvgUnitType.Inch:
_deviceValue = this.Value * ppi;
break;
case SvgUnitType.Millimeter:
_deviceValue = (float)((this.Value / 10) / cmInInch) * ppi;
break;
case SvgUnitType.Pica:
_deviceValue = ((this.Value * 12) / 72) * ppi;
break;
case SvgUnitType.Point:
_deviceValue = (this.Value / 72) * ppi;
break;
case SvgUnitType.Pixel:
_deviceValue = this.Value;
break;
case SvgUnitType.User:
_deviceValue = this.Value;
break;
case SvgUnitType.Percentage:
// Can't calculate if there is no style owner
if (styleOwner == null)
{
_deviceValue = this.Value;
}
// TODO : Support height percentages
System.Drawing.RectangleF size = styleOwner.Bounds;
_deviceValue = (((vertical) ? size.Height : size.Width) / 100) * this.Value;
break;
default:
_deviceValue = this.Value;
break;
}
return this._deviceValue.Value;
}
public override bool Equals(object obj)
{
if (obj == null)
return false;
if (!(obj.GetType() == typeof(SvgUnit)))
return false;
SvgUnit unit = (SvgUnit)obj;
return (unit.Value == this.Value && unit.Type == this.Type);
}
public override string ToString()
{
string type = string.Empty;
switch (this.Type)
{
case SvgUnitType.Pixel:
type = "px";
break;
case SvgUnitType.Point:
type = "pt";
break;
case SvgUnitType.Inch:
type = "in";
break;
case SvgUnitType.Centimeter:
type = "cm";
break;
case SvgUnitType.Millimeter:
type = "mm";
break;
case SvgUnitType.Percentage:
type = "%";
break;
case SvgUnitType.Em:
type = "em";
break;
}
return string.Concat(this.Value.ToString(), type);
}
public static implicit operator float(SvgUnit value)
{
return value.ToDeviceValue();
}
public static implicit operator SvgUnit(float value)
{
return new SvgUnit(value);
}
public SvgUnit(SvgUnitType type, float value)
{
this._type = type;
this._value = value;
this._isEmpty = (this._value == 0.0f);
this._deviceValue = null;
}
public SvgUnit(float value)
{
this._value = value;
this._type = SvgUnitType.User;
this._isEmpty = (this._value == 0.0f);
this._deviceValue = null;
}
}
/// <summary>
/// Defines the various types of unit an <see cref="SvgUnit"/> can be.
/// </summary>
public enum SvgUnitType
{
/// <summary>
/// Indicates that the unit is in pixels.
/// </summary>
Pixel,
/// <summary>
/// Indicates that the unit is equal to the pt size of the current font.
/// </summary>
Em,
/// <summary>
/// Indicates that the unit is a percentage.
/// </summary>
Percentage,
/// <summary>
/// Indicates that the unit has no unit identifier and is a value in the current user coordinate system.
/// </summary>
User,
/// <summary>
/// Indicates the the unit is in inches.
/// </summary>
Inch,
/// <summary>
/// Indicates that the unit is in centimeters.
/// </summary>
Centimeter,
/// <summary>
/// Indicates that the unit is in millimeters.
/// </summary>
Millimeter,
/// <summary>
/// Indicates that the unit is in picas.
/// </summary>
Pica,
/// <summary>
/// Indicates that the unit is in points, the smallest unit of measure, being a subdivision of the larger <see cref="Pica"/>. There are 12 points in the <see cref="Pica"/>.
/// </summary>
Point
}
}
using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Svg
{
/// <summary>
/// Represents a list of <see cref="SvgUnits"/>.
/// </summary>
[TypeConverter(typeof(SvgUnitCollectionConverter))]
public class SvgUnitCollection : List<SvgUnit>
{
}
/// <summary>
/// A class to convert string into <see cref="SvgUnitCollection"/> instances.
/// </summary>
internal class SvgUnitCollectionConverter : TypeConverter
{
private static readonly SvgUnitConverter _unitConverter = new SvgUnitConverter();
/// <summary>
/// Converts the given object to the type of this converter, using the specified context and culture information.
/// </summary>
/// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"/> that provides a format context.</param>
/// <param name="culture">The <see cref="T:System.Globalization.CultureInfo"/> to use as the current culture.</param>
/// <param name="value">The <see cref="T:System.Object"/> to convert.</param>
/// <returns>
/// An <see cref="T:System.Object"/> that represents the converted value.
/// </returns>
/// <exception cref="T:System.NotSupportedException">The conversion cannot be performed. </exception>
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
if (value is string)
{
string[] points = ((string)value).Split(new char[]{',', ' '}, StringSplitOptions.RemoveEmptyEntries);
SvgUnitCollection units = new SvgUnitCollection();
foreach (string point in points)
{
units.Add((SvgUnit)_unitConverter.ConvertFrom(point.Trim()));
}
return units;
}
return base.ConvertFrom(context, culture, value);
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.ComponentModel;
using System.Web.UI.WebControls;
using System.Diagnostics;
namespace Svg
{
public sealed class SvgUnitConverter : TypeConverter
{
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
if (value == null)
{
return new SvgUnit(SvgUnitType.User, 0.0f);
}
if (!(value is string))
{
throw new ArgumentOutOfRangeException("value must be a string.");
}
// http://www.w3.org/TR/CSS21/syndata.html#values
// http://www.w3.org/TR/SVG11/coords.html#Units
string unit = value as string;
int identifierIndex = -1;
for (int i = 0; i < unit.Length; i++)
{
if (char.IsLetter(unit[i]) || unit[i] == '%')
{
identifierIndex = i;
break;
}
}
float val = 0.0f;
float.TryParse((identifierIndex > -1) ? unit.Substring(0, identifierIndex) : unit, out val);
if (identifierIndex == -1)
{
return new SvgUnit(val);
}
switch (unit.Substring(identifierIndex).Trim().ToLower())
{
case "mm":
return new SvgUnit(SvgUnitType.Millimeter, val);
case "cm":
return new SvgUnit(SvgUnitType.Centimeter, val);
case "in":
return new SvgUnit(SvgUnitType.Millimeter, val);
case "px":
return new SvgUnit(SvgUnitType.Pixel, val);
case "pt":
return new SvgUnit(SvgUnitType.Point, val);
case "pc":
return new SvgUnit(SvgUnitType.Pica, val);
case "%":
return new SvgUnit(SvgUnitType.Percentage, val);
default:
throw new FormatException("Unit is in an invalid format '" + unit + "'.");
}
return new SvgUnit(0.0f);
}
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == typeof(string))
return true;
return base.CanConvertFrom(context, sourceType);
}
}
}
\ No newline at end of file
using System;
using System.Drawing;
using System.ComponentModel;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Svg
{
/// <summary>
/// It is often desirable to specify that a given set of graphics stretch to fit a particular container element. The viewBox attribute provides this capability.
/// </summary>
[TypeConverter(typeof(SvgViewBoxConverter))]
public struct SvgViewBox
{
public static readonly SvgViewBox Empty = new SvgViewBox(-1, -1, -1, -1);
/// <summary>
/// Gets or sets the position where the viewport starts horizontally.
/// </summary>
public float MinX
{
get;
set;
}
/// <summary>
/// Gets or sets the position where the viewport starts vertically.
/// </summary>
public float MinY
{
get;
set;
}
/// <summary>
/// Gets or sets the width of the viewport.
/// </summary>
public float Width
{
get;
set;
}
/// <summary>
/// Gets or sets the height of the viewport.
/// </summary>
public float Height
{
get;
set;
}
/// <summary>
/// Performs an implicit conversion from <see cref="Svg.SvgViewBox"/> to <see cref="System.Drawing.RectangleF"/>.
/// </summary>
/// <param name="value">The value.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator RectangleF(SvgViewBox value)
{
return new RectangleF(value.MinX, value.MinY, value.Width, value.Height);
}
/// <summary>
/// Initializes a new instance of the <see cref="SvgViewBox"/> struct.
/// </summary>
/// <param name="minX">The min X.</param>
/// <param name="minY">The min Y.</param>
/// <param name="width">The width.</param>
/// <param name="height">The height.</param>
public SvgViewBox(float minX, float minY, float width, float height) : this()
{
this.MinX = minX;
this.MinY = minY;
this.Width = width;
this.Height = height;
}
}
internal class SvgViewBoxConverter : TypeConverter
{
/// <summary>
/// Converts the given object to the type of this converter, using the specified context and culture information.
/// </summary>
/// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"/> that provides a format context.</param>
/// <param name="culture">The <see cref="T:System.Globalization.CultureInfo"/> to use as the current culture.</param>
/// <param name="value">The <see cref="T:System.Object"/> to convert.</param>
/// <returns>
/// An <see cref="T:System.Object"/> that represents the converted value.
/// </returns>
/// <exception cref="T:System.NotSupportedException">The conversion cannot be performed. </exception>
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
if (value is string)
{
string[] coords = ((string)value).Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
if (coords.Length != 4)
{
throw new SvgException("The 'viewBox' attribute must be in the format 'minX, minY, width, height'.");
}
return new SvgViewBox(float.Parse(coords[0]), float.Parse(coords[1]), float.Parse(coords[2]), float.Parse(coords[3]));
}
return base.ConvertFrom(context, culture, value);
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Text;
namespace Svg
{
public class SvgDefinitionList : SvgElement
{
public SvgDefinitionList()
{
}
protected override void Render(System.Drawing.Graphics graphics)
{
// Do nothing. Children should NOT be rendered.
}
protected override string ElementName
{
get { return "defs"; }
}
}
}
\ No newline at end of file
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