Package com.cburch.logisim.gui.main

Source Code of com.cburch.logisim.gui.main.ExportImage$OptionsPanel

/* Copyright (c) 2010, Carl Burch. License information is located in the
* com.cburch.logisim.Main source code and at www.cburch.com/logisim/. */

package com.cburch.logisim.gui.main;

import static com.cburch.logisim.util.LocaleString.*;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.filechooser.FileFilter;
import org.apache.batik.dom.GenericDOMImplementation;
import org.apache.batik.svggen.SVGGraphics2D;
import java.io.FileOutputStream;
import com.itextpdf.awt.DefaultFontMapper;
import com.itextpdf.awt.DefaultFontMapper.BaseFontParameters;
import com.itextpdf.awt.PdfGraphics2D;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import com.cburch.logisim.circuit.Circuit;
import com.cburch.logisim.circuit.CircuitState;
import com.cburch.logisim.comp.ComponentDrawContext;
import com.cburch.logisim.data.Bounds;
import com.cburch.logisim.file.Loader;
import com.cburch.logisim.proj.Project;

class ExportImage {
  private static final int SLIDER_DIVISIONS = 6;

  private static final int FORMAT_GIF = 0;
  private static final int FORMAT_PNG = 1;
  private static final int FORMAT_JPG = 2;
  private static final int FORMAT_SVG = 3;
  private static final int FORMAT_PDF = 4;
 
  private static final int BORDER_SIZE = 5;

  private ExportImage() { }

  static void doExport(Project proj) {
    // First display circuit/parameter selection dialog
    Frame frame = proj.getFrame();
    CircuitJList list = new CircuitJList(proj, true);
    if (list.getModel().getSize() == 0) {
      JOptionPane.showMessageDialog(proj.getFrame(),
          getFromLocale("exportEmptyCircuitsMessage"),
          getFromLocale("exportEmptyCircuitsTitle"),
          JOptionPane.YES_NO_OPTION);
      return;
    }
    OptionsPanel options = new OptionsPanel(list);
    int action = JOptionPane.showConfirmDialog(frame,
        options, getFromLocale("exportImageSelect"),
        JOptionPane.OK_CANCEL_OPTION,
        JOptionPane.QUESTION_MESSAGE);
    if (action != JOptionPane.OK_OPTION) return;
    List<Circuit> circuits = list.getSelectedValuesList();
    double scale = options.getScale();
    boolean printerView = options.getPrinterView();
    if (circuits.isEmpty()) return;
   
    ImageFileFilter filter;
    int fmt = options.getImageFormat();
    switch (options.getImageFormat()) {
    case FORMAT_GIF:
      filter = new ImageFileFilter(fmt, getFromLocale("exportGifFilter"),
        new String[] { "gif" });
      break;
    case FORMAT_PNG:
      filter = new ImageFileFilter(fmt, getFromLocale("exportPngFilter"),
        new String[] { "png" });
      break;
    case FORMAT_JPG:
      filter = new ImageFileFilter(fmt, getFromLocale("exportJpgFilter"),
        new String[] { "jpg", "jpeg", "jpe", "jfi", "jfif", "jfi" });
      break;
    case FORMAT_SVG:
      filter = null;
      filter = new ImageFileFilter(fmt, getFromLocale("exportSvgFilter"),
        new String[] { "svg" });
      break;
        case FORMAT_PDF:
          filter = null;
          filter = new ImageFileFilter(fmt, getFromLocale("exportPdfFilter"),
              new String[] { "pdf" });
          break;
    default:
      System.err.println("unexpected format; aborted"); //OK
      return;
    }
   
    // Then display file chooser
    Loader loader = proj.getLogisimFile().getLoader();
    JFileChooser chooser = loader.createChooser();
    if (circuits.size() > 1) {
      chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
      chooser.setDialogTitle(getFromLocale("exportImageDirectorySelect"));
    } else {
      chooser.setFileFilter(filter);
      chooser.setDialogTitle(getFromLocale("exportImageFileSelect"));
    }
    int returnVal = chooser.showDialog(frame, getFromLocale("exportImageButton"));
    if (returnVal != JFileChooser.APPROVE_OPTION) return;

    // Determine whether destination is valid
    File dest = chooser.getSelectedFile();
    chooser.setCurrentDirectory(dest.isDirectory() ? dest : dest.getParentFile());
    if (dest.exists()) {
      if (!dest.isDirectory()) {
        int confirm = JOptionPane.showConfirmDialog(proj.getFrame(),
          getFromLocale("confirmOverwriteMessage"),
          getFromLocale("confirmOverwriteTitle"),
          JOptionPane.YES_NO_OPTION);
        if (confirm != JOptionPane.YES_OPTION) return;
      }
    } else {
      if (circuits.size() > 1) {
        boolean created = dest.mkdir();
        if (!created) {
          JOptionPane.showMessageDialog(proj.getFrame(),
              getFromLocale("exportNewDirectoryErrorMessage"),
              getFromLocale("exportNewDirectoryErrorTitle"),
              JOptionPane.YES_NO_OPTION);
          return;
        }
      }
    }

    // Create the progress monitor
    ProgressMonitor monitor = new ProgressMonitor(frame,
        getFromLocale("exportImageProgress"),
        null,
        0, 10000);
    monitor.setMillisToDecideToPopup(100);
    monitor.setMillisToPopup(200);
    monitor.setProgress(0);

    // And start a thread to actually perform the operation
    // (This is run in a thread so that Swing will update the
    // monitor.)
    new ExportThread(frame, frame.getCanvas(), dest, filter,
        circuits, scale, printerView, monitor).start();

  }

