Printing.cs 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the MIT license.
  3. // See the LICENSE file in the project root for more information.
  4. //
  5. // Purpose: Utility class that conatins properties and methods
  6. // for chart printing.
  7. //
  8. using System;
  9. using System.ComponentModel;
  10. using System.ComponentModel.Design;
  11. using System.Drawing;
  12. using System.Drawing.Drawing2D;
  13. using System.Drawing.Printing;
  14. namespace FastReport.DataVisualization.Charting
  15. {
  16. /// <summary>
  17. /// Chart printing class.
  18. /// </summary>
  19. public class PrintingManager : IDisposable
  20. {
  21. #region Private fields
  22. // Reference to the service container
  23. private IServiceContainer _serviceContainer;
  24. // Reference to the chart image object
  25. private ChartImage _chartImage;
  26. // Chart printing document
  27. private PrintDocument _printDocument;
  28. #endregion
  29. #region Constructors and Service Provider methods
  30. /// <summary>
  31. /// Public constructor is unavailable
  32. /// </summary>
  33. private PrintingManager()
  34. {
  35. }
  36. /// <summary>
  37. /// Public constructor
  38. /// </summary>
  39. /// <param name="container">Service container reference.</param>
  40. public PrintingManager(IServiceContainer container)
  41. {
  42. if(container == null)
  43. {
  44. throw(new ArgumentNullException(SR.ExceptionInvalidServiceContainer));
  45. }
  46. _serviceContainer = container;
  47. }
  48. /// <summary>
  49. /// Returns Printing Manager service object
  50. /// </summary>
  51. /// <param name="serviceType">Requested service type.</param>
  52. /// <returns>Printing Manager sevice object.</returns>
  53. internal object GetService(Type serviceType)
  54. {
  55. if(serviceType == typeof(PrintingManager))
  56. {
  57. return this;
  58. }
  59. throw (new ArgumentException( SR.ExceptionChartSerializerUnsupportedType( serviceType.ToString() ) ) );
  60. }
  61. #endregion
  62. #region Printing methods
  63. /// <summary>
  64. /// Draws chart on the printer graphics.
  65. /// </summary>
  66. /// <param name="graphics">Printer graphics.</param>
  67. /// <param name="position">Position to draw in the graphics.</param>
  68. public void PrintPaint(Graphics graphics, Rectangle position)
  69. {
  70. PrintPaint(new FastReport.GdiGraphics(graphics, false), position);
  71. }
  72. /// <summary>
  73. /// Draws chart on the graphics using graphics wrapper.
  74. /// </summary>
  75. /// <param name="graphics">Graphics wrapper.</param>
  76. /// <param name="position">Position to draw in the graphics.</param>
  77. public void PrintPaint(IGraphics graphics, Rectangle position)
  78. {
  79. // Get a reference to the chart image object
  80. if(_chartImage == null && _serviceContainer != null)
  81. {
  82. _chartImage = (ChartImage)_serviceContainer.GetService(typeof(ChartImage));
  83. }
  84. // Draw chart
  85. if(_chartImage != null)
  86. {
  87. // Change chart size to fit the new position
  88. int oldWidth = _chartImage.Width;
  89. int oldHeight = _chartImage.Height;
  90. _chartImage.Width = position.Width;
  91. _chartImage.Height = position.Height;
  92. // Save graphics state.
  93. IGraphicsState transState = graphics.Save();
  94. // Set required transformation
  95. graphics.TranslateTransform(position.X, position.Y);
  96. // Set printing indicator
  97. _chartImage.isPrinting = true;
  98. // Draw chart
  99. _chartImage.Paint(graphics, false);
  100. // Clear printing indicator
  101. _chartImage.isPrinting = false;
  102. // Restore graphics state.
  103. graphics.Restore(transState);
  104. // Restore old chart position
  105. _chartImage.Width = oldWidth;
  106. _chartImage.Height = oldHeight;
  107. }
  108. }
  109. #if PRINTING
  110. /// <summary>
  111. /// Chart printing document.
  112. /// </summary>
  113. [
  114. Bindable(false),
  115. SRDescription("DescriptionAttributePrintingManager_PrintDocument"),
  116. Browsable(false),
  117. DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
  118. Utilities.SerializationVisibilityAttribute(Utilities.SerializationVisibility.Hidden)
  119. ]
  120. public PrintDocument PrintDocument
  121. {
  122. set
  123. {
  124. _printDocument = value;
  125. }
  126. get
  127. {
  128. if(_printDocument == null)
  129. {
  130. // Create new object
  131. _printDocument = new PrintDocument();
  132. // Hook up to the PrintPage event of the document
  133. this.PrintDocument.PrintPage += new PrintPageEventHandler(pd_PrintPage);
  134. }
  135. return _printDocument;
  136. }
  137. }
  138. /// <summary>
  139. /// Shows Page Setup dialog.
  140. /// </summary>
  141. public void PageSetup()
  142. {
  143. // Create print preview dialog
  144. PageSetupDialog pageSetupDialog = new PageSetupDialog();
  145. // Initialize printing document
  146. pageSetupDialog.Document = this.PrintDocument;
  147. // Show page setup dialog
  148. pageSetupDialog.ShowDialog();
  149. }
  150. /// <summary>
  151. /// Print preview the chart.
  152. /// </summary>
  153. public void PrintPreview()
  154. {
  155. // Create print preview dialog
  156. PrintPreviewDialog printPreviewDialog = new PrintPreviewDialog();
  157. // Initialize printing document
  158. printPreviewDialog.Document = this.PrintDocument;
  159. // Show print preview
  160. printPreviewDialog.ShowDialog();
  161. }
  162. /// <summary>
  163. /// Prints chart.
  164. /// </summary>
  165. /// <param name="showPrintDialog">Indicates if printing dialog should be shown.</param>
  166. public void Print(bool showPrintDialog)
  167. {
  168. // Show Print dialog
  169. if(showPrintDialog)
  170. {
  171. // Create and show Print dialog
  172. PrintDialog printDialog = new PrintDialog();
  173. printDialog.UseEXDialog = true;
  174. printDialog.Document = this.PrintDocument;
  175. DialogResult dialogResult = printDialog.ShowDialog();
  176. // Do not proceed with printing if OK button was not pressed
  177. if(dialogResult != DialogResult.OK && dialogResult != DialogResult.Yes)
  178. {
  179. return;
  180. }
  181. }
  182. // Print chart
  183. this.PrintDocument.Print();
  184. }
  185. /// <summary>
  186. /// Handles PrintPage event of the document.
  187. /// </summary>
  188. /// <param name="sender">Sender object.</param>
  189. /// <param name="ev">Event parameters.</param>
  190. private void pd_PrintPage(object sender, PrintPageEventArgs ev)
  191. {
  192. // Get a reference to the chart image object
  193. if(_chartImage == null && _serviceContainer != null)
  194. {
  195. _chartImage = (ChartImage)_serviceContainer.GetService(typeof(ChartImage));
  196. }
  197. if(_chartImage != null)
  198. {
  199. // Save graphics state.
  200. GraphicsState transState = ev.Graphics.Save();
  201. try
  202. {
  203. Rectangle marginPixel = ev.MarginBounds;
  204. // Display units mean different thing depending if chart is rendered on the display or printed.
  205. // Typically pixels for video displays, and 1/100 inch for printers.
  206. if (ev.Graphics.PageUnit != GraphicsUnit.Pixel)
  207. {
  208. ev.Graphics.PageUnit = GraphicsUnit.Pixel;
  209. marginPixel.X = (int)(marginPixel.X * (ev.Graphics.DpiX / 100.0f));
  210. marginPixel.Y = (int)(marginPixel.Y * (ev.Graphics.DpiY / 100.0f));
  211. marginPixel.Width = (int)(marginPixel.Width * (ev.Graphics.DpiX / 100.0f));
  212. marginPixel.Height = (int)(marginPixel.Height * (ev.Graphics.DpiY / 100.0f));
  213. }
  214. // Calculate chart position rectangle
  215. Rectangle chartPosition = new Rectangle(marginPixel.X, marginPixel.Y, _chartImage.Width, _chartImage.Height);
  216. // Make sure chart corretly fits the margin area
  217. float chartWidthScale = ((float)marginPixel.Width) / ((float)chartPosition.Width);
  218. float chartHeightScale = ((float)marginPixel.Height) / ((float)chartPosition.Height);
  219. chartPosition.Width = (int)(chartPosition.Width * Math.Min(chartWidthScale, chartHeightScale));
  220. chartPosition.Height = (int)(chartPosition.Height * Math.Min(chartWidthScale, chartHeightScale));
  221. // Calculate top left position so that chart is aligned in the center
  222. chartPosition.X += (marginPixel.Width - chartPosition.Width) / 2;
  223. chartPosition.Y += (marginPixel.Height - chartPosition.Height) / 2;
  224. // Draw chart on the printer graphisc
  225. this.PrintPaint(ev.Graphics, chartPosition);
  226. }
  227. finally
  228. {
  229. // Restore graphics state.
  230. ev.Graphics.Restore(transState);
  231. }
  232. }
  233. }
  234. #endif
  235. #endregion
  236. #region IDisposable Members
  237. /// <summary>
  238. /// Releases unmanaged and - optionally - managed resources
  239. /// </summary>
  240. /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
  241. protected virtual void Dispose(bool disposing)
  242. {
  243. if (disposing)
  244. {
  245. //Free managed resources
  246. if (_printDocument != null)
  247. {
  248. _printDocument.Dispose();
  249. _printDocument = null;
  250. }
  251. }
  252. }
  253. /// <summary>
  254. /// Performs freeing, releasing, or resetting managed resources.
  255. /// </summary>
  256. public void Dispose()
  257. {
  258. this.Dispose(true);
  259. GC.SuppressFinalize(this);
  260. }
  261. #endregion
  262. }
  263. }