package org.insightech.er.editor.view.action.printer;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Insets;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.GraphicalViewer;
import org.eclipse.gef.print.PrintGraphicalViewerOperation;
import org.eclipse.swt.printing.Printer;
import org.eclipse.swt.widgets.Display;
import org.insightech.er.editor.model.ERDiagram;
import org.insightech.er.editor.model.settings.PageSetting;
public class PrintERDiagramOperation extends PrintGraphicalViewerOperation {
public PrintERDiagramOperation(Printer p, GraphicalViewer g) {
super(p, g);
}
protected ERDiagram getDiagram() {
EditPart editPart = this.getViewer().getContents();
ERDiagram diagram = (ERDiagram) editPart.getModel();
return diagram;
}
/**
* {@inheritDoc}
*/
@Override
public Rectangle getPrintRegion() {
ERDiagram diagram = this.getDiagram();
PageSetting pageSetting = diagram.getPageSetting();
org.eclipse.swt.graphics.Rectangle trim = this.getPrinter()
.computeTrim(0, 0, 0, 0);
org.eclipse.swt.graphics.Point printerDPI = this.getPrinter().getDPI();
Insets notAvailable = new Insets(-trim.y, -trim.x,
trim.height + trim.y, trim.width + trim.x);
Insets userPreferred = new Insets(
(pageSetting.getTopMargin() * printerDPI.x) / 72,
(pageSetting.getLeftMargin() * printerDPI.x) / 72,
(pageSetting.getBottomMargin() * printerDPI.x) / 72,
(pageSetting.getRightMargin() * printerDPI.x) / 72);
Rectangle paperBounds = new Rectangle(this.getPrinter().getBounds());
Rectangle printRegion = shrink(paperBounds, notAvailable);
printRegion.intersect(shrink(paperBounds, userPreferred));
printRegion.translate(trim.x, trim.y);
return printRegion;
}
private Rectangle shrink(Rectangle bounds, Insets insets) {
Rectangle shrinked = bounds.getCopy();
shrinked.x += insets.left;
shrinked.y += insets.top;
shrinked.width -= insets.getWidth();
shrinked.height -= insets.getHeight();
return shrinked;
}
/**
* {@inheritDoc}
*/
@Override
protected void setupPrinterGraphicsFor(Graphics graphics, IFigure figure) {
ERDiagram diagram = this.getDiagram();
PageSetting pageSetting = diagram.getPageSetting();
double dpiScale = (double) getPrinter().getDPI().x
/ Display.getCurrent().getDPI().x * pageSetting.getScale()
/ 100;
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());
}
/**
* {@inheritDoc}
*/
@Override
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;
}
}
}