123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333 |
- using System;
- using System.Drawing;
- using System.Drawing.Drawing2D;
- using System.Xml;
- #pragma warning disable
- namespace Svg
- {
- /// <summary>
- /// An <see cref="SvgFragment"/> represents an SVG fragment that can be the root element or an embedded fragment of an SVG document.
- /// </summary>
- [SvgElement("svg")]
- public class SvgFragment : SvgElement, ISvgViewPort, ISvgBoundable
- {
- /// <summary>
- /// Gets the SVG namespace string.
- /// </summary>
- public static readonly Uri Namespace = new Uri("http://www.w3.org/2000/svg");
- PointF ISvgBoundable.Location
- {
- get
- {
- return PointF.Empty;
- }
- }
- SizeF ISvgBoundable.Size
- {
- get
- {
- return GetDimensions();
- }
- }
- RectangleF ISvgBoundable.Bounds
- {
- get
- {
- return new RectangleF(((ISvgBoundable)this).Location, ((ISvgBoundable)this).Size);
- }
- }
- private SvgUnit _x;
- private SvgUnit _y;
- /// <summary>
- /// Gets or sets the position where the left point of the svg should start.
- /// </summary>
- [SvgAttribute("x")]
- public SvgUnit X
- {
- get { return _x; }
- set
- {
- if (_x != value)
- {
- _x = value;
- OnAttributeChanged(new AttributeEventArgs { Attribute = "x", Value = value });
- }
- }
- }
- /// <summary>
- /// Gets or sets the position where the top point of the svg should start.
- /// </summary>
- [SvgAttribute("y")]
- public SvgUnit Y
- {
- get { return _y; }
- set
- {
- if (_y != value)
- {
- _y = value;
- OnAttributeChanged(new AttributeEventArgs { Attribute = "y", Value = value });
- }
- }
- }
- /// <summary>
- /// Gets or sets the width of the fragment.
- /// </summary>
- /// <value>The width.</value>
- [SvgAttribute("width")]
- public SvgUnit Width
- {
- get { return this.Attributes.GetAttribute<SvgUnit>("width"); }
- set { this.Attributes["width"] = value; }
- }
- /// <summary>
- /// Gets or sets the height of the fragment.
- /// </summary>
- /// <value>The height.</value>
- [SvgAttribute("height")]
- public SvgUnit Height
- {
- get { return this.Attributes.GetAttribute<SvgUnit>("height"); }
- set { this.Attributes["height"] = value; }
- }
- [SvgAttribute("overflow")]
- public virtual SvgOverflow Overflow
- {
- get { return this.Attributes.GetAttribute<SvgOverflow>("overflow"); }
- set { this.Attributes["overflow"] = value; }
- }
- /// <summary>
- /// Gets or sets the viewport of the element.
- /// </summary>
- /// <value></value>
- [SvgAttribute("viewBox")]
- public SvgViewBox ViewBox
- {
- get { return this.Attributes.GetAttribute<SvgViewBox>("viewBox"); }
- set { this.Attributes["viewBox"] = value; }
- }
- /// <summary>
- /// Gets or sets the aspect of the viewport.
- /// </summary>
- /// <value></value>
- [SvgAttribute("preserveAspectRatio")]
- public SvgAspectRatio AspectRatio
- {
- get { return this.Attributes.GetAttribute<SvgAspectRatio>("preserveAspectRatio"); }
- set { this.Attributes["preserveAspectRatio"] = value; }
- }
- /// <summary>
- /// Refers to the size of the font from baseline to baseline when multiple lines of text are set solid in a multiline layout environment.
- /// </summary>
- [SvgAttribute("font-size")]
- public override SvgUnit FontSize
- {
- get { return (this.Attributes["font-size"] == null) ? SvgUnit.Empty : (SvgUnit)this.Attributes["font-size"]; }
- set { this.Attributes["font-size"] = value; }
- }
- /// <summary>
- /// Indicates which font family is to be used to render the text.
- /// </summary>
- [SvgAttribute("font-family")]
- public override string FontFamily
- {
- get { return this.Attributes["font-family"] as string; }
- set { this.Attributes["font-family"] = value; }
- }
- /// <summary>
- /// Applies the required transforms to <see cref="ISvgRenderer"/>.
- /// </summary>
- /// <param name="renderer">The <see cref="ISvgRenderer"/> to be transformed.</param>
- protected internal override bool PushTransforms(ISvgRenderer renderer)
- {
- if (!base.PushTransforms(renderer)) return false;
- this.ViewBox.AddViewBoxTransform(this.AspectRatio, renderer, this);
- return true;
- }
- protected override void Render(ISvgRenderer renderer)
- {
- switch (this.Overflow)
- {
- case SvgOverflow.Auto:
- case SvgOverflow.Visible:
- case SvgOverflow.Inherit:
- base.Render(renderer);
- break;
- default:
- var prevClip = renderer.GetClip();
- try
- {
- var size = (this.Parent == null ? renderer.GetBoundable().Bounds.Size : GetDimensions());
- var clip = new RectangleF(this.X.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this),
- this.Y.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this),
- size.Width, size.Height);
- renderer.SetClip(new Region(clip), CombineMode.Intersect);
- base.Render(renderer);
- }
- finally
- {
- renderer.SetClip(prevClip, CombineMode.Replace);
- }
- break;
- }
- }
- /// <summary>
- /// Gets the <see cref="GraphicsPath"/> for this element.
- /// </summary>
- /// <value></value>
- public GraphicsPath Path
- {
- get
- {
- var path = new GraphicsPath();
- AddPaths(this, path);
- return path;
- }
- }
- /// <summary>
- /// Gets the bounds of the svg element.
- /// </summary>
- /// <value>The bounds.</value>
- public RectangleF Bounds
- {
- get
- {
- var bounds = new RectangleF();
- foreach (var child in this.Children)
- {
- RectangleF childBounds = new RectangleF();
- if (child is SvgFragment)
- {
- childBounds = ((SvgFragment)child).Bounds;
- childBounds.Offset(((SvgFragment)child).X, ((SvgFragment)child).Y);
- }
- else if (child is SvgVisualElement)
- {
- childBounds = ((SvgVisualElement)child).Bounds;
- }
- if (!childBounds.IsEmpty)
- {
- if (bounds.IsEmpty)
- {
- bounds = childBounds;
- }
- else
- {
- bounds = RectangleF.Union(bounds, childBounds);
- }
- }
- }
- return bounds;
- }
- }
- /// <summary>
- /// Initializes a new instance of the <see cref="SvgFragment"/> class.
- /// </summary>
- 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 SizeF GetDimensions()
- {
- float w, h;
- var isWidthperc = Width.Type == SvgUnitType.Percentage;
- var isHeightperc = Height.Type == SvgUnitType.Percentage;
- RectangleF bounds = new RectangleF();
- if (isWidthperc || isHeightperc)
- {
- if (ViewBox.Width > 0 && ViewBox.Height > 0)
- {
- bounds = new RectangleF(0, 0, ViewBox.Width, ViewBox.Height);
- }
- else
- {
- bounds = this.Bounds; //do just one call to the recursive bounds property
- }
- }
- if (isWidthperc)
- {
- w = (bounds.Width + bounds.X) * (Width.Value * 0.01f);
- }
- else
- {
- w = Width.ToDeviceValue(null, UnitRenderingType.Horizontal, this);
- }
- if (isHeightperc)
- {
- h = (bounds.Height + bounds.Y) * (Height.Value * 0.01f);
- }
- else
- {
- h = Height.ToDeviceValue(null, UnitRenderingType.Vertical, this);
- }
- return new SizeF(w, h);
- }
- public override SvgElement DeepCopy()
- {
- return DeepCopy<SvgFragment>();
- }
- public override SvgElement DeepCopy<T>()
- {
- var newObj = base.DeepCopy<T>() as SvgFragment;
- newObj.Height = this.Height;
- newObj.Width = this.Width;
- newObj.Overflow = this.Overflow;
- newObj.ViewBox = this.ViewBox;
- newObj.AspectRatio = this.AspectRatio;
- return newObj;
- }
- //Override the default behavior, writing out the namespaces.
- protected override void WriteStartElement(XmlTextWriter writer)
- {
- base.WriteStartElement(writer);
- foreach (var ns in SvgAttributeAttribute.Namespaces)
- {
- if (string.IsNullOrEmpty(ns.Key))
- writer.WriteAttributeString("xmlns", ns.Value);
- else
- writer.WriteAttributeString("xmlns:" + ns.Key, ns.Value);
- }
- writer.WriteAttributeString("version", "1.1");
- }
- }
- }
- #pragma warning restore
|