  private static class OptionsPanel extends JPanel implements ChangeListener {
    JSlider slider;
    JLabel curScale;
    JCheckBox printerView;
    JRadioButton formatPng;
    JRadioButton formatGif;
    JRadioButton formatJpg;
    JRadioButton formatSvg;
    JRadioButton formatPdf;
    GridBagLayout gridbag;
    GridBagConstraints gbc;
    Dimension curScaleDim;

    OptionsPanel(JList list) {
      // set up components
      formatPng = new JRadioButton("PNG");
      formatGif = new JRadioButton("GIF");
      formatJpg = new JRadioButton("JPEG");
      formatSvg = new JRadioButton("SVG");
      formatPdf = new JRadioButton("PDF");
      ButtonGroup bgroup = new ButtonGroup();
      bgroup.add(formatPng);
      bgroup.add(formatGif);
      bgroup.add(formatJpg);
      bgroup.add(formatSvg);
      bgroup.add(formatPdf);
      formatPng.setSelected(true);

      slider = new JSlider(JSlider.HORIZONTAL,
          -3 * SLIDER_DIVISIONS, 3 * SLIDER_DIVISIONS, 0);
      slider.setMajorTickSpacing(10);
      slider.addChangeListener(this);
      curScale = new JLabel("222%");
      curScale.setHorizontalAlignment(SwingConstants.RIGHT);
      curScale.setVerticalAlignment(SwingConstants.CENTER);
      curScaleDim = new Dimension(curScale.getPreferredSize());
      curScaleDim.height = Math.max(curScaleDim.height,
          slider.getPreferredSize().height);
      stateChanged(null);

      printerView = new JCheckBox();
      printerView.setSelected(true);

      // set up panel
      gridbag = new GridBagLayout();
      gbc = new GridBagConstraints();
      setLayout(gridbag);

      // now add components into panel
      gbc.gridy = 0;
      gbc.gridx = GridBagConstraints.RELATIVE;
      gbc.anchor = GridBagConstraints.NORTHWEST;
      gbc.insets = new Insets(5, 0, 5, 0);
      gbc.fill = GridBagConstraints.NONE;
      addGb(new JLabel(getFromLocale("labelCircuits") + " "));
      gbc.fill = GridBagConstraints.HORIZONTAL;
      addGb(new JScrollPane(list));
      gbc.fill = GridBagConstraints.NONE;
     
      gbc.gridy++;
      addGb(new JLabel(getFromLocale("labelImageFormat") + " "));
      Box formatsPanel = new Box(BoxLayout.Y_AXIS);
      formatsPanel.add(formatPng);
      formatsPanel.add(formatGif);
      formatsPanel.add(formatJpg);
      formatsPanel.add(formatSvg);
      formatsPanel.add(formatPdf);
      addGb(formatsPanel);
     
      gbc.gridy++;
      addGb(new JLabel(getFromLocale("labelScale") + " "));
      addGb(slider);
      addGb(curScale);
     
      gbc.gridy++;
      addGb(new JLabel(getFromLocale("labelPrinterView") + " "));
      addGb(printerView);
    }
   
    private void addGb(JComponent comp) {
      gridbag.setConstraints(comp, gbc);
      add(comp);
    }

    double getScale() {
      return Math.pow(2.0, (double) slider.getValue() / SLIDER_DIVISIONS);
    }
   
    boolean getPrinterView() { return printerView.isSelected(); }
   
    int getImageFormat() {
      if (formatGif.isSelected()) return FORMAT_GIF;
      if (formatJpg.isSelected()) return FORMAT_JPG;
      if (formatSvg.isSelected()) return FORMAT_SVG;
      if (formatPdf.isSelected()) return FORMAT_PDF;
      return FORMAT_PNG;
    }

    public void stateChanged(ChangeEvent e) {
      double scale = getScale();
      curScale.setText((int) Math.round(100.0 * scale) + "%");
      if (curScaleDim != null) curScale.setPreferredSize(curScaleDim);
    }
  }
 
  private static class ImageFileFilter extends FileFilter {
    private int type;
    private String[] extensions;
    private String desc;
   
    private ImageFileFilter(int type, String desc, String[] exts) {
      this.type = type;
      this.desc = desc;
      extensions = new String[exts.length];
      for (int i = 0; i < exts.length; i++) {
        extensions[i] = "." + exts[i].toLowerCase();   
      }
    }
   
    @Override
    public boolean accept(File f) {
      String name = f.getName().toLowerCase();
      for (int i = 0; i < extensions.length; i++) {
        if (name.endsWith(extensions[i])) return true;
      }
      return f.isDirectory();
    }

