diff options
author | Robin Watts <robin.watts@artifex.com> | 2015-12-09 17:57:20 +0000 |
---|---|---|
committer | Tor Andersson <tor.andersson@artifex.com> | 2016-02-29 16:03:34 +0100 |
commit | a6e15a6c904f700543429d94c703a4d1911e1ac2 (patch) | |
tree | c071a9eafc5834a04aad312e961b6099d0919b77 /platform/android/src/com | |
parent | 7621953bf3f8534ce53ae5611f6cbd2ef4cc869a (diff) | |
download | mupdf-a6e15a6c904f700543429d94c703a4d1911e1ac2.tar.xz |
jni: First attempt at generic JNI bindings.
The purpose of JNI bindings is to allow MuPDF to be driven from
Java. There are several possible use cases here.
Firstly, and most simply a java application can ask the core of MuPDF
to open a document and render it using the existing devices to
produce output on a standard Java bitmap.
Secondly, a java application might want to drive the device interface
itself, making use of the standard MuPDF devices (such as using the
rendering engine to render high quality graphics).
Thirdly, a java application might want to implement its own device
and then call MuPDF to run the document to that device (perhaps to do
custom text or image extraction).
The first of these cases requires a simple reflection of the main
document and standard device classes in JNI.
The second of these cases requires the actual device interface itself
to be made available as a java interface, together with the ability
to construct and manipulate data types like paths, text and fonts so
the Java code can build the required objects to pass to implementers
of the device interface.
The final case requires a reflection layer whereby calls through the
device interface in C can be turned into method calls to a Java
interface.
All of this is attempted in this commit. Some highlights:
For each type in the C (such as fz_colorspace) we have a corresponding
java class (such as ColorSpace).
Where the 'fz_' types are reference counted (such as an fz_colorspace),
the java objects (such as ColorSpace) simply take a reference to a
pointer to the underlying fz type. Java accessor methods are then
provided to manipulate these types.
Where the 'fz_' types are not reference counted (such as an fz_rect),
the data is actually contained within the Java object itself (such as
Rect, RectI and Transform).
We add a VS jni project. This doesn't do anything except make the
files accessible for editing in the IDE.
As much as possible, the Java layers do nothing (other than some
programmer friendly type overloading), construction (unavoidable,
as can't be done in JNI) and boiler-plate destruction. All the
smartness is done in the C.
Due to Java and C's differing approach to constness, we need to be
careful that a java device does not destructively alter objects
passed to it. For example, consider running a display list through
a device implemented in java. If the java device were to change a
Font object passed to it, this might affect other objects in the
display list that shared the same underlying fz_font.
Possibly we can achieve this by having an 'isConst' flag on java
objects that are created from device calls and passed to the Java
device (see the Text class, for an attempt at this currently).
This could alternatively be achieved by cloning every such
piece of data (see the path code for an example of this approach),
but this is probably slow. Better to clone 'just in time' as the
first write operation is done to the object.
Diffstat (limited to 'platform/android/src/com')
27 files changed, 1119 insertions, 0 deletions
diff --git a/platform/android/src/com/artifex/mupdf/fitz/AndroidDrawDevice.java b/platform/android/src/com/artifex/mupdf/fitz/AndroidDrawDevice.java new file mode 100644 index 00000000..1537f62a --- /dev/null +++ b/platform/android/src/com/artifex/mupdf/fitz/AndroidDrawDevice.java @@ -0,0 +1,19 @@ +package com.artifex.mupdf.fitz; + +import android.graphics.Bitmap; + +public final class AndroidDrawDevice extends CDevice +{ + // Construction + public AndroidDrawDevice(Bitmap bitmap, int pageX0, int pageY0, int pageX1, int pageY1, int patchX0, int patchY0, int patchX1, int patchY1) + { + nativeDevice = newNative(bitmap, pageX0, pageY0, pageX1, pageY1, patchX0, patchY0, patchX1, patchY1); + } + + public AndroidDrawDevice(Bitmap bitmap, RectI page, RectI patch) + { + nativeDevice = newNative(bitmap, page.x0, page.y0, page.x1, page.y1, patch.x0, patch.y0, patch.x1, patch.y1); + } + + private native long newNative(Bitmap bitmap, int pageX0, int pageY0, int pageX1, int pageY1, int patchX0, int patchY0, int patchX1, int patchY1); +} diff --git a/platform/android/src/com/artifex/mupdf/fitz/Annotation.java b/platform/android/src/com/artifex/mupdf/fitz/Annotation.java new file mode 100644 index 00000000..6e6dd1c1 --- /dev/null +++ b/platform/android/src/com/artifex/mupdf/fitz/Annotation.java @@ -0,0 +1,27 @@ +package com.artifex.mupdf.fitz; + +public class Annotation +{ + // Private data + private long nativeAnnot = 0; + + // Construction + private Annotation(long ptr) + { + nativeAnnot = ptr; + } + + // Operation + public native void run(Device dev, Matrix ctm, Cookie cookie); + + // FIXME: Write accessors + + // Destruction + public void destroy() + { + finalize(); + nativeAnnot = 0; + } + + protected native void finalize(); +} diff --git a/platform/android/src/com/artifex/mupdf/fitz/AwtDrawDevice.java b/platform/android/src/com/artifex/mupdf/fitz/AwtDrawDevice.java new file mode 100644 index 00000000..4e6fb33d --- /dev/null +++ b/platform/android/src/com/artifex/mupdf/fitz/AwtDrawDevice.java @@ -0,0 +1,12 @@ +package com.artifex.mupdf.fitz; + +public final class AwtDrawDevice extends CDevice +{ + // Construction + public AwtDrawDevice(int rgba[], int width, int height) + { + nativeDevice = newNative(rgba, width, height); + } + + private native long newNative(int rgba[], int width, int height); +} diff --git a/platform/android/src/com/artifex/mupdf/fitz/CDevice.java b/platform/android/src/com/artifex/mupdf/fitz/CDevice.java new file mode 100644 index 00000000..3bfe9c70 --- /dev/null +++ b/platform/android/src/com/artifex/mupdf/fitz/CDevice.java @@ -0,0 +1,49 @@ +package com.artifex.mupdf.fitz; + +public abstract class CDevice extends Device +{ + // Private data + private Object nativeResource = null; + protected long nativeInfo = 0; + + // Operation + public native final void beginPage(Rect rect, Matrix ctm); + public native final void endPage(); + + public native final void fillPath(Path path, int even_odd, Matrix ctm, ColorSpace cs, float color[], float alpha); + public native final void strokePath(Path path, StrokeState stroke, Matrix ctm, ColorSpace cs, float color[], float alpha); + public native final void clipPath(Path path, Rect rect, int even_odd, Matrix ctm); + public native final void clipStrokePath(Path path, Rect rect, StrokeState stroke, Matrix ctm); + + public native final void fillText(Text text, Matrix ctm, ColorSpace cs, float color[], float alpha); + public native final void strokeText(Text text, StrokeState stroke, Matrix ctm, ColorSpace cs, float color[], float alpha); + public native final void clipText(Text text, Matrix ctm, int accumulate); + public native final void clipStrokeText(Text text, StrokeState stroke, Matrix ctm); + public native final void ignoreText(Text text, Matrix ctm); + + public native final void fillShade(Shade shade, Matrix ctm, float alpha); + public native final void fillImage(Image img, Matrix ctm, float alpha); + public native final void fillImageMask(Image img, Matrix ctm, ColorSpace cs, float color[], float alpha); + public native final void clipImageMask(Image img, Rect rect, Matrix ctm); + + public native final void popClip(); + + public native final void beginMask(Rect rect, int luminosity, ColorSpace cs, float bc[]); + public native final void endMask(); + public native final void beginGroup(Rect rect, int isolated, int knockout, int blendmode, float alpha); + public native final void endGroup(); + + public native final int beginTile(Rect area, Rect view, float xstep, float ystep, Matrix ctm, int id); + public native final void endTile(); + + // Destruction + public final void destroy() + { + finalize(); + nativeDevice = 0; + nativeResource = null; + nativeInfo = 0; + } + + protected native final void finalize(); +} diff --git a/platform/android/src/com/artifex/mupdf/fitz/ColorSpace.java b/platform/android/src/com/artifex/mupdf/fitz/ColorSpace.java new file mode 100644 index 00000000..cad952c0 --- /dev/null +++ b/platform/android/src/com/artifex/mupdf/fitz/ColorSpace.java @@ -0,0 +1,34 @@ +package com.artifex.mupdf.fitz; + +public class ColorSpace +{ + // Private data + private long nativeColorSpace; + + // Statics + public static ColorSpace DeviceGray = new ColorSpace(newDeviceGray()); + public static ColorSpace DeviceRGB = new ColorSpace(newDeviceRGB()); + public static ColorSpace DeviceCMYK = new ColorSpace(newDeviceCMYK()); + + private static native long newDeviceGray(); + private static native long newDeviceRGB(); + private static native long newDeviceCMYK(); + + // Construction + private ColorSpace(long l) + { + nativeColorSpace = l; + } + + // Accessors + public native int getNumComponents(); + + // Destruction + public final void destroy() + { + finalize(); + nativeColorSpace = 0; + } + + protected final native void finalize(); +} diff --git a/platform/android/src/com/artifex/mupdf/fitz/Context.java b/platform/android/src/com/artifex/mupdf/fitz/Context.java new file mode 100644 index 00000000..1baafb01 --- /dev/null +++ b/platform/android/src/com/artifex/mupdf/fitz/Context.java @@ -0,0 +1,20 @@ +package com.artifex.mupdf.fitz; + +// This class handles the loading of the MuPDF shared library, together +// with the ThreadLocal magic to get the required context. +// +// The only publicly accessible method here is Context.setStoreSize, which +// sets the store size to use. This must be called before any other MuPDF +// function. +public class Context +{ + // Load our native library + static + { + System.loadLibrary("mupdf"); + } + + // FIXME: We should support the store size being changed dynamically. + // This requires changes within the MuPDF core. + //public native static void setStoreSize(long newSize); +} diff --git a/platform/android/src/com/artifex/mupdf/fitz/Cookie.java b/platform/android/src/com/artifex/mupdf/fitz/Cookie.java new file mode 100644 index 00000000..a072e018 --- /dev/null +++ b/platform/android/src/com/artifex/mupdf/fitz/Cookie.java @@ -0,0 +1,30 @@ +package com.artifex.mupdf.fitz; + +public class Cookie +{ + // Private data + private long nativeCookie = 0; + + // Construction + public Cookie() + { + nativeCookie = newNative(); + } + + private native long newNative(); + + // Operation + public native void abort(); + + //FIXME: Cookie accessors + + // Destruction + protected native void finalize(); + + public void destroy() + { + finalize(); + nativeCookie = 0; + } + +} diff --git a/platform/android/src/com/artifex/mupdf/fitz/Device.java b/platform/android/src/com/artifex/mupdf/fitz/Device.java new file mode 100644 index 00000000..366022e9 --- /dev/null +++ b/platform/android/src/com/artifex/mupdf/fitz/Device.java @@ -0,0 +1,172 @@ +package com.artifex.mupdf.fitz; + +public abstract class Device +{ + /* Flags */ + public static final int FZ_DEVFLAG_MASK = 1; + public static final int FZ_DEVFLAG_COLOR = 2; + public static final int FZ_DEVFLAG_UNCACHEABLE = 4; + public static final int FZ_DEVFLAG_FILLCOLOR_UNDEFINED = 8; + public static final int FZ_DEVFLAG_STROKECOLOR_UNDEFINED = 16; + public static final int FZ_DEVFLAG_STARTCAP_UNDEFINED = 32; + public static final int FZ_DEVFLAG_DASHCAP_UNDEFINED = 64; + public static final int FZ_DEVFLAG_ENDCAP_UNDEFINED = 128; + public static final int FZ_DEVFLAG_LINEJOIN_UNDEFINED = 256; + public static final int FZ_DEVFLAG_MITERLIMIT_UNDEFINED = 512; + public static final int FZ_DEVFLAG_LINEWIDTH_UNDEFINED = 1024; + + /* PDF 1.4 -- standard separable */ + public static final int FZ_BLEND_NORMAL = 0; + public static final int FZ_BLEND_MULTIPLY = 1; + public static final int FZ_BLEND_SCREEN = 2; + public static final int FZ_BLEND_OVERLAY = 3; + public static final int FZ_BLEND_DARKEN = 4; + public static final int FZ_BLEND_LIGHTEN = 5; + public static final int FZ_BLEND_COLOR_DODGE = 6; + public static final int FZ_BLEND_COLOR_BURN = 7; + public static final int FZ_BLEND_HARD_LIGHT = 8; + public static final int FZ_BLEND_SOFT_LIGHT = 9; + public static final int FZ_BLEND_DIFFERENCE = 10; + public static final int FZ_BLEND_EXCLUSION = 11; + + /* PDF 1.4 -- standard non-separable */ + public static final int FZ_BLEND_HUE = 12; + public static final int FZ_BLEND_SATURATION = 13; + public static final int FZ_BLEND_COLOR = 14; + public static final int FZ_BLEND_LUMINOSITY = 15; + + /* For packing purposes */ + public static final int FZ_BLEND_MODEMASK = 15; + public static final int FZ_BLEND_ISOLATED = 16; + public static final int FZ_BLEND_KNOCKOUT = 32; + + /* To implement your own device in Java, you should define your own + * class that extends this one, and override as many of the following + * functions as is appropriate. For example: + * + * class ImageTraceDevice extends Device + * { + * void fillImage(Image img, Matrix ctx, float alpha) { + * Debug.Log("Image!"); + * } + * }; + * + * There is no constructor here, as no one will ever construct a + * Device without subclassing. + */ + + /* Everything under here is private implementation details. + * Ideally we'd like to hide these from prying eyes, but Java doesn't + * allow that. + */ + + public static final int FZ_IGNORE_IMAGE = 1; + public static final int FZ_IGNORE_SHADE = 2; + + /* None of our device functions do anything. Anyone interested will + * override them in a subclass either in Java, or (as a subclass of + * CDevice) in C. + */ + public void beginPage(Rect rect, Matrix ctm) + { + } + + public void endPage() + { + } + + public void fillPath(Path path, int even_odd, Matrix ctm, ColorSpace cs, float color[], float alpha) + { + } + + public void strokePath(long ctx, Path path, StrokeState stroke, Matrix ctm, ColorSpace cs, float color[], float alpha) + { + } + + public void clipPath(Path path, Rect rect, int even_odd, Matrix ctm) + { + } + + public void clipStrokePath(Path path, Rect rect, StrokeState stroke, Matrix ctm) + { + } + + public void fillText(Text text, Matrix ctm, ColorSpace cs, float color[], float alpha) + { + } + + public void strokeText(Text text, StrokeState stroke, Matrix ctm, ColorSpace cs, float color[], float alpha) + { + } + + public void clipText(Text text, Matrix ctm) + { + } + + public void clipStrokeText(Text text, StrokeState stroke, Matrix ctm) + { + } + + public void ignoreText(Text text, Matrix ctm) + { + } + + public void fillShade(Shade shade, Matrix ctm, float alpha) + { + } + + public void fillImage(Image img, Matrix ctm, float alpha) + { + } + + public void fillImageMask(Image img, Matrix ctm, ColorSpace cs, float color[], float alpha) + { + } + + public void clipImageMask(Image img, Rect rect, Matrix ctm) + { + } + + public void popClip() + { + } + + public void beginMask(Rect rect, int luminosity, ColorSpace cs, float bc[]) + { + } + + public void endMask() + { + } + + public void beginGroup(Rect rect, int isolated, int knockout, int blendmode, float alpha) + { + } + + public void endGroup() + { + } + + public int beginTile(Rect area, Rect view, float xstep, float ystep, Matrix ctm, int id) + { + return 0; + } + + public void endTile() + { + } + + /* An accessor for device hints */ + final native int getHints(); + final native void enableDeviceHints(int hints); + final native void disableDeviceHints(int hints); + + // Destruction + public void destroy() + { + } + + // Private data. + // All java devices MUST leave this as 0. + protected long nativeDevice; +} diff --git a/platform/android/src/com/artifex/mupdf/fitz/DisplayList.java b/platform/android/src/com/artifex/mupdf/fitz/DisplayList.java new file mode 100644 index 00000000..8a2515e4 --- /dev/null +++ b/platform/android/src/com/artifex/mupdf/fitz/DisplayList.java @@ -0,0 +1,32 @@ +package com.artifex.mupdf.fitz; + +public class DisplayList +{ + // Private data + protected long nativeDisplayList; + + // Constructions + public DisplayList() + { + nativeDisplayList = newNative(); + } + + private native long newNative(); + + // Operation + public native void run(Device device, Matrix ctm, Rect scissor, Cookie cookie); + + public void run(Device device, Matrix ctm, Cookie cookie) + { + run(device, ctm, null, cookie); + } + + // Destruction + public void destroy() + { + finalize(); + nativeDisplayList = 0; + } + + protected native void finalize(); +} diff --git a/platform/android/src/com/artifex/mupdf/fitz/DisplayListDevice.java b/platform/android/src/com/artifex/mupdf/fitz/DisplayListDevice.java new file mode 100644 index 00000000..de3142dc --- /dev/null +++ b/platform/android/src/com/artifex/mupdf/fitz/DisplayListDevice.java @@ -0,0 +1,14 @@ +package com.artifex.mupdf.fitz; + +import android.graphics.Bitmap; + +public final class DisplayListDevice extends CDevice +{ + // Construction + public DisplayListDevice(DisplayList list) + { + nativeDevice = newNative(list); + } + + private native long newNative(DisplayList list); +} diff --git a/platform/android/src/com/artifex/mupdf/fitz/Document.java b/platform/android/src/com/artifex/mupdf/fitz/Document.java new file mode 100644 index 00000000..8c3136df --- /dev/null +++ b/platform/android/src/com/artifex/mupdf/fitz/Document.java @@ -0,0 +1,60 @@ +package com.artifex.mupdf.fitz; + +import java.lang.ref.WeakReference; + +public class Document +{ + // Private data + private long nativeDocument = 0; + + // Construction + public Document(String filename) throws Exception + { + nativeDocument = newNative(filename); + if (nativeDocument == 0) + throw(new Exception("Failed to load Document")); + } + private native final long newNative(String filename); + + // FIXME: Should support opening java streams and from byte buffers etc. + // Streams would need to be seekable. + public Document(byte buffer[], String magic) throws Exception + { + nativeDocument = 0;//newFromBufferNative(buffer, magic); + if (nativeDocument == 0) + throw(new Exception("Failed to load Document")); + } + //private native final long newFromBufferNative(byte buffer[], String magic); + + //public Document(SeekableStream stream, String magic) throws Exception + //{ + // nativeDocument = newFromStreamNative(stream, magic); + // if (nativeDocument == 0) + // throw(new Exception("Failed to load Document")); + //} + //private native final long newFromBufferNative(SeekableStream stream, String magic); + + // Operation + public native boolean needsPassword(); + + public native boolean authenticatePassword(String password); + + public native int countPages(); + + public native Page getPage(int n); + + public native String getFileFormat(); + + public native boolean isUnencryptedPDF(); + + public native Outline getOutline(); + + // Destruction + public void destroy() + { + finalize(); + nativeDocument = 0; + } + + protected native void finalize(); +} diff --git a/platform/android/src/com/artifex/mupdf/fitz/Font.java b/platform/android/src/com/artifex/mupdf/fitz/Font.java new file mode 100644 index 00000000..7630dfa5 --- /dev/null +++ b/platform/android/src/com/artifex/mupdf/fitz/Font.java @@ -0,0 +1,22 @@ +package com.artifex.mupdf.fitz; + +public class Font +{ + // Private data + private long nativeFont; + + // Construction + private Font(long font) + { + nativeFont = font; + } + + // Destruction + public void destroy() + { + finalize(); + nativeFont = 0; + } + + protected native void finalize(); +} diff --git a/platform/android/src/com/artifex/mupdf/fitz/Image.java b/platform/android/src/com/artifex/mupdf/fitz/Image.java new file mode 100644 index 00000000..a736ce5f --- /dev/null +++ b/platform/android/src/com/artifex/mupdf/fitz/Image.java @@ -0,0 +1,56 @@ +package com.artifex.mupdf.fitz; +import android.graphics.Bitmap; + +public class Image +{ + // Private data + private long nativeImage = 0; + + // Construction + Image(Bitmap bm) throws Exception + { + if (bm == null) + throw new Exception("null Bitmap passed to Image"); + nativeImage = newFromBitmapNative(bm, null); + } + + Image(Bitmap bm, Image mask) throws Exception + { + if (bm == null) + throw new Exception("null Bitmap passed to Image"); + nativeImage = newFromBitmapNative(bm, mask); + } + + private native final long newFromBitmapNative(Bitmap bm, Image mask); + + // Private constructor for the C to use. Any objects created by the + // C are done for purposes of calling back to a java device, and + // should therefore be considered const. + private Image(long l) + { + nativeImage = l; + } + + // Accessors + public native int getWidth(); + public native int getHeight(); + public native int getNumComponents(); + public native int getBitsPerComponent(); + public native int getXResolution(); + public native int getYResolution(); + public native boolean getImageMask(); + public native boolean getInterpolate(); + public native Image getMask(); + + // FIXME: Get data back? + // FIXME: Create images from data or java streams? + + // Destruction + public void destroy() + { + finalize(); + nativeImage = 0; + } + + protected native void finalize(); +} diff --git a/platform/android/src/com/artifex/mupdf/fitz/Link.java b/platform/android/src/com/artifex/mupdf/fitz/Link.java new file mode 100644 index 00000000..7c63fcf9 --- /dev/null +++ b/platform/android/src/com/artifex/mupdf/fitz/Link.java @@ -0,0 +1,27 @@ +package com.artifex.mupdf.fitz; + +public class Link +{ + // Private data + private long nativeLink = 0; + + // Construction + private Link(long l) + { + nativeLink = l; + } + + // Operation + public native Link getNext(); + + //FIXME: Accessors + + // Destruction + public void destroy() + { + finalize(); + nativeLink = 0; + } + + protected native void finalize(); +} diff --git a/platform/android/src/com/artifex/mupdf/fitz/Matrix.java b/platform/android/src/com/artifex/mupdf/fitz/Matrix.java new file mode 100644 index 00000000..ede57ccc --- /dev/null +++ b/platform/android/src/com/artifex/mupdf/fitz/Matrix.java @@ -0,0 +1,59 @@ +package com.artifex.mupdf.fitz; + +public class Matrix +{ + public float a; + public float b; + public float c; + public float d; + public float e; + public float f; + + public Matrix(float a, float b, float c, float d, float e, float f) + { + this.a = a; + this.b = b; + this.c = c; + this.d = d; + this.e = e; + this.f = f; + } + + public Matrix(float a, float d) + { + this.a = a; + this.b = 0; + this.c = 0; + this.d = d; + this.e = 0; + this.f = 0; + } + + public Matrix(float a) + { + this.a = a; + this.b = 0; + this.c = 0; + this.d = a; + this.e = 0; + this.f = 0; + } + + public Matrix concat(Matrix m) + { + float a = this.a * m.a + this.b * m.c; + float b = this.a * m.b + this.b * m.d; + float c = this.c * m.a + this.d * m.c; + float d = this.c * m.b + this.d * m.d; + float e = this.e * m.a + this.f * m.c + m.e; + this.f = this.e * m.b + this.f * m.d + m.f; + + this.a = a; + this.b = b; + this.c = c; + this.d = d; + this.e = e; + + return this; + } +} diff --git a/platform/android/src/com/artifex/mupdf/fitz/Outline.java b/platform/android/src/com/artifex/mupdf/fitz/Outline.java new file mode 100644 index 00000000..1b808d7f --- /dev/null +++ b/platform/android/src/com/artifex/mupdf/fitz/Outline.java @@ -0,0 +1,22 @@ +package com.artifex.mupdf.fitz; + +public class Outline +{ + // Private data + private long nativeOutline = 0; + + // Construction + private Outline(long out) + { + nativeOutline = out; + } + + // Destruction + public void destroy() + { + finalize(); + nativeOutline = 0; + } + + protected native void finalize(); +} diff --git a/platform/android/src/com/artifex/mupdf/fitz/Page.java b/platform/android/src/com/artifex/mupdf/fitz/Page.java new file mode 100644 index 00000000..46d598ee --- /dev/null +++ b/platform/android/src/com/artifex/mupdf/fitz/Page.java @@ -0,0 +1,37 @@ +package com.artifex.mupdf.fitz; + +public class Page +{ + // Private data + private long nativePage = 0; + private Annotation nativeAnnots[]; + + // Construction + private Page(long page) + { + nativePage = page; + nativeAnnots = null; + } + + // Operation + public native Rect bound(); + public native void run(Device dev, Matrix ctm, Cookie cookie); + public native void runPageContents(Device dev, Matrix ctm, Cookie cookie); + public native Annotation[] getAnnotations(); + + // FIXME: Later + public native Link[] getLinks(); + + // FIXME: Later. Much later. + //fz_transition *fz_page_presentation(fz_document *doc, fz_page *page, float *duration); + + // Destruction + public void destroy() + { + finalize(); + nativePage = 0; + nativeAnnots = null; + } + + protected native void finalize(); +} diff --git a/platform/android/src/com/artifex/mupdf/fitz/Path.java b/platform/android/src/com/artifex/mupdf/fitz/Path.java new file mode 100644 index 00000000..17257f10 --- /dev/null +++ b/platform/android/src/com/artifex/mupdf/fitz/Path.java @@ -0,0 +1,82 @@ +package com.artifex.mupdf.fitz; + +public class Path implements PathProcessor +{ + // Private data + private long nativePath = 0; + + // Construction + public Path() + { + nativePath = newNative(); + } + + private native long newNative(); + + private Path(long path) + { + nativePath = path; + } + + public Path(Path old) + { + nativePath = clone(old); + } + + private native long clone(Path old); + + // Operation + public native Point currentPoint(); + + public void moveTo(Point xy) + { + moveTo(xy.x, xy.y); + } + + public native void moveTo(float x, float y); + + public void lineTo(Point xy) + { + lineTo(xy.x, xy.y); + } + + public native void lineTo(float x, float y); + + public void curveTo(Point c1, Point c2, Point e) + { + curveTo(c1.x, c1.y, c2.x, c2.y, e.x, e.y); + } + + public native void curveTo(float cx1, float cy1, float cx2, float cy2, float ex, float ey); + + public void curveToV(Point c, Point e) + { + curveToV(c.x, c.y, e.x, e.y); + } + + public native void curveToV(float cx, float cy, float ex, float ey); + + public void curveToY(Point c, Point e) + { + curveToY(c.x, c.y, e.x, e.y); + } + + public native void curveToY(float cx, float cy, float ex, float ey); + + public native void close(); + + public native void transform(Matrix mat); + + public native Rect bound(StrokeState stroke, Matrix ctm); + + public native void process(PathProcessor proc); + + // Destruction + public void destroy() + { + finalize(); + nativePath = 0; + } + + protected native void finalize(); +} diff --git a/platform/android/src/com/artifex/mupdf/fitz/PathProcessor.java b/platform/android/src/com/artifex/mupdf/fitz/PathProcessor.java new file mode 100644 index 00000000..71d03c50 --- /dev/null +++ b/platform/android/src/com/artifex/mupdf/fitz/PathProcessor.java @@ -0,0 +1,9 @@ +package com.artifex.mupdf.fitz; + +public interface PathProcessor +{ + public void moveTo(float x, float y); + public void lineTo(float x, float y); + public void curveTo(float cx1, float cy1, float cx2, float cy2, float ex, float ey); + public void close(); +} diff --git a/platform/android/src/com/artifex/mupdf/fitz/Point.java b/platform/android/src/com/artifex/mupdf/fitz/Point.java new file mode 100644 index 00000000..08989dd7 --- /dev/null +++ b/platform/android/src/com/artifex/mupdf/fitz/Point.java @@ -0,0 +1,29 @@ +package com.artifex.mupdf.fitz; + +public class Point +{ + public float x; + public float y; + + public Point(float x, float y) + { + this.x = x; + this.y = y; + } + + public Point(Point p) + { + this.x = p.x; + this.y = p.y; + } + + public Point transform(Matrix tm) + { + float old_x = this.x; + + this.x = old_x * tm.a + y * tm.c + tm.e; + this.y = old_x * tm.b + y * tm.d + tm.f; + + return this; + } +} diff --git a/platform/android/src/com/artifex/mupdf/fitz/Rect.java b/platform/android/src/com/artifex/mupdf/fitz/Rect.java new file mode 100644 index 00000000..eb9138cf --- /dev/null +++ b/platform/android/src/com/artifex/mupdf/fitz/Rect.java @@ -0,0 +1,79 @@ +package com.artifex.mupdf.fitz; + +public class Rect +{ + public float x0; + public float y0; + public float x1; + public float y1; + + public Rect(float x0, float y0, float x1, float y1) + { + this.x0 = x0; + this.y0 = y0; + this.x1 = x1; + this.y1 = y1; + } + + public Rect(Rect r) + { + this.x0 = r.x0; + this.y0 = r.y0; + this.x1 = r.x1; + this.y1 = r.y1; + } + + public Rect transform(Matrix tm) + { + float ax0 = x0 * tm.a; + float ax1 = x1 * tm.a; + + if (ax0 > ax1) + { + float t = ax0; + ax0 = ax1; + ax1 = t; + } + + float cy0 = y0 * tm.c; + float cy1 = y1 * tm.c; + + if (cy0 > cy1) + { + float t = cy0; + cy0 = cy1; + cy1 = t; + } + ax0 += cy0 + tm.e; + ax1 += cy1 + tm.e; + + float bx0 = x0 * tm.b; + float bx1 = x1 * tm.b; + + if (bx0 > bx1) + { + float t = bx0; + bx0 = bx1; + bx1 = t; + } + + float dy0 = y0 * tm.d; + float dy1 = y1 * tm.d; + + if (dy0 > dy1) + { + float t = dy0; + dy0 = dy1; + dy1 = t; + } + bx0 += dy0 + tm.f; + bx1 += dy1 + tm.f; + + x0 = ax0; + x1 = ax1; + y0 = bx0; + y1 = bx1; + + return this; + } +} diff --git a/platform/android/src/com/artifex/mupdf/fitz/RectI.java b/platform/android/src/com/artifex/mupdf/fitz/RectI.java new file mode 100644 index 00000000..1f91c778 --- /dev/null +++ b/platform/android/src/com/artifex/mupdf/fitz/RectI.java @@ -0,0 +1,79 @@ +package com.artifex.mupdf.fitz; + +public class RectI +{ + public int x0; + public int y0; + public int x1; + public int y1; + + public RectI(int x0, int y0, int x1, int y1) + { + this.x0 = x0; + this.y0 = y0; + this.x1 = x1; + this.y1 = y1; + } + + public RectI(Rect r) + { + this.x0 = (int)Math.floor(r.x0); + this.y0 = (int)Math.ceil(r.y0); + this.x1 = (int)Math.floor(r.x1); + this.y1 = (int)Math.ceil(r.y1); + } + + public RectI transform(Matrix tm) + { + float ax0 = x0 * tm.a; + float ax1 = x1 * tm.a; + + if (ax0 > ax1) + { + float t = ax0; + ax0 = ax1; + ax1 = t; + } + + float cy0 = y0 * tm.c; + float cy1 = y1 * tm.c; + + if (cy0 > cy1) + { + float t = cy0; + cy0 = cy1; + cy1 = t; + } + ax0 += cy0 + tm.e; + ax1 += cy1 + tm.e; + + float bx0 = x0 * tm.b; + float bx1 = x1 * tm.b; + + if (bx0 > bx1) + { + float t = bx0; + bx0 = bx1; + bx1 = t; + } + + float dy0 = y0 * tm.d; + float dy1 = y1 * tm.d; + + if (dy0 > dy1) + { + float t = dy0; + dy0 = dy1; + dy1 = t; + } + bx0 += dy0 + tm.f; + bx1 += dy1 + tm.f; + + x0 = (int)Math.floor(ax0); + x1 = (int)Math.ceil(ax1); + y0 = (int)Math.floor(bx0); + y1 = (int)Math.ceil(bx1); + + return this; + } +} diff --git a/platform/android/src/com/artifex/mupdf/fitz/Shade.java b/platform/android/src/com/artifex/mupdf/fitz/Shade.java new file mode 100644 index 00000000..bfadebc7 --- /dev/null +++ b/platform/android/src/com/artifex/mupdf/fitz/Shade.java @@ -0,0 +1,28 @@ +package com.artifex.mupdf.fitz; + +public class Shade +{ + // Private data + private long nativeShade = 0; + + // Construction + // Private constructor for the C to use. Any objects created by the + // C are done for purposes of calling back to a java device, and + // should therefore be considered const. + private Shade(long l) + { + nativeShade = l; + } + + // FIXME: Constructors for the different types of shade + // FIXME: Accessors for shade data + + // Destruction + public void destroy() + { + finalize(); + nativeShade = 0; + } + + protected native void finalize(); +} diff --git a/platform/android/src/com/artifex/mupdf/fitz/StrokeState.java b/platform/android/src/com/artifex/mupdf/fitz/StrokeState.java new file mode 100644 index 00000000..2f2fcf96 --- /dev/null +++ b/platform/android/src/com/artifex/mupdf/fitz/StrokeState.java @@ -0,0 +1,64 @@ +package com.artifex.mupdf.fitz; + +import android.graphics.Rect; + +public class StrokeState +{ + public static final int FZ_LINECAP_BUTT = 0; + public static final int FZ_LINECAP_ROUND = 1; + public static final int FZ_LINECAP_SQUARE = 2; + public static final int FZ_LINECAP_TRIANGLE = 3; + + public static final int FZ_LINEJOIN_MITER = 0; + public static final int FZ_LINEJOIN_ROUND = 1; + public static final int FZ_LINEJOIN_BEVEL = 2; + public static final int FZ_LINEJOIN_MITER_XPS = 3; + + // Private data + private long nativeStroke; + + // Construction + StrokeState(int startCap, int endCap, int lineJoin, float lineWidth, float miterLimit) + { + nativeStroke = newNative(startCap, 0, endCap, lineJoin, lineWidth, miterLimit, 0, null); + } + + StrokeState(int startCap, int dashCap, int endCap, int lineJoin, float lineWidth, float miterLimit, float dashPhase, float dash[]) + { + nativeStroke = newNative(startCap, dashCap, endCap, lineJoin, lineWidth, miterLimit, dashPhase, dash); + } + + private native long newNative(int startCap, int dashCap, int endCap, int lineJoin, float lineWidth, float miterLimit, float dashPhase, float dash[]); + + // Private constructor for the C to use. Any objects created by the + // C are done for purposes of calling back to a java device, and + // should therefore be considered const. This is fine as we don't + // currently provide mechanisms for changing individual elements + // of the StrokeState. + private StrokeState(long l) + { + nativeStroke = l; + } + + // Operation + public native void adjustRectForStroke(Rect rect, Matrix ctm); + + // Accessors + public native int getStartCap(); + public native int getDashCap(); + public native int getEndCap(); + public native int getLineJoin(); + public native float getLineWidth(); + public native float getMiterLimit(); + public native float getDashPhase(); + public native float[] getDashes(); + + // Destruction + public void destroy() + { + finalize(); + nativeStroke = 0; + } + + protected native void finalize(); +} diff --git a/platform/android/src/com/artifex/mupdf/fitz/Text.java b/platform/android/src/com/artifex/mupdf/fitz/Text.java new file mode 100644 index 00000000..eada4635 --- /dev/null +++ b/platform/android/src/com/artifex/mupdf/fitz/Text.java @@ -0,0 +1,46 @@ +package com.artifex.mupdf.fitz; + +public class Text +{ + // Private data + private long nativeText = 0; + private boolean isConst = false; + + // Cloning + public Text(Text old) + { + nativeText = cloneNative(old); + } + + private native long cloneNative(Text old); + + //public Text(Font font, Matrix trm, int wmode) + //{ + // nativeText = newNative(font, trm, wmode); + //} + + // Private method used for creating Text entries for a + // device implemented in java. These entries should be + // immutable. + private Text(long ptr) + { + nativeText = ptr; + isConst = true; + } + + // Operation + public native Rect bound(StrokeState stroke, Matrix ctm); + + //public native void add(int gid, int ucs, float x, float y); + + // FIXME: Write accessors + + // Destruction + public void destroy() + { + finalize(); + nativeText = 0; + } + + protected native void finalize(); +} diff --git a/platform/android/src/com/artifex/mupdf/fitz/TryLaterException.java b/platform/android/src/com/artifex/mupdf/fitz/TryLaterException.java new file mode 100644 index 00000000..644c6af1 --- /dev/null +++ b/platform/android/src/com/artifex/mupdf/fitz/TryLaterException.java @@ -0,0 +1,9 @@ +package com.artifex.mupdf.fitz; + +public class TryLaterException extends Exception +{ + TryLaterException(String message) + { + super(message); + } +} diff --git a/platform/android/src/com/artifex/mupdfdemo/MuPDFCore.java b/platform/android/src/com/artifex/mupdfdemo/MuPDFCore.java index de202b3c..da3c20cd 100644 --- a/platform/android/src/com/artifex/mupdfdemo/MuPDFCore.java +++ b/platform/android/src/com/artifex/mupdfdemo/MuPDFCore.java @@ -11,7 +11,9 @@ public class MuPDFCore /* load our native library */ private static boolean gs_so_available = false; static { + System.out.println("Loading dll"); System.loadLibrary("mupdf"); + System.out.println("Loaded dll"); if (gprfSupportedInternal()) { try { |