|  | /******************************************************************************* | 
|  | * 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; | 
|  | } | 
|  | } | 
|  | } |