/*

 * Title: japlot.jaxodraw
 * Description: Graphical user interface for drawing Feynman diagrams
 * @author Daniele Binosi 
 * @author Lukas Theussl  

 Copyright (C) 2003-2006,  Daniele Binosi and Lukas Theussl

 See the file LICENSE in the source distribution home directory
 for a full copy of the GPL (GNU General Public License).

    This file is part of japlot.jaxodraw.

    japlot.jaxodraw is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    japlot.jaxodraw is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


 */
package japlot.jaxodraw;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.print.PageFormat;
import java.awt.print.Printable;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

import java.util.Calendar;
import java.util.ResourceBundle;

import org.freehep.graphics2d.VectorGraphics;
import javax.print.Doc;
import javax.print.DocFlavor;
import javax.print.DocFlavor.BYTE_ARRAY;
import javax.print.DocFlavor.SERVICE_FORMATTED;
import javax.print.DocPrintJob;
import javax.print.PrintException;
import javax.print.SimpleDoc;
import javax.print.StreamPrintService;
import javax.print.StreamPrintServiceFactory;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.OrientationRequested;
import javax.print.event.PrintJobAdapter;
import javax.print.event.PrintJobEvent;

import javax.swing.JOptionPane;

import jhplot.jadraw.JaObject;
import japlot.Plot;


/** The class that is responsible for exporting to postscript output: portrait,
 * landscape or EPS are possible options. Asks for an export file name.
 */
public class JaxoExportPS extends JaxoExport implements Printable {
    private ResourceBundle language =
        ResourceBundle.getBundle(JaxoPrefs.getPref(JaxoPrefs.PREF_LANGUAGE));
    private Dimension canvasD;
    private float transX;
    private float transY;
    private double scale = 1.d;

    /** Sets the dimension of the canvas.
     * @param newD The dimension of the canvas.
     */
    public final void setCanvasD(Dimension newD) {
        this.canvasD = newD;
    }

    /** Exports the JaxoGraph graph into a postscript file:
     * asks for an export file name.
     * @param newGraph The graph to be exported.
     */
    public final void export(JaxoGraph newGraph) {
        setGraph(newGraph);

        checkforLatexText();

        int mode = getMode();

        if (mode == JaxoExportPanel.PS_EPS) {
            exportEPS(newGraph);
        } else {
            exportPS(newGraph, mode);
        }
    }

    /** Exports the JaxoGraph graph into a postscript format specified by mode.
     * @param graph The graph to be exported.
     * @param mode An integer specifying the postscript format.
     */
    public final void exportPS(JaxoGraph graph, int mode) {
        checkforLatexText();

        String exportPSFileName = getExportFileName();

        try {
            doExportPS(graph, mode, exportPSFileName);
        } catch (IOException ie) {
            JOptionPane.showMessageDialog(null,
                language.getString("IOException:_Cannot_export_file_")
                + exportPSFileName + "!");
            if (JaxoPrefs.verbose()) {
                System.err.println(ie);
            }
        }
    }

    private void doExportPS(JaxoGraph graph, int mode, String exportPSFileName)
        throws IOException {
        checkforLatexText();

        if (exportPSFileName.length() != 0) {
            if (!exportPSFileName.trim().endsWith(".ps")) {
                exportPSFileName = exportPSFileName.trim() + ".ps";
            }

            String tempFileName = ".temp.ps";
            File tempFile = new File(tempFileName);
            tempFile.deleteOnExit();

            exportPS(graph, canvasD, tempFileName, mode);

            BufferedReader inbr = null;
            BufferedWriter outbr = null;
            try {
                inbr = new BufferedReader(new FileReader(tempFileName));
                outbr = new BufferedWriter(new FileWriter(exportPSFileName));

                Calendar rightNow = Calendar.getInstance();

                String firstLine = "%!PS-Adobe-3.0";
                String thirdLine =
                    "%%Creator: " + JaxoDraw.USER_NAME + " with "
                    + JaxoDraw.VERSION;
                String forthLine = "%%Title: " + graph.getDescription();
                String fifthLine =
                    "%%CreationDate: " + rightNow.get(Calendar.DAY_OF_MONTH)
                    + "/" + (rightNow.get(Calendar.MONTH) + 1) + "/"
                    + rightNow.get(Calendar.YEAR);

                String str;
                boolean isFirstLine = true;

                while ((str = inbr.readLine()) != null) {
                    if (isFirstLine) {
                        outbr.write(firstLine, 0, firstLine.length());
                        outbr.newLine();
                        outbr.write(thirdLine, 0, thirdLine.length());
                        outbr.newLine();
                        outbr.write(forthLine, 0, forthLine.length());
                        outbr.newLine();
                        outbr.write(fifthLine, 0, fifthLine.length());
                        outbr.newLine();
                        isFirstLine = false;
                    } else {
                        outbr.write(str, 0, str.length());
                        outbr.newLine();
                    }
                }
            } finally { // make sure the streams are closed
                if (inbr != null) {
                    inbr.close();
                }
                if (outbr != null) {
                    outbr.close();
                }
            }
        }
    }

