Click here to Skip to main content
Click here to Skip to main content
 
Add your own
alternative version
Go to top

SVG Artiste - An SVG Editor

, 3 Aug 2010
A Vector based tool to create and edit SVG images
SVGArtiste2_exe.zip
SvgArtiste.exe
SvgArtiste.vshost.exe.manifest
SVGLib.dll
Crom.Controls.dll
Draw.dll
SVGArtiste2_SampleSVGDrawings.zip
mercialago18.svg
SVGArtiste.svg
SVGArtiste2_src.zip
SVGLib
SVGLib.csproj.user
SVGLib.ndoc
SvgArtiste2.suo
Crom.Controls
Dock16x16.bmp
Internal
Docking
ControlCollections
Controls
DockButtons
Forms
Engine
Enums
EventArgs
Helpers
SharedHelpers
Properties
Public
Docking
Enums
EventArgs
Helpers
Renderers
TabbedDocument
Controls
Enums
Helpers
Renderers
Base
Draw
Command
Draw.csproj.user
RulerControl
Ruler.bmp
SvgArtiste2
Properties
Settings.settings
Resources
cancel.png
Ellipse.cur
exit.png
exit1.png
Line.cur
new.png
new_page.png
open.png
open1.png
pan.cur
pan_close.cur
Pencil.cur
Rectangle.cur
save.png
save_as.png
save_as1.png
Text.cur
SVGArtiste.csproj.user
Tools
Forms
UserControls
// --------------------------------------------------------------------------------
// Name:     SvgElement
//
// Author:   Maurizio Bigoloni <big71@fastwebnet.it>
//           See the ReleaseNote.txt file for copyright and license information.
//
// Remarks:
//
// --------------------------------------------------------------------------------

using System;
using System.ComponentModel;
using System.Collections;
using System.Diagnostics;
using System.Drawing;

namespace SVGLib
{
	/// <summary>
	/// This is the base class of any Svg element.
	/// </summary>
	[DefaultProperty("Id")]
	public class SvgElement
	{
		/// <summary>
		/// List all SVG element types. For each element a specific class is defined in the library.
		/// </summary>
		public enum _SvgElementType
		{
			typeUnsupported,
			typeSvg,
			typeDesc,
			typeText,
			typeGroup,
			typeRect,
			typeCircle,
			typeEllipse,
			typeLine,
			typePath,
			typePolygon,
			typeImage,
			typePolyline
		};

		// ---------- PUBLIC PROPERTIES

		/// <summary>
		/// Standard XML attribute for assigning a unique name to an element.
		/// </summary>
		/// <remarks></remarks>
		[Category("(Core)")]
		[Description("Standard XML attribute for assigning a unique name to an element.")]
		public string Id
		{
			get	
			{
				return GetAttributeStringValue(SvgAttribute._SvgAttribute.attrCore_Id);	
			}

			set	
			{
				SetAttributeValue(SvgAttribute._SvgAttribute.attrCore_Id, value);
			}
		}

		// ---------- PUBLIC PROPERTIES END

		// ---------- PRIVATE PROPERTIES

		private class CEleComparer : IComparer  
		{
			int IComparer.Compare( Object x, Object y )  
			{
				SvgAttribute ax = (SvgAttribute) x;
				SvgAttribute ay = (SvgAttribute) y;

				if ( ax.AttributeGroup == ay.AttributeGroup )
				{
					if ( ax.AttributeType < ay.AttributeType )
					{
						return -1;
					}
					else
					{
						return 1;
					}
				}
				else if ( ax.AttributeGroup < ay.AttributeGroup )
				{
					return -1;
				}
				else
				{
					return 1;
				}
			}
		}


		// navigation
		protected SvgElement m_Parent;
		protected SvgElement m_Child;
		protected SvgElement m_Next; 
		protected SvgElement m_Previous;

		// document
		protected SvgDoc m_doc;
		
		// internal stuff
		protected int m_nInternalId;
		protected string m_sElementName;
		protected string m_sElementValue;
		protected bool m_bHasValue;
		protected _SvgElementType m_ElementType;

		// attributes
		private ArrayList m_attributes;
		
		// ---------- PRIVATE PROPERTIES END

		// ---------- PUBLIC METHODS

		// constructor is protected!

		/// <summary>
		/// It returns the parent element.
		/// </summary>
		/// <returns></returns>
		public SvgElement getParent()
		{
			return m_Parent;
		}

