summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2016-04-26 20:11:49 +0200
committerTor Andersson <tor.andersson@artifex.com>2016-04-27 17:01:06 +0200
commit9b4acc78d2a56a5f79d69f50e72197930509505e (patch)
treeb30e03bd1e80d859b578324425e2486f122c5ac8
parented763d50c7363af5f09d24d0e04b95ca59ff7960 (diff)
downloadmupdf-9b4acc78d2a56a5f79d69f50e72197930509505e.tar.xz
Add fz_close_device function.
Garbage collected languages need a way to signal that they are done with a device other than freeing it. Call it implicitly on fz_drop_device; so take care not to call it again in case it has been explicitly called already.
-rw-r--r--docs/mutool/examples/draw-device.js2
-rw-r--r--docs/mutool/run.html5
-rw-r--r--include/mupdf/fitz/device.h9
-rw-r--r--platform/java/com/artifex/mupdf/fitz/Device.java1
-rw-r--r--platform/java/com/artifex/mupdf/fitz/NativeDevice.java2
-rw-r--r--platform/java/mupdf_native.c23
-rw-r--r--platform/java/mupdf_native.h8
-rw-r--r--source/fitz/bbox-device.c4
-rw-r--r--source/fitz/device.c38
-rw-r--r--source/fitz/draw-device.c4
-rw-r--r--source/fitz/list-device.c2
-rw-r--r--source/fitz/stext-device.c4
-rw-r--r--source/fitz/svg-device.c4
-rw-r--r--source/pdf/pdf-device.c4
-rw-r--r--source/tools/murun.c12
15 files changed, 105 insertions, 17 deletions
diff --git a/docs/mutool/examples/draw-device.js b/docs/mutool/examples/draw-device.js
index 4912e956..140fb54b 100644
--- a/docs/mutool/examples/draw-device.js
+++ b/docs/mutool/examples/draw-device.js
@@ -40,6 +40,6 @@ var transform = [2,0,0,2,0,0]
}
device.popClip();
}
-//device.flush();
+device.close();
pixmap.saveAsPNG("out.png");
diff --git a/docs/mutool/run.html b/docs/mutool/run.html
index 07f852de..8460f2f8 100644
--- a/docs/mutool/run.html
+++ b/docs/mutool/run.html
@@ -368,6 +368,11 @@ otherwise the color is ignored completely and the mask is derived from the alpha
Apply a clip mask to restrict the pattern to the desired shape.
</dl>
+<dl>
+<dt>Device#close()
+<dd>Tell the device that we are done, and flush any pending output.
+</dl>
+
<h2>
Path
</h2>
diff --git a/include/mupdf/fitz/device.h b/include/mupdf/fitz/device.h
index 34faa06e..f9295349 100644
--- a/include/mupdf/fitz/device.h
+++ b/include/mupdf/fitz/device.h
@@ -101,7 +101,7 @@ struct fz_device_s
int hints;
int flags;
- void (*drop_imp)(fz_context *, fz_device *);
+ void (*close)(fz_context *, fz_device *);
void (*fill_path)(fz_context *, fz_device *, const fz_path *, int even_odd, const fz_matrix *, fz_colorspace *, const float *color, float alpha);
void (*stroke_path)(fz_context *, fz_device *, const fz_path *, const fz_stroke_state *, const fz_matrix *, fz_colorspace *, const float *color, float alpha);
@@ -167,6 +167,13 @@ void fz_render_flags(fz_context *ctx, fz_device *dev, int set, int clear);
void *fz_new_device(fz_context *ctx, int size);
/*
+ fz_close_device: Flush any pending output and free internal memory.
+ This is called implicitly on fz_drop_device, so it's only useful for
+ garbage collected language bindings.
+*/
+void fz_close_device(fz_context *ctx, fz_device *dev);
+
+/*
fz_drop_device: Free a devices of any type and its resources.
*/
void fz_drop_device(fz_context *ctx, fz_device *dev);
diff --git a/platform/java/com/artifex/mupdf/fitz/Device.java b/platform/java/com/artifex/mupdf/fitz/Device.java
index b4e87481..71f0ba54 100644
--- a/platform/java/com/artifex/mupdf/fitz/Device.java
+++ b/platform/java/com/artifex/mupdf/fitz/Device.java
@@ -38,6 +38,7 @@ public class Device
* };
*/
+ public void close() {}
public void fillPath(Path path, boolean evenOdd, Matrix ctm, ColorSpace cs, float color[], float alpha) {}
public void strokePath(Path path, StrokeState stroke, Matrix ctm, ColorSpace cs, float color[], float alpha) {}
public void clipPath(Path path, boolean evenOdd, Matrix ctm) {}
diff --git a/platform/java/com/artifex/mupdf/fitz/NativeDevice.java b/platform/java/com/artifex/mupdf/fitz/NativeDevice.java
index 968c5f09..6ea7b0a5 100644
--- a/platform/java/com/artifex/mupdf/fitz/NativeDevice.java
+++ b/platform/java/com/artifex/mupdf/fitz/NativeDevice.java
@@ -17,6 +17,8 @@ public class NativeDevice extends Device
super(p);
}
+ public native final void close();
+
public native final void fillPath(Path path, boolean evenOdd, 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, boolean evenOdd, Matrix ctm);
diff --git a/platform/java/mupdf_native.c b/platform/java/mupdf_native.c
index ad8d5ccc..e835a76d 100644
--- a/platform/java/mupdf_native.c
+++ b/platform/java/mupdf_native.c
@@ -1284,7 +1284,7 @@ fz_java_device_end_tile(fz_context *ctx, fz_device *dev)
}
static void
-fz_java_device_drop_imp(fz_context *ctx, fz_device *dev)
+fz_java_device_close(fz_context *ctx, fz_device *dev)
{
fz_java_device *jdev = (fz_java_device *)dev;
JNIEnv *env = jdev->env;
@@ -1303,7 +1303,7 @@ static fz_device *fz_new_java_device(fz_context *ctx, JNIEnv *env, jobject self)
dev->self = (*env)->NewGlobalRef(env, self);
- dev->super.drop_imp = fz_java_device_drop_imp;
+ dev->super.close = fz_java_device_close;
dev->super.fill_path = fz_java_device_fill_path;
dev->super.stroke_path = fz_java_device_stroke_path;
@@ -1446,6 +1446,25 @@ FUN(NativeDevice_finalize)(JNIEnv *env, jobject self)
}
JNIEXPORT void JNICALL
+FUN(NativeDevice_close)(JNIEnv *env, jobject self)
+{
+ fz_context *ctx = get_context(env);
+ fz_device *dev = from_Device(env, self, ctx);
+ NativeDeviceInfo *info;
+
+ if (ctx == NULL || dev == NULL)
+ return;
+
+ info = lockNativeDevice(env, self);
+ fz_try(ctx)
+ fz_close_device(ctx, dev);
+ fz_always(ctx)
+ unlockNativeDevice(env, info);
+ fz_catch(ctx)
+ jni_rethrow(env, ctx);
+}
+
+JNIEXPORT void JNICALL
FUN(NativeDevice_fillPath)(JNIEnv *env, jobject self, jobject jpath, jboolean even_odd, jobject jctm, jobject jcs, jfloatArray jcolor, float alpha)
{
fz_context *ctx = get_context(env);
diff --git a/platform/java/mupdf_native.h b/platform/java/mupdf_native.h
index 95f17084..4b88903e 100644
--- a/platform/java/mupdf_native.h
+++ b/platform/java/mupdf_native.h
@@ -840,6 +840,14 @@ JNIEXPORT void JNICALL Java_com_artifex_mupdf_fitz_NativeDevice_finalize
/*
* Class: com_artifex_mupdf_fitz_NativeDevice
+ * Method: close
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_artifex_mupdf_fitz_NativeDevice_close
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_artifex_mupdf_fitz_NativeDevice
* Method: fillPath
* Signature: (Lcom/artifex/mupdf/fitz/Path;ZLcom/artifex/mupdf/fitz/Matrix;Lcom/artifex/mupdf/fitz/ColorSpace;[FF)V
*/
diff --git a/source/fitz/bbox-device.c b/source/fitz/bbox-device.c
index 247fdb30..42ca57ad 100644
--- a/source/fitz/bbox-device.c
+++ b/source/fitz/bbox-device.c
@@ -179,7 +179,7 @@ fz_bbox_end_tile(fz_context *ctx, fz_device *dev)
}
static void
-fz_bbox_drop_imp(fz_context *ctx, fz_device *dev)
+fz_bbox_close(fz_context *ctx, fz_device *dev)
{
fz_bbox_device *bdev = (fz_bbox_device*)dev;
if (bdev->top > 0)
@@ -191,7 +191,7 @@ fz_new_bbox_device(fz_context *ctx, fz_rect *result)
{
fz_bbox_device *dev = fz_new_device(ctx, sizeof *dev);
- dev->super.drop_imp = fz_bbox_drop_imp;
+ dev->super.close = fz_bbox_close;
dev->super.fill_path = fz_bbox_fill_path;
dev->super.stroke_path = fz_bbox_stroke_path;
diff --git a/source/fitz/device.c b/source/fitz/device.c
index 5a293bce..df2d4f86 100644
--- a/source/fitz/device.c
+++ b/source/fitz/device.c
@@ -7,12 +7,46 @@ fz_new_device(fz_context *ctx, int size)
}
void
+fz_close_device(fz_context *ctx, fz_device *dev)
+{
+ if (dev == NULL)
+ return;
+ if (dev->close)
+ dev->close(ctx, dev);
+
+ /* Don't call more than once! */
+ dev->close = NULL;
+
+ /* And disable all further device calls. */
+ dev->fill_path = NULL;
+ dev->stroke_path = NULL;
+ dev->clip_path = NULL;
+ dev->clip_stroke_path = NULL;
+ dev->fill_text = NULL;
+ dev->stroke_text = NULL;
+ dev->clip_text = NULL;
+ dev->clip_stroke_text = NULL;
+ dev->ignore_text = NULL;
+ dev->fill_shade = NULL;
+ dev->fill_image = NULL;
+ dev->fill_image_mask = NULL;
+ dev->clip_image_mask = NULL;
+ dev->pop_clip = NULL;
+ dev->begin_mask = NULL;
+ dev->end_mask = NULL;
+ dev->begin_group = NULL;
+ dev->end_group = NULL;
+ dev->begin_tile = NULL;
+ dev->end_tile = NULL;
+}
+
+void
fz_drop_device(fz_context *ctx, fz_device *dev)
{
if (dev == NULL)
return;
- if (dev->drop_imp)
- dev->drop_imp(ctx, dev);
+ if (dev->close)
+ dev->close(ctx, dev);
fz_free(ctx, dev->container);
fz_free(ctx, dev);
}
diff --git a/source/fitz/draw-device.c b/source/fitz/draw-device.c
index 83195cd1..b9db1558 100644
--- a/source/fitz/draw-device.c
+++ b/source/fitz/draw-device.c
@@ -2013,7 +2013,7 @@ fz_draw_end_tile(fz_context *ctx, fz_device *devp)
}
static void
-fz_draw_drop_imp(fz_context *ctx, fz_device *devp)
+fz_draw_close(fz_context *ctx, fz_device *devp)
{
fz_draw_device *dev = (fz_draw_device*)devp;
fz_gel *gel = dev->gel;
@@ -2056,7 +2056,7 @@ fz_new_draw_device(fz_context *ctx, fz_pixmap *dest)
{
fz_draw_device *dev = fz_new_device(ctx, sizeof *dev);
- dev->super.drop_imp = fz_draw_drop_imp;
+ dev->super.close = fz_draw_close;
dev->super.fill_path = fz_draw_fill_path;
dev->super.stroke_path = fz_draw_stroke_path;
diff --git a/source/fitz/list-device.c b/source/fitz/list-device.c
index 156e50f6..5f7d69c8 100644
--- a/source/fitz/list-device.c
+++ b/source/fitz/list-device.c
@@ -1243,7 +1243,7 @@ fz_new_list_device(fz_context *ctx, fz_display_list *list)
dev->super.render_flags = fz_list_render_flags;
- dev->super.drop_imp = drop_writer;
+ dev->super.close = drop_writer;
dev->list = list;
dev->path = NULL;
diff --git a/source/fitz/stext-device.c b/source/fitz/stext-device.c
index 35a6568a..94ff9fd6 100644
--- a/source/fitz/stext-device.c
+++ b/source/fitz/stext-device.c
@@ -1010,7 +1010,7 @@ fz_bidi_reorder_stext_page(fz_context *ctx, fz_stext_page *page)
}
static void
-fz_stext_drop_imp(fz_context *ctx, fz_device *dev)
+fz_stext_close(fz_context *ctx, fz_device *dev)
{
fz_stext_device *tdev = (fz_stext_device*)dev;
@@ -1034,7 +1034,7 @@ fz_new_stext_device(fz_context *ctx, fz_stext_sheet *sheet, fz_stext_page *page)
dev->super.hints = FZ_IGNORE_IMAGE | FZ_IGNORE_SHADE;
- dev->super.drop_imp = fz_stext_drop_imp;
+ dev->super.close = fz_stext_close;
dev->super.fill_text = fz_stext_fill_text;
dev->super.stroke_text = fz_stext_stroke_text;
dev->super.clip_text = fz_stext_clip_text;
diff --git a/source/fitz/svg-device.c b/source/fitz/svg-device.c
index e57b8f5a..d36a5872 100644
--- a/source/fitz/svg-device.c
+++ b/source/fitz/svg-device.c
@@ -1057,7 +1057,7 @@ svg_dev_end_tile(fz_context *ctx, fz_device *dev)
}
static void
-svg_dev_drop_imp(fz_context *ctx, fz_device *dev)
+svg_dev_close(fz_context *ctx, fz_device *dev)
{
svg_device *sdev = (svg_device*)dev;
fz_output *out = sdev->out;
@@ -1073,7 +1073,7 @@ fz_device *fz_new_svg_device(fz_context *ctx, fz_output *out, float page_width,
{
svg_device *dev = fz_new_device(ctx, sizeof *dev);
- dev->super.drop_imp = svg_dev_drop_imp;
+ dev->super.close = svg_dev_close;
dev->super.fill_path = svg_dev_fill_path;
dev->super.stroke_path = svg_dev_stroke_path;
diff --git a/source/pdf/pdf-device.c b/source/pdf/pdf-device.c
index 9c38dd41..7ece963d 100644
--- a/source/pdf/pdf-device.c
+++ b/source/pdf/pdf-device.c
@@ -1037,7 +1037,7 @@ pdf_dev_end_tile(fz_context *ctx, fz_device *dev)
}
static void
-pdf_dev_drop_imp(fz_context *ctx, fz_device *dev)
+pdf_dev_close(fz_context *ctx, fz_device *dev)
{
pdf_device *pdev = (pdf_device*)dev;
int i;
@@ -1066,7 +1066,7 @@ fz_device *pdf_new_pdf_device(fz_context *ctx, pdf_document *doc, const fz_matri
{
pdf_device *dev = fz_new_device(ctx, sizeof *dev);
- dev->super.drop_imp = pdf_dev_drop_imp;
+ dev->super.close = pdf_dev_close;
dev->super.fill_path = pdf_dev_fill_path;
dev->super.stroke_path = pdf_dev_stroke_path;
diff --git a/source/tools/murun.c b/source/tools/murun.c
index 541930eb..b5726770 100644
--- a/source/tools/murun.c
+++ b/source/tools/murun.c
@@ -1134,6 +1134,16 @@ static fz_device *new_js_device(fz_context *ctx, js_State *J)
/* device calling into c from js */
+static void ffi_Device_close(js_State *J)
+{
+ fz_context *ctx = js_getcontext(J);
+ fz_device *dev = js_touserdata(J, 0, "fz_device");
+ fz_try(ctx)
+ fz_close_device(ctx, dev);
+ fz_catch(ctx)
+ rethrow(J);
+}
+
static void ffi_Device_fillPath(js_State *J)
{
fz_context *ctx = js_getcontext(J);
@@ -2953,6 +2963,8 @@ int murun_main(int argc, char **argv)
js_newobject(J);
{
+ jsB_propfun(J, "Device.close", ffi_Device_close, 0);
+
jsB_propfun(J, "Device.fillPath", ffi_Device_fillPath, 6);
jsB_propfun(J, "Device.strokePath", ffi_Device_strokePath, 6);
jsB_propfun(J, "Device.clipPath", ffi_Device_clipPath, 3);