/* * This file is part of LaTeXDraw. * Copyright (c) 2005-2017 Arnaud BLOUIN * LaTeXDraw 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. * LaTeXDraw is distributed 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. */ package net.sf.latexdraw.actions; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import javafx.embed.swing.SwingFXUtils; import javafx.geometry.Bounds; import javafx.scene.Group; import javafx.scene.SnapshotParameters; import javafx.scene.image.WritableImage; import javafx.scene.paint.Color; import javafx.scene.transform.Scale; import javafx.stage.FileChooser; import javax.imageio.ImageIO; import net.sf.latexdraw.badaboom.BadaboomCollector; import net.sf.latexdraw.view.jfx.Canvas; import net.sf.latexdraw.view.pst.PSTCodeGenerator; import org.malai.action.ActionImpl; /** * This action allows to export a drawing in different formats. * @author Arnaud Blouin */ public class Export extends ActionImpl { /** The format with which the drawing must be exported. */ private ExportFormat format; /** The canvas that contains views. */ private Canvas canvas; /** Defines if the shapes have been successfully exported. */ private boolean exported; /** The dialogue chooser used to select the targeted file. */ private FileChooser dialogueBox; /** The PST generator to use. */ private PSTCodeGenerator pstGen; private File outputFile; /** * Creates the action. * @since 3.0 */ public Export() { super(); exported = false; } @Override public void flush() { super.flush(); canvas = null; format = null; dialogueBox = null; } @Override protected void doActionBody() { // Showing the dialog. File file = dialogueBox.showSaveDialog(canvas.getScene().getWindow()); exported = true; // Analysing the result of the dialog. if(file == null) { exported = false; }else { if(!file.getName().toLowerCase().endsWith(format.getFileExtension().toLowerCase())) { file = new File(file.getPath() + format.getFileExtension()); } } if(exported) { exported = export(file); if(exported) { outputFile = file; } } } private boolean export(final File file) { switch(format) { case BMP: return exportAsPicture(file, "bmp", false); case EPS_LATEX: return exportAsEPS(file); case JPG: return exportAsPicture(file, "jpg", false); case PDF: return exportAsPDF(file); case PDF_CROP: return exportAsPDF(file); case PNG: return exportAsPicture(file, "png", true); case TEX: return exportAsPST(file); } return false; } @Override public boolean canDo() { return canvas != null && format != null && dialogueBox != null && (format == ExportFormat.BMP || format == ExportFormat.JPG || format == ExportFormat.PNG || pstGen != null); } @Override public boolean hadEffect() { return super.hadEffect() && exported; } /** * Exports the drawing as a PNG picture. * @param file The targeted location. * @return true if the picture was well created. */ private boolean exportAsPicture(final File file, final String format, final boolean alpha) { BufferedImage rendImage = createRenderedImage(); boolean success = false; if(!alpha) { final BufferedImage copy = new BufferedImage(rendImage.getWidth(), rendImage.getHeight(), BufferedImage.TYPE_INT_RGB); Graphics2D g2d = copy.createGraphics(); g2d.drawImage(rendImage, 0, 0, null); g2d.dispose(); rendImage.flush(); rendImage = copy; } try { ImageIO.write(rendImage, format, file); //$NON-NLS-1$ success = true; }catch(final IOException e) { BadaboomCollector.INSTANCE.add(e); } rendImage.flush(); return success; } /** * Creates a ps document of the given views (compiled using latex). * @param file The targeted location. * @return True: the file has been created. * @since 3.0 */ private boolean exportAsEPS(final File file) { File psFile; try { psFile = pstGen.createEPSFile(file.getAbsolutePath()).orElse(null); }catch(final Exception e) { BadaboomCollector.INSTANCE.add(e); psFile = null; } return psFile != null && psFile.exists(); } /** * Creates a pdf document of the given views (compiled using latex). * @param file The targeted location. * @return True: the file has been created. * @since 3.0 */ private boolean exportAsPDF(final File file) { File pdfFile; try { pdfFile = pstGen.createPDFFile(file.getAbsolutePath(), format == ExportFormat.PDF_CROP).orElse(null); }catch(final Exception e) { BadaboomCollector.INSTANCE.add(e); pdfFile = null; } return pdfFile != null && pdfFile.exists(); } /** * Exports the drawing as a PST document. * @param file The targeted location. * @return true if the PST document was been successfully created. */ private boolean exportAsPST(final File file) { boolean ok; try { try(final FileWriter fw = new FileWriter(file); final BufferedWriter bw = new BufferedWriter(fw); final PrintWriter out = new PrintWriter(bw)) { out.println(pstGen.getDrawingCode()); ok = true; } }catch(final IOException e) { BadaboomCollector.INSTANCE.add(e); ok = false; } return ok; } /** * @return A writable image that contains given views (not null). */ private BufferedImage createRenderedImage() { final Group views = canvas.getViews(); final Bounds bounds = views.getBoundsInParent(); final double scale = 3d; final WritableImage img = new WritableImage((int) (bounds.getWidth() * scale), (int) (bounds.getHeight() * scale)); final SnapshotParameters snapshotParameters = new SnapshotParameters(); snapshotParameters.setFill(Color.WHITE); snapshotParameters.setTransform(new Scale(scale, scale)); views.snapshot(snapshotParameters, img); while(img.isBackgroundLoading()) { try { Thread.sleep(100); }catch(InterruptedException e) { BadaboomCollector.INSTANCE.add(e); } } return SwingFXUtils.fromFXImage(img, null); } /** * @param dialogBox The file chooser to set. * @since 3.0 */ public void setDialogueBox(final FileChooser dialogBox) { dialogueBox = dialogBox; } /** * @param expFormat The expFormat to set. * @since 3.0 */ public void setFormat(final ExportFormat expFormat) { format = expFormat; } /** * @param theCanvas The theCanvas to set. * @since 3.0 */ public void setCanvas(final Canvas theCanvas) { canvas = theCanvas; } /** * @param gen The PST generator to use for latex, ps, or pdf exports. * @since 3.0 */ public void setPstGen(final PSTCodeGenerator gen) { pstGen = gen; } /** * @return The output file produced during the export. */ public File getOutputFile() { return outputFile; } }