[gs-commits] mupdf 1.16.1.8 Revised annotation QuadPoints/InkList/Vert

[email protected] (Tor Andersson)
Newsgroups gmane.comp.printing.ghostscript.cvs
Message-ID <[email protected]>
commit 32aa69e90ae2f51bdefa120e12a4c767f7cb9a0a
Author: Tor Andersson <[email protected]>
Date:   Tue Jul 2 14:35:09 2019 +0200

    Revised annotation QuadPoints/InkList/Vertices accessors.
    
    * Use fz_quad and fz_point structs in arguments and return values.
    * Use Point and Quad classes for Java instead of passing float arrays.
    * Provide piece-meal accessors and constructors so callers don't need
      to allocate temporary lists.
    * Add accessors for Java and mutool run.

diff --git a/include/mupdf/fitz/geometry.h b/include/mupdf/fitz/geometry.h
index 8ae1074..c572604 100644
--- a/include/mupdf/fitz/geometry.h
+++ b/include/mupdf/fitz/geometry.h
@@ -351,6 +351,21 @@ struct fz_quad_s
 	fz_point ul, ur, ll, lr;
 };
 
+static inline fz_quad fz_make_quad(
+	float ul_x, float ul_y,
+	float ur_x, float ur_y,
+	float ll_x, float ll_y,
+	float lr_x, float lr_y)
+{
+	fz_quad q = {
+		{ ul_x, ul_y },
+		{ ur_x, ur_y },
+		{ ll_x, ll_y },
+		{ lr_x, lr_y },
+	};
+	return q;
+}
+
 fz_rect fz_rect_from_quad(fz_quad q);
 fz_quad fz_transform_quad(fz_quad q, fz_matrix m);
 
diff --git a/include/mupdf/pdf/annot.h b/include/mupdf/pdf/annot.h
index b6f3db9..f532d18 100644
--- a/include/mupdf/pdf/annot.h
+++ b/include/mupdf/pdf/annot.h
@@ -151,7 +151,7 @@ int pdf_annot_MK_BG_rgb(fz_context *ctx, pdf_annot *annot, float rgb[3]);
 int pdf_annot_MK_BC_rgb(fz_context *ctx, pdf_annot *annot, float rgb[3]);
 
 int pdf_annot_quad_point_count(fz_context *ctx, pdf_annot *annot);
-void pdf_annot_quad_point(fz_context *ctx, pdf_annot *annot, int i, float qp[8]);
+fz_quad pdf_annot_quad_point(fz_context *ctx, pdf_annot *annot, int i);
 
 int pdf_annot_ink_list_count(fz_context *ctx, pdf_annot *annot);
 int pdf_annot_ink_list_stroke_count(fz_context *ctx, pdf_annot *annot, int i);
@@ -165,12 +165,14 @@ void pdf_set_annot_color(fz_context *ctx, pdf_annot *annot, int n, const float c
 void pdf_set_annot_interior_color(fz_context *ctx, pdf_annot *annot, int n, const float color[4]);
 void pdf_set_annot_quadding(fz_context *ctx, pdf_annot *annot, int q);
 
-void pdf_set_annot_quad_points(fz_context *ctx, pdf_annot *annot, int n, const float *v);
+void pdf_set_annot_quad_points(fz_context *ctx, pdf_annot *annot, int n, const fz_quad *qv);
 void pdf_clear_annot_quad_points(fz_context *ctx, pdf_annot *annot);
 void pdf_add_annot_quad_point(fz_context *ctx, pdf_annot *annot, fz_quad quad);
 
 void pdf_set_annot_ink_list(fz_context *ctx, pdf_annot *annot, int n, const int *count, const fz_point *v);
 void pdf_clear_annot_ink_list(fz_context *ctx, pdf_annot *annot);
+void pdf_add_annot_ink_list_stroke(fz_context *ctx, pdf_annot *annot);
+void pdf_add_annot_ink_list_stroke_vertex(fz_context *ctx, pdf_annot *annot, fz_point p);
 void pdf_add_annot_ink_list(fz_context *ctx, pdf_annot *annot, int n, fz_point stroke[]);
 
 void pdf_set_annot_icon_name(fz_context *ctx, pdf_annot *annot, const char *name);
diff --git a/platform/java/mupdf_native.c b/platform/java/mupdf_native.c
index 0ae437f..54d019e 100644
--- a/platform/java/mupdf_native.c
+++ b/platform/java/mupdf_native.c
@@ -2069,6 +2069,25 @@ static inline fz_rect from_Rect(JNIEnv *env, jobject jrect)
 	return rect;
 }
 
+static inline fz_quad from_Quad(JNIEnv *env, jobject jquad)
+{
+	fz_quad quad;
+
+	if (!jquad)
+		return fz_make_quad(0, 0, 0, 0, 0, 0, 0, 0);
+
+	quad.ul.x = (*env)->GetFloatField(env, jquad, fid_Quad_ul_x);
+	quad.ul.y = (*env)->GetFloatField(env, jquad, fid_Quad_ul_y);
+	quad.ur.x = (*env)->GetFloatField(env, jquad, fid_Quad_ur_x);
+	quad.ur.y = (*env)->GetFloatField(env, jquad, fid_Quad_ur_y);
+	quad.ll.x = (*env)->GetFloatField(env, jquad, fid_Quad_ll_x);
+	quad.ll.y = (*env)->GetFloatField(env, jquad, fid_Quad_ll_y);
+	quad.lr.x = (*env)->GetFloatField(env, jquad, fid_Quad_lr_x);
+	quad.lr.y = (*env)->GetFloatField(env, jquad, fid_Quad_lr_y);
+
+	return quad;
+}
+
 /* Conversion functions: Java to C. None of these throw java exceptions. */
 
 static inline fz_buffer *from_Buffer_safe(JNIEnv *env, jobject jobj)
@@ -9270,377 +9289,288 @@ FUN(PDFAnnotation_setInteriorColor)(JNIEnv *env, jobject self, jobject jcolor)
 		jni_rethrow(env, ctx);
 }
 
-JNIEXPORT jobject JNICALL
-FUN(PDFAnnotation_getQuadPoints)(JNIEnv *env, jobject self)
+JNIEXPORT jint JNICALL
+FUN(PDFAnnotation_getQuadPointCount)(JNIEnv *env, jobject self)
 {
 	fz_context *ctx = get_context(env);
 	pdf_annot *annot = from_PDFAnnotation(env, self);
-	int i, n;
-	float qp[8];
-	jobject jqps;
-	jfloatArray jqp;
-
-	if (!ctx || !annot) return NULL;
+	int n = 0;
 
 	fz_try(ctx)
 		n = pdf_annot_quad_point_count(ctx, annot);
 	fz_catch(ctx)
 	{
 		jni_rethrow(env, ctx);
-		return NULL;
-	}
-
-	jqps = (*env)->NewObjectArray(env, n, cls_FloatArray, NULL);
-	if (!jqps) return NULL;
-
-	for (i = 0; i < n; i++)
-	{
-		fz_try(ctx)
-			pdf_annot_quad_point(ctx, annot, i, qp);
-		fz_catch(ctx)
-		{
-			jni_rethrow(env, ctx);
-			return NULL;
-		}
-
-		jqp = (*env)->NewFloatArray(env, 8);
-		if (!jqp) return NULL;
-
-		(*env)->SetFloatArrayRegion(env, jqp, 0, 8, &qp[0]);
-		if ((*env)->ExceptionCheck(env)) return NULL;
-
-		(*env)->SetObjectArrayElement(env, jqps, i, jqp);
-		if ((*env)->ExceptionCheck(env)) return NULL;
-
-		(*env)->DeleteLocalRef(env, jqp);
+		return 0;
 	}
 
-	return jqps;
+	return n;
 }
 
