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
}