    /** Exports the JaxoGraph graph into an EPS file:
     * asks for an export file name.
     * @param newGraph The graph to be exported.
     */
    public final void exportEPS(JaxoGraph newGraph) {
        setGraph(newGraph);

        String exportEPSFileName = getExportFileName();
        exportEPS(newGraph, exportEPSFileName);
    }

    /** Exports the JaxoGraph graph into the EPS file exportEPSFileName.
     * @param graph The graph to be exported.
     * @param exportEPSFileName The name of the export file.
     */
    public final void exportEPS(JaxoGraph graph, String exportEPSFileName) {
        try {
            doExportEPS(graph, exportEPSFileName);
        } catch (IOException ie) {
            JOptionPane.showMessageDialog(null,
                language.getString("IOException:_Cannot_export_file_")
                + exportEPSFileName + "!");
            if (JaxoPrefs.verbose()) {
                System.err.println(ie);
            }
        }
    }

    private void doExportEPS(JaxoGraph graph, String exportEPSFileName)
        throws IOException {
        if (exportEPSFileName.length() != 0) {
            if (!exportEPSFileName.trim().endsWith(".eps")) {
                exportEPSFileName = exportEPSFileName.trim() + ".eps";
            }

            String tempFileName = ".temp.eps";
            File tempFile = new File(tempFileName);
            tempFile.deleteOnExit();

            exportPS(graph, canvasD, tempFileName, JaxoExportPanel.PS_EPS);

            BufferedReader inbr = null;
            BufferedWriter outbr = null;
            try {
                inbr = new BufferedReader(new FileReader(tempFileName));
                outbr = new BufferedWriter(new FileWriter(exportEPSFileName));

                double[] bb = getBB();

                Calendar rightNow = Calendar.getInstance();

                String firstLine = "%!PS-Adobe-3.0 EPSF-3.0";
                String secondLine =
                    "%%BoundingBox: " + (int) bb[0] + " " + (int) bb[1] + " "
                    + (int) bb[2] + " " + (int) bb[3];
                String thirdLine =
                    "%%Creator: " + JaxoDraw.USER_NAME + " with "
                    + JaxoDraw.VERSION;
                String forthLine = "%%Title: " + graph.getDescription();
                String fifthLine =
                    "%%CreationDate: " + rightNow.get(Calendar.DAY_OF_MONTH)
                    + "/" + (rightNow.get(Calendar.MONTH) + 1) + "/"
                    + rightNow.get(Calendar.YEAR);

                String str;
                String setpagedevice = "setpagedevice";
                boolean isFirstLine = true;

                while ((str = inbr.readLine()) != null) {
                    if (isFirstLine) {
                        outbr.write(firstLine, 0, firstLine.length());
                        outbr.newLine();
                        outbr.write(secondLine, 0, secondLine.length());
                        outbr.newLine();
                        outbr.write(thirdLine, 0, thirdLine.length());
                        outbr.newLine();
                        outbr.write(forthLine, 0, forthLine.length());
                        outbr.newLine();
                        outbr.write(fifthLine, 0, fifthLine.length());
                        outbr.newLine();
                        isFirstLine = false;
                    } else {
                        /* check whether the line contains
                           the postscript command "setpagedevice",
                           which is not allowed in EPS

                           other forbidden commands:
                                banddevice      exitserver    quit
                                clear           framedevice   renderbands
                                cleardictstack  grestoreall   setglobal
                                copypage        initclip      setpagedevice
                                erasepage       initgraphics  setshared
                                initmatrix      startjob
                         */
                        if (str.indexOf(setpagedevice) != -1) {
                            str = str.replaceAll(setpagedevice, "");
                        }
                        outbr.write(str, 0, str.length());
                        outbr.newLine();
                    }
                }
            } finally {
                if (inbr != null) {
                    inbr.close();
                }
                if (outbr != null) {
                    outbr.close();
                }
            }
        }
    }

    /** The actual printing routine required by the Printable interface.
     * @param g The specified graphics context.
     * @param pf The specified page format.
     * @param pageIndex The specified page index.
     * @return Either Printable.PAGE_EXISTS or Printable.NO_SUCH_PAGE.
     */
    public final int print(Graphics g, PageFormat pf, int pageIndex) {
        transX = (float) pf.getImageableX();
        transY = (float) pf.getImageableY();

        double scaleX = pf.getImageableWidth() / canvasD.width;
        double scaleY = pf.getImageableHeight() / canvasD.height;

        if (pageIndex == 0) {
            VectorGraphics g2 = VectorGraphics.create(g);
  
            scale = scaleX;

            if (scaleY < scaleX) {
                scale = scaleY;
            }

            if (scale > 1.) {
                scale = 1.d;
            }

            g2.translate((double) transX, (double) transY);
            g2.scale(scale, scale);

            JaxoGraph graph = getGraph();
            int length = graph.listSize();

             // this is first
            for (int i = 0; i < length; i++) {
                JaObject ob = (JaObject) graph.listElementAt(i);
                if (Plot.drawFirst(ob)) ob.jaxoDraw(g2, false);
            }

            // this is second
            for (int i = 0; i < length; i++) {
                JaObject ob = (JaObject) graph.listElementAt(i);
                Plot.drawRest(ob,g2,false);
            }



            return Printable.PAGE_EXISTS;
        } else {
            return Printable.NO_SUCH_PAGE;
        }
    }

