using System;
using System.IO;
using System.Net;
using System.Xml;
using System.Globalization;
namespace SharpVectors.Dom.Svg
{
public sealed class SvgImageElement : SvgTransformableElement, ISvgImageElement
{
#region Private Fields
private ISvgAnimatedLength x;
private ISvgAnimatedLength y;
private ISvgAnimatedLength width;
private ISvgAnimatedLength height;
private SvgTests svgTests;
private SvgUriReference svgURIReference;
private SvgFitToViewBox svgFitToViewBox;
private SvgExternalResourcesRequired svgExternalResourcesRequired;
#endregion
#region Constructors and Destructor
public SvgImageElement(string prefix, string localname, string ns, SvgDocument doc)
: base(prefix, localname, ns, doc)
{
svgExternalResourcesRequired = new SvgExternalResourcesRequired(this);
svgTests = new SvgTests(this);
svgURIReference = new SvgUriReference(this);
svgFitToViewBox = new SvgFitToViewBox(this);
}
#endregion
#region Public properties
//public SvgRect CalculatedViewbox
//{
// get
// {
// SvgRect viewBox = null;
// if (IsSvgImage)
// {
// SvgDocument doc = GetImageDocument();
// SvgSvgElement outerSvg = (SvgSvgElement)doc.DocumentElement;
// if (outerSvg.HasAttribute("viewBox"))
// {
// viewBox = (SvgRect)outerSvg.ViewBox.AnimVal;
// }
// else
// {
// viewBox = SvgRect.Empty;
// }
// }
// else
// {
// viewBox = new SvgRect(0, 0, Bitmap.Size.Width, Bitmap.Size.Height);
// }
// return viewBox;
// }
//}
public bool IsSvgImage
{
get
{
if (!Href.AnimVal.StartsWith("data:"))
{
try
{
WebResponse resource = svgURIReference.ReferencedResource;
if (resource == null)
{
return false;
}
// local files are returning as binary/octet-stream
// this "fix" tests the file extension for .svg and .svgz
string name = resource.ResponseUri.ToString().ToLower(CultureInfo.InvariantCulture);
return (resource.ContentType.StartsWith("image/svg+xml") ||
name.EndsWith(".svg") || name.EndsWith(".svgz"));
}
catch (WebException)
{
return false;
}
catch (IOException)
{
return false;
}
}
return false;
}
}
public SvgWindow SvgWindow
{
get
{
if (IsSvgImage)
{
SvgWindow parentWindow = (SvgWindow)OwnerDocument.Window;
if (parentWindow != null)
{
SvgWindow wnd = parentWindow.CreateOwnedWindow(
(long)Width.AnimVal.Value, (long)Height.AnimVal.Value);
SvgDocument doc = new SvgDocument(wnd);
wnd.Document = doc;
string absoluteUri = svgURIReference.AbsoluteUri;
Stream resStream = svgURIReference.ReferencedResource.GetResponseStream();
doc.Load(absoluteUri, resStream);
return wnd;
}
}
return null;
}
}
#endregion
#region ISvgElement Members
///
/// Gets a value providing a hint on the rendering defined by this element.
///
///
/// An enumeration of the specifying the rendering hint.
/// This will always return
///
public override SvgRenderingHint RenderingHint
{
get
{
return SvgRenderingHint.Image;
}
}
#endregion
#region ISvgImageElement Members
public ISvgAnimatedLength Width
{
get
{
if (width == null)
{
width = new SvgAnimatedLength(this, "width", SvgLengthDirection.Horizontal, "0");
}
return width;
}
}
public ISvgAnimatedLength Height
{
get
{
if (height == null)
{
height = new SvgAnimatedLength(this, "height", SvgLengthDirection.Vertical, "0");
}
return height;
}
}
public ISvgAnimatedLength X
{
get
{
if (x == null)
{
x = new SvgAnimatedLength(this, "x", SvgLengthDirection.Horizontal, "0");
}
return x;
}
}
public ISvgAnimatedLength Y
{
get
{
if (y == null)
{
y = new SvgAnimatedLength(this, "y", SvgLengthDirection.Vertical, "0");
}
return y;
}
}
public ISvgColorProfileElement ColorProfile
{
get
{
string colorProfile = this.GetAttribute("color-profile");
if (String.IsNullOrEmpty(colorProfile))
{
return null;
}
XmlElement profileElement = this.OwnerDocument.GetElementById(colorProfile);
if (profileElement == null)
{
XmlElement root = this.OwnerDocument.DocumentElement;
XmlNodeList elemList = root.GetElementsByTagName("color-profile");
if (elemList != null && elemList.Count != 0)
{
for (int i = 0; i < elemList.Count; i++)
{
XmlElement elementNode = elemList[i] as XmlElement;
if (elementNode != null && String.Equals(colorProfile,
elementNode.GetAttribute("id")))
{
profileElement = elementNode;
break;
}
}
}
}
return profileElement as SvgColorProfileElement;
}
}
#endregion
#region ISvgURIReference Members
public ISvgAnimatedString Href
{
get
{
return svgURIReference.Href;
}
}
public SvgUriReference UriReference
{
get
{
return svgURIReference;
}
}
public XmlElement ReferencedElement
{
get
{
return svgURIReference.ReferencedNode as XmlElement;
}
}
#endregion
#region ISvgFitToViewBox Members
public ISvgAnimatedPreserveAspectRatio PreserveAspectRatio
{
get
{
return svgFitToViewBox.PreserveAspectRatio;
}
}
#endregion
#region ISvgImageElement Members from SVG 1.2
public SvgDocument GetImageDocument()
{
SvgWindow window = this.SvgWindow;
if (window == null)
{
return null;
}
else
{
return (SvgDocument)window.Document;
}
}
#endregion
#region Update handling
public override void HandleAttributeChange(XmlAttribute attribute)
{
if (attribute.NamespaceURI.Length == 0)
{
// This list may be too long to be useful...
switch (attribute.LocalName)
{
// Additional attributes
case "x":
x = null;
return;
case "y":
y = null;
return;
case "width":
width = null;
return;
case "height":
height = null;
return;
}
base.HandleAttributeChange(attribute);
}
}
#endregion
#region ISvgExternalResourcesRequired Members
public ISvgAnimatedBoolean ExternalResourcesRequired
{
get
{
return svgExternalResourcesRequired.ExternalResourcesRequired;
}
}
#endregion
#region ISvgTests Members
public ISvgStringList RequiredFeatures
{
get { return svgTests.RequiredFeatures; }
}
public ISvgStringList RequiredExtensions
{
get { return svgTests.RequiredExtensions; }
}
public ISvgStringList SystemLanguage
{
get { return svgTests.SystemLanguage; }
}
public bool HasExtension(string extension)
{
return svgTests.HasExtension(extension);
}
#endregion
}
}