/*
* Copyright (c) 2007 Matthew Hall and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Matthew Hall - initial API and implementation
*/
package org.eclipse.nebula.paperclips.core;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.printing.Printer;
/**
* An enumeration of pages for given print job on the given printer device. Each
* element in the enumeration has already had the page orientation and page
* margins applied. Therefore, when calling the paint(GC, int, int) method on
* each page, the printer's trim should be provided as the x and y arguments. In
* other words, the trim is taken as a minimum margin while applying calculating
* margins, but the position where the page's content is drawn is determined
* solely by the margin, and is not offset by the trim. This behavior is helpful
* for screen display, and is already compensated for in the
* {@link PaperClips#print(PrintJob, Printer) } method.
*
* @see PaperClips#getPages(PrintJob, Printer)
* @author Matthew Hall
*/
public class PageEnumeration {
private PrintIterator document;
private Rectangle marginBounds;
private Rectangle paperBounds;
private boolean hasNext;
PageEnumeration(PrintJob job, Printer printer, GC gc) {
// Rotate the document (and margins with it) depending on print job
// orientation.
job = applyOrientation(job, printer);
Margins margins = job.getMargins();
marginBounds = PaperClips.getMarginBounds(margins, printer);
paperBounds = PaperClips.getPaperBounds(printer);
document = job.getDocument().iterator(printer, gc);
hasNext = document.hasNext();
}
/**
* Returns whether any pages remain.
*
* @return whether any pages remain.
*/
public boolean hasNext() {
return hasNext;
}
/**
* Returns the next page.
*
* @return the next page.
*/
public PrintPiece nextPage() {
if (!hasNext)
return null;
PrintPiece page = PaperClips.next(document, marginBounds.width,
marginBounds.height);
hasNext = notNull(page) && notDebugPiece(page) && document.hasNext();
PrintPiece result = page == null ? null : createPagePiece(page);
if (!hasNext) {
document = null;
marginBounds = null;
paperBounds = null;
}
return result;
}
private PrintPiece createPagePiece(PrintPiece page) {
Point offset = new Point(marginBounds.x - paperBounds.x, marginBounds.y
- paperBounds.y);
CompositeEntry entry = new CompositeEntry(page, offset);
Point size = new Point(paperBounds.width, paperBounds.height);
return new CompositePiece(new CompositeEntry[] { entry }, size);
}
private static boolean notNull(PrintPiece page) {
return page != null;
}
private static boolean notDebugPiece(PrintPiece page) {
return !(PaperClips.debug && page instanceof NullPrintPiece);
}
private static PrintJob applyOrientation(PrintJob printJob, Printer printer) {
int orientation = printJob.getOrientation();
Rectangle paperBounds = PaperClips.getPaperBounds(printer);
if (((orientation == PaperClips.ORIENTATION_LANDSCAPE) && (paperBounds.width < paperBounds.height))
|| ((orientation == PaperClips.ORIENTATION_PORTRAIT) && (paperBounds.height < paperBounds.width))) {
String name = printJob.getName();
Print document = new RotatePrint(printJob.getDocument());
Margins margins = printJob.getMargins().rotate();
printJob = new PrintJob(name, document).setMargins(margins)
.setOrientation(PaperClips.ORIENTATION_DEFAULT);
}
return printJob;
}
}