		/// <summary>
		/// It sets the parent element.
		/// </summary>
		/// <param name="ele">New parent element</param>
		public void setParent(SvgElement ele)
		{
			m_Parent = ele;
		}

		/// <summary>
		/// It gest the first child element.
		/// </summary>
		/// <returns>First child element.</returns>
		public SvgElement getChild()
		{
			return m_Child;
		}

		/// <summary>
		/// It sets the first child element.
		/// </summary>
		/// <param name="ele">New child.</param>
		public void setChild(SvgElement ele)
		{
			m_Child = ele;
		}

		/// <summary>
		/// It gets the next sibling element.
		/// </summary>
		/// <returns>Next element.</returns>
		public SvgElement getNext()
		{
			return m_Next;
		}

		/// <summary>
		/// It sets the next sibling element.
		/// </summary>
		/// <param name="ele">New next element.</param>
		public void setNext(SvgElement ele)
		{
			m_Next = ele;
		}

		/// <summary>
		/// It gets the previous sibling element.
		/// </summary>
		/// <returns>Previous element.</returns>
		public SvgElement getPrevious()
		{
			return m_Previous;
		}

		/// <summary>
		/// It sets the previous element.
		/// </summary>
		/// <param name="ele">New previous element.</param>
		public void setPrevious(SvgElement ele)
		{
			m_Previous = ele;
		}

		/// <summary>
		/// It gets the internal Id of the element.
		/// </summary>
		/// <returns>Internal Id.</returns>
		/// <remarks>The internal Id is a unique number inside the SVG document.
		/// It is assigned when the element is added to the document.</remarks>
		public int getInternalId()
		{
			return m_nInternalId;
		}

		/// <summary>
		/// It sets the internal Id of the element.
		/// </summary>
		/// <param name="nId">New internal Id.</param>
		public void setInternalId(int nId)
		{
			m_nInternalId = nId;
		}

		/// <summary>
		/// It returns the SVG element name.
		/// </summary>
		/// <returns>SVG name.</returns>
		public string getElementName()
		{
			return m_sElementName;
		}

		/// <summary>
		/// It returns the current element value.
		/// </summary>
		/// <returns>Element value.</returns>
		/// <remarks>Not all SVG elements are supposed to have a value. For instance a rect element or 
		/// a circle do not usually have a value while a desc or a text they normally have it.</remarks>
		public string getElementValue()
		{
			return m_sElementValue;
		}

		/// <summary>
		/// Sets the element value.
		/// </summary>
		/// <param name="sValue">New element value.</param>
		public void setElementValue(string sValue)
		{
			m_sElementValue = sValue;
		}

		/// <summary>
		/// Flag indicating if a value is expected for the SVG element.
		/// </summary>
		/// <returns>true if the SVG element has normally a value.</returns>
		public bool HasValue()
		{
			return m_bHasValue;
		}

		/// <summary>
		/// It returns the SVG element type.
		/// </summary>
		/// <returns></returns>
		public _SvgElementType getElementType()
		{
			return m_ElementType;
		}

		/// <summary>
		/// It returns the XML string of the SVG tree starting from the element.
		/// </summary>
		/// <returns>XML string.</returns>
		/// <remarks>The method is recursive so it creates the SVG string for the current element and for its
		/// sub-tree. If the element is the root of the SVG document the method return the entire SVG XML string.</remarks>
		public string GetXML()
		{
			string sXML;

			sXML = OpenXMLTag();

			if ( m_Child != null )
			{
				sXML += m_Child.GetXML();
			}

			sXML += CloseXMLTag();

			SvgElement ele = m_Next;
			if (ele != null)
			{
				sXML += ele.GetXML();
			}

			ErrH.Log("SvgElement", "GetXML", ElementInfo(), ErrH._LogPriority.Info);
		
			return sXML;
		}

		/// <summary>
		/// It returns the XML string of the SVG element.
		/// </summary>
		/// <returns>XML string.</returns>
		public string GetTagXml()
		{
			string sXML;

			sXML = OpenXMLTag();
			sXML += CloseXMLTag();

			return sXML;
		}

