| /****************************************************************************** |
| * Copyright (c) 2008, 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 |
| ****************************************************************************/ |
| |
| package org.eclipse.gmf.runtime.diagram.ui.printing.render.internal; |
| |
| import java.awt.BasicStroke; |
| import java.awt.Graphics2D; |
| import java.awt.print.PageFormat; |
| import java.awt.print.PrinterException; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Locale; |
| |
| import javax.print.Doc; |
| import javax.print.DocFlavor; |
| import javax.print.DocPrintJob; |
| import javax.print.PrintException; |
| import javax.print.PrintService; |
| import javax.print.PrintServiceLookup; |
| import javax.print.SimpleDoc; |
| import javax.print.attribute.AttributeSet; |
| import javax.print.attribute.HashDocAttributeSet; |
| import javax.print.attribute.HashPrintRequestAttributeSet; |
| import javax.print.attribute.HashPrintServiceAttributeSet; |
| import javax.print.attribute.PrintRequestAttributeSet; |
| import javax.print.attribute.standard.Chromaticity; |
| import javax.print.attribute.standard.Copies; |
| import javax.print.attribute.standard.JobName; |
| import javax.print.attribute.standard.Media; |
| import javax.print.attribute.standard.MediaPrintableArea; |
| import javax.print.attribute.standard.MediaSize; |
| import javax.print.attribute.standard.MediaSizeName; |
| import javax.print.attribute.standard.OrientationRequested; |
| import javax.print.attribute.standard.PrintQuality; |
| import javax.print.attribute.standard.PrinterName; |
| import javax.print.attribute.standard.SheetCollate; |
| import javax.print.attribute.standard.Sides; |
| |
| import org.eclipse.draw2d.Graphics; |
| import org.eclipse.draw2d.SWTGraphics; |
| import org.eclipse.draw2d.geometry.Rectangle; |
| import org.eclipse.gef.LayerConstants; |
| import org.eclipse.gef.RootEditPart; |
| import org.eclipse.gmf.runtime.common.core.util.Log; |
| import org.eclipse.gmf.runtime.common.core.util.Trace; |
| import org.eclipse.gmf.runtime.common.ui.printing.IPrintHelper; |
| import org.eclipse.gmf.runtime.common.ui.util.DisplayUtils; |
| import org.eclipse.gmf.runtime.diagram.core.preferences.PreferencesHint; |
| import org.eclipse.gmf.runtime.diagram.core.util.ViewUtil; |
| import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart; |
| import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramRootEditPart; |
| import org.eclipse.gmf.runtime.diagram.ui.internal.pagesetup.PageInfoHelper; |
| import org.eclipse.gmf.runtime.diagram.ui.internal.pagesetup.PageSetupPageType; |
| import org.eclipse.gmf.runtime.diagram.ui.internal.pagesetup.PageInfoHelper.PageMargins; |
| import org.eclipse.gmf.runtime.diagram.ui.internal.properties.WorkspaceViewerProperties; |
| import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramEditor; |
| import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramGraphicalViewer; |
| import org.eclipse.gmf.runtime.diagram.ui.printing.internal.DiagramPrintingDebugOptions; |
| import org.eclipse.gmf.runtime.diagram.ui.printing.internal.DiagramPrintingPlugin; |
| import org.eclipse.gmf.runtime.diagram.ui.printing.internal.DiagramPrintingStatusCodes; |
| import org.eclipse.gmf.runtime.diagram.ui.printing.internal.l10n.DiagramUIPrintingMessages; |
| import org.eclipse.gmf.runtime.diagram.ui.printing.internal.util.DiagramPrinter; |
| import org.eclipse.gmf.runtime.diagram.ui.printing.internal.util.PrintHelperUtil; |
| import org.eclipse.gmf.runtime.diagram.ui.printing.render.model.PrintOptions; |
| import org.eclipse.gmf.runtime.diagram.ui.printing.render.util.PrintHelper; |
| import org.eclipse.gmf.runtime.diagram.ui.printing.util.DiagramPrinterUtil; |
| import org.eclipse.gmf.runtime.diagram.ui.util.DiagramEditorUtil; |
| import org.eclipse.gmf.runtime.draw2d.ui.internal.graphics.MapModeGraphics; |
| import org.eclipse.gmf.runtime.draw2d.ui.internal.graphics.ScaledGraphics; |
| import org.eclipse.gmf.runtime.draw2d.ui.mapmode.IMapMode; |
| import org.eclipse.gmf.runtime.draw2d.ui.mapmode.MapModeUtil; |
| import org.eclipse.gmf.runtime.draw2d.ui.render.awt.internal.graphics.GraphicsToGraphics2DAdaptor; |
| import org.eclipse.gmf.runtime.draw2d.ui.render.internal.graphics.RenderedMapModeGraphics; |
| import org.eclipse.gmf.runtime.draw2d.ui.render.internal.graphics.RenderedScaledGraphics; |
| import org.eclipse.gmf.runtime.notation.Diagram; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.jface.preference.IPreferenceStore; |
| import org.eclipse.jface.resource.JFaceResources; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.graphics.FontData; |
| import org.eclipse.swt.graphics.GC; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.swt.graphics.Point; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.swt.widgets.Shell; |
| |
| /** |
| * This class supports printing using the Java Print Service API. The logic of |
| * calculating page break etc. follows that of SWT printing but the actual |
| * printing is done asynchronously in a platform independent way. |
| * |
| * Much of the paging code was derived from the previous DiagramPrinter. |
| * |
| * @author James Bruck (jbruck) |
| */ |
| public class JPSDiagramPrinter extends DiagramPrinter implements java.awt.print.Printable { |
| |
| // A constant that takes into account screen display DPI and the graphic DPI |
| // 72.0 DPI is an AWT constant @see java.awt.Graphics2D |
| private static double AWT_DPI_CONST = 72.0; |
| |
| // The print service used during printing. |
| private PrintService printService; |
| |
| // Page information that is collected up front and used during the async |
| // printing calls. |
| private PageData[] pages; |
| |
| // The print helper contains page information. |
| private IPrintHelper printHelper; |
| |
| public JPSDiagramPrinter(PreferencesHint preferencesHint, IMapMode mm) { |
| super(preferencesHint, mm); |
| this.preferencesHint = preferencesHint; |
| this.mapMode = mm; |
| } |
| |
| public JPSDiagramPrinter(PreferencesHint preferencesHint) { |
| this(preferencesHint, MapModeUtil.getMapMode()); |
| } |
| |
| public void setPrintHelper(IPrintHelper helper) { |
| this.printHelper = helper; |
| } |
| |
| /** |
| * Create a new print service given a printer name. |
| * |
| * @param printerName |
| */ |
| public void setPrinter(String printerName) { |
| AttributeSet attributes = new HashPrintServiceAttributeSet(new PrinterName(printerName, Locale.getDefault())); |
| PrintService[] services = PrintServiceLookup.lookupPrintServices(DocFlavor.SERVICE_FORMATTED.PRINTABLE, attributes); |
| printService = services[0]; |
| } |
| |
| /** |
| * Prints the contents of the diagram editor part. |
| */ |
| public void run() { |
| |
| Iterator<Diagram> it = diagrams.iterator(); |
| Shell shell = new Shell(); |
| try { |
| while (it.hasNext()) { |
| Diagram diagram = it.next(); |
| DiagramEditor openedDiagramEditor = DiagramEditorUtil.findOpenedDiagramEditorForID(ViewUtil.getIdStr(diagram)); |
| DiagramEditPart dgrmEP = openedDiagramEditor == null ? PrintHelperUtil.createDiagramEditPart(diagram, preferencesHint, shell) : openedDiagramEditor.getDiagramEditPart(); |
| |
| boolean loadedPreferences = openedDiagramEditor != null || PrintHelperUtil.initializePreferences(dgrmEP, preferencesHint); |
| |
| RootEditPart rep = dgrmEP.getRoot(); |
| if (rep instanceof DiagramRootEditPart) { |
| this.mapMode = ((DiagramRootEditPart) rep).getMapMode(); |
| } |
| |
| IPreferenceStore preferenceStore = ((DiagramGraphicalViewer) dgrmEP.getViewer()).getWorkspaceViewerPreferenceStore(); |
| if (preferenceStore.getBoolean(WorkspaceViewerProperties.PREF_USE_WORKSPACE_SETTINGS)) { |
| if (dgrmEP.getDiagramPreferencesHint().getPreferenceStore() != null) { |
| preferenceStore = (IPreferenceStore) dgrmEP.getDiagramPreferencesHint().getPreferenceStore(); |
| } |
| } |
| doPrintDiagram(printService.createPrintJob(), dgrmEP, loadedPreferences, preferenceStore); |
| } |
| } finally { |
| dispose(); |
| shell.dispose(); |
| } |
| } |
| |
| /** |
| * Print the diagram figure using specified scale factor. |
| * |
| * @param dgrmEP |
| * The diagram edit part to print |
| * @param loadedPreferences |
| * true if existing prefs could be loaded successfully, false if |
| * not and defaults are being used. This parameter is important |
| * to obtain the correct page break bounds. |
| * @param fPreferences |
| * the preferenceStore that could either contain existing |
| * preferences or defaults |
| */ |
| protected void printToScale(DiagramEditPart dgrmEP, boolean loadedPreferences, IPreferenceStore fPreferences) { |
| |
| Rectangle figureBounds = PrintHelperUtil.getPageBreakBounds(dgrmEP, loadedPreferences); |
| |
| org.eclipse.draw2d.geometry.Point pageBounds = PageInfoHelper.getPageSize(fPreferences, getMapMode()); |
| // |
| // Translate to offset initial figure position |
| // |
| translated = new Point((int) (-figureBounds.x * userScale), (int) (-figureBounds.y * userScale)); |
| // |
| // Calculate the number of page rows and columns |
| // |
| int numRows = 0, numCols = 0; |
| |
| PageMargins margins = adjustMarginsToScale(PageInfoHelper.getPageMargins(fPreferences, getMapMode())); |
| |
| FontData fontData = JFaceResources.getDefaultFont().getFontData()[0]; |
| |
| org.eclipse.draw2d.geometry.Point pageCount = getPageCount(dgrmEP, figureBounds, pageBounds, true); |
| |
| numCols = pageCount.x; |
| numRows = pageCount.y; |
| |
| int row = 1, col = 1, finalRow = 0, finalColumn = 0; |
| |
| List<PageData> pageList = new java.util.ArrayList<PageData>(); |
| |
| if (this.printRangePageSelection) { |
| // |
| // Print only the pages specified in the page range... |
| // |
| row = calculateRowFromPage(this.pageFrom, numCols); |
| col = calculateColumnFromPage(this.pageFrom, numCols, row); |
| |
| finalRow = calculateRowFromPage(this.pageTo, numCols); |
| finalColumn = calculateColumnFromPage(this.pageTo, numCols, finalRow); |
| } |
| // |
| // Print the pages in row, column order |
| // |
| for (; row <= numRows; row++) { |
| for (; col <= numCols; col++) { |
| |
| pageList.add(new PageData(pageList.size(), row, col, dgrmEP, figureBounds, margins, fontData, fPreferences)); |
| |
| if (row == finalRow && col == finalColumn && this.printRangePageSelection == true) { |
| break; |
| } |
| } |
| if (row == finalRow && col == finalColumn && this.printRangePageSelection == true) { |
| break; |
| } |
| col = 1; |
| } |
| pages = pageList.toArray(new PageData[pageList.size()]); |
| } |
| |
| /** |
| * Print the diagram figure to fit the number and rows and columns specified |
| * by the user. |
| * |
| * @param dgrmEP |
| * The diagram edit part to print |
| * @param loadedPreferences |
| * true if existing prefs could be loaded successfully, false if |
| * not and defaults are being used. This parameter is important |
| * to obtain the correct page break bounds. |
| * @param fPreferences |
| * the preferenceStore that could either contain existing |
| * preferences or defaults |
| */ |
| protected void printToPages(DiagramEditPart dgrmEP, boolean loadedPreferences, IPreferenceStore fPreferences) { |
| |
| Rectangle figureBounds = PrintHelperUtil.getPageBreakBounds(dgrmEP, loadedPreferences); |
| |
| org.eclipse.draw2d.geometry.Point pageBounds = PageInfoHelper.getPageSize(fPreferences, getMapMode()); |
| org.eclipse.draw2d.geometry.Point pageCount = getPageCount(dgrmEP, figureBounds, pageBounds, false); |
| int numCols = pageCount.x; |
| int numRows = pageCount.y; |
| |
| float actualWidth = 0; |
| float actualHeight = 0; |
| if (this.rows == 1 && this.columns == 1 && fitToPage) { |
| figureBounds = dgrmEP.getChildrenBounds(); |
| actualWidth = figureBounds.width; |
| actualHeight = figureBounds.height; |
| } else { |
| actualWidth = numCols * pageBounds.x; |
| actualHeight = numRows * pageBounds.y; |
| } |
| |
| int totalHeight = (this.rows * pageBounds.y); |
| int totalWidth = (this.columns * pageBounds.x); |
| |
| float vScale = totalHeight / actualHeight; |
| float hScale = totalWidth / actualWidth; |
| |
| this.userScale = Math.min(hScale, vScale); |
| |
| PageMargins margins = adjustMarginsToScale(PageInfoHelper.getPageMargins(fPreferences, getMapMode())); |
| |
| translated = new Point((int) (-figureBounds.x * userScale), (int) (-figureBounds.y * userScale)); |
| |
| FontData fontData = JFaceResources.getDefaultFont().getFontData()[0]; |
| |
| int row = 1, col = 1, finalRow = 0, finalColumn = 0; |
| List<PageData> pageList = new java.util.ArrayList<PageData>(); |
| |
| if (this.printRangePageSelection) { |
| // |
| // Print only the pages specified in the page range |
| // this corresponds to the physical pages, not the print range of |
| // pages on one physical page. |
| // |
| row = calculateRowFromPage(this.pageFrom, this.columns); |
| col = calculateColumnFromPage(this.pageFrom, this.columns, row); |
| |
| finalRow = calculateRowFromPage(this.pageTo, this.columns); |
| finalColumn = calculateColumnFromPage(this.pageTo, this.columns, finalRow); |
| } |
| |
| for (; row <= rows; row++) { |
| for (; col <= columns; col++) { |
| |
| pageList.add(new PageData(pageList.size(), row, col, dgrmEP, figureBounds, margins, fontData, fPreferences)); |
| |
| if (row == finalRow && col == finalColumn && this.printRangePageSelection == true) { |
| break; |
| } |
| } |
| if (row == finalRow && col == finalColumn && this.printRangePageSelection == true) { |
| break; |
| } |
| col = 1; |
| } |
| pages = pageList.toArray(new PageData[pageList.size()]); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see java.awt.print.Printable#print(java.awt.Graphics, |
| * java.awt.print.PageFormat, int) |
| */ |
| public int print(java.awt.Graphics printGraphics, PageFormat pageFormat, int pageIndex) throws PrinterException { |
| |
| if (pageIndex >= pages.length) { |
| return java.awt.print.Printable.NO_SUCH_PAGE; |
| } |
| |
| try { |
| printGraphics.setClip(0, 0, (int) pageFormat.getWidth(), (int) pageFormat.getHeight()); |
| |
| swtGraphics = new PrinterGraphicsToGraphics2DAdapter((java.awt.Graphics2D) printGraphics, new Rectangle(0, 0, (int) pageFormat.getWidth(), (int) pageFormat.getHeight())); |
| |
| graphics = createMapModeGraphics(createPrinterGraphics(swtGraphics)); |
| graphics.scale(AWT_DPI_CONST / display_dpi.x); |
| drawPage(pages[pageIndex]); |
| } finally { |
| dispose(); |
| |
| } |
| |
| return java.awt.print.Printable.PAGE_EXISTS; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see |
| * org.eclipse.gmf.runtime.diagram.ui.printing.internal.util.DiagramPrinter |
| * #createMapModeGraphics(org.eclipse.draw2d.Graphics) |
| */ |
| protected MapModeGraphics createMapModeGraphics(Graphics theGraphics) { |
| return new RenderedMapModeGraphics(theGraphics, getMapMode()); |
| } |
| |
| protected ScaledGraphics createPrinterGraphics(Graphics theGraphics) { |
| return new RenderedScaledGraphics(theGraphics); |
| } |
| |
| /** |
| * Set printing options in a format that is suitable for the Java print |
| * service |
| * |
| * @param jobName |
| * The printer job name to use |
| * @param fPreferences |
| * obtain page information from preferences |
| * @return PrintRequestAttribute set suitable for Java print service |
| */ |
| protected PrintRequestAttributeSet initializePrintOptions(DocPrintJob printJob, String jobName, IPreferenceStore fPreferences) { |
| |
| PrintOptions advancedOptions = ((PrintHelper) (printHelper)).getPrintOptions(); |
| |
| PrintRequestAttributeSet printRequestAttributeSet = new HashPrintRequestAttributeSet(); |
| |
| if (fPreferences.getBoolean(WorkspaceViewerProperties.PREF_USE_PORTRAIT)) { |
| printRequestAttributeSet.add(OrientationRequested.PORTRAIT); |
| } else { |
| printRequestAttributeSet.add(OrientationRequested.LANDSCAPE); |
| } |
| |
| String pageSize = fPreferences.getString(WorkspaceViewerProperties.PREF_PAGE_SIZE); |
| |
| if (pageSize.compareToIgnoreCase(PageSetupPageType.LETTER.getName()) == 0) { |
| printRequestAttributeSet.add(MediaSizeName.NA_LETTER); |
| } else if (pageSize.compareToIgnoreCase(PageSetupPageType.LEGAL.getName()) == 0) { |
| printRequestAttributeSet.add(MediaSizeName.NA_LEGAL); |
| } else if (pageSize.compareToIgnoreCase(PageSetupPageType.EXECUTIVE.getName()) == 0) { |
| printRequestAttributeSet.add(MediaSizeName.EXECUTIVE); |
| } else if (pageSize.compareToIgnoreCase(PageSetupPageType.A3.getName()) == 0) { |
| printRequestAttributeSet.add(MediaSizeName.ISO_A3); |
| } else if (pageSize.compareToIgnoreCase(PageSetupPageType.A4.getName()) == 0) { |
| printRequestAttributeSet.add(MediaSizeName.ISO_A4); |
| } else if (pageSize.compareToIgnoreCase(PageSetupPageType.B4.getName()) == 0) { |
| printRequestAttributeSet.add(MediaSizeName.ISO_B4); |
| } else if (pageSize.compareToIgnoreCase(PageSetupPageType.B5.getName()) == 0) { |
| printRequestAttributeSet.add(MediaSizeName.ISO_B5); |
| } |
| if (advancedOptions.isQualityLow()) { |
| printRequestAttributeSet.add(PrintQuality.DRAFT); |
| } else if (advancedOptions.isQualityMed()) { |
| printRequestAttributeSet.add(PrintQuality.NORMAL); |
| } else if (advancedOptions.isQualityHigh()) { |
| printRequestAttributeSet.add(PrintQuality.HIGH); |
| } |
| if (advancedOptions.isSideDuplex()) { |
| printRequestAttributeSet.add(Sides.DUPLEX); |
| } else if (advancedOptions.isSideOneSided()) { |
| printRequestAttributeSet.add(Sides.ONE_SIDED); |
| } else if (advancedOptions.isSideTumble()) { |
| printRequestAttributeSet.add(Sides.TUMBLE); |
| } |
| if (advancedOptions.isChromaticityColor()) { |
| printRequestAttributeSet.add(Chromaticity.COLOR); |
| } else { |
| printRequestAttributeSet.add(Chromaticity.MONOCHROME); |
| } |
| |
| final MediaSize mediaSize = getMediaSize(pageSize, printRequestAttributeSet, fPreferences); |
| |
| printRequestAttributeSet.add(new MediaPrintableArea(0f, 0f, (mediaSize.getX(MediaSize.INCH)), (mediaSize.getY(MediaSize.INCH)), MediaPrintableArea.INCH)); |
| |
| printRequestAttributeSet.add(new Copies(printHelper.getDlgNumberOfCopies())); |
| |
| if (printHelper.getDlgCollate()) { |
| printRequestAttributeSet.add(SheetCollate.COLLATED); |
| } else { |
| printRequestAttributeSet.add(SheetCollate.UNCOLLATED); |
| } |
| |
| String userJobName = advancedOptions.getJobName(); |
| if (userJobName != null && userJobName.length() > 0) { |
| jobName = userJobName; |
| } |
| printRequestAttributeSet.add(new JobName(jobName, Locale.getDefault())); |
| |
| return printRequestAttributeSet; |
| } |
| |
| /** |
| * Get the media size to use for printing. |
| * |
| * @return the media size. <code>null</code> is never returned. |
| */ |
| private MediaSize getMediaSize(String pageSize, PrintRequestAttributeSet printRequestAttributeSet, IPreferenceStore fPreferences) { |
| |
| MediaSize mediaSize; |
| |
| if (pageSize.compareToIgnoreCase(PageSetupPageType.USER_DEFINED.getName()) == 0) { |
| float width = (float) fPreferences.getDouble(WorkspaceViewerProperties.PREF_PAGE_WIDTH); |
| float height = (float) fPreferences.getDouble(WorkspaceViewerProperties.PREF_PAGE_HEIGHT); |
| int units = fPreferences.getBoolean(WorkspaceViewerProperties.PREF_USE_INCHES) ? MediaSize.INCH : MediaSize.MM; |
| mediaSize = new MediaSize(width, height, units); |
| } else { |
| MediaSizeName media = (MediaSizeName) printRequestAttributeSet.get(Media.class); |
| mediaSize = MediaSize.getMediaSizeForName(media); |
| } |
| /* we were not able to find the media size, use the default one */ |
| if (mediaSize == null) { |
| mediaSize = MediaSize.ISO.A4; |
| } |
| return mediaSize; |
| } |
| |
| /** |
| * Prints to scale or prints to rows x columns pages |
| * |
| * @param printJob |
| * @param diagramEditPart |
| * @param loadedPreferences |
| * @param fPreferences |
| */ |
| protected void doPrintDiagram(DocPrintJob printJob, DiagramEditPart diagramEditPart, boolean loadedPreferences, IPreferenceStore fPreferences) { |
| |
| PrintRequestAttributeSet printRequestAttributeSet = initializePrintOptions(printJob, diagramEditPart.getDiagramView().getName(), fPreferences); |
| |
| if (isScaledPercent) { |
| printToScale(diagramEditPart, loadedPreferences, fPreferences); |
| } else { |
| printToPages(diagramEditPart, loadedPreferences, fPreferences); |
| } |
| |
| Doc doc = new SimpleDoc(this, DocFlavor.SERVICE_FORMATTED.PRINTABLE, new HashDocAttributeSet()); |
| |
| try { |
| printJob.print(doc, printRequestAttributeSet); |
| } catch (PrintException e) { |
| |
| Trace.catching(DiagramPrintingPlugin.getInstance(), DiagramPrintingDebugOptions.EXCEPTIONS_CATCHING, DiagramPrinterUtil.class, e.getMessage(), e); |
| Log.warning(DiagramPrintingPlugin.getInstance(), DiagramPrintingStatusCodes.RESOURCE_FAILURE, e.getMessage(), e); |
| |
| Display display = diagramEditPart.getViewer().getControl().getDisplay(); |
| if (display == null) { |
| display = DisplayUtils.getDisplay(); |
| } |
| |
| MessageDialog.openError(display.getActiveShell(), DiagramUIPrintingMessages.JPSDiagramPrinterUtil_ErrorTitle, DiagramUIPrintingMessages.JPSDiagramPrinterUtil_ErrorMessage); |
| } |
| } |
| |
| /** |
| * |
| * This method paints a portion of the diagram. (The area painted |
| * representing one page.) |
| * |
| * @param page |
| * indicates which page to print. |
| */ |
| protected void drawPage(PageData page) { |
| |
| this.graphics.pushState(); |
| |
| Display display = DisplayUtils.getDisplay(); |
| |
| int shellStyle = display.getActiveShell().getStyle(); |
| boolean rtlEnabled = (shellStyle & SWT.MIRRORED) != 0; |
| |
| if (rtlEnabled) { |
| |
| org.eclipse.draw2d.geometry.Point pageSize = PageInfoHelper.getPageSize(page.preferences, false, getMapMode()); |
| |
| Image image = new Image(display, getMapMode().LPtoDP(pageSize.x), getMapMode().LPtoDP(pageSize.y)); |
| |
| GC imgGC = new GC(image, SWT.RIGHT_TO_LEFT); |
| SWTGraphics tempSWTGraphic = new SWTGraphics(imgGC); |
| ScaledGraphics tempScaledGraphic = new RenderedScaledGraphics(tempSWTGraphic); |
| MapModeGraphics tempMapModeGraphic = createMapModeGraphics(tempScaledGraphic); |
| |
| imgGC.setFont(tempMapModeGraphic.getFont()); |
| |
| internalDrawPage(page.diagram, page.bounds, page.preferences, page.margins, tempMapModeGraphic, page.row, page.column, true); |
| |
| this.graphics.drawImage(image, 0, 0); |
| |
| tempMapModeGraphic.dispose(); |
| tempScaledGraphic.dispose(); |
| tempSWTGraphic.dispose(); |
| imgGC.dispose(); |
| image.dispose(); |
| |
| } else { |
| |
| internalDrawPage(page.diagram, page.bounds, page.preferences, page.margins, graphics, page.row, page.column, false); |
| } |
| |
| this.graphics.popState(); |
| } |
| |
| /** |
| * The real rendering of the page to the given graphical object occurs here. |
| */ |
| protected void internalDrawPage(DiagramEditPart dgrmEP, Rectangle figureBounds, IPreferenceStore fPreferences, PageMargins margins, Graphics g, int rowIndex, int colIndex, boolean RTL_ENABLED) { |
| |
| org.eclipse.draw2d.geometry.Point pageSize = PageInfoHelper.getPageSize(fPreferences, false, getMapMode()); |
| |
| int width = pageSize.x, height = pageSize.y; |
| |
| g.pushState(); |
| |
| g.translate(translated.x, translated.y); |
| g.scale(userScale); |
| |
| int translateX = -(width * (colIndex - 1)); |
| int translateY = -(height * (rowIndex - 1)); |
| |
| int scaledTranslateX = (int) (translateX / userScale); |
| int scaledTranslateY = (int) (translateY / userScale); |
| |
| int scaledWidth = (int) (width / userScale); |
| int scaledHeight = (int) (height / userScale); |
| |
| if (RTL_ENABLED) { |
| scaledTranslateX += (margins.left * (colIndex - 1)) + (margins.right * (colIndex)); |
| scaledTranslateY += ((margins.top * rowIndex) + (margins.bottom * (rowIndex - 1))); |
| } else { |
| scaledTranslateX += ((margins.left * colIndex) + (margins.right * (colIndex - 1))); |
| scaledTranslateY += ((margins.top * rowIndex) + (margins.bottom * (rowIndex - 1))); |
| } |
| |
| g.translate(scaledTranslateX, scaledTranslateY); |
| |
| Rectangle clip = new Rectangle((scaledWidth - margins.left - margins.right) * (colIndex - 1) + figureBounds.x, (scaledHeight - margins.bottom - margins.top) * (rowIndex - 1) + figureBounds.y, |
| scaledWidth - margins.right - margins.left, scaledHeight - margins.top - margins.bottom); |
| g.clipRect(clip); |
| |
| dgrmEP.getLayer(LayerConstants.PRINTABLE_LAYERS).paint(g); |
| |
| g.popState(); |
| } |
| |
| /** |
| * Adjust the page margins to be compatible with the user scale. |
| * |
| * @param margins |
| * the page margins to adjust |
| * @return adjusted page margins |
| */ |
| private PageMargins adjustMarginsToScale(PageMargins margins) { |
| |
| margins.left /= userScale; |
| margins.top /= userScale; |
| margins.bottom /= userScale; |
| margins.right /= userScale; |
| |
| return margins; |
| } |
| |
| /** |
| * A specialized graphics adapter used in printing. |
| * |
| * There are several issues with the base adapter such as incorrect line |
| * width settings and issues with gradient fill causing printing to be |
| * offset wich are concerns specific to printing. |
| * |
| * @author James Bruck (jbruck) |
| * |
| */ |
| private class PrinterGraphicsToGraphics2DAdapter extends GraphicsToGraphics2DAdaptor { |
| |
| public PrinterGraphicsToGraphics2DAdapter(Graphics2D graphics, Rectangle viewPort) { |
| super(graphics, viewPort); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.gmf.runtime.draw2d.ui.render.awt.internal.graphics. |
| * GraphicsToGraphics2DAdaptor#setLineWidth(int) |
| */ |
| public void setLineWidth(int width) { |
| super.setLineWidth(width); |
| |
| BasicStroke scaledStroke = getStroke(); |
| // |
| // Make a special case for line thickness to take the |
| // printer resolution into account. |
| // |
| scaledStroke = new BasicStroke((float) (width * AWT_DPI_CONST / 100), scaledStroke.getEndCap(), scaledStroke.getLineJoin(), scaledStroke.getMiterLimit(), scaledStroke.getDashArray(), 0); |
| |
| getGraphics2D().setStroke(scaledStroke); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.gmf.runtime.draw2d.ui.render.awt.internal.graphics. |
| * GraphicsToGraphics2DAdaptor#fillGradient(int, int, int, int, boolean) |
| */ |
| public void fillGradient(int x, int y, int w, int h, boolean vertical) { |
| // |
| // A bug in the draw2d layer causes printed output to be |
| // offset if we use gradient fill. We will use an image |
| // instead. |
| // |
| Image tempImage = new Image(DisplayUtils.getDisplay(), new org.eclipse.swt.graphics.Rectangle(x, y, w, h)); |
| GC gc = new GC(tempImage); |
| SWTGraphics tempGraphics = new SWTGraphics(gc); |
| |
| tempGraphics.setForegroundColor(swtGraphics.getForegroundColor()); |
| tempGraphics.setBackgroundColor(swtGraphics.getBackgroundColor()); |
| tempGraphics.fillGradient(new org.eclipse.draw2d.geometry.Rectangle(0, 0, w, h), vertical); |
| drawImage(tempImage, 0, 0, w, h, x, y, w, h); |
| |
| tempGraphics.dispose(); |
| gc.dispose(); |
| tempImage.dispose(); |
| } |
| } |
| |
| } |