-JNIEXPORT void JNICALL
-FUN(PDFAnnotation_setQuadPoints)(JNIEnv *env, jobject self, jobject jqps)
+JNIEXPORT jobject JNICALL
+FUN(PDFAnnotation_getQuadPoint)(JNIEnv *env, jobject self, jint i)
 {
 	fz_context *ctx = get_context(env);
 	pdf_annot *annot = from_PDFAnnotation(env, self);
-	int i, n, m;
-	float *qp;
-	jfloatArray jqp;
-
-	if (!ctx || !annot) return;
-
-	n = (*env)->GetArrayLength(env, jqps);
+	fz_quad q;
 
 	fz_try(ctx)
-		qp = fz_malloc(ctx, n * 8 * sizeof *qp);
+		q = pdf_annot_quad_point(ctx, annot, i);
 	fz_catch(ctx)
-		jni_rethrow(env, ctx);
-
-	for (i = 0; i < n; i++)
 	{
-		jqp = (*env)->GetObjectArrayElement(env, jqps, i);
-		if ((*env)->ExceptionCheck(env))
-		{
-			fz_free(ctx, qp);
-			return;
-		}
-
-		if (!jqp)
-			continue;
-
-		m = (*env)->GetArrayLength(env, jqp);
-		if (m > 8)
-			m = 8;
-
-		(*env)->GetFloatArrayRegion(env, jqp, 0, m, &qp[i * 8]);
-		if ((*env)->ExceptionCheck(env))
-		{
-			fz_free(ctx, qp);
-			return;
-		}
+		jni_rethrow(env, ctx);
+		return NULL;
+	}
 
-		if (m < 8)
-			memset(&qp[i * 8 + m], 0, (8 - m) * sizeof (float));
+	return to_Quad_safe(ctx, env, q);
+}
 
-		(*env)->DeleteLocalRef(env, jqp);
-	}
+JNIEXPORT void JNICALL
+FUN(PDFAnnotation_clearQuadPoints)(JNIEnv *env, jobject self)
+{
+	fz_context *ctx = get_context(env);
+	pdf_annot *annot = from_PDFAnnotation(env, self);
 
 	fz_try(ctx)
-		pdf_set_annot_quad_points(ctx, annot, n, qp);
-	fz_always(ctx)
-		fz_free(ctx, qp);
+		pdf_clear_annot_quad_points(ctx, annot);
 	fz_catch(ctx)
 		jni_rethrow(env, ctx);
 }
 
 JNIEXPORT void JNICALL
-FUN(PDFAnnotation_eventEnter)(JNIEnv *env, jobject self)
+FUN(PDFAnnotation_addQuadPoint)(JNIEnv *env, jobject self, jobject qobj)
 {
 	fz_context *ctx = get_context(env);
 	pdf_annot *annot = from_PDFAnnotation(env, self);
-
-	if (!ctx || !annot) return;
+	fz_quad q = from_Quad(env, qobj);
 
 	fz_try(ctx)
-	{
-		pdf_annot_event_enter(ctx, annot);
-		annot->is_hot = 1;
-	}
+		pdf_add_annot_quad_point(ctx, annot, q);
 	fz_catch(ctx)
 		jni_rethrow(env, ctx);
 }
 
-JNIEXPORT void JNICALL
-FUN(PDFAnnotation_eventExit)(JNIEnv *env, jobject self)
+JNIEXPORT jint JNICALL
+FUN(PDFAnnotation_getVertexCount)(JNIEnv *env, jobject self)
 {
 	fz_context *ctx = get_context(env);
 	pdf_annot *annot = from_PDFAnnotation(env, self);
-
-	if (!ctx || !annot) return;
+	int n = 0;
 
 	fz_try(ctx)
-	{
-		pdf_annot_event_exit(ctx, annot);
-		annot->is_hot = 0;
-	}
+		n = pdf_annot_vertex_count(ctx, annot);
 	fz_catch(ctx)
+	{
 		jni_rethrow(env, ctx);
+		return 0;
+	}
+
+	return n;
 }
 
-JNIEXPORT void JNICALL
-FUN(PDFAnnotation_eventDown)(JNIEnv *env, jobject self)
+JNIEXPORT jobject JNICALL
+FUN(PDFAnnotation_getVertex)(JNIEnv *env, jobject self, jint i)
 {
 	fz_context *ctx = get_context(env);
 	pdf_annot *annot = from_PDFAnnotation(env, self);
-
-	if (!ctx || !annot) return;
+	fz_point v;
 
 	fz_try(ctx)
-	{
-		pdf_annot_event_down(ctx, annot);
-		annot->is_active = 1;
-	}
+		v = pdf_annot_vertex(ctx, annot, i);
 	fz_catch(ctx)
+	{
 		jni_rethrow(env, ctx);
+		return NULL;
+	}
+
+	return to_Point_safe(ctx, env, v);
 }
 
 JNIEXPORT void JNICALL
-FUN(PDFAnnotation_eventUp)(JNIEnv *env, jobject self)
+FUN(PDFAnnotation_clearVertices)(JNIEnv *env, jobject self)
 {
 	fz_context *ctx = get_context(env);
 	pdf_annot *annot = from_PDFAnnotation(env, self);
 
-	if (!ctx || !annot) return;
-
 	fz_try(ctx)
-	{
-		if (annot->is_hot && annot->is_active)
-			pdf_annot_event_up(ctx, annot);
-		annot->is_active = 0;
-	}
+		pdf_clear_annot_vertices(ctx, annot);
 	fz_catch(ctx)
 		jni_rethrow(env, ctx);
 }
 
 JNIEXPORT void JNICALL
-FUN(PDFAnnotation_eventFocus)(JNIEnv *env, jobject self)
+FUN(PDFAnnotation_addVertex)(JNIEnv *env, jobject self, float x, float y)
 {
 	fz_context *ctx = get_context(env);
 	pdf_annot *annot = from_PDFAnnotation(env, self);
 
-	if (!ctx || !annot) return;
-
 	fz_try(ctx)
-		pdf_annot_event_focus(ctx, annot);
+		pdf_add_annot_vertex(ctx, annot, fz_make_point(x, y));
 	fz_catch(ctx)
 		jni_rethrow(env, ctx);
 }
 
-JNIEXPORT void JNICALL
-FUN(PDFAnnotation_eventBlur)(JNIEnv *env, jobject self)
+JNIEXPORT jint JNICALL
+FUN(PDFAnnotation_getInkListCount)(JNIEnv *env, jobject self)
 {
 	fz_context *ctx = get_context(env);
 	pdf_annot *annot = from_PDFAnnotation(env, self);
-
-	if (!ctx || !annot) return;
+	int n = 0;
 
 	fz_try(ctx)
-		pdf_annot_event_blur(ctx, annot);
+		n = pdf_annot_ink_list_count(ctx, annot);
 	fz_catch(ctx)
+	{
 		jni_rethrow(env, ctx);
+		return 0;
+	}
+
+	return n;
 }
 
