| /******************************************************************************* | 
 |  * You may amend and distribute as you like, but don't remove this header! | 
 |  * | 
 |  * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets. | 
 |  * See http://www.codeplex.com/EPPlus for details. | 
 |  * | 
 |  * Copyright (C) 2011  Jan Källman | 
 |  * | 
 |  * This library is free software; you can redistribute it and/or | 
 |  * modify it under the terms of the GNU Lesser General Public | 
 |  * License as published by the Free Software Foundation; either | 
 |  * version 2.1 of the License, or (at your option) any later version. | 
 |  | 
 |  * This library is distributed in the hope that it will be useful, | 
 |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
 |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.   | 
 |  * See the GNU Lesser General Public License for more details. | 
 |  * | 
 |  * The GNU Lesser General Public License can be viewed at http://www.opensource.org/licenses/lgpl-license.php | 
 |  * If you unfamiliar with this license or have questions about it, here is an http://www.gnu.org/licenses/gpl-faq.html | 
 |  * | 
 |  * All code and executables are provided "as is" with no warranty either express or implied.  | 
 |  * The author accepts no liability for any damage or loss of business that this product may cause. | 
 |  * | 
 |  * Code change notes: | 
 |  *  | 
 |  * Author							Change						Date | 
 |  * ****************************************************************************** | 
 |  * Jan Källman		Initial Release		        2010-06-01 | 
 |  * Jan Källman		License changed GPL-->LGPL 2011-12-16 | 
 |  *******************************************************************************/ | 
 | using System; | 
 | using System.Collections; | 
 | using System.Collections.Generic; | 
 | using System.Globalization; | 
 | using System.Text; | 
 | using System.Xml; | 
 | using OfficeOpenXml.Drawing.Chart; | 
 | namespace OfficeOpenXml.Drawing | 
 | { | 
 |     /// <summary> | 
 |     /// Text anchoring | 
 |     /// </summary> | 
 |     public enum eTextAnchoringType | 
 |     { | 
 |         Bottom, | 
 |         Center, | 
 |         Distributed, | 
 |         Justify, | 
 |         Top | 
 |     } | 
 |     /// <summary> | 
 |     /// Vertical text type | 
 |     /// </summary> | 
 |     public enum eTextVerticalType | 
 |     { | 
 |         EastAsianVertical, | 
 |         Horizontal, | 
 |         MongolianVertical, | 
 |         Vertical, | 
 |         Vertical270, | 
 |         WordArtVertical, | 
 |         WordArtVerticalRightToLeft | 
 |  | 
 |     } | 
 |     /// <summary> | 
 |     /// How the drawing will be resized. | 
 |     /// </summary> | 
 |     public enum eEditAs | 
 |     { | 
 |         /// <summary> | 
 |         /// Specifies that the current start and end positions shall | 
 |         /// be maintained with respect to the distances from the | 
 |         /// absolute start point of the worksheet. | 
 |         /// </summary> | 
 |         Absolute, | 
 |         /// <summary> | 
 |         /// Specifies that the current drawing shall move with its | 
 |         ///row and column (i.e. the object is anchored to the | 
 |         /// actual from row and column), but that the size shall | 
 |         ///remain absolute. | 
 |         /// </summary> | 
 |         OneCell, | 
 |         /// <summary> | 
 |         /// Specifies that the current drawing shall move and | 
 |         /// resize to maintain its row and column anchors (i.e. the | 
 |         /// object is anchored to the actual from and to row and column). | 
 |         /// </summary> | 
 |         TwoCell | 
 |     } | 
 |     /// <summary> | 
 |     /// Base class for twoanchored drawings.  | 
 |     /// Drawings are Charts, shapes and Pictures. | 
 |     /// </summary> | 
 |     public class ExcelDrawing : XmlHelper, IDisposable  | 
 |     { | 
 |         /// <summary> | 
 |         /// Position of the a drawing. | 
 |         /// </summary> | 
 |         public class ExcelPosition : XmlHelper | 
 |         { | 
 |             XmlNode _node; | 
 |             XmlNamespaceManager _ns;             | 
 |             internal ExcelPosition(XmlNamespaceManager ns, XmlNode node) : | 
 |                 base (ns,node) | 
 |             { | 
 |                 _node = node; | 
 |                 _ns = ns; | 
 |             } | 
 |             const string colPath="xdr:col"; | 
 |             public int Column | 
 |             { | 
 |                 get | 
 |                 { | 
 |                     return GetXmlNodeInt(colPath); | 
 |                 } | 
 |                 set | 
 |                 { | 
 |                     SetXmlNodeString(colPath, value.ToString()); | 
 |                 } | 
 |             } | 
 |             const string rowPath="xdr:row"; | 
 |             public int Row | 
 |             { | 
 |                 get | 
 |                 { | 
 |                     return GetXmlNodeInt(rowPath); | 
 |                 } | 
 |                 set | 
 |                 { | 
 |                     SetXmlNodeString(rowPath, value.ToString()); | 
 |                 } | 
 |             } | 
 |             const string colOffPath = "xdr:colOff"; | 
 |             /// <summary> | 
 |             /// Column Offset | 
 |             ///  | 
 |             /// EMU units   1cm         =   1/360000  | 
 |             ///             1US inch    =   1/914400 | 
 |             ///             1pixel      =   1/9525 | 
 |             /// </summary> | 
 |             public int ColumnOff | 
 |             { | 
 |                 get | 
 |                 { | 
 |                     return GetXmlNodeInt(colOffPath); | 
 |                 } | 
 |                 set | 
 |                 { | 
 |                     SetXmlNodeString(colOffPath, value.ToString()); | 
 |                 } | 
 |             } | 
 |             const string rowOffPath = "xdr:rowOff"; | 
 |             /// <summary> | 
 |             /// Row Offset | 
 |             ///  | 
 |             /// EMU units   1cm         =   1/360000  | 
 |             ///             1US inch    =   1/914400 | 
 |             ///             1pixel      =   1/9525 | 
 |             /// </summary> | 
 |             public int RowOff | 
 |             { | 
 |                 get | 
 |                 { | 
 |                     return GetXmlNodeInt(rowOffPath); | 
 |                 } | 
 |                 set | 
 |                 { | 
 |                     SetXmlNodeString(rowOffPath, value.ToString()); | 
 |                 } | 
 |             } | 
 |         } | 
 |         protected ExcelDrawings _drawings; | 
 |         protected XmlNode _topNode; | 
 |         string _nameXPath; | 
 |         protected internal int _id; | 
 |         const float STANDARD_DPI = 96; | 
 |         public const int EMU_PER_PIXEL = 9525; | 
 |  | 
 |         internal ExcelDrawing(ExcelDrawings drawings, XmlNode node, string nameXPath) : | 
 |             base(drawings.NameSpaceManager, node) | 
 |         { | 
 |             _drawings = drawings; | 
 |             _topNode = node; | 
 |             _id = drawings.Worksheet.Workbook._nextDrawingID++; | 
 |             XmlNode posNode = node.SelectSingleNode("xdr:from", drawings.NameSpaceManager); | 
 |             if (node != null) | 
 |             { | 
 |                 From = new ExcelPosition(drawings.NameSpaceManager, posNode); | 
 |             } | 
 |             posNode = node.SelectSingleNode("xdr:to", drawings.NameSpaceManager); | 
 |             if (node != null) | 
 |             { | 
 |                 To = new ExcelPosition(drawings.NameSpaceManager, posNode); | 
 |             } | 
 |             else | 
 |             { | 
 |                 To = null; | 
 |             } | 
 |             _nameXPath = nameXPath; | 
 |             SchemaNodeOrder = new string[] { "from", "to", "graphicFrame", "sp", "clientData"  }; | 
 |         } | 
 |         /// <summary> | 
 |         /// The name of the drawing object | 
 |         /// </summary> | 
 |         public string Name  | 
 |         { | 
 |             get | 
 |             { | 
 |                 try | 
 |                 { | 
 |                     if (_nameXPath == "") return ""; | 
 |                     return GetXmlNodeString(_nameXPath); | 
 |                 } | 
 |                 catch | 
 |                 { | 
 |                     return "";  | 
 |                 } | 
 |             } | 
 |             set | 
 |             { | 
 |                 try | 
 |                 { | 
 |                     if (_nameXPath == "") throw new NotImplementedException(); | 
 |                     SetXmlNodeString(_nameXPath, value); | 
 |                 } | 
 |                 catch | 
 |                 { | 
 |                     throw new NotImplementedException(); | 
 |                 } | 
 |             } | 
 |         } | 
 |         /// <summary> | 
 |         /// How Excel resize drawings when the column width is changed within Excel. | 
 |         /// The width of drawings are currently NOT resized in EPPLus when the column width changes | 
 |         /// </summary> | 
 |         public eEditAs EditAs | 
 |         { | 
 |             get | 
 |             { | 
 |                 try | 
 |                 { | 
 |                     string s = GetXmlNodeString("@editAs"); | 
 |                     if (s == "") | 
 |                     { | 
 |                         return eEditAs.TwoCell; | 
 |                     } | 
 |                     else | 
 |                     { | 
 |                         return (eEditAs)Enum.Parse(typeof(eEditAs), s,true); | 
 |                     } | 
 |                 } | 
 |                 catch | 
 |                 { | 
 |                     return eEditAs.TwoCell; | 
 |                 } | 
 |             } | 
 |             set | 
 |             { | 
 |                 string s=value.ToString(); | 
 |                 SetXmlNodeString("@editAs", s.Substring(0,1).ToLower(CultureInfo.InvariantCulture)+s.Substring(1,s.Length-1)); | 
 |             } | 
 |         } | 
 |         const string lockedPath="xdr:clientData/@fLocksWithSheet"; | 
 |         /// <summary> | 
 |         /// Lock drawing | 
 |         /// </summary> | 
 |         public bool Locked | 
 |         { | 
 |             get | 
 |             { | 
 |                 return GetXmlNodeBool(lockedPath, true); | 
 |             } | 
 |             set | 
 |             { | 
 |                 SetXmlNodeBool(lockedPath, value); | 
 |             } | 
 |         } | 
 |         const string printPath = "xdr:clientData/@fPrintsWithSheet"; | 
 |         /// <summary> | 
 |         /// Print drawing with sheet | 
 |         /// </summary> | 
 |         public bool Print | 
 |         { | 
 |             get | 
 |             { | 
 |                 return GetXmlNodeBool(printPath, true); | 
 |             } | 
 |             set | 
 |             { | 
 |                 SetXmlNodeBool(printPath, value); | 
 |             } | 
 |         }        /// <summary> | 
 |         /// Top Left position | 
 |         /// </summary> | 
 |         public ExcelPosition From { get; set; } | 
 |         /// <summary> | 
 |         /// Bottom right position | 
 |         /// </summary> | 
 |         public ExcelPosition To | 
 |         { | 
 |             get; | 
 |             set; | 
 |         } | 
 |         /// <summary> | 
 |         /// Add new Drawing types here | 
 |         /// </summary> | 
 |         /// <param name="drawings">The drawing collection</param> | 
 |         /// <param name="node">Xml top node</param> | 
 |         /// <returns>The Drawing object</returns> | 
 |         internal static ExcelDrawing GetDrawing(ExcelDrawings drawings, XmlNode node) | 
 |         { | 
 |             if (node.SelectSingleNode("xdr:sp", drawings.NameSpaceManager) != null) | 
 |             { | 
 |                 return new ExcelShape(drawings, node); | 
 |             } | 
 |             else if (node.SelectSingleNode("xdr:pic", drawings.NameSpaceManager) != null) | 
 |             { | 
 |                 return new ExcelPicture(drawings, node); | 
 |             } | 
 |             else if (node.SelectSingleNode("xdr:graphicFrame", drawings.NameSpaceManager) != null) | 
 |             { | 
 |                 return ExcelChart.GetChart(drawings, node); | 
 |             } | 
 |             else | 
 |             { | 
 |                 return new ExcelDrawing(drawings, node, ""); | 
 |             } | 
 |         } | 
 |         internal string Id | 
 |         { | 
 |             get { return _id.ToString(); } | 
 |         } | 
 |         internal static string GetTextAchoringText(eTextAnchoringType value) | 
 |         { | 
 |             switch (value) | 
 |             { | 
 |                 case eTextAnchoringType.Bottom: | 
 |                     return "b"; | 
 |                 case eTextAnchoringType.Center: | 
 |                     return "ctr"; | 
 |                 case eTextAnchoringType.Distributed: | 
 |                     return "dist"; | 
 |                 case eTextAnchoringType.Justify: | 
 |                     return "just"; | 
 |                 default: | 
 |                     return "t"; | 
 |             } | 
 |         } | 
 |         internal static eTextAnchoringType GetTextAchoringEnum(string text) | 
 |         { | 
 |             switch (text) | 
 |             { | 
 |                 case "b": | 
 |                     return eTextAnchoringType.Bottom; | 
 |                 case "ctr": | 
 |                     return eTextAnchoringType.Center; | 
 |                 case "dist": | 
 |                     return eTextAnchoringType.Distributed; | 
 |                 case "just": | 
 |                     return eTextAnchoringType.Justify; | 
 |                 default: | 
 |                     return eTextAnchoringType.Top; | 
 |             } | 
 |         } | 
 |         internal static string GetTextVerticalText(eTextVerticalType value) | 
 |         { | 
 |             switch (value) | 
 |             { | 
 |                 case eTextVerticalType.EastAsianVertical: | 
 |                     return "eaVert"; | 
 |                 case eTextVerticalType.MongolianVertical: | 
 |                     return "mongolianVert"; | 
 |                 case eTextVerticalType.Vertical: | 
 |                     return "vert"; | 
 |                 case eTextVerticalType.Vertical270: | 
 |                     return "vert270"; | 
 |                 case eTextVerticalType.WordArtVertical: | 
 |                     return "wordArtVert"; | 
 |                 case eTextVerticalType.WordArtVerticalRightToLeft: | 
 |                     return "wordArtVertRtl"; | 
 |                 default: | 
 |                     return "horz"; | 
 |             } | 
 |         } | 
 |         internal static eTextVerticalType GetTextVerticalEnum(string text) | 
 |         { | 
 |             switch (text) | 
 |             { | 
 |                 case "eaVert": | 
 |                     return eTextVerticalType.EastAsianVertical; | 
 |                 case "mongolianVert": | 
 |                     return eTextVerticalType.MongolianVertical; | 
 |                 case "vert": | 
 |                     return eTextVerticalType.Vertical; | 
 |                 case "vert270": | 
 |                     return eTextVerticalType.Vertical270; | 
 |                 case "wordArtVert": | 
 |                     return eTextVerticalType.WordArtVertical; | 
 |                 case "wordArtVertRtl": | 
 |                     return eTextVerticalType.WordArtVerticalRightToLeft; | 
 |                 default: | 
 |                     return eTextVerticalType.Horizontal; | 
 |             } | 
 |         } | 
 |         #region "Internal sizing functions" | 
 |         internal int GetPixelLeft() | 
 |         { | 
 |             ExcelWorksheet ws = _drawings.Worksheet; | 
 |             decimal mdw = ws.Workbook.MaxFontWidth; | 
 |  | 
 |             int pix = 0; | 
 |             for (int col = 0; col < From.Column; col++) | 
 |             { | 
 |                 pix += (int)decimal.Truncate(((256 * GetColumnWidth(col + 1) + decimal.Truncate(128 / (decimal)mdw)) / 256) * mdw); | 
 |             } | 
 |             pix += From.ColumnOff / EMU_PER_PIXEL; | 
 |             return pix; | 
 |         } | 
 |         internal int GetPixelTop() | 
 |         { | 
 |             ExcelWorksheet ws = _drawings.Worksheet; | 
 |             int pix = 0; | 
 |             for (int row = 0; row < From.Row; row++) | 
 |             { | 
 |                 pix += (int)(GetRowWidth(row + 1) / 0.75); | 
 |             } | 
 |             pix += From.RowOff / EMU_PER_PIXEL; | 
 |             return pix; | 
 |         } | 
 |         internal int GetPixelWidth() | 
 |         { | 
 |             ExcelWorksheet ws = _drawings.Worksheet; | 
 |             decimal mdw = ws.Workbook.MaxFontWidth; | 
 |  | 
 |             int pix = -From.ColumnOff / EMU_PER_PIXEL; | 
 |             for (int col = From.Column + 1; col <= To.Column; col++) | 
 |             { | 
 |                 pix += (int)decimal.Truncate(((256 * GetColumnWidth(col) + decimal.Truncate(128 / (decimal)mdw)) / 256) * mdw); | 
 |             } | 
 |             pix += To.ColumnOff / EMU_PER_PIXEL; | 
 |             return pix; | 
 |         } | 
 |         internal int GetPixelHeight() | 
 |         { | 
 |             ExcelWorksheet ws = _drawings.Worksheet; | 
 |  | 
 |             int pix = -(From.RowOff / EMU_PER_PIXEL); | 
 |             for (int row = From.Row + 1; row <= To.Row; row++) | 
 |             { | 
 |                 pix += (int)(GetRowWidth(row) / 0.75); | 
 |             } | 
 |             pix += To.RowOff / EMU_PER_PIXEL; | 
 |             return pix; | 
 |         } | 
 |  | 
 |         private decimal GetColumnWidth(int col) | 
 |         { | 
 |             ExcelWorksheet ws = _drawings.Worksheet; | 
 |             var column = ws._values.GetValue(0, col) as ExcelColumn; | 
 |             if (column == null)   //Check that the column exists | 
 |             { | 
 |                 return (decimal)ws.DefaultColWidth; | 
 |             } | 
 |             else | 
 |             { | 
 |                 return (decimal)ws.Column(col).VisualWidth; | 
 |             } | 
 |         } | 
 |         private double GetRowWidth(int row) | 
 |         { | 
 |             ExcelWorksheet ws = _drawings.Worksheet; | 
 |             object o = null; | 
 |             if (ws._values.Exists(row, 0, ref o) && o != null)   //Check that the row exists | 
 |             { | 
 |                 var internalRow = (RowInternal)o; | 
 |                 if (internalRow.Height >= 0) | 
 |                 { | 
 |                     return internalRow.Height; | 
 |                 } | 
 |             } | 
 |             return (double)ws.DefaultRowHeight; | 
 |         } | 
 |         internal void SetPixelTop(int pixels) | 
 |         { | 
 |             ExcelWorksheet ws = _drawings.Worksheet; | 
 |             decimal mdw = ws.Workbook.MaxFontWidth; | 
 |             int prevPix = 0; | 
 |             int pix = (int)(GetRowWidth(1) / 0.75); | 
 |             int row = 2; | 
 |  | 
 |             while (pix < pixels) | 
 |             { | 
 |                 prevPix = pix; | 
 |                 pix += (int)(GetRowWidth(row++) / 0.75); | 
 |             } | 
 |  | 
 |             if (pix == pixels) | 
 |             { | 
 |                 From.Row = row - 1; | 
 |                 From.RowOff = 0; | 
 |             } | 
 |             else | 
 |             { | 
 |                 From.Row = row - 2; | 
 |                 From.RowOff = (pixels - prevPix) * EMU_PER_PIXEL; | 
 |             } | 
 |         } | 
 |         internal void SetPixelLeft(int pixels) | 
 |         { | 
 |             ExcelWorksheet ws = _drawings.Worksheet; | 
 |             decimal mdw = ws.Workbook.MaxFontWidth; | 
 |             int prevPix = 0; | 
 |             int pix = (int)decimal.Truncate(((256 * GetColumnWidth(1) + decimal.Truncate(128 / (decimal)mdw)) / 256) * mdw); | 
 |             int col = 2; | 
 |  | 
 |             while (pix < pixels) | 
 |             { | 
 |                 prevPix = pix; | 
 |                 pix += (int)decimal.Truncate(((256 * GetColumnWidth(col++) + decimal.Truncate(128 / (decimal)mdw)) / 256) * mdw); | 
 |             } | 
 |             if (pix == pixels) | 
 |             { | 
 |                 From.Column = col - 1; | 
 |                 From.ColumnOff = 0; | 
 |             } | 
 |             else | 
 |             { | 
 |                 From.Column = col - 2; | 
 |                 From.ColumnOff = (pixels - prevPix) * EMU_PER_PIXEL; | 
 |             } | 
 |         } | 
 |         internal void SetPixelHeight(int pixels) | 
 |         { | 
 |             SetPixelHeight(pixels, STANDARD_DPI); | 
 |         } | 
 |         internal void SetPixelHeight(int pixels, float dpi) | 
 |         { | 
 |             ExcelWorksheet ws = _drawings.Worksheet; | 
 |             //decimal mdw = ws.Workbook.MaxFontWidth; | 
 |             pixels = (int)(pixels / (dpi / STANDARD_DPI) + .5); | 
 |             int pixOff = pixels - ((int)(ws.Row(From.Row + 1).Height / 0.75) - (int)(From.RowOff / EMU_PER_PIXEL)); | 
 |             int prevPixOff = pixels; | 
 |             int row = From.Row + 1; | 
 |  | 
 |             while (pixOff >= 0) | 
 |             { | 
 |                 prevPixOff = pixOff; | 
 |                 pixOff -= (int)(GetRowWidth(++row) / 0.75); | 
 |             } | 
 |             To.Row = row - 1; | 
 |             if (From.Row == To.Row) | 
 |             { | 
 |                 To.RowOff = From.RowOff + (pixels) * EMU_PER_PIXEL; | 
 |             } | 
 |             else | 
 |             { | 
 |                 To.RowOff = prevPixOff * EMU_PER_PIXEL; | 
 |             } | 
 |         } | 
 |         internal void SetPixelWidth(int pixels) | 
 |         { | 
 |             SetPixelWidth(pixels, STANDARD_DPI); | 
 |         } | 
 |         internal void SetPixelWidth(int pixels, float dpi) | 
 |         { | 
 |             ExcelWorksheet ws = _drawings.Worksheet; | 
 |             decimal mdw = ws.Workbook.MaxFontWidth; | 
 |  | 
 |             pixels = (int)(pixels / (dpi / STANDARD_DPI) + .5); | 
 |             int pixOff = (int)pixels - ((int)decimal.Truncate(((256 * GetColumnWidth(From.Column + 1) + decimal.Truncate(128 / (decimal)mdw)) / 256) * mdw) - From.ColumnOff / EMU_PER_PIXEL); | 
 |             int prevPixOff = From.ColumnOff / EMU_PER_PIXEL + (int)pixels; | 
 |             int col = From.Column + 2; | 
 |  | 
 |             while (pixOff >= 0) | 
 |             { | 
 |                 prevPixOff = pixOff; | 
 |                 pixOff -= (int)decimal.Truncate(((256 * GetColumnWidth(col++) + decimal.Truncate(128 / (decimal)mdw)) / 256) * mdw); | 
 |             } | 
 |  | 
 |             To.Column = col - 2; | 
 |             To.ColumnOff = prevPixOff * EMU_PER_PIXEL; | 
 |         } | 
 |         #endregion | 
 |         #region "Public sizing functions" | 
 |         /// <summary> | 
 |         /// Set the top left corner of a drawing.  | 
 |         /// Note that resizing columns / rows after using this function will effect the position of the drawing | 
 |         /// </summary> | 
 |         /// <param name="PixelTop">Top pixel</param> | 
 |         /// <param name="PixelLeft">Left pixel</param> | 
 |         public void SetPosition(int PixelTop, int PixelLeft) | 
 |         { | 
 |             int width = GetPixelWidth(); | 
 |             int height = GetPixelHeight(); | 
 |  | 
 |             SetPixelTop(PixelTop); | 
 |             SetPixelLeft(PixelLeft); | 
 |  | 
 |             SetPixelWidth(width); | 
 |             SetPixelHeight(height); | 
 |         } | 
 |         /// <summary> | 
 |         /// Set the top left corner of a drawing.  | 
 |         /// Note that resizing columns / rows after using this function will effect the position of the drawing | 
 |         /// </summary> | 
 |         /// <param name="Row">Start row</param> | 
 |         /// <param name="RowOffsetPixels">Offset in pixels</param> | 
 |         /// <param name="Column">Start Column</param> | 
 |         /// <param name="ColumnOffsetPixels">Offset in pixels</param> | 
 |         public void SetPosition(int Row, int RowOffsetPixels, int Column, int ColumnOffsetPixels) | 
 |         { | 
 |             int width = GetPixelWidth(); | 
 |             int height = GetPixelHeight(); | 
 |  | 
 |             From.Row = Row; | 
 |             From.RowOff = RowOffsetPixels * EMU_PER_PIXEL; | 
 |             From.Column = Column; | 
 |             From.ColumnOff = ColumnOffsetPixels * EMU_PER_PIXEL; | 
 |  | 
 |             SetPixelWidth(width); | 
 |             SetPixelHeight(height); | 
 |         } | 
 |         /// <summary> | 
 |         /// Set size in Percent | 
 |         /// Note that resizing columns / rows after using this function will effect the size of the drawing | 
 |         /// </summary> | 
 |         /// <param name="Percent"></param> | 
 |         public virtual void SetSize(int Percent) | 
 |         { | 
 |             int width = GetPixelWidth(); | 
 |             int height = GetPixelHeight(); | 
 |  | 
 |             width = (int)(width * ((decimal)Percent / 100)); | 
 |             height = (int)(height * ((decimal)Percent / 100)); | 
 |  | 
 |             SetPixelWidth(width, 96); | 
 |             SetPixelHeight(height, 96); | 
 |         } | 
 |         /// <summary> | 
 |         /// Set size in pixels | 
 |         /// Note that resizing columns / rows after using this function will effect the size of the drawing | 
 |         /// </summary> | 
 |         /// <param name="PixelWidth">Width in pixels</param> | 
 |         /// <param name="PixelHeight">Height in pixels</param> | 
 |         public void SetSize(int PixelWidth, int PixelHeight) | 
 |         { | 
 |             SetPixelWidth(PixelWidth); | 
 |             SetPixelHeight(PixelHeight); | 
 |         } | 
 |         #endregion | 
 |         internal virtual void DeleteMe() | 
 |         { | 
 |             TopNode.ParentNode.RemoveChild(TopNode); | 
 |         } | 
 |  | 
 |         public virtual void Dispose() | 
 |         { | 
 |             _topNode = null; | 
 |         } | 
 |     } | 
 | } |