// Copyright 2007 FreeHEP package org.freehep.graphicsio.ps; import java.awt.Component; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Insets; import java.awt.Rectangle; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; import org.freehep.graphicsio.PageConstants; /** * Writes Encapsulated PostScript with bounding box. * @author duns * @version $Id$ */ public class EPSGraphics2D extends AbstractPSGraphics2D { public EPSGraphics2D(File file, Dimension size) throws FileNotFoundException { this(new FileOutputStream(file), size); } public EPSGraphics2D(File file, Component component) throws FileNotFoundException { this(new FileOutputStream(file), component); } public EPSGraphics2D(OutputStream os, Dimension size) { super(size, false); init(os); } public EPSGraphics2D(OutputStream os, Component component) { super(component, false); init(os); } protected EPSGraphics2D(EPSGraphics2D graphics, boolean doRestoreOnDispose) { super(graphics, doRestoreOnDispose); } /** * Get the bounding box for this page. * * @return pageSize - margins */ private Rectangle getBoundingBox() { // determine page size Dimension pageSize = getPageSize(); // Our PS Header has internal page orientation mode, all sizes given in // portrait Insets margins = getPropertyInsets(PAGE_MARGINS); boolean isPortrait = getProperty(ORIENTATION).equals( PageConstants.PORTRAIT); // Available width and height. double awidth = (pageSize.width - margins.left - margins.right); double aheight = (pageSize.height - margins.top - margins.bottom); // Image width and height (adjusted for portrait or landscape) Dimension size = getSize(); double iwidth = (isPortrait ? size.width : size.height); double iheight = (isPortrait ? size.height : size.width); // Choose the minimum scale factor. double sf = Math.min(awidth / iwidth, aheight / iheight); if (!isProperty(FIT_TO_PAGE)) { sf = Math.min(sf, 1.); } // Lower left corner. double x0 = awidth / 2. + margins.left - sf * iwidth / 2.; double y0 = aheight / 2. + margins.bottom - sf * iheight / 2.; // Upper right corner. double x1 = x0 + sf * iwidth; double y1 = y0 + sf * iheight; int llx = (int) x0; int lly = (int) y0; int urx = (int) Math.ceil(x1); int ury = (int) Math.ceil(y1); // Convert these back to integer values. return new Rectangle(llx, lly, urx - llx, ury - lly); } public void writeHeader() throws IOException { Dimension size = getSize(); // moved to openPage for multiPage resetClip(new Rectangle(0, 0, size.width, size.height)); os = new PrintStream(ros, true); os.println("%!PS-Adobe-3.0" + " EPSF-3.0"); Rectangle bbox = getBoundingBox(); os.println("%%BoundingBox: " + bbox.x + " " + bbox.y + " " + (bbox.x + bbox.width) + " " + (bbox.y + bbox.height)); super.writeHeader(); os.println("%%BeginSetup"); super.openPage(getSize(), null, getComponent()); os.println("%%EndSetup"); os.println(); try { writeGraphicsState(); writeBackground(); } catch (Exception e) { handleException(e); } } public void writeTrailer() throws IOException { super.writeTrailer(); os.println("%%EOF"); } public Graphics create() { try { writeGraphicsSave(); } catch (IOException e) { handleException(e); } return new EPSGraphics2D(this, true); } public Graphics create(double x, double y, double width, double height) { try { writeGraphicsSave(); } catch (IOException e) { handleException(e); } EPSGraphics2D graphics = new EPSGraphics2D(this, true); graphics.translate(x, y); graphics.clipRect(0, 0, width, height); return graphics; } }