-JNIEXPORT jboolean JNICALL
-FUN(PDFAnnotation_update)(JNIEnv *env, jobject self)
+JNIEXPORT jint JNICALL
+FUN(PDFAnnotation_getInkListStrokeCount)(JNIEnv *env, jobject self, jint i)
 {
 	fz_context *ctx = get_context(env);
 	pdf_annot *annot = from_PDFAnnotation(env, self);
-	jboolean changed = JNI_FALSE;
-
-	if (!ctx || !annot) return JNI_FALSE;
+	int n = 0;
 
 	fz_try(ctx)
-		changed = pdf_update_annot(ctx, annot);
+		n = pdf_annot_ink_list_stroke_count(ctx, annot, i);
 	fz_catch(ctx)
+	{
 		jni_rethrow(env, ctx);
+		return 0;
+	}
 
-	return changed;
+	return n;
 }
 
 JNIEXPORT jobject JNICALL
-FUN(PDFAnnotation_getInkList)(JNIEnv *env, jobject self)
+FUN(PDFAnnotation_getInkListStrokeVertex)(JNIEnv *env, jobject self, jint i, jint k)
 {
 	fz_context *ctx = get_context(env);
 	pdf_annot *annot = from_PDFAnnotation(env, self);
-	int i, k, n, m;
 	fz_point v;
-	jobject jinklist;
-	jfloatArray jpath;
-
-	if (!ctx || !annot) return NULL;
 
 	fz_try(ctx)
-		n = pdf_annot_ink_list_count(ctx, annot);
+		v = pdf_annot_ink_list_stroke_vertex(ctx, annot, i, k);
 	fz_catch(ctx)
 	{
 		jni_rethrow(env, ctx);
 		return NULL;
 	}
 
-	jinklist = (*env)->NewObjectArray(env, n, cls_FloatArray, NULL);
-	if (!jinklist) return NULL;
-
-	for (i = 0; i < n; i++)
-	{
-		fz_try(ctx)
-			m = pdf_annot_ink_list_stroke_count(ctx, annot, i);
-		fz_catch(ctx)
-		{
-			jni_rethrow(env, ctx);
-			return NULL;
-		}
+	return to_Point_safe(ctx, env, v);
+}
 
-		jpath = (*env)->NewFloatArray(env, m * 2);
-		if (!jpath) return NULL;
+JNIEXPORT void JNICALL
+FUN(PDFAnnotation_clearInkList)(JNIEnv *env, jobject self)
+{
+	fz_context *ctx = get_context(env);
+	pdf_annot *annot = from_PDFAnnotation(env, self);
 
-		for (k = 0; k < m; k++)
-		{
-			fz_try(ctx)
-				v = pdf_annot_ink_list_stroke_vertex(ctx, annot, i, k);
-			fz_catch(ctx)
-			{
-				jni_rethrow(env, ctx);
-				return NULL;
-			}
+	fz_try(ctx)
+		pdf_clear_annot_ink_list(ctx, annot);
+	fz_catch(ctx)
+		jni_rethrow(env, ctx);
+}
 
-			(*env)->SetFloatArrayRegion(env, jpath, k * 2, 2, (float*)&v);
-			if ((*env)->ExceptionCheck(env)) return NULL;
-		}
+JNIEXPORT void JNICALL
+FUN(PDFAnnotation_addInkListStroke)(JNIEnv *env, jobject self)
+{
+	fz_context *ctx = get_context(env);
+	pdf_annot *annot = from_PDFAnnotation(env, self);
 
-		(*env)->SetObjectArrayElement(env, jinklist, i, jpath);
-		if ((*env)->ExceptionCheck(env)) return NULL;
+	fz_try(ctx)
+		pdf_add_annot_ink_list_stroke(ctx, annot);
+	fz_catch(ctx)
+		jni_rethrow(env, ctx);
+}
 
-		(*env)->DeleteLocalRef(env, jpath);
-	}
+JNIEXPORT void JNICALL
+FUN(PDFAnnotation_addInkListStrokeVertex)(JNIEnv *env, jobject self, float x, float y)
+{
+	fz_context *ctx = get_context(env);
+	pdf_annot *annot = from_PDFAnnotation(env, self);
 
-	return jinklist;
+	fz_try(ctx)
+		pdf_add_annot_ink_list_stroke_vertex(ctx, annot, fz_make_point(x, y));
+	fz_catch(ctx)
+		jni_rethrow(env, ctx);
 }
 
 JNIEXPORT void JNICALL
-FUN(PDFAnnotation_setInkList)(JNIEnv *env, jobject self, jobject jinklist)
+FUN(PDFAnnotation_eventEnter)(JNIEnv *env, jobject self)
 {
 	fz_context *ctx = get_context(env);
 	pdf_annot *annot = from_PDFAnnotation(env, self);
-	int i, k, n, m;
-	jfloatArray jpath;
-	fz_point *points = NULL;
-	int *counts = NULL;
 
 	if (!ctx || !annot) return;
 
-	n = (*env)->GetArrayLength(env, jinklist);
-
-	for (i = m = 0; i < n; i++)
+	fz_try(ctx)
 	{
-		jpath = (*env)->GetObjectArrayElement(env, jinklist, i);
-		if ((*env)->ExceptionCheck(env)) return;
-
-		if (!jpath)
-			continue;
+		pdf_annot_event_enter(ctx, annot);
+		annot->is_hot = 1;
+	}
+	fz_catch(ctx)
+		jni_rethrow(env, ctx);
+}
 
-		m += (*env)->GetArrayLength(env, jpath) / 2;
+JNIEXPORT void JNICALL
+FUN(PDFAnnotation_eventExit)(JNIEnv *env, jobject self)
+{
+	fz_context *ctx = get_context(env);
+	pdf_annot *annot = from_PDFAnnotation(env, self);
 
-		(*env)->DeleteLocalRef(env, jpath);
-	}
+	if (!ctx || !annot) return;
 
 	fz_try(ctx)
 	{
-		counts = fz_malloc(ctx, n * sizeof(int));
-		points = fz_malloc(ctx, m * sizeof(fz_point));
+		pdf_annot_event_exit(ctx, annot);
+		annot->is_hot = 0;
 	}
 	fz_catch(ctx)
-	{
-		fz_free(ctx, counts);
-		fz_free(ctx, points);
 		jni_rethrow(env, ctx);
-	}
-
-	for (i = k = 0; i < n; k += counts[i++])
-	{
-		jpath = (*env)->GetObjectArrayElement(env, jinklist, i);
-		if ((*env)->ExceptionCheck(env))
-		{
-			fz_free(ctx, counts);
-			fz_free(ctx, points);
-			return;
-		}
-
-		if (!jpath)
-			continue;
+}
 
-		counts[i] = (*env)->GetArrayLength(env, jpath);
-		(*env)->GetFloatArrayRegion(env, jpath, 0, counts[i], (float*)&points[k]);
-		if ((*env)->ExceptionCheck(env))
-		{
-			fz_free(ctx, counts);
-			fz_free(ctx, points);
-			return;
-		}
-		counts[i] /= 2;
+JNIEXPORT void JNICALL
+FUN(PDFAnnotation_eventDown)(JNIEnv *env, jobject self)
+{
+	fz_context *ctx = get_context(env);
+	pdf_annot *annot = from_PDFAnnotation(env, self);
 
-		(*env)->DeleteLocalRef(env, jpath);
-	}
+	if (!ctx || !annot) return;
 
 	fz_try(ctx)
