summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEthan Vrhel <ethanvrhel@gmail.com>2020-08-19 17:38:34 -0700
committerevrhel <ethanvrhel@gmail.com>2020-09-24 15:23:44 -0700
commit5b08d9eadfe64d87cf26869c47a2a5f78755dd4b (patch)
tree6d12c3e939b8495efb58fd1b35e1d7453d480a28
parent4a78a968777521f23fefaeb277d378b9dc08b555 (diff)
downloadghostpdl-5b08d9eadfe64d87cf26869c47a2a5f78755dd4b.tar.gz
Implemented distilling documents
Users now have the option to distill a document if the desired input is not a PDF.
-rw-r--r--demos/java/gsviewer/src/com/artifex/gsviewer/Document.java170
-rw-r--r--demos/java/gsviewer/src/com/artifex/gsviewer/ViewerController.java29
-rw-r--r--demos/java/gsviewer/src/com/artifex/gsviewer/gui/ViewerWindow.java8
3 files changed, 129 insertions, 78 deletions
diff --git a/demos/java/gsviewer/src/com/artifex/gsviewer/Document.java b/demos/java/gsviewer/src/com/artifex/gsviewer/Document.java
index 202de60e6..5e2c4af91 100644
--- a/demos/java/gsviewer/src/com/artifex/gsviewer/Document.java
+++ b/demos/java/gsviewer/src/com/artifex/gsviewer/Document.java
@@ -5,6 +5,7 @@ import static com.artifex.gsjava.GSAPI.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
@@ -43,6 +44,8 @@ public class Document implements List<Page> {
private static final Condition operationCv = operationLock.newCondition(); // The operation condition variable
private static volatile boolean operationInProgress = false; // Whether an operation is in progress
+ private static GSInstance gsInstance = null;
+
/**
* Asynchronous execution dispatch returns.
*/
@@ -199,6 +202,46 @@ public class Document implements List<Page> {
return loadDocumentAsync(filename, cb, null, operationMode);
}
+ public static boolean shouldDistill(File file) {
+ String path = file.getAbsolutePath();
+ int extensionInd = path.lastIndexOf('.');
+ if (extensionInd == -1 || !GSFileFilter.INSTANCE.accept(file))
+ throw new IllegalArgumentException("Invalid file type");
+ String extension = path.substring(extensionInd);
+ return !extension.equalsIgnoreCase(".pdf");
+ }
+
+ public static File distillDocument(File input, File out) throws IOException, IllegalStateException {
+ if (gsInstance != null)
+ throw new IllegalStateException("gsInstance is non-null");
+
+ out = out == null ? File.createTempFile(input.getName() + ".pdf", null) : out;
+ if (!out.exists())
+ out.createNewFile();
+
+ try {
+ int code = initGSInstance(
+ "gs",
+ "-sDEVICE=pdfwrite",
+ "-dFirstPage=1",
+ "-dDisplayFormat=" + format,
+ "-o", out.getAbsolutePath(),
+ "-f", input.getAbsolutePath()
+ );
+
+ if (code != GS_ERROR_OK)
+ throw new IllegalStateException("Failed to distill document (code = " + code + ")");
+
+ /*Reference<Integer> pExitCode = new Reference<>();
+ int code = gsInstance.run_file(out.getAbsolutePath(), 0, pExitCode);
+ if (code != GS_ERROR_OK)
+ throw new IllegalStateException("failed to run file (code = " + code + ")");*/
+ } finally {
+ deleteGSInstance();
+ }
+ return out;
+ }
+
/**
* Call, internally, on the start of an operation.
*/
@@ -299,7 +342,9 @@ public class Document implements List<Page> {
}
}
- private static GSInstance initDocInstance() throws IllegalStateException {
+ private static int initGSInstance(String... args) throws IllegalStateException {
+ deleteGSInstance();
+
GSInstance instance = new GSInstance();
int code;
@@ -315,20 +360,45 @@ public class Document implements List<Page> {
throw new IllegalStateException("Failed to set display callback (code = " + code + ")");
}
- String[] gsargs = new String[] {
- "gs",
- "-dNOPAUSE", "-dSAFER", "-I%rom%Resource%/Init/", "-dBATCH",
- "-sDEVICE=display",
- "-dFirstPage=1",
- "-dDisplayFormat=" + format
- };
- code = instance.init_with_args(gsargs);
+ code = instance.init_with_args(args);
if (code != GS_ERROR_OK) {
instance.delete_instance();
throw new IllegalStateException("Failed to init with args (code = " + code + ")");
}
- return instance;
+ gsInstance = instance;
+ return code;
+ }
+
+ private static void deleteGSInstance() {
+ if (gsInstance != null) {
+ gsInstance.exit();
+ gsInstance.delete_instance();
+ gsInstance = null;
+ }
+ }
+
+ private static void setParams(int dpi, int startPage, int lastPage) throws NullPointerException, IllegalStateException {
+ if (gsInstance == null)
+ throw new NullPointerException("gsInstance is null");
+
+ int code = gsInstance.set_param("HWResolution", Page.toDPIString(dpi), GS_SPT_PARSED);
+ if (code != GS_ERROR_OK) {
+ operationDone();
+ throw new IllegalStateException("Failed to set HWResolution (code = " + code + ")");
+ }
+
+ code = gsInstance.set_param("FirstPage", startPage, GS_SPT_INT);
+ if (code != GS_ERROR_OK) {
+ operationDone();
+ throw new IllegalStateException("Failed to set dFirstPage (code = " + code + ")");
+ }
+
+ code = gsInstance.set_param("LastPage", lastPage, GS_SPT_INT);
+ if (code != GS_ERROR_OK) {
+ operationDone();
+ throw new IllegalStateException("Failed to set dEndPage (code = " + code + ")");
+ }
}
/**
@@ -361,14 +431,12 @@ public class Document implements List<Page> {
@Override
public int onDisplayPresize(long handle, long device, int width, int height, int raster, int format) {
- System.out.println("Presize");
return 0;
}
@Override
public int onDisplaySize(long handle, long device, int width, int height, int raster, int format,
BytePointer pimage) {
- System.out.println("Size");
this.pageWidth = width;
this.pageHeight = height;
this.pageRaster = raster;
@@ -396,7 +464,6 @@ public class Document implements List<Page> {
private File file;
private List<Page> pages;
- private GSInstance gsInstance;
/**
* Creates and loads a new document.
@@ -424,9 +491,6 @@ public class Document implements List<Page> {
if (!file.exists())
throw new FileNotFoundException(file.getAbsolutePath());
- final String[] gargs = { "gs", "-dNOPAUSE", "-dSAFER", "-I%rom%Resource%/Init/", "-dBATCH", "-r" + Page.PAGE_LOW_DPI,
- "-sDEVICE=display", "-dDisplayFormat=" + format, "-f", file.getAbsolutePath() };
-
if (!handleOperationMode(operationMode))
return;
@@ -434,7 +498,12 @@ public class Document implements List<Page> {
startOperation();
- gsInstance = initDocInstance();
+ int code = initGSInstance(
+ "gs",
+ "-sDEVICE=display",
+ "-dFirstPage=1",
+ "-dDisplayFormat=" + format
+ );
if (gsInstance == null)
throw new IllegalStateException("Failed to initialize Ghostscript");
@@ -442,7 +511,7 @@ public class Document implements List<Page> {
documentLoader.callback = loadCallback;
- int code = gsInstance.set_param("HWResolution", Page.PAGE_LOW_DPI_STR, GS_SPT_PARSED);
+ code = gsInstance.set_param("HWResolution", Page.PAGE_LOW_DPI_STR, GS_SPT_PARSED);
if (code != GS_ERROR_OK)
throw new IllegalStateException("Failed to set HWResolution (code = " + code + ")");
@@ -566,15 +635,9 @@ public class Document implements List<Page> {
try {
startOperation();
- final String[] gargs = { "gs", "-dNOPAUSE", "-dSAFER", "-I%rom%Resource%/Init/",
- "-dBATCH", "-r" + Page.PAGE_HIGH_DPI, "-sDEVICE=display",
- "-dFirstPage=" + startPage, "-dLastPage=" + endPage, "-dDisplayFormat=" + format,
- "-dTextAlphaBits=4", "-dGraphicsAlphaBits=4",
- "-f", file.getAbsolutePath() };
-
documentLoader.images.clear();
- this.setParams(Page.PAGE_HIGH_DPI, startPage, endPage);
+ setParams(Page.PAGE_HIGH_DPI, startPage, endPage);
Reference<Integer> exitCode = new Reference<>();
int code = gsInstance.run_file(file.getAbsolutePath(), 0, exitCode);
@@ -748,14 +811,14 @@ public class Document implements List<Page> {
* call.
*/
public void unload() {
- gsInstance.exit();
- gsInstance.delete_instance();
- gsInstance = null;
+ if (pages != null)
+ deleteGSInstance();
for (Page p : pages) {
p.unloadAll();
}
pages.clear();
+ pages = null;
}
/**
@@ -803,42 +866,16 @@ public class Document implements List<Page> {
int end = page + 1;
end = end > pages.size() ? page : end;
- final String[] gargs = {
- "gs", "-dNOPAUSE", "-dSAFER", "-I%rom%Resource%/Init/",
- "-dBATCH", "-r" + (int)(Page.PAGE_HIGH_DPI * zoom),
- "-sDEVICE=display", "-dFirstPage=" + start, "-dLastPage=" + end,
- "-dDisplayFormat=" + format,
- "-dTextAlphaBits=4", "-dGraphicsAlphaBits=4",
- "-f", file.getAbsolutePath() };
-
documentLoader.images.clear();
- this.setParams((int)(Page.PAGE_HIGH_DPI * zoom), start, end);
+ setParams((int)(Page.PAGE_HIGH_DPI * zoom), start, end);
Reference<Integer> exitCode = new Reference<>();
- int code = this.gsInstance.run_file(file.getAbsolutePath(), 0, exitCode);
+ int code = gsInstance.run_file(file.getAbsolutePath(), 0, exitCode);
if (code != GS_ERROR_OK)
throw new IllegalStateException("Failed to run file (code = " + code + ")");
-// GSInstance instance = null;
-// try {
-// instance = initDocInstance();
-// } catch (IllegalStateException e) {
-// operationDone();
-// }
-//
-// if (instance == null)
-// throw new IllegalStateException("Failed to initialize Ghoscript");
-//
-// int code = instance.init_with_args(gargs);
-// instance.exit();
-// instance.delete_instance();
-// if (code != GS_ERROR_OK) {
-// operationDone();
-// throw new IllegalStateException("Failed to gsapi_init_with_args code=" + code);
-// }
-
int ind = start - 1;
for (final BufferedImage img : documentLoader.images) {
this.pages.get(ind++).setZoomed(img);
@@ -867,27 +904,6 @@ public class Document implements List<Page> {
throw new IndexOutOfBoundsException("end < start");
}
- private void setParams(int dpi, int startPage, int lastPage) {
- int code = gsInstance.set_param("HWResolution", Page.toDPIString(dpi), GS_SPT_PARSED);
- if (code != GS_ERROR_OK) {
- operationDone();
- throw new IllegalStateException("Failed to set HWResolution (code = " + code + ")");
- }
-
- code = gsInstance.set_param("FirstPage", startPage, GS_SPT_INT);
- if (code != GS_ERROR_OK) {
- operationDone();
- throw new IllegalStateException("Failed to set dFirstPage (code = " + code + ")");
- }
-
- code = gsInstance.set_param("LastPage", lastPage, GS_SPT_INT);
- if (code != GS_ERROR_OK) {
- operationDone();
- throw new IllegalStateException("Failed to set dEndPage (code = " + code + ")");
- }
- }
-
-
// Implementations of inherited methods from java.util.List.
@Override
diff --git a/demos/java/gsviewer/src/com/artifex/gsviewer/ViewerController.java b/demos/java/gsviewer/src/com/artifex/gsviewer/ViewerController.java
index 92e7d725e..39b3aae7f 100644
--- a/demos/java/gsviewer/src/com/artifex/gsviewer/ViewerController.java
+++ b/demos/java/gsviewer/src/com/artifex/gsviewer/ViewerController.java
@@ -2,6 +2,7 @@ package com.artifex.gsviewer;
import java.io.ByteArrayOutputStream;
import java.io.File;
+import java.io.IOException;
import java.io.PrintStream;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
@@ -28,7 +29,33 @@ public class ViewerController implements ViewerGUIListener {
private Document currentDocument;
private SmartLoader smartLoader;
- public void open(final File file) {
+ public void open(File file) {
+ if (Document.shouldDistill(file)) {
+ int ret = source.showConfirmDialog("Distill", "Would you like to distill this document before opening?");
+ if (ret == ViewerWindow.CANCEL)
+ return;
+ else if (ret == ViewerWindow.YES) {
+ try {
+ JFileChooser chooser = new JFileChooser();
+ chooser.setCurrentDirectory(new File("."));
+ ret = chooser.showSaveDialog(source);
+ if (ret != JFileChooser.APPROVE_OPTION)
+ return;
+ File out = chooser.getSelectedFile();
+ if (out.exists()) {
+ ret = source.showConfirmDialog("Overwrite?", out.getName() + " already exists. Overwrite?");
+ if (ret != ViewerWindow.YES)
+ return;
+ }
+ if (currentDocument != null)
+ close();
+ file = Document.distillDocument(file, out);
+ } catch (IllegalStateException | IOException e) {
+ System.err.println("Failed to distill: " + e);
+ }
+ }
+ }
+
if (currentDocument != null)
close();
Document.loadDocumentAsync(file, (final Document doc, final Exception exception) -> {
diff --git a/demos/java/gsviewer/src/com/artifex/gsviewer/gui/ViewerWindow.java b/demos/java/gsviewer/src/com/artifex/gsviewer/gui/ViewerWindow.java
index fb7c78c29..0b701ddc3 100644
--- a/demos/java/gsviewer/src/com/artifex/gsviewer/gui/ViewerWindow.java
+++ b/demos/java/gsviewer/src/com/artifex/gsviewer/gui/ViewerWindow.java
@@ -44,6 +44,10 @@ public class ViewerWindow extends javax.swing.JFrame {
*/
public static final int MINI_VIEWER_PAGE_GAP = 10;
+ public static final int YES = JOptionPane.YES_OPTION;
+ public static final int NO = JOptionPane.NO_OPTION;
+ public static final int CANCEL = JOptionPane.CANCEL_OPTION;
+
private ViewerGUIListener guiListener;
private int currentPage, maxPage;
private double currentZoom;
@@ -782,6 +786,10 @@ public class ViewerWindow extends javax.swing.JFrame {
JOptionPane.showMessageDialog(this, message, title, JOptionPane.WARNING_MESSAGE);
}
+ public int showConfirmDialog(String title, String message) {
+ return JOptionPane.showConfirmDialog(this, message, title, JOptionPane.YES_NO_CANCEL_OPTION);
+ }
+
/**
* Refresh each button's state.
*/