using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Drawing.Drawing2D;
using System.Drawing;
using System.ComponentModel;
namespace Svg
{
///
/// An represents an SVG fragment that can be the root element or an embedded fragment of an SVG document.
///
[SvgElement("svg")]
public class SvgFragment : SvgElement, ISvgViewPort
{
///
/// Gets the SVG namespace string.
///
public static readonly Uri Namespace = new Uri("http://www.w3.org/2000/svg");
private SvgUnit _x;
private SvgUnit _y;
///
/// Gets or sets the position where the left point of the svg should start.
///
[SvgAttribute("x")]
public SvgUnit X
{
get { return _x; }
set
{
if(_x != value)
{
_x = value;
OnAttributeChanged(new AttributeEventArgs{ Attribute = "x", Value = value });
}
}
}
///
/// Gets or sets the position where the top point of the svg should start.
///
[SvgAttribute("y")]
public SvgUnit Y
{
get { return _y; }
set
{
if(_y != value)
{
_y = value;
OnAttributeChanged(new AttributeEventArgs{ Attribute = "y", Value = value });
}
}
}
///
/// Gets or sets the width of the fragment.
///
/// The width.
[SvgAttribute("width")]
public SvgUnit Width
{
get { return this.Attributes.GetAttribute("width"); }
set { this.Attributes["width"] = value; }
}
///
/// Gets or sets the height of the fragment.
///
/// The height.
[SvgAttribute("height")]
public SvgUnit Height
{
get { return this.Attributes.GetAttribute("height"); }
set { this.Attributes["height"] = value; }
}
[SvgAttribute("overflow")]
public virtual SvgOverflow Overflow
{
get { return this.Attributes.GetAttribute("overflow"); }
set { this.Attributes["overflow"] = value; }
}
///
/// Gets or sets the viewport of the element.
///
///
[SvgAttribute("viewBox")]
public SvgViewBox ViewBox
{
get { return this.Attributes.GetAttribute("viewBox"); }
set { this.Attributes["viewBox"] = value; }
}
///
/// Gets or sets the aspect of the viewport.
///
///
[SvgAttribute("preserveAspectRatio")]
public SvgAspectRatio AspectRatio
{
get { return this.Attributes.GetAttribute("preserveAspectRatio"); }
set { this.Attributes["preserveAspectRatio"] = value; }
}
///
/// Applies the required transforms to .
///
/// The to be transformed.
protected internal override void PushTransforms(SvgRenderer renderer)
{
base.PushTransforms(renderer);
if (!this.ViewBox.Equals(SvgViewBox.Empty))
{
float fScaleX = this.Width.ToDeviceValue() / this.ViewBox.Width;
float fScaleY = this.Height.ToDeviceValue() / this.ViewBox.Height;
float fMinX = -this.ViewBox.MinX;
float fMinY = -this.ViewBox.MinY;
if (AspectRatio.Align != SvgPreserveAspectRatio.none)
{
if (AspectRatio.Slice)
{
fScaleX = Math.Max(fScaleX, fScaleY);
fScaleY = Math.Max(fScaleX, fScaleY);
}
else
{
fScaleX = Math.Min(fScaleX, fScaleY);
fScaleY = Math.Min(fScaleX, fScaleY);
}
float fViewMidX = (this.ViewBox.Width / 2) * fScaleX;
float fViewMidY = (this.ViewBox.Height / 2) * fScaleY;
float fMidX = this.Width.ToDeviceValue() / 2;
float fMidY = this.Height.ToDeviceValue() / 2;
switch (AspectRatio.Align)
{
case SvgPreserveAspectRatio.xMinYMin:
break;
case SvgPreserveAspectRatio.xMidYMin:
fMinX += (fMidX - fViewMidX) / fScaleX;
break;
case SvgPreserveAspectRatio.xMaxYMin:
fMinX += (this.Width.ToDeviceValue() / fScaleX) - this.ViewBox.Width;
break;
case SvgPreserveAspectRatio.xMinYMid:
fMinY += (fMidY - fViewMidY) / fScaleY;
break;
case SvgPreserveAspectRatio.xMidYMid:
fMinX += (fMidX - fViewMidX) / fScaleX;
fMinY += (fMidY - fViewMidY) / fScaleY;
break;
case SvgPreserveAspectRatio.xMaxYMid:
fMinX += (this.Width.ToDeviceValue() / fScaleX) - this.ViewBox.Width;
fMinY += (fMidY - fViewMidY) / fScaleY;
break;
case SvgPreserveAspectRatio.xMinYMax:
fMinY += (this.Height.ToDeviceValue() / fScaleY) - this.ViewBox.Height;
break;
case SvgPreserveAspectRatio.xMidYMax:
fMinX += (fMidX - fViewMidX) / fScaleX;
fMinY += (this.Height.ToDeviceValue() / fScaleY) - this.ViewBox.Height;
break;
case SvgPreserveAspectRatio.xMaxYMax:
fMinX += (this.Width.ToDeviceValue() / fScaleX) - this.ViewBox.Width;
fMinY += (this.Height.ToDeviceValue() / fScaleY) - this.ViewBox.Height;
break;
default:
break;
}
}
renderer.TranslateTransform(_x, _y);
renderer.TranslateTransform(fMinX, fMinY);
renderer.ScaleTransform(fScaleX, fScaleY);
}
}
///
/// Gets the for this element.
///
///
public GraphicsPath Path
{
get
{
var path = new GraphicsPath();
AddPaths(this, path);
return path;
}
}
///
/// Gets the bounds of the svg element.
///
/// The bounds.
public RectangleF Bounds
{
get
{
return this.Path.GetBounds();
}
}
///
/// Initializes a new instance of the class.
///
public SvgFragment()
{
_x = 0.0f;
_y = 0.0f;
this.Height = new SvgUnit(SvgUnitType.Percentage, 100.0f);
this.Width = new SvgUnit(SvgUnitType.Percentage, 100.0f);
this.ViewBox = SvgViewBox.Empty;
this.AspectRatio = new SvgAspectRatio(SvgPreserveAspectRatio.xMidYMid);
}
public override SvgElement DeepCopy()
{
return DeepCopy();
}
public override SvgElement DeepCopy()
{
var newObj = base.DeepCopy() as SvgFragment;
newObj.Height = this.Height;
newObj.Width = this.Width;
newObj.Overflow = this.Overflow;
newObj.ViewBox = this.ViewBox;
newObj.AspectRatio = this.AspectRatio;
return newObj;
}
}
}