-		pdf_set_annot_ink_list(ctx, annot, n, counts, points);
-	fz_always(ctx)
 	{
-		fz_free(ctx, counts);
-		fz_free(ctx, points);
+		pdf_annot_event_down(ctx, annot);
+		annot->is_active = 1;
 	}
 	fz_catch(ctx)
 		jni_rethrow(env, ctx);
 }
 
-JNIEXPORT jboolean JNICALL
-FUN(PDFAnnotation_isOpen)(JNIEnv *env, jobject self)
+JNIEXPORT void JNICALL
+FUN(PDFAnnotation_eventUp)(JNIEnv *env, jobject self)
 {
 	fz_context *ctx = get_context(env);
 	pdf_annot *annot = from_PDFAnnotation(env, self);
-	jboolean open = JNI_FALSE;
 
-	if (!ctx || !annot) return JNI_FALSE;
+	if (!ctx || !annot) return;
 
 	fz_try(ctx)
-		open = pdf_annot_is_open(ctx, annot);
+	{
+		if (annot->is_hot && annot->is_active)
+			pdf_annot_event_up(ctx, annot);
+		annot->is_active = 0;
+	}
 	fz_catch(ctx)
 		jni_rethrow(env, ctx);
-
-	return open;
 }
 
 JNIEXPORT void JNICALL
-FUN(PDFAnnotation_setIsOpen)(JNIEnv *env, jobject self, jboolean open)
+FUN(PDFAnnotation_eventFocus)(JNIEnv *env, jobject self)
 {
 	fz_context *ctx = get_context(env);
 	pdf_annot *annot = from_PDFAnnotation(env, self);
@@ -9648,78 +9578,69 @@ FUN(PDFAnnotation_setIsOpen)(JNIEnv *env, jobject self, jboolean open)
 	if (!ctx || !annot) return;
 
 	fz_try(ctx)
-		pdf_set_annot_is_open(ctx, annot, open);
+		pdf_annot_event_focus(ctx, annot);
 	fz_catch(ctx)
 		jni_rethrow(env, ctx);
 }
 
-JNIEXPORT jobject JNICALL
-FUN(PDFAnnotation_getVertices)(JNIEnv *env, jobject self)
+JNIEXPORT void JNICALL
+FUN(PDFAnnotation_eventBlur)(JNIEnv *env, jobject self)
 {
 	fz_context *ctx = get_context(env);
 	pdf_annot *annot = from_PDFAnnotation(env, self);
-	int i, n;
-	fz_point v;
-	jobject jvertices;
 
-	if (!ctx || !annot) return NULL;
+	if (!ctx || !annot) return;
 
 	fz_try(ctx)
-		n = pdf_annot_vertex_count(ctx, annot);
+		pdf_annot_event_blur(ctx, annot);
 	fz_catch(ctx)
-	{
 		jni_rethrow(env, ctx);
-		return NULL;
-	}
+}
 
-	jvertices = (*env)->NewObjectArray(env, 2 * n, cls_FloatArray, NULL);
-	if (!jvertices) return NULL;
+JNIEXPORT jboolean JNICALL
+FUN(PDFAnnotation_update)(JNIEnv *env, jobject self)
+{
+	fz_context *ctx = get_context(env);
+	pdf_annot *annot = from_PDFAnnotation(env, self);
+	jboolean changed = JNI_FALSE;
 
-	for (i = 0; i < n; i++)
-	{
-		fz_try(ctx)
-			v = pdf_annot_vertex(ctx, annot, i);
-		fz_catch(ctx)
-		{
-			jni_rethrow(env, ctx);
-			return NULL;
-		}
+	if (!ctx || !annot) return JNI_FALSE;
 
-		(*env)->SetFloatArrayRegion(env, jvertices, i * 2, 2, (float*)&v);
-		if ((*env)->ExceptionCheck(env)) return NULL;
-	}
+	fz_try(ctx)
+		changed = pdf_update_annot(ctx, annot);
+	fz_catch(ctx)
+		jni_rethrow(env, ctx);
 
-	return jvertices;
+	return changed;
 }
 
-JNIEXPORT void JNICALL
-FUN(PDFAnnotation_setVertices)(JNIEnv *env, jobject self, jobject jvertices)
+JNIEXPORT jboolean JNICALL
+FUN(PDFAnnotation_isOpen)(JNIEnv *env, jobject self)
 {
 	fz_context *ctx = get_context(env);
 	pdf_annot *annot = from_PDFAnnotation(env, self);
-	float *vertices = NULL;
-	int n;
-
-	if (!ctx || !annot) return;
+	jboolean open = JNI_FALSE;
 
-	n = (*env)->GetArrayLength(env, jvertices);
+	if (!ctx || !annot) return JNI_FALSE;
 
 	fz_try(ctx)
-		vertices = fz_malloc(ctx, n * sizeof *vertices);
+		open = pdf_annot_is_open(ctx, annot);
 	fz_catch(ctx)
 		jni_rethrow(env, ctx);
 
-	(*env)->GetFloatArrayRegion(env, jvertices, 0, n, vertices);
-	if ((*env)->ExceptionCheck(env))
-	{
-		fz_free(ctx, vertices);
-		return;
-	}
+	return open;
+}
+
+JNIEXPORT void JNICALL
+FUN(PDFAnnotation_setIsOpen)(JNIEnv *env, jobject self, jboolean open)
+{
+	fz_context *ctx = get_context(env);
+	pdf_annot *annot = from_PDFAnnotation(env, self);
+
+	if (!ctx || !annot) return;
 
 	fz_try(ctx)
-		pdf_set_annot_vertices(ctx, annot, n, (fz_point*)vertices);
-	fz_always(ctx)
-		fz_free(ctx, vertices);
+		pdf_set_annot_is_open(ctx, annot, open);
 	fz_catch(ctx)
 		jni_rethrow(env, ctx);
 }
diff --git a/platform/java/mupdf_native.h b/platform/java/mupdf_native.h
index f584c7f..ba990d8 100644
--- a/platform/java/mupdf_native.h
+++ b/platform/java/mupdf_native.h
@@ -1390,51 +1390,115 @@ JNIEXPORT void JNICALL Java_com_artifex_mupdf_fitz_PDFAnnotation_setLineEndingSt
 
 /*
  * Class:     com_artifex_mupdf_fitz_PDFAnnotation
- * Method:    getVertices
- * Signature: ()[F
+ * Method:    getQuadPointCount
+ * Signature: ()I
  */
-JNIEXPORT jfloatArray JNICALL Java_com_artifex_mupdf_fitz_PDFAnnotation_getVertices
+JNIEXPORT jint JNICALL Java_com_artifex_mupdf_fitz_PDFAnnotation_getQuadPointCount
   (JNIEnv *, jobject);
 
 /*
  * Class:     com_artifex_mupdf_fitz_PDFAnnotation
- * Method:    setVertices
- * Signature: ([F)V
+ * Method:    getQuadPoint
+ * Signature: (I)Lcom/artifex/mupdf/fitz/Quad;
  */
