blob: d745f15cb95fb3ab086d4a69494f9fc853c95797 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2010 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() ? org.eclipse.draw2d.rap.swt.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());
}
}