package com.aspose.words.examples.rendering_printing;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Point2D;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import javax.print.attribute.AttributeSet;
import javax.print.attribute.standard.PageRanges;
import com.aspose.words.Document;
public class MultipagePrintDocument implements Printable {
private Document mDocument;
private int mPagesPerSheet;
private boolean mPrintPageBorders;
private AttributeSet mAttributeSet;
public MultipagePrintDocument(Document document, int pagesPerSheet, boolean printPageBorders, AttributeSet attributes) {
if (document == null)
throw new IllegalArgumentException("document");
mDocument = document;
mPagesPerSheet = pagesPerSheet;
mPrintPageBorders = printPageBorders;
mAttributeSet = attributes;
}
public int print(Graphics g, PageFormat pf, int page) {
// The page start and end indices as defined in the attribute set.
int[][] pageRanges = ((PageRanges) mAttributeSet.get(PageRanges.class)).getMembers();
int fromPage = pageRanges[0][0] - 1;
int toPage = pageRanges[0][1] - 1;
Dimension thumbCount = getThumbCount(mPagesPerSheet, pf);
// Calculate the page index which is to be rendered next.
int pagesOnCurrentSheet = (int) (page * (thumbCount.getWidth() * thumbCount.getHeight()));
// If the page index is more than the total page range then there is nothing more to render.
if (pagesOnCurrentSheet > (toPage - fromPage))
return Printable.NO_SUCH_PAGE;
// Calculate the size of each thumbnail placeholder in points.
Point2D.Float thumbSize = new Point2D.Float((float) (pf.getImageableWidth() / thumbCount.getWidth()), (float) (pf.getImageableHeight() / thumbCount.getHeight()));
// Calculate the number of the first page to be printed on this sheet of paper.
int startPage = pagesOnCurrentSheet + fromPage;
// Select the number of the last page to be printed on this sheet of paper.
int pageTo = Math.max(startPage + mPagesPerSheet - 1, toPage);
// Loop through the selected pages from the stored current page to calculated last page.
for (int pageIndex = startPage; pageIndex <= pageTo; pageIndex++) {
// Calculate the column and row indices.
int rowIdx = (int) Math.floor((pageIndex - startPage) / thumbCount.getWidth());
int columnIdx = (int) Math.floor((pageIndex - startPage) % thumbCount.getWidth());
// Define the thumbnail location in world coordinates (points in this case).
float thumbLeft = columnIdx * thumbSize.x;
float thumbTop = rowIdx * thumbSize.y;
try {
// Calculate the left and top starting positions.
int leftPos = (int) (thumbLeft + pf.getImageableX());
int topPos = (int) (thumbTop + pf.getImageableY());
// Render the document page to the Graphics object using calculated coordinates and thumbnail placeholder size.
// The useful return value is the scale at which the page was rendered.
float scale = mDocument.renderToSize(pageIndex, (Graphics2D) g, leftPos, topPos, (int) thumbSize.x, (int) thumbSize.y);
// Draw the page borders (the page thumbnail could be smaller than the thumbnail placeholder size).
if (mPrintPageBorders) {
// Get the real 100% size of the page in points.
Point2D.Float pageSize = mDocument.getPageInfo(pageIndex).getSizeInPoints();
// Draw the border around the scaled page using the known scale factor.
g.setColor(Color.black);
g.drawRect(leftPos, topPos, (int) (pageSize.x * scale), (int) (pageSize.y * scale));
// Draw the border around the thumbnail placeholder.
g.setColor(Color.red);
g.drawRect(leftPos, topPos, (int) thumbSize.x, (int) thumbSize.y);
}
}
catch (Exception e) {
// If there are any errors that occur during rendering then do nothing.
// This will draw a blank page if there are any errors during rendering.
}
}
return Printable.PAGE_EXISTS;
}
private Dimension getThumbCount(int pagesPerSheet, PageFormat pf) {
Dimension size;
// Define the number of the columns and rows on the sheet for the Landscape-oriented paper.
switch (pagesPerSheet) {
case 16:
size = new Dimension(4, 4);
break;
case 9:
size = new Dimension(3, 3);
break;
case 8:
size = new Dimension(4, 2);
break;
case 6:
size = new Dimension(3, 2);
break;
case 4:
size = new Dimension(2, 2);
break;
case 2:
size = new Dimension(2, 1);
break;
default:
size = new Dimension(1, 1);
break;
}
// Swap the width and height if the paper is in the Portrait orientation.
if ((pf.getWidth() - pf.getImageableX()) < (pf.getHeight() - pf.getImageableY()))
return new Dimension((int) size.getHeight(), (int) size.getWidth());
return size;
}
}