/******************************************************************************* * Copyright (c) 2000, 2005 IBM Corporation 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: * IBM Corporation - initial API and implementation * Sven M�ller - Added tiling support *******************************************************************************/ package org.eclipse.draw2d; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.printing.Printer; import org.eclipse.swt.widgets.Display; import org.eclipse.draw2d.geometry.Rectangle; /** * Class responsible for printing Figures. * * @author Dan Lee * @author Eric Bordeau * @author Sven M�ller */ public class PrintFigureOperation extends PrintOperation { /** * The default print mode. Prints at 100% scale and tiles horizontally and/or vertically, * if necessary. */ public static final int TILE = 1; /** * A print mode that scales the printer graphics so that the entire printed image fits on * one page. */ public static final int FIT_PAGE = 2; /** * A print mode that scales the printer graphics so that the width of the printed image * fits on one page and tiles vertically, if necessary. */ public static final int FIT_WIDTH = 3; /** * A print mode that scales the printer graphics so that the height of the printed image * fits on one page and tiles horizontally, if necessary. */ public static final int FIT_HEIGHT = 4; private IFigure printSource; private Color oldBGColor; private int printMode = TILE; /** * Constructor for PrintFigureOperation. * <p> * Note: Descendants must call setPrintSource(IFigure) to set the IFigure that is to be * printed. * @see org.eclipse.draw2d.PrintOperation#PrintOperation(Printer) */ protected PrintFigureOperation(Printer p) { super(p); } /** * Constructor for PrintFigureOperation. * * @param p Printer to print on * @param srcFigure Figure to print */ public PrintFigureOperation(Printer p, IFigure srcFigure) { super(p); setPrintSource(srcFigure); } /** * @return SWT.RIGHT_TO_LEFT if the print source is mirrored; SWT.LEFT_TO_RIGHT otherwise * @see org.eclipse.draw2d.PrintOperation#getGraphicsOrientation() */ int getGraphicsOrientation() { return getPrintSource().isMirrored() ? SWT.RIGHT_TO_LEFT : SWT.LEFT_TO_RIGHT; } /** * Returns the current print mode. The print mode is one of: {@link #FIT_HEIGHT}, * {@link #FIT_PAGE}, or {@link #FIT_WIDTH}. * @return the print mode */ protected int getPrintMode() { return printMode; } /** * Returns the printSource. * * @return IFigure The source IFigure */ protected IFigure getPrintSource() { return printSource; } /** * @see org.eclipse.draw2d.PrintOperation#preparePrintSource() */ protected void preparePrintSource() { oldBGColor = getPrintSource().getLocalBackgroundColor(); getPrintSource().setBackgroundColor(ColorConstants.white); } /** * Prints the pages based on the current print mode. * @see org.eclipse.draw2d.PrintOperation#printPages() */ protected void printPages() { Graphics graphics = getFreshPrinterGraphics(); IFigure figure = getPrintSource(); setupPrinterGraphicsFor(graphics, figure); Rectangle bounds = figure.getBounds(); int x = bounds.x, y = bounds.y; Rectangle clipRect = new Rectangle(); while (y < bounds.y + bounds.height) { while (x < bounds.x + bounds.width) { graphics.pushState(); getPrinter().startPage(); graphics.translate(-x, -y); graphics.getClip(clipRect); clipRect.setLocation(x, y); graphics.clipRect(clipRect); figure.paint(graphics); getPrinter().endPage(); graphics.popState(); x += clipRect.width; } x = bounds.x; y += clipRect.height; } } /** * @see org.eclipse.draw2d.PrintOperation#restorePrintSource() */ protected void restorePrintSource() { getPrintSource().setBackgroundColor(oldBGColor); oldBGColor = null; } /** * Sets the print mode. Possible values are {@link #TILE}, {@link #FIT_HEIGHT}, * {@link #FIT_WIDTH} and {@link #FIT_PAGE}. * @param mode the print mode */ public void setPrintMode(int mode) { printMode = mode; } /** * Sets the printSource. * @param printSource The printSource to set */ protected void setPrintSource(IFigure printSource) { this.printSource = printSource; } /** * Sets up Graphics object for the given IFigure. * @param graphics The Graphics to setup * @param figure The IFigure used to setup graphics */ protected void setupPrinterGraphicsFor(Graphics graphics, IFigure figure) { double dpiScale = (double)getPrinter().getDPI().x / Display.getCurrent().getDPI().x; Rectangle printRegion = getPrintRegion(); // put the print region in display coordinates printRegion.width /= dpiScale; printRegion.height /= dpiScale; Rectangle bounds = figure.getBounds(); double xScale = (double)printRegion.width / bounds.width; double yScale = (double)printRegion.height / bounds.height; switch (getPrintMode()) { case FIT_PAGE: graphics.scale(Math.min(xScale, yScale) * dpiScale); break; case FIT_WIDTH: graphics.scale(xScale * dpiScale); break; case FIT_HEIGHT: graphics.scale(yScale * dpiScale); break; default: graphics.scale(dpiScale); } graphics.setForegroundColor(figure.getForegroundColor()); graphics.setBackgroundColor(figure.getBackgroundColor()); graphics.setFont(figure.getFont()); } }