    @Override
    public String getDescription() {
      return desc.toString();
    }
  }

  private static class ExportThread extends Thread {
    Frame frame;
    Canvas canvas;
    File dest;
    ImageFileFilter filter;
    List<Circuit> circuits;
    double scale;
    boolean printerView;
    ProgressMonitor monitor;

    ExportThread(Frame frame, Canvas canvas, File dest, ImageFileFilter f,
        List<Circuit> circuits, double scale, boolean printerView,
        ProgressMonitor monitor) {
      this.frame = frame;
      this.canvas = canvas;
      this.dest = dest;
      this.filter = f;
      this.circuits = circuits;
      this.scale = scale;
      this.printerView = printerView;
      this.monitor = monitor;
    }

    @Override
    public void run() {
      for (Circuit circ : circuits) {
        export(circ);
      }
    }
   
    private void export(Circuit circuit) {
          Bounds bds = circuit.getBounds(canvas.getGraphics())
              .expand(BORDER_SIZE);
          int width = (int) Math.round(bds.getWidth() * scale);
          int height = (int) Math
              .round(bds.getHeight() * scale);
          BufferedImage img = new BufferedImage(width, height,
              BufferedImage.TYPE_INT_RGB);
   
          File where;
          if (dest.isDirectory()) {
            where = new File(dest, circuit.getName()
                + filter.extensions[0]);
          } else if (filter.accept(dest)) {
            where = dest;
          } else {
            String newName = dest.getName()
                + filter.extensions[0];
            where = new File(dest.getParentFile(), newName);
          }
   
          try (FileOutputStream stream = new FileOutputStream(
              where)) {
   
            if (filter.type == FORMAT_SVG) {
              DOMImplementation domImpl = GenericDOMImplementation
                  .getDOMImplementation();
   
              // Create an instance of org.w3c.dom.Document.
              String svgNS = "http://www.w3.org/2000/svg";
              Document document = domImpl.createDocument(svgNS,
                  "svg", null);
   
              // Create an instance of the SVG Generator.
              SVGGraphics2D svgGenerator = new SVGGraphics2D(
                  document);
   
              paint(svgGenerator, bds, circuit, width, height);
   
              // Finally, stream out SVG to the standard output using
              // UTF-8 encoding.
              boolean useCSS = true; // we want to use CSS style attributes
   
              Writer out = new OutputStreamWriter(stream,
                  "UTF-8");
              svgGenerator.stream(out, useCSS);
            } else if (filter.type == FORMAT_PDF) {
              com.itextpdf.text.Document document = new com.itextpdf.text.Document(new Rectangle(width, height));
              PdfWriter writer = PdfWriter.getInstance(document, stream);
              document.open();
              PdfContentByte cb = writer.getDirectContent();
              DefaultFontMapper fontMapper = new DefaultFontMapper();
              BaseFontParameters fontParameters = new BaseFontParameters("LiberationSans-Regular.ttf");
              fontParameters.encoding = BaseFont.IDENTITY_H;
              fontMapper.putName("Dialog.plain", fontParameters);
              fontMapper.putName("SansSerif.plain", fontParameters);
              PdfGraphics2D pdfGraphics = new PdfGraphics2D(cb, width, height, fontMapper);
              paint(pdfGraphics, bds, circuit, width, height);
              pdfGraphics.dispose();
              document.close();
            } else {
              paint(img.getGraphics(), bds, circuit, width,
                  height);
              String formatName = null;
              switch (filter.type) {
              case FORMAT_GIF:
                formatName = "GIF";
                break;
              case FORMAT_PNG:
                formatName = "PNG";
                break;
              case FORMAT_JPG:
                formatName = "JPEG";
                break;
              }
              ImageIO.write(img, formatName, stream);
            }
   
          } catch (Exception e) {
            StringWriter writer = new StringWriter();
            e.printStackTrace(new PrintWriter(writer));
            String stackTrace = writer.toString();
            JTextArea textArea = new JTextArea( getFromLocale("couldNotCreateFile") + "\n" + stackTrace);
            JOptionPane.showMessageDialog(frame, textArea);
            monitor.close();
            return;
          }
          monitor.close();
    }
   
    private void paint(Graphics base, Bounds bds, Circuit circuit, int width, int height) {
      Graphics g = base.create();
      g.setColor(Color.white);
      g.fillRect(0, 0, width, height);
      g.setColor(Color.black);
      if (g instanceof Graphics2D) {
        ((Graphics2D) g).scale(scale, scale);
        ((Graphics2D) g).translate(-bds.getX(), -bds.getY());
      } else {
        JOptionPane.showMessageDialog(frame,
            getFromLocale("couldNotCreateImage"));
        monitor.close();
      }

      CircuitState circuitState = canvas.getProject().getCircuitState(circuit);
      ComponentDrawContext context = new ComponentDrawContext(canvas,
          circuit, circuitState, base, g, printerView);
      circuit.draw(context, null);
      g.dispose();
    }
  }
}
TOP

Related Classes of com.cburch.logisim.gui.main.ExportImage$OptionsPanel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.