    private double[] getBB() {
        double[] bBox = getGraph().getBoundingBox();
        double tmp = bBox[JaObject.BB_MIN_Y];

        bBox[JaObject.BB_MIN_X] =
            ((bBox[JaObject.BB_MIN_X] * scale) + (double) transX) - 1.;
        bBox[JaObject.BB_MIN_Y] =
            840. - 47. - ((bBox[JaObject.BB_MAX_Y] * scale) + (double) transY) - 1.;
        bBox[JaObject.BB_MAX_X] =
            ((bBox[JaObject.BB_MAX_X] * scale) + (double) transX) + 1.;
        bBox[JaObject.BB_MAX_Y] =
            840. - 47. - ((tmp * scale) + (double) transY) + 1.;

        return bBox;
    }

    /** The class that is responsible for exporting to postscript output:
     * portrait, landscape or EPS are possible options.
     * The export file name is given by fileName.
     * @param newGraph The JaxoGraph to be exported.
     * @param d The current dimension of the Canvas.
     * @param fileName The export file name.
     * @param mode An integer specifying the postscript format:
     * 0=portrait, 1 = landscape.
     */
    public final void exportPS(JaxoGraph newGraph, Dimension d, String fileName,
        int mode) {
        setGraph(newGraph);
        this.canvasD = d;

        DocFlavor flavor = SERVICE_FORMATTED.PRINTABLE;
        String psMimeType = BYTE_ARRAY.POSTSCRIPT.getMimeType();
        StreamPrintServiceFactory[] factories =
            StreamPrintServiceFactory.lookupStreamPrintServiceFactories(flavor,
                psMimeType);

        if (factories.length == 0) {
            JOptionPane.showMessageDialog(null,
                language.getString("No_suitable_factories_found!"));
        } else {
            FileOutputStream fos = null;
            try {
                // Create a file for the exported postscript
                fos = new FileOutputStream(fileName);

                // Create a Stream printer for Postscript
                StreamPrintService sps = factories[0].getPrintService(fos);

                // Create and call a Print Job
                DocPrintJob job = sps.createPrintJob();

                PrintRequestAttributeSet aset =
                    new HashPrintRequestAttributeSet();

                if (mode == JaxoExportPanel.PS_PORTRAIT) {
                    aset.add(OrientationRequested.PORTRAIT);
                } else {
                    if (mode == JaxoExportPanel.PS_LANDSCAPE) {
                        aset.add(OrientationRequested.LANDSCAPE);
                    } else {
                        aset.add(OrientationRequested.PORTRAIT);
                    }
                }

                Doc doc = new SimpleDoc(this, flavor, null);
                PrintJobWatcher pjDone = new PrintJobWatcher(job);
                job.print(doc, aset);
                pjDone.waitForDone();

            } catch (PrintException pe) {
                JOptionPane.showMessageDialog(null,
                    language.getString("PrintException:_Cannot_print_file")
                    + fileName + "!");
                if (JaxoPrefs.verbose()) {
                    System.err.println(pe);
                }
            } catch (IOException ie) {
                JOptionPane.showMessageDialog(null,
                    language.getString("IOException:_Cannot_print_file")
                    + fileName + "!");
                if (JaxoPrefs.verbose()) {
                    System.err.println(ie);
                }
            } finally {
                try {
                    if (fos != null) {
                        fos.close();
                    }
                } catch (IOException ioEx) {
                    if (JaxoPrefs.verbose()) {
                        System.err.println(ioEx);
                    }
                }
            }
        }
    }

    class PrintJobWatcher {
        // true if it is safe to close the print job's input stream
        private boolean done = false;

        PrintJobWatcher(DocPrintJob job) {
            // Add a listener to the print job
            job.addPrintJobListener(new PrintJobAdapter() {
                    public final void printJobCanceled(PrintJobEvent pje) {
                        allDone();
                    }

                    public final void printJobCompleted(PrintJobEvent pje) {
                        allDone();
                    }

                    public final void printJobFailed(PrintJobEvent pje) {
                        allDone();
                    }

                    public final void printJobNoMoreEvents(PrintJobEvent pje) {
                        allDone();
                    }

                    void allDone() {
                        synchronized (PrintJobWatcher.this) {
                            done = true;
                            PrintJobWatcher.this.notifyAll();
                        }
                    }
                });
        }

        public final synchronized void waitForDone() {
            try {
                while (!done) {
                    super.wait();
                }
            } catch (InterruptedException e) {
                JOptionPane.showMessageDialog(null,
                    language.getString(
                        "InterruptedException_:_Print_job_aborted!"));

                if (JaxoPrefs.verbose()) {
                    System.err.println(e);
                }
            }
        }
    }
}

 

Ads help maintain this website.