using System; using System.ComponentModel; using System.Drawing; using System.Drawing.Printing; namespace DevComponents.DotNetBar.Charts { [ToolboxItem(false)] public class ChartPrint : PrintDocument { #region Private variables private ChartControl _ChartControl; private Image _ChartImage; private Rectangle _PrintBounds; private int _Columns; private int _Rows; private int _CurCell; private FitToPageScale _FitToPageScale = FitToPageScale.Normal; #endregion #region Constructors /// /// ChartPrint /// public ChartPrint() : base() { } /// /// ChartPrint /// /// ChartControl public ChartPrint(ChartControl chartControl) : base() { _ChartControl = chartControl; } /// /// ChartPrint /// /// ChartControl /// FitToPageScale public ChartPrint(ChartControl chartControl, FitToPageScale fitToPageScale) : base() { _ChartControl = chartControl; _FitToPageScale = fitToPageScale; } #endregion #region Public properties #region FitToPageScale /// /// Gets or sets how the chart is scaled /// to fit the page when printing. /// public FitToPageScale FitToPageScale { get { return (_FitToPageScale); } set { _FitToPageScale = value; } } #endregion #endregion #region OnBeginPrint protected override void OnBeginPrint(PrintEventArgs e) { base.OnBeginPrint(e); if (_ChartControl == null) throw new Exception("ChartControl has not been set."); Size size = _ChartControl.ClientSize; _PrintBounds = DefaultPageSettings.Bounds; Margins margins = DefaultPageSettings.Margins; _PrintBounds.X += margins.Left; _PrintBounds.Width -= (margins.Left + margins.Right); _PrintBounds.Y += margins.Top; _PrintBounds.Height -= (margins.Top + margins.Bottom); _Columns = (int)Math.Ceiling((double)size.Width / _PrintBounds.Width); _Rows = (int)Math.Ceiling((double)size.Height / _PrintBounds.Height); _CurCell = 0; _ChartImage = new Bitmap(size.Width, size.Height); using (Graphics g = Graphics.FromImage(_ChartImage)) _ChartControl.PaintTo(g); } #endregion #region OnPrintPage protected override void OnPrintPage(PrintPageEventArgs e) { base.OnPrintPage(e); switch (FitToPageScale) { case Charts.FitToPageScale.Stretch: PrintStretchPage(e); break; case Charts.FitToPageScale.Zoom: PrintZoomPage(e); break; default: PrintNormalPage(e); break; } } #region PrintNormalPage private void PrintNormalPage(PrintPageEventArgs e) { Graphics g = e.Graphics; int curRow = _CurCell / _Columns; int curColumn = _CurCell % _Columns; int x = curColumn * _PrintBounds.Width; int y = curRow * _PrintBounds.Height; Rectangle rs = new Rectangle(x, y, _ChartImage.Width - x, _ChartImage.Height - y); Rectangle rd = new Rectangle(_PrintBounds.X, _PrintBounds.Y, _ChartImage.Width - x, _ChartImage.Height - y); Region saveClip = g.Clip; g.SetClip(_PrintBounds); g.DrawImage(_ChartImage, rd, rs, GraphicsUnit.Pixel); g.Clip = saveClip; _CurCell++; e.HasMorePages = (_CurCell < _Columns * _Rows); } #endregion #region PrintStretchPage private void PrintStretchPage(PrintPageEventArgs e) { Rectangle rs = new Rectangle(0, 0, _ChartImage.Width, _ChartImage.Height); e.Graphics.DrawImage(_ChartImage, _PrintBounds, rs, GraphicsUnit.Pixel); e.HasMorePages = false; } #endregion #region PrintZoomPage private void PrintZoomPage(PrintPageEventArgs e) { Rectangle rd = _PrintBounds; SizeF size = new SizeF(_ChartImage.Width / _ChartImage.HorizontalResolution, _ChartImage.Height / _ChartImage.VerticalResolution); float scale = Math.Min(rd.Width / size.Width, rd.Height / size.Height); size.Width *= scale; size.Height *= scale; e.Graphics.DrawImage(_ChartImage, rd.X, rd.Y, size.Width, size.Height); e.HasMorePages = false; } #endregion #endregion #region OnEndPrint protected override void OnEndPrint(PrintEventArgs e) { base.OnEndPrint(e); if (_ChartImage != null) _ChartImage.Dispose(); _ChartImage = null; } #endregion } #region FitToPageScale public enum FitToPageScale { Normal, Stretch, Zoom, } #endregion }