--- /dev/null
+/* $Id$ $Revision$ */\r
+/* vim:set shiftwidth=4 ts=8: */\r
+\r
+/**********************************************************\r
+* This software is part of the graphviz package *\r
+* http://www.graphviz.org/ *\r
+* *\r
+* Copyright (c) 1994-2008 AT&T Corp. *\r
+* and is licensed under the *\r
+* Common Public License, Version 1.0 *\r
+* by AT&T Corp. *\r
+* *\r
+* Information and Software Systems Research *\r
+* AT&T Research, Florham Park NJ *\r
+**********************************************************/\r
+\r
+using System;\r
+using System.Drawing;\r
+using System.Drawing.Printing;\r
+using System.Text;\r
+\r
+namespace Graphviz\r
+{\r
+ public class TileableImagePrinter\r
+ {\r
+ public TileableImagePrinter(PrintDocument document, Image image)\r
+ {\r
+ _image = image;\r
+ \r
+ /* calculate imageable area = page area - margins */\r
+ Rectangle bounds = document.DefaultPageSettings.Bounds;\r
+ Margins margins = document.DefaultPageSettings.Margins;\r
+ Rectangle pageBounds = new Rectangle(\r
+ bounds.Location + new Size(margins.Left, margins.Right),\r
+ bounds.Size - new Size(margins.Left + margins.Right, margins.Top + margins.Bottom));\r
+ _pageSize = pageBounds.Size;\r
+ _pageRegion = new Region(pageBounds);\r
+ \r
+ /* calculate image size in 1/100 of an inch */\r
+ _imageSize = new SizeF(image.Size.Width * HUNDREDTH_INCH_PER_PIXEL,\r
+ image.Size.Height * HUNDREDTH_INCH_PER_PIXEL);\r
+\r
+ /* calculate how many page columns + rows required to tile out the image */\r
+ _pageColumnCount = ((int)(_imageSize.Width / _pageSize.Width)) + 1;\r
+ _pageRowCount = ((int)(_imageSize.Height / _pageSize.Height)) + 1;\r
+ \r
+ /* calculate the offset of the image on the first page, from page margins + 1/2 of difference between image size and total page size */\r
+ _imageOffset = new PointF(\r
+ pageBounds.Left + (_pageColumnCount * _pageSize.Width - _imageSize.Width) / 2.0f,\r
+ pageBounds.Top + (_pageRowCount * _pageSize.Height - _imageSize.Height) / 2.0f);\r
+ \r
+ /* start at page 0 */\r
+ _page = 0;\r
+ \r
+ _printPage = delegate(object sender, PrintPageEventArgs eventArgs)\r
+ {\r
+ /* which page column + row we are printing */\r
+ int pageColumn = _page % _pageColumnCount;\r
+ int pageRow = _page / _pageColumnCount;\r
+\r
+ /* clip to the imageable area and draw the offset image into it */\r
+ eventArgs.Graphics.Clip = _pageRegion;\r
+ eventArgs.Graphics.DrawImage(_image, new RectangleF(\r
+ _imageOffset - new SizeF(pageColumn * _pageSize.Width, pageRow * _pageSize.Height),\r
+ _imageSize));\r
+ \r
+ /* only print column * row pages */\r
+ eventArgs.HasMorePages = ++_page < _pageColumnCount * _pageRowCount;\r
+ };\r
+ \r
+ _endPrint = delegate(object sender, PrintEventArgs eventArgs)\r
+ {\r
+ /* detach handlers from the print document */\r
+ PrintDocument printDocument = (PrintDocument)sender;\r
+ printDocument.PrintPage -= _printPage;\r
+ printDocument.EndPrint -= _endPrint;\r
+ };\r
+ \r
+ /* attach handlers to the print document */\r
+ document.PrintPage += _printPage;\r
+ document.EndPrint += _endPrint;\r
+ \r
+ }\r
+ \r
+ private const float HUNDREDTH_INCH_PER_PIXEL = 100.0f / 96.0f;\r
+ \r
+ private readonly Image _image;\r
+ \r
+ private readonly Size _pageSize;\r
+ private readonly Region _pageRegion;\r
+ private readonly SizeF _imageSize;\r
+ private readonly int _pageColumnCount;\r
+ private readonly int _pageRowCount;\r
+ private readonly PointF _imageOffset;\r
+ \r
+ private int _page;\r
+ \r
+ private readonly PrintPageEventHandler _printPage;\r
+ private readonly PrintEventHandler _endPrint; }\r
+}\r