		/// <summary>
		/// It gets all element attributes.
		/// </summary>
		/// <param name="aType">Attribute type array.</param>
		/// <param name="aName">Attribute name array.</param>
		/// <param name="aValue">Attribute value array.</param>
		public void FillAttributeList(ArrayList aType, ArrayList aName, ArrayList aValue)
		{
			IComparer myComparer = new CEleComparer();
			m_attributes.Sort(myComparer);


			for (int i = 0; i < m_attributes.Count; i++ )
			{
				SvgAttribute attr = (SvgAttribute) m_attributes[i];

				aType.Add(attr.AttributeType);
				aName.Add(attr.Name);
				aValue.Add(attr.Value);
			}
		}

		/// <summary>
		/// It copies all the attributes of the element eleToClone to the
		/// current element.
		/// </summary>
		/// <param name="eleToClone">Element that has to be cloned.</param>
		public void CloneAttributeList(SvgElement eleToClone)
		{
			ArrayList aType = new ArrayList();
			ArrayList aName = new ArrayList();
			ArrayList aValue = new ArrayList();

			eleToClone.FillAttributeList(aType, aName, aValue);

			m_attributes.Clear();


			// copy the attributes
			for (int i = 0; i < aType.Count; i++ )
			{
				AddAttr((SvgAttribute._SvgAttribute) aType[i], aValue[i]);
			}

			// copy the value
			if ( m_bHasValue )
			{
				m_sElementValue = eleToClone.m_sElementValue;
			}
		}

		/// <summary>
		/// It returns a string containing current element info for logging purposes.
		/// </summary>
		/// <returns></returns>
		public string ElementInfo()
		{
			string sMsg = "InternalId:" + m_nInternalId.ToString();

			if ( m_Parent != null )
			{
				sMsg += " - Parent:" + m_Parent.getInternalId().ToString();
			}

			if ( m_Previous != null )
			{
				sMsg += " - Previous:" + m_Previous.getInternalId().ToString();
			}

			if ( m_Next != null )
			{
				sMsg += " - Next:" + m_Next.getInternalId().ToString();
			}

			if ( m_Child != null )
			{
				sMsg += " - Child:" + m_Child.getInternalId().ToString();
			}

			return sMsg;
		}

		// ---------- PUBLIC METHODS END

		// ---------- PRIVATE METHODS

		protected SvgElement(SvgDoc doc)
		{
			ErrH.Log("SvgElement", "SvgElement", "Element created", ErrH._LogPriority.Info);

			m_doc = doc;

			m_attributes = new ArrayList();

			AddAttr(SvgAttribute._SvgAttribute.attrCore_Id, null);

			m_Parent = null;
			m_Child = null;
			m_Next = null;
			m_Previous = null;

			m_sElementName = "unsupported";
			m_sElementValue = "";
			m_bHasValue = false;
			m_ElementType = _SvgElementType.typeUnsupported;
		}

		~SvgElement()
		{
			ErrH.Log("SvgElement", "SvgElement", "Element destroyed, InternalId:" + m_nInternalId.ToString(), ErrH._LogPriority.Info);

			m_Parent = null;
			m_Child = null;
			m_Next = null;
			m_Previous = null;
		}

		protected string OpenXMLTag()
		{
			string sXML;

			sXML = "<" + m_sElementName;

			for (int i = 0; i < m_attributes.Count; i++ )
			{
				SvgAttribute attr = (SvgAttribute) m_attributes[i];
				sXML += attr.GetXML();
			}

			if ( m_sElementValue == "")
			{
				if (m_Child == null)
				{
					sXML += " />\r\n";
				}
				else
				{
					sXML += ">\r\n";
				}
			}
			else
			{
				sXML += ">";
				sXML += m_sElementValue;
			}
			
			return sXML;
		}

		protected string CloseXMLTag()
		{
			if ( (m_sElementValue == "") && (m_Child == null) )
			{
				return "";
			}
			else
			{
				return "</" + m_sElementName + ">\r\n";
			}
		}

		protected void AddAttr(SvgAttribute._SvgAttribute type, object objValue)
		{
			SvgAttribute attrToAdd = new SvgAttribute(type);
			attrToAdd.Value = objValue;

			m_attributes.Add(attrToAdd);
		}

		internal SvgAttribute GetAttribute(string sName)
		{
			for (int i = 0; i < m_attributes.Count; i++ )
			{
				SvgAttribute attr = (SvgAttribute) m_attributes[i];
				if ( attr.Name == sName )
				{
					return attr;
				}
			}
			
			return null;
		}