-JNIEXPORT void JNICALL Java_com_artifex_mupdf_fitz_PDFAnnotation_setVertices
-  (JNIEnv *, jobject, jfloatArray);
+JNIEXPORT jobject JNICALL Java_com_artifex_mupdf_fitz_PDFAnnotation_getQuadPoint
+  (JNIEnv *, jobject, jint);
 
 /*
  * Class:     com_artifex_mupdf_fitz_PDFAnnotation
- * Method:    getQuadPoints
- * Signature: ()[[F
+ * Method:    clearQuadPoints
+ * Signature: ()V
  */
-JNIEXPORT jobjectArray JNICALL Java_com_artifex_mupdf_fitz_PDFAnnotation_getQuadPoints
+JNIEXPORT void JNICALL Java_com_artifex_mupdf_fitz_PDFAnnotation_clearQuadPoints
   (JNIEnv *, jobject);
 
 /*
  * Class:     com_artifex_mupdf_fitz_PDFAnnotation
- * Method:    setQuadPoints
- * Signature: ([[F)V
+ * Method:    addQuadPoint
+ * Signature: (Lcom/artifex/mupdf/fitz/Quad;)V
  */
-JNIEXPORT void JNICALL Java_com_artifex_mupdf_fitz_PDFAnnotation_setQuadPoints
-  (JNIEnv *, jobject, jobjectArray);
+JNIEXPORT void JNICALL Java_com_artifex_mupdf_fitz_PDFAnnotation_addQuadPoint
+  (JNIEnv *, jobject, jobject);
 
 /*
  * Class:     com_artifex_mupdf_fitz_PDFAnnotation
- * Method:    getInkList
- * Signature: ()[[F
+ * Method:    getVertexCount
+ * Signature: ()I
  */
-JNIEXPORT jobjectArray JNICALL Java_com_artifex_mupdf_fitz_PDFAnnotation_getInkList
+JNIEXPORT jint JNICALL Java_com_artifex_mupdf_fitz_PDFAnnotation_getVertexCount
   (JNIEnv *, jobject);
 
 /*
  * Class:     com_artifex_mupdf_fitz_PDFAnnotation
- * Method:    setInkList
- * Signature: ([[F)V
+ * Method:    getVertex
+ * Signature: (I)Lcom/artifex/mupdf/fitz/Point;
  */
-JNIEXPORT void JNICALL Java_com_artifex_mupdf_fitz_PDFAnnotation_setInkList
-  (JNIEnv *, jobject, jobjectArray);
+JNIEXPORT jobject JNICALL Java_com_artifex_mupdf_fitz_PDFAnnotation_getVertex
+  (JNIEnv *, jobject, jint);
+
+/*
+ * Class:     com_artifex_mupdf_fitz_PDFAnnotation
+ * Method:    clearVertices
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_artifex_mupdf_fitz_PDFAnnotation_clearVertices
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     com_artifex_mupdf_fitz_PDFAnnotation
+ * Method:    addVertex
+ * Signature: (FF)V
+ */
+JNIEXPORT void JNICALL Java_com_artifex_mupdf_fitz_PDFAnnotation_addVertex
+  (JNIEnv *, jobject, jfloat, jfloat);
+
+/*
+ * Class:     com_artifex_mupdf_fitz_PDFAnnotation
+ * Method:    getInkListCount
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_com_artifex_mupdf_fitz_PDFAnnotation_getInkListCount
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     com_artifex_mupdf_fitz_PDFAnnotation
+ * Method:    getInkListStrokeCount
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_com_artifex_mupdf_fitz_PDFAnnotation_getInkListStrokeCount
+  (JNIEnv *, jobject, jint);
+
+/*
+ * Class:     com_artifex_mupdf_fitz_PDFAnnotation
+ * Method:    getInkListStrokeVertex
+ * Signature: (II)Lcom/artifex/mupdf/fitz/Point;
+ */
+JNIEXPORT jobject JNICALL Java_com_artifex_mupdf_fitz_PDFAnnotation_getInkListStrokeVertex
+  (JNIEnv *, jobject, jint, jint);
+
+/*
+ * Class:     com_artifex_mupdf_fitz_PDFAnnotation
+ * Method:    clearInkList
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_artifex_mupdf_fitz_PDFAnnotation_clearInkList
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     com_artifex_mupdf_fitz_PDFAnnotation
+ * Method:    addInkListStroke
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_artifex_mupdf_fitz_PDFAnnotation_addInkListStroke
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     com_artifex_mupdf_fitz_PDFAnnotation
+ * Method:    addInkListVertex
+ * Signature: (FF)V
+ */
+JNIEXPORT void JNICALL Java_com_artifex_mupdf_fitz_PDFAnnotation_addInkListVertex
+  (JNIEnv *, jobject, jfloat, jfloat);
 
 /*
  * Class:     com_artifex_mupdf_fitz_PDFAnnotation
@@ -2599,6 +2663,46 @@ JNIEXPORT jboolean JNICALL Java_com_artifex_mupdf_fitz_PDFWidget_isEditing
 JNIEXPORT jboolean JNICALL Java_com_artifex_mupdf_fitz_PDFWidget_setChoiceValue
   (JNIEnv *, jobject, jstring);
 
+/*
+ * Class:     com_artifex_mupdf_fitz_PDFWidget
+ * Method:    isSigned
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_artifex_mupdf_fitz_PDFWidget_isSigned
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     com_artifex_mupdf_fitz_PDFWidget
+ * Method:    clearSignature
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_artifex_mupdf_fitz_PDFWidget_clearSignature
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     com_artifex_mupdf_fitz_PDFWidget
+ * Method:    signWithPFX
+ * Signature: ([B[B)V
+ */
+JNIEXPORT void JNICALL Java_com_artifex_mupdf_fitz_PDFWidget_signWithPFX
+  (JNIEnv *, jobject, jbyteArray, jbyteArray);
+
+/*
+ * Class:     com_artifex_mupdf_fitz_PDFWidget
+ * Method:    checkSignatureDigest
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_com_artifex_mupdf_fitz_PDFWidget_checkSignatureDigest
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     com_artifex_mupdf_fitz_PDFWidget
+ * Method:    checkSignatureCertificate
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_com_artifex_mupdf_fitz_PDFWidget_checkSignatureCertificate
+  (JNIEnv *, jobject);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/platform/java/src/com/artifex/mupdf/fitz/PDFAnnotation.java b/platform/java/src/com/artifex/mupdf/fitz/PDFAnnotation.java
index 4e45ed2..a7bdf04 100644
--- a/platform/java/src/com/artifex/mupdf/fitz/PDFAnnotation.java
+++ b/platform/java/src/com/artifex/mupdf/fitz/PDFAnnotation.java
@@ -115,12 +115,76 @@ public class PDFAnnotation
 		setLineEndingStyles(styles[0], styles[1]);
 	}
 
-	public native float[] getVertices();
-	public native void setVertices(float[] vertices);
-	public native float[][] getQuadPoints();
-	public native void setQuadPoints(float[][] quadPoints);
-	public native float[][] getInkList();
-	public native void setInkList(float[][] inkList);
+	public native int getQuadPointCount();
+	public native Quad getQuadPoint(int i);
+	public native void clearQuadPoints();
+	public native void addQuadPoint(Quad q);
+	public Quad[] getQuadPoints() {
+		int n = getQuadPointCount();
+		Quad[] list = new Quad[n];
+		for (int i = 0; i < n; ++i)
+			list[i] = getQuadPoint(i);
+		return list;
+	}
+	public void setQuadPoints(Quad[] quadPoints) {
+		clearQuadPoints();
+		for (Quad q : quadPoints)
+			addQuadPoint(q);
+	}
+
+	public native int getVertexCount();
+	public native Point getVertex(int i);
+	public native void clearVertices();
+	public native void addVertex(float x, float y);
+	public void addVertex(Point p) {
+		addVertex(p.x, p.y);
+	}
+	public Point[] getVertices() {
+		int n = getVertexCount();
+		Point[] list = new Point[n];
+		for (int i = 0; i < n; ++i)
+			list[i] = getVertex(i);
+		return list;
+	}
+	public void setVertices(Point[] vertices) {
+		clearVertices();
+		for (Point p : vertices)
+			addVertex(p);
+	}
+
+	public native int getInkListCount();
+	public native int getInkListStrokeCount(int i);
+	public native Point getInkListStrokeVertex(int i, int k);
+	public native void clearInkList();
+	public native void addInkListStroke();
+	public native void addInkListVertex(float x, float y);
+	public void addInkListVertex(Point p) {
+		addInkListVertex(p.x, p.y);
+	}
+	public void addInkList(Point[] stroke) {
+		addInkListStroke();
+		for (Point p : stroke)
+			addInkListVertex(p);
+	}
+	public void setInkList(Point[][] inkList) {
+		clearInkList();
+		for (Point[] stroke : inkList) {
+			addInkListStroke();
+			for (Point p : stroke)
+				addInkListVertex(p);
+		}
+	}
+	public Point[][] getInkList() {
+		int i, k, n, m = getInkListCount();
+		Point[][] list = new Point[m][];
+		for (i = 0; i < m; ++i) {
+			n = getInkListStrokeCount(i);
+			list[i] = new Point[n];
+			for (k = 0; k < n; ++k)
+				list[i][k] = getInkListStrokeVertex(i, k);
+		}
+		return list;
+	}
 
 	public native String getIcon();
 	public native void setIcon(String icon);
diff --git a/source/pdf/pdf-annot.c b/source/pdf/pdf-annot.c
index 4dfdf36..12e04cc 100644
--- a/source/pdf/pdf-annot.c
+++ b/source/pdf/pdf-annot.c
@@ -1172,11 +1172,12 @@ pdf_annot_quad_point_count(fz_context *ctx, pdf_annot *annot)
 	return pdf_array_len(ctx, quad_points) / 8;
 }
 
-void
-pdf_annot_quad_point(fz_context *ctx, pdf_annot *annot, int idx, float v[8])
+fz_quad
+pdf_annot_quad_point(fz_context *ctx, pdf_annot *annot, int idx)
 {
 	pdf_obj *quad_points;
 	fz_matrix page_ctm;
+	float v[8];
 	int i;
 
 	check_allowed_subtypes(ctx, annot, PDF_NAME(QuadPoints), quad_point_subtypes);
@@ -1192,35 +1193,38 @@ pdf_annot_quad_point(fz_context *ctx, pdf_annot *annot, int idx, float v[8])
 		v[i+0] = point.x;
 		v[i+1] = point.y;
 	}
+
+	return fz_make_quad(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]);
 }
 
 void
-pdf_set_annot_quad_points(fz_context *ctx, pdf_annot *annot, int n, const float *v)
+pdf_set_annot_quad_points(fz_context *ctx, pdf_annot *annot, int n, const fz_quad *q)
 {
 	pdf_document *doc = annot->page->doc;
 	fz_matrix page_ctm, inv_page_ctm;
 	pdf_obj *quad_points;
-	fz_point point;
-	int i, k;
+	fz_quad quad;
+	int i;
 
 	check_allowed_subtypes(ctx, annot, PDF_NAME(QuadPoints), quad_point_subtypes);
-	if (n <= 0 || !v)
+	if (n <= 0 || !q)
 		fz_throw(ctx, FZ_ERROR_GENERIC, "invalid number of quadrilaterals");
 
 	pdf_page_transform(ctx, annot->page, NULL, &page_ctm);
 	inv_page_ctm = fz_invert_matrix(page_ctm);
 
-	quad_points = pdf_new_array(ctx, doc, n * 8);
+	quad_points = pdf_new_array(ctx, doc, n);
 	for (i = 0; i < n; ++i)
 	{
-		for (k = 0; k < 4; ++k)
-		{
-			point.x = v[i * 8 + k * 2 + 0];
-			point.y = v[i * 8 + k * 2 + 1];
-			point = fz_transform_point(point, inv_page_ctm);
-			pdf_array_push_real(ctx, quad_points, point.x);
-			pdf_array_push_real(ctx, quad_points, point.y);
-		}
+		quad = fz_transform_quad(q[i], inv_page_ctm);
+		pdf_array_push_real(ctx, quad_points, quad.ul.x);
+		pdf_array_push_real(ctx, quad_points, quad.ul.y);
+		pdf_array_push_real(ctx, quad_points, quad.ur.x);
+		pdf_array_push_real(ctx, quad_points, quad.ur.y);
+		pdf_array_push_real(ctx, quad_points, quad.ll.x);
+		pdf_array_push_real(ctx, quad_points, quad.ll.y);
+		pdf_array_push_real(ctx, quad_points, quad.lr.x);
+		pdf_array_push_real(ctx, quad_points, quad.lr.y);
 	}
 	pdf_dict_put_drop(ctx, annot->obj, PDF_NAME(QuadPoints), quad_points);
 	pdf_dirty_annot(ctx, annot);
@@ -1356,11 +1360,39 @@ pdf_set_annot_ink_list(fz_context *ctx, pdf_annot *annot, int n, const int *coun
 void
 pdf_clear_annot_ink_list(fz_context *ctx, pdf_annot *annot)
 {
-	check_allowed_subtypes(ctx, annot, PDF_NAME(InkList), ink_list_subtypes);
 	pdf_dict_del(ctx, annot->obj, PDF_NAME(InkList));
 	pdf_dirty_annot(ctx, annot);
 }
 
+void pdf_add_annot_ink_list_stroke(fz_context *ctx, pdf_annot *annot)
+{
+	pdf_obj *ink_list;
+
+	ink_list = pdf_dict_get(ctx, annot->obj, PDF_NAME(InkList));
+	if (!pdf_is_array(ctx, ink_list))
+		ink_list = pdf_dict_put_array(ctx, annot->obj, PDF_NAME(InkList), 10);
+
+	pdf_array_push_array(ctx, ink_list, 16);
+
+	pdf_dirty_annot(ctx, annot);
+}
+
+void pdf_add_annot_ink_list_stroke_vertex(fz_context *ctx, pdf_annot *annot, fz_point p)
+{
+	fz_matrix page_ctm, inv_page_ctm;
+	pdf_obj *ink_list, *stroke;
+
+	pdf_page_transform(ctx, annot->page, NULL, &page_ctm);
+	inv_page_ctm = fz_invert_matrix(page_ctm);
+
+	ink_list = pdf_dict_get(ctx, annot->obj, PDF_NAME(InkList));
+	stroke = pdf_array_get(ctx, ink_list, pdf_array_len(ctx, ink_list)-1);
+
+	p = fz_transform_point(p, inv_page_ctm);
+	pdf_array_push_real(ctx, stroke, p.x);
+	pdf_array_push_real(ctx, stroke, p.y);
+}
+
 void
 pdf_add_annot_ink_list(fz_context *ctx, pdf_annot *annot, int n, fz_point p[])
 {
diff --git a/source/tools/murun.c b/source/tools/murun.c
index df0c913..b666353 100644
--- a/source/tools/murun.c
+++ b/source/tools/murun.c
@@ -424,6 +424,13 @@ static fz_point ffi_topoint(js_State *J, int idx)
 	return point;
 }
 
+static void ffi_pushpoint(js_State *J, fz_point point)
+{
+	js_newarray(J);
+	js_pushnumber(J, point.x); js_setindex(J, -2, 0);
+	js_pushnumber(J, point.y); js_setindex(J, -2, 1);
+}
+
 static fz_rect ffi_torect(js_State *J, int idx)
 {
 	fz_rect rect;
@@ -443,6 +450,20 @@ static void ffi_pushrect(js_State *J, fz_rect rect)
 	js_pushnumber(J, rect.y1); js_setindex(J, -2, 3);
 }
 
+static fz_quad ffi_toquad(js_State *J, int idx)
+{
+	fz_quad quad;
+	js_getindex(J, idx, 0); quad.ul.x = js_tonumber(J, -1); js_pop(J, 1);
+	js_getindex(J, idx, 1); quad.ul.y = js_tonumber(J, -1); js_pop(J, 1);
+	js_getindex(J, idx, 2); quad.ur.x = js_tonumber(J, -1); js_pop(J, 1);
+	js_getindex(J, idx, 3); quad.ur.y = js_tonumber(J, -1); js_pop(J, 1);
+	js_getindex(J, idx, 4); quad.ll.x = js_tonumber(J, -1); js_pop(J, 1);
+	js_getindex(J, idx, 5); quad.ll.y = js_tonumber(J, -1); js_pop(J, 1);
+	js_getindex(J, idx, 6); quad.lr.x = js_tonumber(J, -1); js_pop(J, 1);
+	js_getindex(J, idx, 7); quad.lr.y = js_tonumber(J, -1); js_pop(J, 1);
+	return quad;
+}
+
 static void ffi_pushquad(js_State *J, fz_quad quad)
 {
 	js_newarray(J);
@@ -4250,8 +4271,8 @@ static void ffi_PDFAnnotation_getQuadPoints(js_State *J)
 {
 	fz_context *ctx = js_getcontext(J);
 	pdf_annot *annot = js_touserdata(J, 0, "pdf_annot");
-	float qp[8] = { 0 };
-	int i, k, n = 0;
+	fz_quad q;
+	int i, n = 0;
 
 	fz_try(ctx)
 		n = pdf_annot_quad_point_count(ctx, annot);
@@ -4261,14 +4282,10 @@ static void ffi_PDFAnnotation_getQuadPoints(js_State *J)
 	js_newarray(J);
 	for (i = 0; i < n; ++i) {
 		fz_try(ctx)
-			pdf_annot_quad_point(ctx, annot, i, qp);
+			q = pdf_annot_quad_point(ctx, annot, i);
 		fz_catch(ctx)
 			rethrow(J);
-		js_newarray(J);
-		for (k = 0; k < 8; ++k) {
-			js_pushnumber(J, qp[k]);
-			js_setindex(J, -2, k);
-		}
+		ffi_pushquad(J, q);
 		js_setindex(J, -2, i);
 	}
 }
@@ -4277,23 +4294,19 @@ static void ffi_PDFAnnotation_setQuadPoints(js_State *J)
 {
 	fz_context *ctx = js_getcontext(J);
 	pdf_annot *annot = js_touserdata(J, 0, "pdf_annot");
-	float *qp = NULL;
-	int k, i, n;
+	fz_quad *qp = NULL;
+	int i, n;
 
 	n = js_getlength(J, 1);
 
 	fz_try(ctx)
-		qp = fz_malloc(ctx, n * 8 * sizeof *qp);
+		qp = fz_malloc_array(ctx, n, fz_quad);
 	fz_catch(ctx)
 		rethrow(J);
 
 	for (i = 0; i < n; ++i) {
 		js_getindex(J, 1, i);
-		for (k = 0; k < 8; ++k) {
-			js_getindex(J, -1, k);
-			qp[i * 8 + k] = js_tonumber(J, -1);
-			js_pop(J, 1);
-		}
+		qp[i] = ffi_toquad(J, -1);
 		js_pop(J, 1);
 	}
 
@@ -4305,6 +4318,101 @@ static void ffi_PDFAnnotation_setQuadPoints(js_State *J)
 		rethrow(J);
 }
 
+static void ffi_PDFAnnotation_clearQuadPoints(js_State *J)
+{
+	fz_context *ctx = js_getcontext(J);
+	pdf_annot *annot = js_touserdata(J, 0, "pdf_annot");
+
+	fz_try(ctx)
+		pdf_clear_annot_quad_points(ctx, annot);
+	fz_catch(ctx)
+		rethrow(J);
+}
+
+static void ffi_PDFAnnotation_addQuadPoint(js_State *J)
+{
+	fz_context *ctx = js_getcontext(J);
+	pdf_annot *annot = js_touserdata(J, 0, "pdf_annot");
+	fz_quad q = ffi_toquad(J, 1);
+
+	fz_try(ctx)
+		pdf_add_annot_quad_point(ctx, annot, q);
+	fz_catch(ctx)
+		rethrow(J);
+}
+
+static void ffi_PDFAnnotation_getVertices(js_State *J)
+{
+	fz_context *ctx = js_getcontext(J);
+	pdf_annot *annot = js_touserdata(J, 0, "pdf_annot");
+	fz_point p;
+	int i, n = 0;
+
+	fz_try(ctx)
+		n = pdf_annot_vertex_count(ctx, annot);
+	fz_catch(ctx)
+		rethrow(J);
+
+	js_newarray(J);
+	for (i = 0; i < n; ++i) {
+		fz_try(ctx)
+			p = pdf_annot_vertex(ctx, annot, i);
+		fz_catch(ctx)
+			rethrow(J);
+		ffi_pushpoint(J, p);
+		js_setindex(J, -2, i);
+	}
+}
+
+static void ffi_PDFAnnotation_setVertices(js_State *J)
+{
+	fz_context *ctx = js_getcontext(J);
+	pdf_annot *annot = js_touserdata(J, 0, "pdf_annot");
+	fz_point p;
+	int i, n;
+
+	n = js_getlength(J, 1);
+
+	fz_try(ctx)
+		pdf_clear_annot_vertices(ctx, annot);
+	fz_catch(ctx)
+		rethrow(J);
+
+	for (i = 0; i < n; ++i) {
+		js_getindex(J, 1, i);
+		p = ffi_topoint(J, -1);
+		js_pop(J, 1);
+
+		fz_try(ctx)
+			pdf_add_annot_vertex(ctx, annot, p);
+		fz_catch(ctx)
+			rethrow(J);
+	}
+}
+
+static void ffi_PDFAnnotation_clearVertices(js_State *J)
+{
+	fz_context *ctx = js_getcontext(J);
+	pdf_annot *annot = js_touserdata(J, 0, "pdf_annot");
+
+	fz_try(ctx)
+		pdf_clear_annot_vertices(ctx, annot);
+	fz_catch(ctx)
+		rethrow(J);
+}
+
+static void ffi_PDFAnnotation_addVertex(js_State *J)
+{
+	fz_context *ctx = js_getcontext(J);
+	pdf_annot *annot = js_touserdata(J, 0, "pdf_annot");
+	fz_point p = ffi_topoint(J, 1);
+
+	fz_try(ctx)
+		pdf_add_annot_vertex(ctx, annot, p);
+	fz_catch(ctx)
+		rethrow(J);
+}
+
 static void ffi_PDFAnnotation_getInkList(js_State *J)
 {
 	fz_context *ctx = js_getcontext(J);
@@ -4399,6 +4507,68 @@ static void ffi_PDFAnnotation_setInkList(js_State *J)
 		rethrow(J);
 }
 
+static void ffi_PDFAnnotation_clearInkList(js_State *J)
+{
+	fz_context *ctx = js_getcontext(J);
+	pdf_annot *annot = js_touserdata(J, 0, "pdf_annot");
+	fz_try(ctx)
+		pdf_clear_annot_ink_list(ctx, annot);
+	fz_catch(ctx)
+		rethrow(J);
+}
+
+static void ffi_PDFAnnotation_addInkList(js_State *J)
+{
+	fz_context *ctx = js_getcontext(J);
+	pdf_annot *annot = js_touserdata(J, 0, "pdf_annot");
+	int i, n;
+	float x, y;
+
+	n = js_getlength(J, 1);
+
+	fz_try(ctx)
+		pdf_add_annot_ink_list_stroke(ctx, annot);
+	fz_catch(ctx)
+		rethrow(J);
+
+	for (i = 0; i < n; i += 2) {
+		js_getindex(J, 1, i);
+		x = js_tonumber(J, -1);
+		js_pop(J, 1);
+
+		js_getindex(J, 1, i+1);
+		y = js_tonumber(J, -1);
+		js_pop(J, 1);
+
+		fz_try(ctx)
+			pdf_add_annot_ink_list_stroke_vertex(ctx, annot, fz_make_point(x, y));
+		fz_catch(ctx)
+			rethrow(J);
+	}
+}
+
+static void ffi_PDFAnnotation_addInkListStroke(js_State *J)
+{
+	fz_context *ctx = js_getcontext(J);
+	pdf_annot *annot = js_touserdata(J, 0, "pdf_annot");
+	fz_try(ctx)
+		pdf_add_annot_ink_list_stroke(ctx, annot);
+	fz_catch(ctx)
+		rethrow(J);
+}
+
+static void ffi_PDFAnnotation_addInkListStrokeVertex(js_State *J)
+{
+	fz_context *ctx = js_getcontext(J);
+	pdf_annot *annot = js_touserdata(J, 0, "pdf_annot");
+	float x = js_tonumber(J, 1);
+	float y = js_tonumber(J, 2);
+	fz_try(ctx)
+		pdf_add_annot_ink_list_stroke_vertex(ctx, annot, fz_make_point(x, y));
+	fz_catch(ctx)
+		rethrow(J);
+}
+
 static void ffi_PDFAnnotation_getAuthor(js_State *J)
 {
 	fz_context *ctx = js_getcontext(J);
@@ -5030,15 +5200,28 @@ int murun_main(int argc, char **argv)
 		jsB_propfun(J, "PDFAnnotation.setColor", ffi_PDFAnnotation_setColor, 1);
 		jsB_propfun(J, "PDFAnnotation.getInteriorColor", ffi_PDFAnnotation_getInteriorColor, 0);
 		jsB_propfun(J, "PDFAnnotation.setInteriorColor", ffi_PDFAnnotation_setInteriorColor, 1);
-		jsB_propfun(J, "PDFAnnotation.getQuadPoints", ffi_PDFAnnotation_getQuadPoints, 0);
-		jsB_propfun(J, "PDFAnnotation.setQuadPoints", ffi_PDFAnnotation_setQuadPoints, 1);
-		jsB_propfun(J, "PDFAnnotation.getInkList", ffi_PDFAnnotation_getInkList, 0);
-		jsB_propfun(J, "PDFAnnotation.setInkList", ffi_PDFAnnotation_setInkList, 1);
 		jsB_propfun(J, "PDFAnnotation.getAuthor", ffi_PDFAnnotation_getAuthor, 0);
 		jsB_propfun(J, "PDFAnnotation.setAuthor", ffi_PDFAnnotation_setAuthor, 1);
 		jsB_propfun(J, "PDFAnnotation.getModificationDate", ffi_PDFAnnotation_getModificationDate, 0);
 		jsB_propfun(J, "PDFAnnotation.setModificationDate", ffi_PDFAnnotation_setModificationDate, 0);
 
+		jsB_propfun(J, "PDFAnnotation.getInkList", ffi_PDFAnnotation_getInkList, 0);
+		jsB_propfun(J, "PDFAnnotation.setInkList", ffi_PDFAnnotation_setInkList, 1);
+		jsB_propfun(J, "PDFAnnotation.clearInkList", ffi_PDFAnnotation_clearInkList, 0);
+		jsB_propfun(J, "PDFAnnotation.addInkList", ffi_PDFAnnotation_addInkList, 1);
+		jsB_propfun(J, "PDFAnnotation.addInkListStroke", ffi_PDFAnnotation_addInkListStroke, 0);
+		jsB_propfun(J, "PDFAnnotation.addInkListStrokeVertex", ffi_PDFAnnotation_addInkListStrokeVertex, 2);
+
+		jsB_propfun(J, "PDFAnnotation.getQuadPoints", ffi_PDFAnnotation_getQuadPoints, 0);
+		jsB_propfun(J, "PDFAnnotation.setQuadPoints", ffi_PDFAnnotation_setQuadPoints, 1);
+		jsB_propfun(J, "PDFAnnotation.clearQuadPoints", ffi_PDFAnnotation_clearQuadPoints, 0);
+		jsB_propfun(J, "PDFAnnotation.addQuadPoint", ffi_PDFAnnotation_addQuadPoint, 1);
+
+		jsB_propfun(J, "PDFAnnotation.getVertices", ffi_PDFAnnotation_getVertices, 0);
+		jsB_propfun(J, "PDFAnnotation.setVertices", ffi_PDFAnnotation_setVertices, 1);
+		jsB_propfun(J, "PDFAnnotation.clearVertices", ffi_PDFAnnotation_clearVertices, 0);
+		jsB_propfun(J, "PDFAnnotation.addVertex", ffi_PDFAnnotation_addVertex, 2);
+
 		jsB_propfun(J, "PDFAnnotation.updateAppearance", ffi_PDFAnnotation_updateAppearance, 0);
 		jsB_propfun(J, "PDFAnnotation.update", ffi_PDFAnnotation_update, 0);
 	}

http://git.ghostscript.com/?p=mupdf.git;a=commit;h=32aa69e90ae2f51bdefa120e12a4c767f7cb9a0a

--
MuPDF library
Artifex Software, Inc.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.