From 4258cf2ceb7e0c367831c6f8d0bd91262b944e54 Mon Sep 17 00:00:00 2001 From: Ethan Vrhel Date: Wed, 9 Sep 2020 15:30:58 -0700 Subject: Worked on PDFPostscriptDeviceFamily implementation Added all of the parameter types specified in https://ghostscript.com/doc/current/VectorDevices.htm for PDF/Postscript devices. Added several devices, updated documentation, and README.txt. --- demos/java/gsjava/README.txt | 72 +++++- .../src/com/artifex/gsjava/devices/Device.java | 18 +- .../com/artifex/gsjava/devices/DisplayDevice.java | 55 +++++ .../src/com/artifex/gsjava/devices/EPSDevice.java | 9 + .../src/com/artifex/gsjava/devices/PDFDevice.java | 87 ++++++- .../gsjava/devices/PDFPostscriptDeviceFamily.java | 265 ++++++++++++++++++++- .../artifex/gsjava/devices/PostScriptDevice.java | 59 +++++ 7 files changed, 556 insertions(+), 9 deletions(-) create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/devices/DisplayDevice.java create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/devices/EPSDevice.java create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/devices/PostScriptDevice.java diff --git a/demos/java/gsjava/README.txt b/demos/java/gsjava/README.txt index 70265efc4..5eb068cb9 100644 --- a/demos/java/gsjava/README.txt +++ b/demos/java/gsjava/README.txt @@ -1,6 +1,72 @@ -required libraries for this library: +Required libraries for this library: gpdldll64.dll gs_jni.dll -this project should be compiled as a JAR file and is -not runnable \ No newline at end of file +Java Library: + +This library contains direct bindings to Ghostscript as +well as several utility methods to make using the +Ghostscript calls easier. + +The direct Ghostscript calls are found in +com.artifex.gsjava.GSAPI and are named in the same way +in which they are documented on https://www.ghostscript.com/doc/current/API.htm + +The com.artifex.gsjava.callbacks package contains +interfaces which store interfaces and abstract classes +used to implement Ghostscript callbacks in Java. These +can be passed to Ghostscript through the GSAPI class. + +The com.artifex.gsjava.util package contains several +classes to assist in passing parameters and handling +native values. The Reference and ByteArrayReference are +the only classes which need to be used, however the others +are avaliable if needed. The Reference class acts as +a pointer parameter in a C function. An example use of this +is in gsapi_new_instance which takes a Reference as +a parameter. Calling the method would place the new +Ghoscript instance in the Reference's value field. + +The com.artifex.gsjava.GSInstance is a +utility class. The GSInstance class stores an instance +of Ghostscript and a client handle. The methods in this +class are named the same in which they are documented without +the need to pass the "instance" parameter through. + +The com.artifex.gsjava.devices package contains several +classes representing Ghoscript devices. Using the classes +in this package is the greatest amount of separation from +using the raw Ghoscript calls and it requires no direct +calls through the GSAPI class. All device classes in this +package are extensions of Device which provides a way +of setting up a Ghoscript device and setting parameters. +Subclasses have utility methods to set individual parameters +through method calls instead of using a String and parameter +type to specify the parameter name and type, respectively. + +Example code segment to set up an instance of Ghoscript: + +import com.artifex.gsjava.*; +import com.artifex.gsjava.util.*; + +public static void main(String[] args) { + // Stores a reference to the Ghoscript instance + Reference instanceReference = new Reference<>(); + + // Creates a new Ghoscript instance with a NULL caller handle, + // placing the instance into instanceReference + int code = GSAPI.gsapi_new_instance(instanceReference, GSAPI.GS_NULL); + + if (code != GSAPI.GS_ERROR_OK) { + // An error has occured. + return; + } + + // Returns the value the instanceReference references. + // This value is equivalent to a void * and has the same + // size in bytes. + long instance = instanceReference.getValue(); + + // Deletes the Ghoscript instance + GSAPI.gsapi_delete_instance(instance); +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/Device.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/Device.java index 448483dfc..74dc53329 100644 --- a/demos/java/gsjava/src/com/artifex/gsjava/devices/Device.java +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/Device.java @@ -36,7 +36,7 @@ public abstract class Device { /** * Creates a new device with the given device name. When this constructor is called, - * an instance of Ghostcript cannot exist or an exception will be thrown. The check of + * an instance of Ghostscript cannot exist or an exception will be thrown. The check of * whether an instance already exists does not include instances directly created * through GSAPI.gsapi_new_instance. * @@ -256,6 +256,22 @@ public abstract class Device { return instance; } + protected final String toArrayParameter(String[] array) { + StringBuilder builder = new StringBuilder(); + if (array.length > 0) { + builder.append(array[0]); + for (int i = 1; i < array.length; i++) { + builder.append(','); + builder.append(array[i]); + } + } + return builder.toString(); + } + + protected final String toArrayParameter(List list) { + return toArrayParameter(list.toArray(new String[list.size()])); + } + @Override public String toString() { return "Device[instance=" + instance + ",deviceName=" + deviceName + "]"; diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/DisplayDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/DisplayDevice.java new file mode 100644 index 000000000..959ed4d8c --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/DisplayDevice.java @@ -0,0 +1,55 @@ +package com.artifex.gsjava.devices; + +import static com.artifex.gsjava.GSAPI.*; + +import java.util.List; + +public class DisplayDevice extends Device { + + public static final String X11 = "x11"; + public static final String X11ALPHA = "x11alpha"; + public static final String X11CMYK = "x11cmyk"; + public static final String X11MONO = "x11mono"; + public static final String X11GRAY2 = "x11gray2"; + public static final String X11GRAY4 = "x11gray4"; + + public DisplayDevice() throws IllegalStateException, DeviceNotSupportedException, DeviceInUseException { + super("display"); + } + + public DisplayDevice(String device) throws IllegalStateException, DeviceNotSupportedException, DeviceInUseException { + super(device); + } + + public void setDisplayFormat(int format) { + setParam("DisplayFormat", format, GS_SPT_INT); + } + + public void setDisplayResolution(int dpi) { + setParam("DisplayResolution", dpi, GS_SPT_INT); + } + + public void setSeparationColorNames(String nameArray) { + setParam("SeparationColorNames", nameArray, GS_SPT_PARSED); + } + + public void setSeparationColorNames(String[] names) { + setSeparationColorNames(toArrayParameter(names)); + } + + public void setSeparationColorNames(List names) { + setSeparationColorNames(toArrayParameter(names)); + } + + public void setSeparationOrder(String orderArray) { + setParam("SeparationOrder", orderArray, GS_SPT_PARSED); + } + + public void setSeparationOrder(String[] order) { + setSeparationOrder(toArrayParameter(order)); + } + + public void setSeparationOrder(List order) { + setSeparationOrder(toArrayParameter(order)); + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/EPSDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/EPSDevice.java new file mode 100644 index 000000000..efa999a16 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/EPSDevice.java @@ -0,0 +1,9 @@ +package com.artifex.gsjava.devices; + +public class EPSDevice extends PostScriptDevice { + + public EPSDevice() throws IllegalStateException, DeviceNotSupportedException, DeviceInUseException { + super("eps2write"); + } + +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/PDFDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/PDFDevice.java index 4c8f875c0..2d084f715 100644 --- a/demos/java/gsjava/src/com/artifex/gsjava/devices/PDFDevice.java +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/PDFDevice.java @@ -1,9 +1,90 @@ package com.artifex.gsjava.devices; -public class PDFDevice { +import static com.artifex.gsjava.GSAPI.*; - public PDFDevice() { - // TODO Auto-generated constructor stub +public class PDFDevice extends PDFPostscriptDeviceFamily { + + public PDFDevice() throws IllegalStateException, DeviceNotSupportedException, DeviceInUseException { + super("pdfwrite"); + } + + public void setMaxInlineImageSize(int value) { + setParam("MaxInlineImageSize", value, GS_SPT_INT); + } + + public void setDoNumCopies(boolean state) { + setParam("DoNumCopies", state, GS_SPT_BOOL); + } + + public void setDetectDuplicateImages(boolean state) { + setParam("DetectDuplicateImages", state, GS_SPT_BOOL); + } + + public void setFastWebView(boolean state) { + setParam("FastWebView", state, GS_SPT_BOOL); + } + + public void setPreserveAnnots(boolean state) { + setParam("PreserveAnnots", state, GS_SPT_BOOL); + } + + public void setPatternImagemask(boolean state) { + setParam("PatternImagemask", state, GS_SPT_BOOL); + } + + public void setMaxClipPathSize(int value) { + setParam("MaxClipPathSize", value, GS_SPT_INT); + } + + public void setMaxShadingBitmapSize(int value) { + setParam("MaxShadingBitmapSize", value, GS_SPT_INT); + } + + public void setHaveTrueTypes(boolean state) { + setParam("HaveTrueTypes", state, GS_SPT_BOOL); + } + + public void setHaveTransparency(boolean state) { + setParam("HaveTransparency", state, GS_SPT_BOOL); + } + + public void setPDFX(boolean state) { + setParam("PDFX", state, GS_SPT_BOOL); + } + + public void setOwnerPassword(String value) { + setParam("OwnerPassword", value, GS_SPT_STRING); + } + + public void setUserPassword(String value) { + setParam("UserPassword", value, GS_SPT_STRING); + } + + public void setPermissions(int value) { + setParam("Permissions", value, GS_SPT_INT); + } + + public void setEncryptionR(int num) { + setParam("EncryptionR", num, GS_SPT_INT); + } + + public void setKeyLength(int length) { + setParam("KeyLength", length, GS_SPT_INT); + } + + public void setDocumentUUID(String value) { + setParam("DocumentUUID", value, GS_SPT_STRING); } + public void setInstanceUUID(String value) { + setParam("InstanceUUID", value, GS_SPT_STRING); + } + + public void setDocumentTimeSeq(int value) { + setParam("DocumentTimeSeq", value, GS_SPT_INT); + } + + public void setDSCEncoding(String encoding) { + setParam("DSCEncoding", encoding, GS_SPT_STRING); + } } diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/PDFPostscriptDeviceFamily.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/PDFPostscriptDeviceFamily.java index 1fb659340..6afc997c1 100644 --- a/demos/java/gsjava/src/com/artifex/gsjava/devices/PDFPostscriptDeviceFamily.java +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/PDFPostscriptDeviceFamily.java @@ -2,7 +2,16 @@ package com.artifex.gsjava.devices; import static com.artifex.gsjava.GSAPI.*; -public abstract class PDFPostscriptDeviceFamily extends FileDevice { +/** + * This class is the root device containing methods to set parameters defined + * in section 6.1 in the + * Vector Devices + * documentation. + * + * @author Ethan Vrhel + * + */ +public abstract class PDFPostscriptDeviceFamily extends FileDevice implements HighLevelDevice { public PDFPostscriptDeviceFamily(String device) throws IllegalStateException, DeviceNotSupportedException, DeviceInUseException { @@ -76,4 +85,256 @@ public abstract class PDFPostscriptDeviceFamily extends FileDevice { public void setColorACSImageDict(String dict) { setParam("ColorACSImageDict", dict, GS_SPT_PARSED); } -} + + public void setColorConversionStrategy(String strat) { + setParam("ColorConversionSrategy", strat, GS_SPT_STRING); + } + + public void setColorImageDepth(int value) { + setParam("ColorImageDepth", value, GS_SPT_INT); + } + + public void setColorImageDict(String dict) { + setParam("ColorImageDict", dict, GS_SPT_PARSED); + } + + public void setColorImageFilter(String filter) { + setParam("ColorImageFilter", filter, GS_SPT_STRING); + } + + public void setColorImageDownscaleThreshold(float value) { + setParam("ColorImageDownscaleThreshold", value, GS_SPT_FLOAT); + } + + public void setColorImageDownsampleType(String type) { + setParam("ColorImageDownsampleType", type, GS_SPT_STRING); + } + + public void setColorImageResolution(int value) { + setParam("ColorImageResolution", value, GS_SPT_INT); + } + + public void setCompatabilityLevel(String level) { + setParam("CompatabilityLevel", level, GS_SPT_PARSED); + } + + public void setCompressPages(boolean state) { + setParam("CompressPages", state, GS_SPT_BOOL); + } + + public void setConvertCMYKImagesToRGB(boolean state) { + setParam("ConvertCMYKImagesToRGB", state, GS_SPT_BOOL); + } + + public void setConvertColorImagesToIndexed(boolean state) { + setParam("ConvertColorImagesToIndexed", state, GS_SPT_BOOL); + } + + public void setCoreDictVersion(int version) { + setParam("CoreDictVersion", version, GS_SPT_INT); + } + + public void setCreateJobTicket(boolean state) { + setParam("CreateJobTicket", state, GS_SPT_BOOL); + } + + public void setDefaultRenderingIntent(String intent) { + setParam("DefaultRenderingIntent", intent, GS_SPT_STRING); + } + + public void setDetectBlends(boolean state) { + setParam("DetectBlends", state, GS_SPT_BOOL); + } + + public void setDoThumbnails(boolean state) { + setParam("DoThumbnails", state, GS_SPT_BOOL); + } + + public void setDownsampleColorImages(boolean state) { + setParam("DownsampleColorImages", state, GS_SPT_BOOL); + } + + public void setDownsampleGrayImages(boolean state) { + setParam("DownsampleGrayImages", state, GS_SPT_BOOL); + } + + public void setDownsampleMonoImages(boolean state) { + setParam("DownsampleMonoImages", state, GS_SPT_BOOL); + } + + public void setEmbedAllFonts(boolean state) { + setParam("EmbedAllFonts", state, GS_SPT_BOOL); + } + + public void setEmitDSCWarnings(boolean state) { + setParam("EmitDSCWarnings", state, GS_SPT_BOOL); + } + + public void setEncodeColorImages(boolean state) { + setParam("EncodeColorImages", state, GS_SPT_BOOL); + } + + public void setEncodeGrayImages(boolean state) { + setParam("EncodeGrayImages", state, GS_SPT_BOOL); + } + + public void setEncodeMonoImages(boolean state) { + setParam("EncodeMonoImages", state, GS_SPT_BOOL); + } + + public void setEndPage(int page) { + setParam("EndPage", page, GS_SPT_INT); + } + + public void setGrayACSImageDict(String dict) { + setParam("GrayACSImageDict", dict, GS_SPT_PARSED); + } + + public void setGrayImageDepth(int value) { + setParam("GrayImageDepth", value, GS_SPT_INT); + } + + public void setGrayImageDict(String dict) { + setParam("GrayImageDict", dict, GS_SPT_PARSED); + } + + public void setGrayImageDownsampleThreshold(float thresh) { + setParam("GrayImageDownsampleThreshold", thresh, GS_SPT_FLOAT); + } + + public void setGrayImageDownsampleType(String type) { + setParam("GrayImageDownsampleType", type, GS_SPT_STRING); + } + + public void setGrayImageFilter(String filter) { + setParam("GrayImageFilter", filter, GS_SPT_STRING); + } + + public void setGrayImageResolution(int resolution) { + setParam("GrayImageResolution", resolution, GS_SPT_INT); + } + + public void setImageMemory(long memory) { + setParam("ImageMemory", memory, GS_SPT_SIZE_T); + } + + public void setLockDistillerParams(boolean state) { + setParam("LockDistillerParams", state, GS_SPT_BOOL); + } + + public void setLZWEncodePages(boolean state) { + setParam("LZWEncodePages", state, GS_SPT_BOOL); + } + + public void setMaxSubsetPct(int value) { + setParam("MaxSubsetPct", value, GS_SPT_INT); + } + + public void setMonoImageDepth(int depth) { + setParam("MonoImageDepth", depth, GS_SPT_INT); + } + + public void setMonoImageDict(String dict) { + setParam("MonoImageDict", dict, GS_SPT_PARSED); + } + + public void setMonoImageDownsampleThreshold(float thresh) { + setParam("MonoImageDownsampleThreshold", thresh, GS_SPT_FLOAT); + } + + public void setMonoImageDownsampleType(String type) { + setParam("MonoImageDownsampleType", type, GS_SPT_STRING); + } + + public void setMonoImageFilter(String filter) { + setParam("MonoImageFilter", filter, GS_SPT_STRING); + } + + public void setMonoImageResolution(int resolution) { + setParam("MonoImageResolution", resolution, GS_SPT_INT); + } + + public void setNeverEmbed(String value) { + setParam("NeverEmbed", value, GS_SPT_PARSED); + } + + public void setOffOptimizations(int value) { + setParam("OffOptimizations", value, GS_SPT_INT); + } + + public void setOPM(int value) { + setParam("OPM", value, GS_SPT_INT); + } + + public void setOptimize(boolean state) { + setParam("Optimize", state, GS_SPT_BOOL); + } + + public void setParseDSCComments(boolean state) { + setParam("ParseDSCComments", state, GS_SPT_BOOL); + } + + public void setParseDSCCommentsForDocInfo(boolean state) { + setParam("ParseDSCCommentsForDocInfo", state, GS_SPT_BOOL); + } + + public void setPreserveCopyPage(boolean state) { + setParam("PreserveCopyPage", state, GS_SPT_BOOL); + } + + public void setPreserveEPSInfo(boolean state) { + setParam("PreserveEPSInfo", state, GS_SPT_BOOL); + } + + public void setPreserveHalftoneInfo(boolean state) { + setParam("PreserveHalftoneInfo", state, GS_SPT_BOOL); + } + + public void setPreserveOPIComments(boolean state) { + setParam("PreserveOPIComments", state, GS_SPT_BOOL); + } + + public void setPreserveOverprintSettings(boolean state) { + setParam("PreserveOverprintSettings", state, GS_SPT_BOOL); + } + + public void setsRGBProfile(String profile) { + setParam("sRGBProfile", profile, GS_SPT_PARSED); + } + + public void setStartPage(int page) { + setParam("StartPage", page, GS_SPT_INT); + } + + public void setSubsetFonts(boolean state) { + setParam("SubsetFonts", state, GS_SPT_BOOL); + } + + public void setTransferFunctionInfo(String info) { + setParam("TransferFunctionInfo", info, GS_SPT_STRING); + } + + public void setUCRandBGInfo(String info) { + setParam("UCRandBGInfo", info, GS_SPT_STRING); + } + + public void setUseFlateCompression(boolean state) { + setParam("UseFlateCompression", state, GS_SPT_BOOL); + } + + public void setUsePrologue(boolean state) { + setParam("UsePrologue", state, GS_SPT_BOOL); + } + + public void setPassThroughJPEGImages(boolean state) { + setParam("PassThroughJPEGImages", state, GS_SPT_BOOL); + } + + // Specific to PostScript and PDF input + + public void setPDFSETTINGS(String config) { + setParam("PDFSETTINGS", config, GS_SPT_STRING); + } + + // Specific to PCL and PXL input +} \ No newline at end of file diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/PostScriptDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/PostScriptDevice.java new file mode 100644 index 000000000..3926ebf9b --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/PostScriptDevice.java @@ -0,0 +1,59 @@ +package com.artifex.gsjava.devices; + +import static com.artifex.gsjava.GSAPI.*; + +public class PostScriptDevice extends PDFPostscriptDeviceFamily { + + public PostScriptDevice() throws IllegalStateException, DeviceNotSupportedException, DeviceInUseException { + super("ps2write"); + } + + /** + * Intended to be an internal way to override the normal + * ps2write device. + * + * @param override The device override name. + * @throws IllegalStateException {@link Device#Device(String)} + * @throws DeviceNotSupportedException {@link Device#Device(String)} + * @throws DeviceInUseException {@link Device#Device(String)} + */ + protected PostScriptDevice(String override) throws IllegalStateException, DeviceNotSupportedException, DeviceInUseException { + super(override); + } + +// public void setPSDocOptions(String options) { +// setParam("PSDocOptions", options, GS_SPT_STRING); +// } +// +// public void setPSPageOptions(String[] options) { +// +// } +// +// public void setPSPageOptions(List options) { +// setPSPageOptions(options.toArray(new String[options.size()])); +// } + + public void setProduceDSC(boolean state) { + setParam("ProduceDSC", state, GS_SPT_BOOL); + } + + public void setCompressEntireFile(boolean state) { + setParam("CompressEntireFile", state, GS_SPT_BOOL); + } + + public void setRotatePages(boolean state) { + setParam("RotatePages", state, GS_SPT_BOOL); + } + + public void setCenterPages(boolean state) { + setParam("CenterPages", state, GS_SPT_BOOL); + } + + public void setSetPageSize(boolean state) { + setParam("SetPageSize", state, GS_SPT_BOOL); + } + + public void setDoNumCopies(boolean state) { + setParam("DoNumCopies", state, GS_SPT_BOOL); + } +} -- cgit v1.2.1