1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
|
/* $Id: TileableImagePrinter.cs,v 1.3 2009/06/03 01:10:59 ellson Exp $ $Revision: 1.3 $ */
/* vim:set shiftwidth=4 ts=8: */
/**********************************************************
* This software is part of the graphviz package *
* http://www.graphviz.org/ *
* *
* Copyright (c) 1994-2008 AT&T Corp. *
* and is licensed under the *
* Common Public License, Version 1.0 *
* by AT&T Corp. *
* *
* Information and Software Systems Research *
* AT&T Research, Florham Park NJ *
**********************************************************/
using System;
using System.Drawing;
using System.Drawing.Printing;
using System.Text;
namespace Graphviz
{
public class TileableImagePrinter
{
public TileableImagePrinter(PrintDocument document, Image image)
{
_image = image;
/* calculate imageable area = page area - margins */
Rectangle bounds = document.DefaultPageSettings.Bounds;
Margins margins = document.DefaultPageSettings.Margins;
Rectangle pageBounds = new Rectangle(
bounds.Location + new Size(margins.Left, margins.Right),
bounds.Size - new Size(margins.Left + margins.Right, margins.Top + margins.Bottom));
_pageSize = pageBounds.Size;
_pageRegion = new Region(pageBounds);
/* calculate image size in 1/100 of an inch */
_imageSize = new SizeF(image.Size.Width * HUNDREDTH_INCH_PER_PIXEL,
image.Size.Height * HUNDREDTH_INCH_PER_PIXEL);
/* calculate how many page columns + rows required to tile out the image */
_pageColumnCount = ((int)(_imageSize.Width / _pageSize.Width)) + 1;
_pageRowCount = ((int)(_imageSize.Height / _pageSize.Height)) + 1;
/* calculate the offset of the image on the first page, from page margins + 1/2 of difference between image size and total page size */
_imageOffset = new PointF(
pageBounds.Left + (_pageColumnCount * _pageSize.Width - _imageSize.Width) / 2.0f,
pageBounds.Top + (_pageRowCount * _pageSize.Height - _imageSize.Height) / 2.0f);
/* start at page 0 */
_page = 0;
_printPage = delegate(object sender, PrintPageEventArgs eventArgs)
{
/* which page column + row we are printing */
int pageColumn = _page % _pageColumnCount;
int pageRow = _page / _pageColumnCount;
/* clip to the imageable area and draw the offset image into it */
eventArgs.Graphics.Clip = _pageRegion;
eventArgs.Graphics.DrawImage(_image, new RectangleF(
_imageOffset - new SizeF(pageColumn * _pageSize.Width, pageRow * _pageSize.Height),
_imageSize));
/* only print column * row pages */
eventArgs.HasMorePages = ++_page < _pageColumnCount * _pageRowCount;
};
_endPrint = delegate(object sender, PrintEventArgs eventArgs)
{
/* detach handlers from the print document */
PrintDocument printDocument = (PrintDocument)sender;
printDocument.PrintPage -= _printPage;
printDocument.EndPrint -= _endPrint;
};
/* attach handlers to the print document */
document.PrintPage += _printPage;
document.EndPrint += _endPrint;
}
private const float HUNDREDTH_INCH_PER_PIXEL = 100.0f / 96.0f;
private readonly Image _image;
private readonly Size _pageSize;
private readonly Region _pageRegion;
private readonly SizeF _imageSize;
private readonly int _pageColumnCount;
private readonly int _pageRowCount;
private readonly PointF _imageOffset;
private int _page;
private readonly PrintPageEventHandler _printPage;
private readonly PrintEventHandler _endPrint; }
}
|