		internal SvgAttribute GetAttribute(SvgAttribute._SvgAttribute type)
		{
			for (int i = 0; i < m_attributes.Count; i++ )
			{
				SvgAttribute attr = (SvgAttribute) m_attributes[i];
				if ( attr.AttributeType == type )
				{
					return attr;
				}
			}
			
			return null;
		}
		internal bool SetAttributeValue(string sName, string sValue)
		{
			bool bReturn = false;

			for (int i = 0; i < m_attributes.Count; i++ )
			{
				SvgAttribute attr = (SvgAttribute) m_attributes[i];
				if ( attr.Name == sName )
				{
					switch (attr.AttributeDataType)
					{
						case SvgAttribute._SvgAttributeDataType.datatypeString:
						case SvgAttribute._SvgAttributeDataType.datatypeHRef:
							attr.Value = sValue;
							if (attr.AttributeType == SvgAttribute._SvgAttribute.attrStyle_Style)
								ParseStyle(sValue);
							break;

						case SvgAttribute._SvgAttributeDataType.datatypeEnum:
							int nValue = 0;
							try
							{
								nValue = Convert.ToInt32(sValue);
							}
							catch
							{
							}

							attr.Value = nValue;
							break;

						case SvgAttribute._SvgAttributeDataType.datatypeColor:

							if (sValue == "")
							{
								attr.Value = Color.Transparent;
							}
							else
							{
								Color c = attr.String2Color(sValue);
								attr.Value = c;
							}
							break;
					}

					bReturn = true;

					break;
				}
			}
			
			return bReturn;
		}

		internal bool SetAttributeValue(SvgAttribute._SvgAttribute type, object objValue)
		{
			bool bReturn = false;

			for (int i = 0; i < m_attributes.Count; i++ )
			{
				SvgAttribute attr = (SvgAttribute) m_attributes[i];
				if ( attr.AttributeType == type )
				{
					bReturn = true;
					attr.Value = objValue;

					break;
				}
			}
			
			return bReturn;
		}

		internal bool GetAttributeValue(SvgAttribute._SvgAttribute type, out object objValue)
		{
			bool bReturn = false;
			objValue = null;

			for (int i = 0; i < m_attributes.Count; i++ )
			{
				SvgAttribute attr = (SvgAttribute) m_attributes[i];
				if ( attr.AttributeType == type )
				{
					bReturn = true;
					objValue = attr.Value;

					break;
				}
			}
			
			return bReturn;
		}

		internal object GetAttributeValue(SvgAttribute._SvgAttribute type)
		{
			object objValue;

			if ( GetAttributeValue(type, out objValue) )
			{
				return objValue;
			}
			else
			{
				return null;
			}
		}

		internal string GetAttributeStringValue(SvgAttribute._SvgAttribute type)
		{
			object objValue = GetAttributeValue(type);

			if ( objValue != null )
			{
				return objValue.ToString();
			}
			else
			{
				return "";
			}
		}

		internal int GetAttributeIntValue(SvgAttribute._SvgAttribute type)
		{
			object objValue = GetAttributeValue(type);

			if ( objValue != null )
			{
				int nValue = 0;
				try
				{
					nValue = Convert.ToInt32(objValue.ToString());
				}
				catch
				{
				}

				return nValue;
			}
			else
			{
				return 0;
			}
		}

		internal Color GetAttributeColorValue(SvgAttribute._SvgAttribute type)
		{
			object objValue = GetAttributeValue(type);

			if ( objValue != null )
			{
				Color cValue = Color.Black;
				try
				{
					cValue = (Color) (objValue);
				}
				catch
				{
				}

				return cValue;
			}
			else
			{
				return Color.Black;
			}
		}

		// ---------- PRIVATE METHODS END
		public virtual void ParseStyle(string sval)
		{
		}
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Ajay Britto
Engineer
Singapore Singapore
He is a Microsoft technology enthusiast, who wish to create applications which others find useful.He loves making small tools and getting involved in architecting bigger systems.

He is currently working as a professional developer in a software development firm in .Net technologies.
 
He likes reading technical blogs, contributing to opensource and most importantly, enjoying life.
 
His ambition is to be an impressive software maker.

| Advertise | Privacy | Mobile
Web01 | 2.8.140921.1 | Last Updated 3 Aug 2010
Article Copyright 2010 by Ajay Britto
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid