/*******************************************************************************
* Copyright (c) 2006-2012
* Software Technology Group, Dresden University of Technology
* DevBoost GmbH, Berlin, Amtsgericht Charlottenburg, HRB 140026
*
* 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:
* Software Technology Group - TU Dresden, Germany;
* DevBoost GmbH - Berlin, Germany
* - initial API and implementation
******************************************************************************/
/*
* @(#)DrawingPageable.java 1.0 January 1, 2007
*
* Copyright (c) 1996-2007 by the original authors of JHotDraw
* and all its contributors.
* All rights reserved.
*
* The copyright of this software is owned by the authors and
* contributors of the JHotDraw project ("the copyright holders").
* You may not use, copy or modify this software, except in
* accordance with the license agreement you entered into with
* the copyright holders. For details see accompanying license terms.
*/
package org.jhotdraw.draw;
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.awt.print.*;
/**
* DrawingPageable can be used to print a Drawing using the
* java.awt.print API.
* <p>
* Usage:
* <pre>
* Pageable pageable = new DrawingPageable(aDrawing);
* PrinterJob job = PrinterJob.getPrinterJob();
* job.setPageable(pageable);
* if (job.printDialog()) {
* try {
* job.print();
* } catch (PrinterException e) {
* ...inform the user that we couldn't print...
* }
* }
* </pre>
*
* @author Werner Randelshofer
* @version 1.0 January 1, 2007 Created.
* @see org.jhotdraw.app.action.PrintAction
*/
public class DrawingPageable implements Pageable {
private Drawing drawing;
private PageFormat pageFormat;
private boolean isAutorotate = false;
/** Creates a new instance. */
public DrawingPageable(Drawing drawing) {
this.drawing = drawing;
Paper paper = new Paper();
pageFormat = new PageFormat();
pageFormat.setPaper(paper);
}
public int getNumberOfPages() {
return 1;
}
public PageFormat getPageFormat(int pageIndex) throws IndexOutOfBoundsException {
return pageFormat;
}
public Printable getPrintable(int pageIndex) throws IndexOutOfBoundsException {
if (pageIndex < 0 || pageIndex >= getNumberOfPages()) {
throw new IndexOutOfBoundsException("Invalid page index:"+pageIndex);
}
return new Printable() {
public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {
return printPage(graphics, pageFormat, pageIndex);
}
};
}
public int printPage(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {
if (pageIndex < 0 || pageIndex >= getNumberOfPages()) {
return Printable.NO_SUCH_PAGE;
}
if (drawing.getChildCount() > 0) {
Graphics2D g = (Graphics2D) graphics;
setRenderingHints(g);
// Determine the draw bounds of the drawing
Rectangle2D.Double drawBounds = null;
for (Figure f : drawing.getChildren()) {
if (drawBounds == null) {
drawBounds = f.getDrawingArea();
} else {
drawBounds.add(f.getDrawingArea());
}
}
// Setup a transformation for the drawing
AffineTransform tx = new AffineTransform();
tx.translate(
pageFormat.getImageableX(),
pageFormat.getImageableY()
);
// Maybe rotate drawing
if (isAutorotate &&
drawBounds.width > drawBounds.height &&
pageFormat.getImageableWidth() < pageFormat.getImageableHeight()) {
double scaleFactor = Math.min(
pageFormat.getImageableWidth() / drawBounds.height,
pageFormat.getImageableHeight() / drawBounds.width
);
tx.scale(scaleFactor, scaleFactor);
tx.translate(drawBounds.height, 0d);
tx.rotate(Math.PI / 2d, 0, 0);
tx.translate(-drawBounds.x, -drawBounds.y);
} else {
double scaleFactor = Math.min(
pageFormat.getImageableWidth() / drawBounds.width,
pageFormat.getImageableHeight() / drawBounds.height
);
tx.scale(scaleFactor, scaleFactor);
tx.translate(-drawBounds.x, -drawBounds.y);
}
g.transform(tx);
// Draw the drawing
drawing.draw(g);
}
return Printable.PAGE_EXISTS;
}
protected void setRenderingHints(Graphics2D g) {
g.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,
RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING,
RenderingHints.VALUE_COLOR_RENDER_QUALITY);
g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
RenderingHints.VALUE_STROKE_NORMALIZE);
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
}
}