summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mupdf/pdf/annot.h53
-rw-r--r--platform/android/viewer/jni/mupdf.c47
-rw-r--r--platform/ios/Classes/MuPageViewNormal.m36
-rw-r--r--resources/pdf/names.txt3
-rw-r--r--source/pdf/pdf-annot-edit.c383
-rw-r--r--source/pdf/pdf-annot.c58
-rw-r--r--source/tools/murun.c349
7 files changed, 742 insertions, 187 deletions
diff --git a/include/mupdf/pdf/annot.h b/include/mupdf/pdf/annot.h
index 8aeae76c..9cd80e06 100644
--- a/include/mupdf/pdf/annot.h
+++ b/include/mupdf/pdf/annot.h
@@ -30,6 +30,9 @@ typedef enum
PDF_ANNOT_3D
} fz_annot_type;
+const char *pdf_string_from_annot_type(fz_annot_type type);
+int pdf_annot_type_from_string(const char *subtype);
+
enum
{
PDF_ANNOT_IS_INVISIBLE = 1 << (1-1),
@@ -68,7 +71,7 @@ fz_rect *pdf_bound_annot(fz_context *ctx, pdf_annot *annot, fz_rect *rect);
/*
pdf_annot_type: Return the type of an annotation
*/
-fz_annot_type pdf_annot_type(fz_context *ctx, pdf_annot *annot);
+int pdf_annot_type(fz_context *ctx, pdf_annot *annot);
/*
pdf_run_annot: Interpret an annotation and render it on a device.
@@ -124,26 +127,48 @@ pdf_annot *pdf_create_annot(fz_context *ctx, pdf_page *page, fz_annot_type type)
*/
void pdf_delete_annot(fz_context *ctx, pdf_page *page, pdf_annot *annot);
-/*
- pdf_set_markup_annot_quadpoints: set the quadpoints for a text-markup annotation.
-*/
-void pdf_set_markup_annot_quadpoints(fz_context *ctx, pdf_document *doc, pdf_annot *annot, fz_point *qp, int n);
+int pdf_annot_flags(fz_context *ctx, pdf_annot *annot);
+void pdf_annot_rect(fz_context *ctx, pdf_annot *annot, fz_rect *rect);
+float pdf_annot_border(fz_context *ctx, pdf_annot *annot);
+void pdf_annot_color(fz_context *ctx, pdf_annot *annot, int *n, float color[4]);
+void pdf_annot_interior_color(fz_context *ctx, pdf_annot *annot, int *n, float color[4]);
-/*
- pdf_set_ink_annot_list: set the details of an ink annotation. All the points of the multiple arcs
- are carried in a single array, with the counts for each arc held in a secondary array.
-*/
-void pdf_set_ink_annot_list(fz_context *ctx, pdf_document *doc, pdf_annot *annot, fz_point *pts, int *counts, int ncount, float color[3], float thickness);
+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]);
+
+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);
+void pdf_annot_ink_list_stroke_vertex(fz_context *ctx, pdf_annot *annot, int i, int k, float v[2]);
+
+void pdf_set_annot_flags(fz_context *ctx, pdf_annot *annot, int flags);
+void pdf_set_annot_rect(fz_context *ctx, pdf_annot *annot, const fz_rect *rect);
+void pdf_set_annot_border(fz_context *ctx, pdf_annot *annot, float width);
+void pdf_set_annot_color(fz_context *ctx, pdf_annot *annot, int n, const float color[4]);
+void pdf_set_annot_interior_color(fz_context *ctx, pdf_annot *annot, int n, const float color[4]);
+void pdf_set_annot_quad_points(fz_context *ctx, pdf_annot *annot, int n, const float *v);
+void pdf_set_annot_ink_list(fz_context *ctx, pdf_annot *annot, int n, const int *count, const float *v);
+
+void pdf_set_annot_line_ending_styles(fz_context *ctx, pdf_annot *annot, int start_style, int end_style);
+void pdf_set_annot_vertices(fz_context *ctx, pdf_annot *annot, int n, const float *v);
+void pdf_set_annot_icon_name(fz_context *ctx, pdf_annot *annot, const char *name);
+void pdf_set_annot_is_open(fz_context *ctx, pdf_annot *annot, int is_open);
+
+void pdf_annot_line_ending_styles(fz_context *ctx, pdf_annot *annot, int *start_style, int *end_style);
+const char *pdf_annot_icon_name(fz_context *ctx, pdf_annot *annot);
+int pdf_annot_is_open(fz_context *ctx, pdf_annot *annot);
+
+int pdf_annot_vertex_count(fz_context *ctx, pdf_annot *annot);
+void pdf_annot_vertex(fz_context *ctx, pdf_annot *annot, int i, float v[2]);
/*
pdf_set_text_annot_position: set the position on page for a text (sticky note) annotation.
*/
-void pdf_set_text_annot_position(fz_context *ctx, pdf_document *doc, pdf_annot *annot, fz_point pt);
+void pdf_set_text_annot_position(fz_context *ctx, pdf_annot *annot, fz_point pt);
/*
pdf_set_annot_contents: set the contents of an annotation.
*/
-void pdf_set_annot_contents(fz_context *ctx, pdf_document *doc, pdf_annot *annot, char *text);
+void pdf_set_annot_contents(fz_context *ctx, pdf_annot *annot, const char *text);
/*
pdf_annot_contents: return the contents of an annotation.
@@ -158,6 +183,8 @@ const char *pdf_annot_author(fz_context *ctx, pdf_annot *annot);
/*
pdf_annot_author: return the date of an annotation.
*/
+// TODO: creation date
+// TODO: modification date
const char *pdf_annot_date(fz_context *ctx, pdf_annot *annot);
/*
@@ -169,7 +196,7 @@ pdf_obj *pdf_annot_irt(fz_context *ctx, pdf_annot *annot);
pdf_set_free_text_details: set the position, text, font and color for a free text annotation.
Only base 14 fonts are supported and are specified by name.
*/
-void pdf_set_free_text_details(fz_context *ctx, pdf_document *doc, pdf_annot *annot, fz_point *pos, char *text, char *font_name, float font_size, float color[3]);
+void pdf_set_free_text_details(fz_context *ctx, pdf_annot *annot, fz_point *pos, char *text, char *font_name, float font_size, float color[3]);
/*
pdf_new_annot: Internal function for creating a new pdf annotation.
diff --git a/platform/android/viewer/jni/mupdf.c b/platform/android/viewer/jni/mupdf.c
index 96dc36df..9f26651b 100644
--- a/platform/android/viewer/jni/mupdf.c
+++ b/platform/android/viewer/jni/mupdf.c
@@ -1541,7 +1541,7 @@ JNI_FN(MuPDFCore_addMarkupAnnotationInternal)(JNIEnv * env, jobject thiz, jobjec
jclass pt_cls;
jfieldID x_fid, y_fid;
int i, n;
- fz_point *pts = NULL;
+ float *pts = NULL;
float color[3];
float alpha;
float line_height;
@@ -1598,19 +1598,22 @@ JNI_FN(MuPDFCore_addMarkupAnnotationInternal)(JNIEnv * env, jobject thiz, jobjec
n = (*env)->GetArrayLength(env, points);
- pts = fz_malloc_array(ctx, n, sizeof(fz_point));
+ pts = fz_malloc_array(ctx, n * 2, sizeof(float));
for (i = 0; i < n; i++)
{
+ fz_point pt;
jobject opt = (*env)->GetObjectArrayElement(env, points, i);
- pts[i].x = opt ? (*env)->GetFloatField(env, opt, x_fid) : 0.0f;
- pts[i].y = opt ? (*env)->GetFloatField(env, opt, y_fid) : 0.0f;
- fz_transform_point(&pts[i], &ctm);
+ pt.x = opt ? (*env)->GetFloatField(env, opt, x_fid) : 0.0f;
+ pt.y = opt ? (*env)->GetFloatField(env, opt, y_fid) : 0.0f;
+ fz_transform_point(&pt, &ctm);
+ pts[i*2+0] = pt.x;
+ pts[i*2+1] = pt.y;
}
- annot = (fz_annot *)pdf_create_annot(ctx, idoc, (pdf_page *)pc->page, type);
+ annot = (fz_annot *)pdf_create_annot(ctx, (pdf_page *)pc->page, type);
- pdf_set_markup_annot_quadpoints(ctx, idoc, (pdf_annot *)annot, pts, n);
+ pdf_set_annot_quad_points(ctx, (pdf_annot *)annot, n / 4, pts);
pdf_set_markup_appearance(ctx, idoc, (pdf_annot *)annot, color, alpha, line_thickness, line_height);
dump_annotation_display_lists(glo);
@@ -1640,10 +1643,10 @@ JNI_FN(MuPDFCore_addInkAnnotationInternal)(JNIEnv * env, jobject thiz, jobjectAr
jclass pt_cls;
jfieldID x_fid, y_fid;
int i, j, k, n;
- fz_point *pts = NULL;
+ float *pts = NULL;
int *counts = NULL;
int total = 0;
- float color[3];
+ float color[4];
if (idoc == NULL)
return;
@@ -1651,12 +1654,13 @@ JNI_FN(MuPDFCore_addInkAnnotationInternal)(JNIEnv * env, jobject thiz, jobjectAr
color[0] = 1.0;
color[1] = 0.0;
color[2] = 0.0;
+ color[3] = 0.0;
fz_var(pts);
fz_var(counts);
fz_try(ctx)
{
- fz_annot *annot;
+ pdf_annot *annot;
fz_matrix ctm;
float zoom = glo->resolution / 72;
@@ -1682,7 +1686,7 @@ JNI_FN(MuPDFCore_addInkAnnotationInternal)(JNIEnv * env, jobject thiz, jobjectAr
total += count;
}
- pts = fz_malloc_array(ctx, total, sizeof(fz_point));
+ pts = fz_malloc_array(ctx, total * 2, sizeof(float));
k = 0;
for (i = 0; i < n; i++)
@@ -1692,20 +1696,23 @@ JNI_FN(MuPDFCore_addInkAnnotationInternal)(JNIEnv * env, jobject thiz, jobjectAr
for (j = 0; j < count; j++)
{
- jobject pt = (*env)->GetObjectArrayElement(env, arc, j);
-
- pts[k].x = pt ? (*env)->GetFloatField(env, pt, x_fid) : 0.0f;
- pts[k].y = pt ? (*env)->GetFloatField(env, pt, y_fid) : 0.0f;
- (*env)->DeleteLocalRef(env, pt);
- fz_transform_point(&pts[k], &ctm);
- k++;
+ jobject jpt = (*env)->GetObjectArrayElement(env, arc, j);
+ fz_point pt;
+ pt.x = jpt ? (*env)->GetFloatField(env, jpt, x_fid) : 0.0f;
+ pt.y = jpt ? (*env)->GetFloatField(env, jpt, y_fid) : 0.0f;
+ (*env)->DeleteLocalRef(env, jpt);
+ fz_transform_point(&pt, &ctm);
+ pts[k++] = pt.x;
+ pts[k++] = pt.y;
}
(*env)->DeleteLocalRef(env, arc);
}
- annot = (fz_annot *)pdf_create_annot(ctx, idoc, (pdf_page *)pc->page, PDF_ANNOT_INK);
+ annot = pdf_create_annot(ctx, (pdf_page *)pc->page, PDF_ANNOT_INK);
- pdf_set_ink_annot_list(ctx, idoc, (pdf_annot *)annot, pts, counts, n, color, INK_THICKNESS);
+ pdf_set_annot_border(ctx, annot, INK_THICKNESS);
+ pdf_set_annot_color(ctx, annot, 3, color);
+ pdf_set_annot_ink_list(ctx, annot, n, counts, pts);
dump_annotation_display_lists(glo);
}
diff --git a/platform/ios/Classes/MuPageViewNormal.m b/platform/ios/Classes/MuPageViewNormal.m
index f5afdcee..08f38786 100644
--- a/platform/ios/Classes/MuPageViewNormal.m
+++ b/platform/ios/Classes/MuPageViewNormal.m
@@ -203,7 +203,7 @@ static void addMarkupAnnot(fz_document *doc, fz_page *page, int type, NSArray *r
int i;
pdf_annot *annot;
- quadpts = fz_malloc_array(ctx, (int)rects.count * 4, sizeof(fz_point));
+ quadpts = fz_malloc_array(ctx, (int)rects.count * 8, sizeof(float));
for (i = 0; i < rects.count; i++)
{
CGRect rect = [rects[i] CGRectValue];
@@ -211,18 +211,18 @@ static void addMarkupAnnot(fz_document *doc, fz_page *page, int type, NSArray *r
float bot = top + rect.size.height;
float left = rect.origin.x;
float right = left + rect.size.width;
- quadpts[i*4].x = left;
- quadpts[i*4].y = bot;
- quadpts[i*4+1].x = right;
- quadpts[i*4+1].y = bot;
- quadpts[i*4+2].x = right;
- quadpts[i*4+2].y = top;
- quadpts[i*4+3].x = left;
- quadpts[i*4+3].y = top;
+ quadpts[i*8+0] = left;
+ quadpts[i*8+1] = bot;
+ quadpts[i*8+2] = right;
+ quadpts[i*8+3] = bot;
+ quadpts[i*8+4] = right;
+ quadpts[i*8+5] = top;
+ quadpts[i*8+6] = left;
+ quadpts[i*8+7] = top;
}
annot = pdf_create_annot(ctx, idoc, (pdf_page *)page, type);
- pdf_set_markup_annot_quadpoints(ctx, idoc, annot, quadpts, (int)rects.count*4);
+ pdf_set_annot_quad_points(ctx, idoc, annot, rects.count, quadpts);
pdf_set_markup_appearance(ctx, idoc, annot, color, alpha, line_thickness, line_height);
}
fz_always(ctx)
@@ -238,10 +238,10 @@ static void addMarkupAnnot(fz_document *doc, fz_page *page, int type, NSArray *r
static void addInkAnnot(fz_document *doc, fz_page *page, NSArray *curves)
{
pdf_document *idoc;
- fz_point *pts = NULL;
+ float *pts = NULL;
int *counts = NULL;
int total;
- float color[3] = {1.0, 0.0, 0.0};
+ float color[4] = {1.0, 0.0, 0.0, 0.0};
idoc = pdf_specifics(ctx, doc);
if (!idoc)
@@ -266,7 +266,7 @@ static void addInkAnnot(fz_document *doc, fz_page *page, NSArray *curves)
total += (int)curve.count;
}
- pts = fz_malloc_array(ctx, total, sizeof(fz_point));
+ pts = fz_malloc_array(ctx, total * 2, sizeof(float));
k = 0;
for (i = 0; i < n; i++)
@@ -277,14 +277,16 @@ static void addInkAnnot(fz_document *doc, fz_page *page, NSArray *curves)
for (j = 0; j < count; j++)
{
CGPoint pt = [curve[j] CGPointValue];
- pts[k].x = pt.x;
- pts[k].y = pt.y;
- k++;
+ pts[k++] = pt.x;
+ pts[k++] = pt.y;
}
}
annot = pdf_create_annot(ctx, idoc, (pdf_page *)page, PDF_ANNOT_INK);
- pdf_set_ink_annot_list(ctx, idoc, annot, pts, counts, n, color, INK_THICKNESS);
+
+ pdf_set_annot_border(ctx, annot, INK_THICKNESS);
+ pdf_set_annot_color(ctx, annot, 3, color);
+ pdf_set_annot_ink_list(ctx, annot, ncount, counts, pts);
}
fz_always(ctx)
{
diff --git a/resources/pdf/names.txt b/resources/pdf/names.txt
index ff91055b..57228c15 100644
--- a/resources/pdf/names.txt
+++ b/resources/pdf/names.txt
@@ -23,6 +23,7 @@ Ascent
B
BBox
BC
+BE
BG
BM
BPC
@@ -38,6 +39,7 @@ BitsPerSample
BlackIs1
BleedBox
Blinds
+Border
Bounds
Box
Bt
@@ -167,6 +169,7 @@ H
Height
Highlight
I
+IC
ICCBased
ID
IM
diff --git a/source/pdf/pdf-annot-edit.c b/source/pdf/pdf-annot-edit.c
index 63a05e1c..5dbe77ca 100644
--- a/source/pdf/pdf-annot-edit.c
+++ b/source/pdf/pdf-annot-edit.c
@@ -2,7 +2,7 @@
#define TEXT_ANNOT_SIZE (25.0)
-static const char *annot_type_str(fz_annot_type type)
+const char *pdf_string_from_annot_type(fz_annot_type type)
{
switch (type)
{
@@ -31,10 +31,40 @@ static const char *annot_type_str(fz_annot_type type)
case PDF_ANNOT_TRAP_NET: return "TrapNet";
case PDF_ANNOT_WATERMARK: return "Watermark";
case PDF_ANNOT_3D: return "3D";
- default: return "";
+ default: return "Unknown";
}
}
+int pdf_annot_type_from_string(const char *subtype)
+{
+ if (!strcmp("Text", subtype)) return PDF_ANNOT_TEXT;
+ if (!strcmp("Link", subtype)) return PDF_ANNOT_LINK;
+ if (!strcmp("FreeText", subtype)) return PDF_ANNOT_FREE_TEXT;
+ if (!strcmp("Line", subtype)) return PDF_ANNOT_LINE;
+ if (!strcmp("Square", subtype)) return PDF_ANNOT_SQUARE;
+ if (!strcmp("Circle", subtype)) return PDF_ANNOT_CIRCLE;
+ if (!strcmp("Polygon", subtype)) return PDF_ANNOT_POLYGON;
+ if (!strcmp("PolyLine", subtype)) return PDF_ANNOT_POLY_LINE;
+ if (!strcmp("Highlight", subtype)) return PDF_ANNOT_HIGHLIGHT;
+ if (!strcmp("Underline", subtype)) return PDF_ANNOT_UNDERLINE;
+ if (!strcmp("Squiggly", subtype)) return PDF_ANNOT_SQUIGGLY;
+ if (!strcmp("StrikeOut", subtype)) return PDF_ANNOT_STRIKE_OUT;
+ if (!strcmp("Stamp", subtype)) return PDF_ANNOT_STAMP;
+ if (!strcmp("Caret", subtype)) return PDF_ANNOT_CARET;
+ if (!strcmp("Ink", subtype)) return PDF_ANNOT_INK;
+ if (!strcmp("Popup", subtype)) return PDF_ANNOT_POPUP;
+ if (!strcmp("FileAttachment", subtype)) return PDF_ANNOT_FILE_ATTACHMENT;
+ if (!strcmp("Sound", subtype)) return PDF_ANNOT_SOUND;
+ if (!strcmp("Movie", subtype)) return PDF_ANNOT_MOVIE;
+ if (!strcmp("Widget", subtype)) return PDF_ANNOT_WIDGET;
+ if (!strcmp("Screen", subtype)) return PDF_ANNOT_SCREEN;
+ if (!strcmp("PrinterMark", subtype)) return PDF_ANNOT_PRINTER_MARK;
+ if (!strcmp("TrapNet", subtype)) return PDF_ANNOT_TRAP_NET;
+ if (!strcmp("Watermark", subtype)) return PDF_ANNOT_WATERMARK;
+ if (!strcmp("3D", subtype)) return PDF_ANNOT_3D;
+ return -1;
+}
+
pdf_annot *
pdf_create_annot(fz_context *ctx, pdf_page *page, fz_annot_type type)
{
@@ -49,7 +79,7 @@ pdf_create_annot(fz_context *ctx, pdf_page *page, fz_annot_type type)
{
int ind_obj_num;
fz_rect rect = {0.0, 0.0, 0.0, 0.0};
- const char *type_str = annot_type_str(type);
+ const char *type_str = pdf_string_from_annot_type(type);
pdf_obj *annot_arr = pdf_dict_get(ctx, page->obj, PDF_NAME_Annots);
if (annot_arr == NULL)
{
@@ -158,97 +188,300 @@ pdf_delete_annot(fz_context *ctx, pdf_page *page, pdf_annot *annot)
doc->dirty = 1;
}
+int
+pdf_annot_type(fz_context *ctx, pdf_annot *annot)
+{
+ pdf_obj *obj = annot->obj;
+ pdf_obj *subtype = pdf_dict_get(ctx, obj, PDF_NAME_Subtype);
+ return pdf_annot_type_from_string(pdf_to_name(ctx, subtype));
+}
+
+int
+pdf_annot_flags(fz_context *ctx, pdf_annot *annot)
+{
+ return pdf_to_int(ctx, pdf_dict_get(ctx, annot->obj, PDF_NAME_F));
+}
+
void
-pdf_set_markup_annot_quadpoints(fz_context *ctx, pdf_document *doc, pdf_annot *annot, fz_point *qp, int n)
+pdf_set_annot_flags(fz_context *ctx, pdf_annot *annot, int flags)
{
- pdf_obj *arr = pdf_new_array(ctx, doc, n*2);
+ pdf_document *doc = annot->page->doc;
+ pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_F, pdf_new_int(ctx, doc, flags));
+ annot->changed = 1;
+}
+
+void
+pdf_annot_rect(fz_context *ctx, pdf_annot *annot, fz_rect *rect)
+{
+ fz_matrix page_ctm;
+ pdf_page_transform(ctx, annot->page, NULL, &page_ctm);
+ pdf_to_rect(ctx, pdf_dict_get(ctx, annot->obj, PDF_NAME_Rect), rect);
+ fz_transform_rect(rect, &page_ctm);
+}
+
+void
+pdf_set_annot_rect(fz_context *ctx, pdf_annot *annot, const fz_rect *rect)
+{
+ pdf_document *doc = annot->page->doc;
+ fz_rect trect = *rect;
fz_matrix page_ctm, inv_page_ctm;
- int i;
pdf_page_transform(ctx, annot->page, NULL, &page_ctm);
fz_invert_matrix(&inv_page_ctm, &page_ctm);
+ fz_transform_rect(&trect, &inv_page_ctm);
+
+ pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_Rect, pdf_new_rect(ctx, doc, &trect));
+ annot->changed = 1;
+}
+
+const char *pdf_annot_contents(fz_context *ctx, pdf_annot *annot)
+{
+ return pdf_to_str_buf(ctx, pdf_dict_get(ctx, annot->obj, PDF_NAME_Contents));
+}
+
+void pdf_set_annot_contents(fz_context *ctx, pdf_annot *annot, const char *text)
+{
+ pdf_document *doc = annot->page->doc;
+ pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_Contents, pdf_new_string(ctx, doc, text, strlen(text)));
+ annot->changed = 1;
+}
- pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_QuadPoints, arr);
+float
+pdf_annot_border(fz_context *ctx, pdf_annot *annot)
+{
+ pdf_obj *border = pdf_dict_get(ctx, annot->obj, PDF_NAME_Border);
+ if (pdf_is_array(ctx, border))
+ return pdf_to_real(ctx, pdf_array_get(ctx, border, 2));
+ return 1;
+}
- for (i = 0; i < n; i++)
+void
+pdf_set_annot_border(fz_context *ctx, pdf_annot *annot, float w)
+{
+ pdf_document *doc = annot->page->doc;
+ pdf_obj *border = pdf_dict_get(ctx, annot->obj, PDF_NAME_Border);
+ if (pdf_is_array(ctx, border))
+ pdf_array_put_drop(ctx, border, 2, pdf_new_real(ctx, doc, w));
+ else
{
- fz_point pt = qp[i];
- pdf_obj *r;
-
- fz_transform_point(&pt, &inv_page_ctm);
- r = pdf_new_real(ctx, doc, pt.x);
- pdf_array_push_drop(ctx, arr, r);
- r = pdf_new_real(ctx, doc, pt.y);
- pdf_array_push_drop(ctx, arr, r);
+ border = pdf_new_array(ctx, doc, 3);
+ pdf_array_push_drop(ctx, border, pdf_new_real(ctx, doc, 0));
+ pdf_array_push_drop(ctx, border, pdf_new_real(ctx, doc, 0));
+ pdf_array_push_drop(ctx, border, pdf_new_real(ctx, doc, w));
+ pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_Border, border);
}
+
+ /* Remove border style and effect dictionaries so they won't interfere. */
+ pdf_dict_del(ctx, annot->obj, PDF_NAME_BS);
+ pdf_dict_del(ctx, annot->obj, PDF_NAME_BE);
+
+ annot->changed = 1;
+}
+
+static void
+pdf_annot_color_imp(fz_context *ctx, pdf_annot *annot, pdf_obj *key, int *n, float color[4])
+{
+ pdf_obj *obj = pdf_dict_get(ctx, annot->obj, key);
+ *n = 0;
+ if (pdf_is_array(ctx, obj))
+ {
+ switch (pdf_array_len(ctx, obj))
+ {
+ case 1:
+ *n = 1;
+ color[0] = pdf_to_real(ctx, pdf_array_get(ctx, obj, 0));
+ break;
+ case 3:
+ *n = 3;
+ color[0] = pdf_to_real(ctx, pdf_array_get(ctx, obj, 0));
+ color[1] = pdf_to_real(ctx, pdf_array_get(ctx, obj, 1));
+ color[2] = pdf_to_real(ctx, pdf_array_get(ctx, obj, 2));
+ break;
+ case 4:
+ *n = 4;
+ color[0] = pdf_to_real(ctx, pdf_array_get(ctx, obj, 0));
+ color[1] = pdf_to_real(ctx, pdf_array_get(ctx, obj, 1));
+ color[2] = pdf_to_real(ctx, pdf_array_get(ctx, obj, 2));
+ color[3] = pdf_to_real(ctx, pdf_array_get(ctx, obj, 3));
+ break;
+ }
+ }
+}
+
+static void
+pdf_set_annot_color_imp(fz_context *ctx, pdf_annot *annot, pdf_obj *key, int n, const float color[4])
+{
+ pdf_document *doc = annot->page->doc;
+ pdf_obj *obj = pdf_new_array(ctx, doc, 4);
+ switch (n)
+ {
+ default:
+ case 0:
+ break;
+ case 1:
+ pdf_array_push_drop(ctx, obj, pdf_new_real(ctx, doc, color[0]));
+ break;
+ case 3:
+ pdf_array_push_drop(ctx, obj, pdf_new_real(ctx, doc, color[0]));
+ pdf_array_push_drop(ctx, obj, pdf_new_real(ctx, doc, color[1]));
+ pdf_array_push_drop(ctx, obj, pdf_new_real(ctx, doc, color[2]));
+ break;
+ case 4:
+ pdf_array_push_drop(ctx, obj, pdf_new_real(ctx, doc, color[0]));
+ pdf_array_push_drop(ctx, obj, pdf_new_real(ctx, doc, color[1]));
+ pdf_array_push_drop(ctx, obj, pdf_new_real(ctx, doc, color[2]));
+ pdf_array_push_drop(ctx, obj, pdf_new_real(ctx, doc, color[3]));
+ break;
+ }
+ pdf_dict_put_drop(ctx, annot->obj, key, obj);
+ annot->changed = 1;
}
void
-pdf_set_ink_annot_list(fz_context *ctx, pdf_document *doc, pdf_annot *annot, fz_point *pts, int *counts, int ncount, float color[3], float thickness)
+pdf_annot_color(fz_context *ctx, pdf_annot *annot, int *n, float color[4])
{
- pdf_obj *list = pdf_new_array(ctx, doc, ncount);
- fz_matrix page_ctm, inv_page_ctm;
- pdf_obj *bs, *col;
- fz_rect rect;
- int i, k = 0;
+ pdf_annot_color_imp(ctx, annot, PDF_NAME_C, n, color);
+}
- pdf_page_transform(ctx, annot->page, NULL, &page_ctm);
- fz_invert_matrix(&inv_page_ctm, &page_ctm);
+void
+pdf_set_annot_color(fz_context *ctx, pdf_annot *annot, int n, const float color[4])
+{
+ pdf_set_annot_color_imp(ctx, annot, PDF_NAME_C, n, color);
+}
- pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_InkList, list);
+void
+pdf_annot_interior_color(fz_context *ctx, pdf_annot *annot, int *n, float color[4])
+{
+ // TODO: check annot type
+ pdf_annot_color_imp(ctx, annot, PDF_NAME_IC, n, color);
+}
- for (i = 0; i < ncount; i++)
+void
+pdf_set_annot_interior_color(fz_context *ctx, pdf_annot *annot, int n, const float color[4])
+{
+ // TODO: check annot type
+ pdf_set_annot_color_imp(ctx, annot, PDF_NAME_IC, n, color);
+}
+
+
+int pdf_annot_quad_point_count(fz_context *ctx, pdf_annot *annot)
+{
+ pdf_obj *quad_points = pdf_dict_get(ctx, annot->obj, PDF_NAME_QuadPoints);
+ return pdf_array_len(ctx, quad_points);
+}
+
+void pdf_annot_quad_point(fz_context *ctx, pdf_annot *annot, int idx, float v[8])
+{
+ pdf_obj *quad_points = pdf_dict_get(ctx, annot->obj, PDF_NAME_QuadPoints);
+ pdf_obj *quad_point = pdf_array_get(ctx, quad_points, idx);
+ fz_matrix page_ctm;
+ int i;
+
+ pdf_page_transform(ctx, annot->page, NULL, &page_ctm);
+
+ for (i = 0; i < 8; i += 2)
{
- int j;
- pdf_obj *arc = pdf_new_array(ctx, doc, counts[i]);
+ fz_point point;
+ point.x = pdf_to_real(ctx, pdf_array_get(ctx, quad_point, i+0));
+ point.y = pdf_to_real(ctx, pdf_array_get(ctx, quad_point, i+1));
+ fz_transform_point(&point, &page_ctm);
+ v[i+0] = point.x;
+ v[i+1] = point.y;
+ }
+}
+
+void
+pdf_set_annot_quad_points(fz_context *ctx, pdf_annot *annot, int n, const float *v)
+{
+ pdf_document *doc = annot->page->doc;
+ fz_matrix page_ctm, inv_page_ctm;
+ pdf_obj *quad_points;
+ fz_point point;
+ int i, k;
- pdf_array_push_drop(ctx, list, arc);
+ // TODO: check annot type
+
+ pdf_page_transform(ctx, annot->page, NULL, &page_ctm);
+ fz_invert_matrix(&inv_page_ctm, &page_ctm);
- for (j = 0; j < counts[i]; j++)
+ quad_points = pdf_new_array(ctx, doc, n * 8);
+ for (i = 0; i < n; ++i)
+ {
+ for (k = 0; k < 4; ++k)
{
- fz_point pt = pts[k];
-
- fz_transform_point(&pt, &inv_page_ctm);
-
- if (i == 0 && j == 0)
- {
- rect.x0 = rect.x1 = pt.x;
- rect.y0 = rect.y1 = pt.y;
- }
- else
- {
- fz_include_point_in_rect(&rect, &pt);
- }
-
- pdf_array_push_drop(ctx, arc, pdf_new_real(ctx, doc, pt.x));
- pdf_array_push_drop(ctx, arc, pdf_new_real(ctx, doc, pt.y));
- k++;
+ point.x = v[i * 8 + k * 2 + 0];
+ point.y = v[i * 8 + k * 2 + 1];
+ fz_transform_point(&point, &inv_page_ctm);
+ pdf_array_push_drop(ctx, quad_points, pdf_new_real(ctx, doc, point.x));
+ pdf_array_push_drop(ctx, quad_points, pdf_new_real(ctx, doc, point.y));
}
}
+ pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_QuadPoints, quad_points);
+ annot->changed = 1;
+}
- /*
- Expand the rectangle by thickness all around. We cannot use
- fz_expand_rect because the rectangle might be empty in the
- single point case
- */
- if (k > 0)
- {
- rect.x0 -= thickness;
- rect.y0 -= thickness;
- rect.x1 += thickness;
- rect.y1 += thickness;
- }
+int pdf_annot_ink_list_count(fz_context *ctx, pdf_annot *annot)
+{
+ pdf_obj *ink_list = pdf_dict_get(ctx, annot->obj, PDF_NAME_InkList);
+ return pdf_array_len(ctx, ink_list);
+}
- pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_Rect, pdf_new_rect(ctx, doc, &rect));
+int pdf_annot_ink_list_stroke_count(fz_context *ctx, pdf_annot *annot, int i)
+{
+ pdf_obj *ink_list = pdf_dict_get(ctx, annot->obj, PDF_NAME_InkList);
+ pdf_obj *stroke = pdf_array_get(ctx, ink_list, i);
+ return pdf_array_len(ctx, stroke);
+}
+
+void pdf_annot_ink_list_stroke_vertex(fz_context *ctx, pdf_annot *annot, int i, int k, float v[2])
+{
+ pdf_obj *ink_list = pdf_dict_get(ctx, annot->obj, PDF_NAME_InkList);
+ pdf_obj *stroke = pdf_array_get(ctx, ink_list, i);
+ fz_matrix page_ctm;
+ fz_point point;
+
+ pdf_page_transform(ctx, annot->page, NULL, &page_ctm);
+
+ point.x = pdf_to_real(ctx, pdf_array_get(ctx, stroke, k * 2 + 0));
+ point.y = pdf_to_real(ctx, pdf_array_get(ctx, stroke, k * 2 + 1));
+ fz_transform_point(&point, &page_ctm);
+ v[0] = point.x;
+ v[1] = point.y;
+}
+
+void
+pdf_set_annot_ink_list(fz_context *ctx, pdf_annot *annot, int n, const int *count, const float *v)
+{
+ pdf_document *doc = annot->page->doc;
+ fz_matrix page_ctm, inv_page_ctm;
+ pdf_obj *ink_list, *stroke;
+ fz_point point;
+ int i, k;
+
+ if (pdf_annot_type(ctx, annot) != PDF_ANNOT_INK)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "cannot set InkList on non-ink annotations");
+
+ pdf_page_transform(ctx, annot->page, NULL, &page_ctm);
+ fz_invert_matrix(&inv_page_ctm, &page_ctm);
- bs = pdf_new_dict(ctx, doc, 1);
- pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_BS, bs);
- pdf_dict_put_drop(ctx, bs, PDF_NAME_W, pdf_new_real(ctx, doc, thickness));
+ // TODO: update Rect (in update appearance perhaps?)
- col = pdf_new_array(ctx, doc, 3);
- pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_C, col);
- for (i = 0; i < 3; i++)
- pdf_array_push_drop(ctx, col, pdf_new_real(ctx, doc, color[i]));
+ ink_list = pdf_new_array(ctx, doc, n);
+ for (i = 0; i < n; ++i)
+ {
+ stroke = pdf_new_array(ctx, doc, count[i]);
+ for (k = 0; k < count[i]; ++k)
+ {
+ point.x = *v++;
+ point.y = *v++;
+ fz_transform_point(&point, &inv_page_ctm);
+ pdf_array_push_drop(ctx, stroke, pdf_new_real(ctx, doc, point.x));
+ pdf_array_push_drop(ctx, stroke, pdf_new_real(ctx, doc, point.y));
+ }
+ pdf_array_push_drop(ctx, ink_list, stroke);
+ }
+ pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_InkList, ink_list);
+ annot->changed = 1;
}
static void find_free_font_name(fz_context *ctx, pdf_obj *fdict, char *buf, int buf_size)
@@ -265,8 +498,9 @@ static void find_free_font_name(fz_context *ctx, pdf_obj *fdict, char *buf, int
}
}
-void pdf_set_text_annot_position(fz_context *ctx, pdf_document *doc, pdf_annot *annot, fz_point pt)
+void pdf_set_text_annot_position(fz_context *ctx, pdf_annot *annot, fz_point pt)
{
+ pdf_document *doc = annot->page->doc;
fz_matrix page_ctm, inv_page_ctm;
fz_rect rect;
int flags;
@@ -287,16 +521,6 @@ void pdf_set_text_annot_position(fz_context *ctx, pdf_document *doc, pdf_annot *
pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_F, pdf_new_int(ctx, doc, flags));
}
-void pdf_set_annot_contents(fz_context *ctx, pdf_document *doc, pdf_annot *annot, char *text)
-{
- pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_Contents, pdf_new_string(ctx, doc, text, strlen(text)));
-}
-
-const char *pdf_annot_contents(fz_context *ctx, pdf_annot *annot)
-{
- return pdf_to_str_buf(ctx, pdf_dict_get(ctx, annot->obj, PDF_NAME_Contents));
-}
-
const char *pdf_annot_author(fz_context *ctx, pdf_annot *annot)
{
return pdf_to_str_buf(ctx, pdf_dict_get(ctx, annot->obj, PDF_NAME_T));
@@ -313,8 +537,9 @@ pdf_obj *pdf_annot_irt(fz_context *ctx, pdf_annot *annot)
return pdf_dict_get(ctx, annot->obj, PDF_NAME_IRT);
}
-void pdf_set_free_text_details(fz_context *ctx, pdf_document *doc, pdf_annot *annot, fz_point *pos, char *text, char *font_name, float font_size, float color[3])
+void pdf_set_free_text_details(fz_context *ctx, pdf_annot *annot, fz_point *pos, char *text, char *font_name, float font_size, float color[3])
{
+ pdf_document *doc = annot->page->doc;
char nbuf[32];
pdf_obj *dr;
pdf_obj *form_fonts;
diff --git a/source/pdf/pdf-annot.c b/source/pdf/pdf-annot.c
index ae6bd907..f14cd79c 100644
--- a/source/pdf/pdf-annot.c
+++ b/source/pdf/pdf-annot.c
@@ -429,64 +429,6 @@ pdf_annot_transform(fz_context *ctx, pdf_annot *annot, fz_matrix *annot_ctm)
fz_pre_scale(fz_translate(annot_ctm, x, y), w, h);
}
-fz_annot_type pdf_annot_type(fz_context *ctx, pdf_annot *annot)
-{
- pdf_obj *obj = annot->obj;
- pdf_obj *subtype = pdf_dict_get(ctx, obj, PDF_NAME_Subtype);
- if (pdf_name_eq(ctx, PDF_NAME_Text, subtype))
- return PDF_ANNOT_TEXT;
- else if (pdf_name_eq(ctx, PDF_NAME_Link, subtype))
- return PDF_ANNOT_LINK;
- else if (pdf_name_eq(ctx, PDF_NAME_FreeText, subtype))
- return PDF_ANNOT_FREE_TEXT;
- else if (pdf_name_eq(ctx, PDF_NAME_Line, subtype))
- return PDF_ANNOT_LINE;
- else if (pdf_name_eq(ctx, PDF_NAME_Square, subtype))
- return PDF_ANNOT_SQUARE;
- else if (pdf_name_eq(ctx, PDF_NAME_Circle, subtype))
- return PDF_ANNOT_CIRCLE;
- else if (pdf_name_eq(ctx, PDF_NAME_Polygon, subtype))
- return PDF_ANNOT_POLYGON;
- else if (pdf_name_eq(ctx, PDF_NAME_PolyLine, subtype))
- return PDF_ANNOT_POLY_LINE;
- else if (pdf_name_eq(ctx, PDF_NAME_Highlight, subtype))
- return PDF_ANNOT_HIGHLIGHT;
- else if (pdf_name_eq(ctx, PDF_NAME_Underline, subtype))
- return PDF_ANNOT_UNDERLINE;
- else if (pdf_name_eq(ctx, PDF_NAME_Squiggly, subtype))
- return PDF_ANNOT_SQUIGGLY;
- else if (pdf_name_eq(ctx, PDF_NAME_StrikeOut, subtype))
- return PDF_ANNOT_STRIKE_OUT;
- else if (pdf_name_eq(ctx, PDF_NAME_Stamp, subtype))
- return PDF_ANNOT_STAMP;
- else if (pdf_name_eq(ctx, PDF_NAME_Caret, subtype))
- return PDF_ANNOT_CARET;
- else if (pdf_name_eq(ctx, PDF_NAME_Ink, subtype))
- return PDF_ANNOT_INK;
- else if (pdf_name_eq(ctx, PDF_NAME_Popup, subtype))
- return PDF_ANNOT_POPUP;
- else if (pdf_name_eq(ctx, PDF_NAME_FileAttachment, subtype))
- return PDF_ANNOT_FILE_ATTACHMENT;
- else if (pdf_name_eq(ctx, PDF_NAME_Sound, subtype))
- return PDF_ANNOT_SOUND;
- else if (pdf_name_eq(ctx, PDF_NAME_Movie, subtype))
- return PDF_ANNOT_MOVIE;
- else if (pdf_name_eq(ctx, PDF_NAME_Widget, subtype))
- return PDF_ANNOT_WIDGET;
- else if (pdf_name_eq(ctx, PDF_NAME_Screen, subtype))
- return PDF_ANNOT_SCREEN;
- else if (pdf_name_eq(ctx, PDF_NAME_PrinterMark, subtype))
- return PDF_ANNOT_PRINTER_MARK;
- else if (pdf_name_eq(ctx, PDF_NAME_TrapNet, subtype))
- return PDF_ANNOT_TRAP_NET;
- else if (pdf_name_eq(ctx, PDF_NAME_Watermark, subtype))
- return PDF_ANNOT_WATERMARK;
- else if (pdf_name_eq(ctx, PDF_NAME_3D, subtype))
- return PDF_ANNOT_3D;
- else
- return -1;
-}
-
pdf_annot *pdf_new_annot(fz_context *ctx, pdf_page *page)
{
pdf_annot *annot = fz_new_annot(ctx, sizeof(pdf_annot));
diff --git a/source/tools/murun.c b/source/tools/murun.c
index d5659304..15426776 100644
--- a/source/tools/murun.c
+++ b/source/tools/murun.c
@@ -3615,6 +3615,337 @@ static void ffi_PDFObject_forEach(js_State *J)
}
}
+static void ffi_PDFPage_createAnnotation(js_State *J)
+{
+ fz_context *ctx = js_getcontext(J);
+ pdf_page *page = js_touserdata(J, 0, "pdf_page");
+ const char *name = js_tostring(J, 1);
+ pdf_annot *annot;
+ int subtype = pdf_annot_type_from_string(name);
+ if (subtype < 0)
+ js_error(J, "unknown PDF annotation subtype: %s", name);
+ fz_try(ctx)
+ annot = pdf_create_annot(ctx, page, subtype);
+ fz_catch(ctx)
+ rethrow(J);
+ ffi_pushannot(J, (fz_annot*)annot);
+}
+
+static void ffi_PDFPage_deleteAnnotation(js_State *J)
+{
+ fz_context *ctx = js_getcontext(J);
+ pdf_page *page = js_touserdata(J, 0, "pdf_page");
+ pdf_annot *annot = js_touserdata(J, 1, "pdf_annot");
+ fz_try(ctx)
+ pdf_delete_annot(ctx, page, annot);
+ fz_catch(ctx)
+ rethrow(J);
+ ffi_pushannot(J, (fz_annot*)annot);
+}
+
+static void ffi_PDFAnnotation_getType(js_State *J)
+{
+ fz_context *ctx = js_getcontext(J);
+ pdf_annot *annot = js_touserdata(J, 0, "pdf_annot");
+ int subtype;
+ fz_try(ctx)
+ subtype = pdf_annot_type(ctx, annot);
+ fz_catch(ctx)
+ rethrow(J);
+ js_pushstring(J, pdf_string_from_annot_type(subtype));
+}
+
+static void ffi_PDFAnnotation_getFlags(js_State *J)
+{
+ fz_context *ctx = js_getcontext(J);
+ pdf_annot *annot = js_touserdata(J, 0, "pdf_annot");
+ int flags;
+ fz_try(ctx)
+ flags = pdf_annot_flags(ctx, annot);
+ fz_catch(ctx)
+ rethrow(J);
+ js_pushnumber(J, flags);
+}
+
+static void ffi_PDFAnnotation_setFlags(js_State *J)
+{
+ fz_context *ctx = js_getcontext(J);
+ pdf_annot *annot = js_touserdata(J, 0, "pdf_annot");
+ int flags = js_tonumber(J, 1);
+ fz_try(ctx)
+ pdf_set_annot_flags(ctx, annot, flags);
+ fz_catch(ctx)
+ rethrow(J);
+}
+
+static void ffi_PDFAnnotation_getContents(js_State *J)
+{
+ fz_context *ctx = js_getcontext(J);
+ pdf_annot *annot = js_touserdata(J, 0, "pdf_annot");
+ const char *contents;
+ fz_try(ctx)
+ contents = pdf_annot_contents(ctx, annot);
+ fz_catch(ctx)
+ rethrow(J);
+ js_pushstring(J, contents);
+}
+
+static void ffi_PDFAnnotation_setContents(js_State *J)
+{
+ fz_context *ctx = js_getcontext(J);
+ pdf_annot *annot = js_touserdata(J, 0, "pdf_annot");
+ const char *contents = js_tostring(J, 1);
+ fz_try(ctx)
+ pdf_set_annot_contents(ctx, annot, contents);
+ fz_catch(ctx)
+ rethrow(J);
+}
+
+static void ffi_PDFAnnotation_getRect(js_State *J)
+{
+ fz_context *ctx = js_getcontext(J);
+ pdf_annot *annot = js_touserdata(J, 0, "pdf_annot");
+ fz_rect rect;
+ fz_try(ctx)
+ pdf_annot_rect(ctx, annot, &rect);
+ fz_catch(ctx)
+ rethrow(J);
+ ffi_pushrect(J, rect);
+}
+
+static void ffi_PDFAnnotation_setRect(js_State *J)
+{
+ fz_context *ctx = js_getcontext(J);
+ pdf_annot *annot = js_touserdata(J, 0, "pdf_annot");
+ fz_rect rect = ffi_torect(J, 1);
+ fz_try(ctx)
+ pdf_set_annot_rect(ctx, annot, &rect);
+ fz_catch(ctx)
+ rethrow(J);
+}
+
+static void ffi_PDFAnnotation_getBorder(js_State *J)
+{
+ fz_context *ctx = js_getcontext(J);
+ pdf_annot *annot = js_touserdata(J, 0, "pdf_annot");
+ float border;
+ fz_try(ctx)
+ border = pdf_annot_border(ctx, annot);
+ fz_catch(ctx)
+ rethrow(J);
+ js_pushnumber(J, border);
+}
+
+static void ffi_PDFAnnotation_setBorder(js_State *J)
+{
+ fz_context *ctx = js_getcontext(J);
+ pdf_annot *annot = js_touserdata(J, 0, "pdf_annot");
+ float border = js_tonumber(J, 1);
+ fz_try(ctx)
+ pdf_set_annot_border(ctx, annot, border);
+ fz_catch(ctx)
+ rethrow(J);
+}
+
+static void ffi_PDFAnnotation_getColor(js_State *J)
+{
+ fz_context *ctx = js_getcontext(J);
+ pdf_annot *annot = js_touserdata(J, 0, "pdf_annot");
+ int i, n;
+ float color[4];
+ fz_try(ctx)
+ pdf_annot_color(ctx, annot, &n, color);
+ fz_catch(ctx)
+ rethrow(J);
+ js_newarray(J);
+ for (i = 0; i < n; ++i) {
+ js_pushnumber(J, color[i]);
+ js_setindex(J, -2, i);
+ }
+}
+
+static void ffi_PDFAnnotation_setColor(js_State *J)
+{
+ fz_context *ctx = js_getcontext(J);
+ pdf_annot *annot = js_touserdata(J, 0, "pdf_annot");
+ int i, n = js_getlength(J, 1);
+ float color[4];
+ if (n != 0 && n != 1 && n != 3 && n != 4)
+ js_error(J, "color must be 0, 1, 3, or 4 components");
+ for (i = 0; i < n; ++i) {
+ js_getindex(J, 1, 0);
+ color[i] = js_tonumber(J, -1);
+ js_pop(J, 1);
+ }
+ fz_try(ctx)
+ pdf_set_annot_color(ctx, annot, n, color);
+ fz_catch(ctx)
+ rethrow(J);
+}
+
+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];
+ int i, k, n;
+
+ fz_try(ctx)
+ n = pdf_annot_quad_point_count(ctx, annot);
+ fz_catch(ctx)
+ rethrow(J);
+
+ js_newarray(J);
+ for (i = 0; i < n; ++i) {
+ fz_try(ctx)
+ pdf_annot_quad_point(ctx, annot, i, qp);
+ fz_catch(ctx)
+ rethrow(J);
+ js_newarray(J);
+ for (k = 0; k < 8; ++k) {
+ js_pushnumber(J, qp[k]);
+ js_setindex(J, -2, k);
+ }
+ js_setindex(J, -2, i);
+ }
+}
+
+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;
+ int n, k, i;
+
+ n = js_getlength(J, 1);
+
+ fz_try(ctx)
+ qp = fz_malloc(ctx, n * 8 * sizeof *qp);
+ 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[n * 8 + k] = js_tonumber(J, -1);
+ js_pop(J, 1);
+ }
+ js_pop(J, 1);
+ }
+
+ fz_try(ctx)
+ pdf_set_annot_quad_points(ctx, annot, n, qp);
+ fz_catch(ctx) {
+ fz_free(ctx, qp);
+ rethrow(J);
+ }
+
+ fz_free(ctx, qp);
+}
+
+static void ffi_PDFAnnotation_getInkList(js_State *J)
+{
+ fz_context *ctx = js_getcontext(J);
+ pdf_annot *annot = js_touserdata(J, 0, "pdf_annot");
+ int i, k, n, m;
+ float v[2];
+
+ js_newarray(J);
+
+ fz_try(ctx)
+ n = pdf_annot_ink_list_count(ctx, annot);
+ fz_catch(ctx)
+ rethrow(J);
+
+ for (i = 0; i < n; ++n) {
+ fz_try(ctx)
+ m = pdf_annot_ink_list_stroke_count(ctx, annot, i);
+ fz_catch(ctx)
+ rethrow(J);
+
+ js_newarray(J);
+ for (k = 0; k < m; ++k) {
+ fz_try(ctx)
+ pdf_annot_ink_list_stroke_vertex(ctx, annot, i, k, v);
+ fz_catch(ctx)
+ rethrow(J);
+ js_pushnumber(J, v[0]);
+ js_pushnumber(J, v[1]);
+ js_setindex(J, -2, k);
+ }
+ js_setindex(J, -2, i);
+ }
+}
+
+static void ffi_PDFAnnotation_setInkList(js_State *J)
+{
+ fz_context *ctx = js_getcontext(J);
+ pdf_annot *annot = js_touserdata(J, 0, "pdf_annot");
+ float *points = NULL;
+ int *counts = NULL;
+ int n, nv, k, i, v;
+
+ fz_var(counts);
+ fz_var(points);
+
+ n = js_getlength(J, 1);
+ nv = 0;
+ for (i = 0; i < n; ++i) {
+ js_getindex(J, 1, i);
+ nv += js_getlength(J, -1);
+ js_pop(J, 1);
+ }
+
+ fz_try(ctx) {
+ counts = fz_malloc(ctx, n * sizeof(int));
+ points = fz_malloc(ctx, nv * sizeof(float));
+ } fz_catch(ctx) {
+ fz_free(ctx, counts);
+ fz_free(ctx, points);
+ rethrow(J);
+ }
+
+ if (js_try(J)) {
+ fz_free(ctx, counts);
+ fz_free(ctx, points);
+ js_throw(J);
+ }
+ for (i = v = 0; i < n; ++i) {
+ js_getindex(J, 1, i);
+ counts[i] = js_getlength(J, -1);
+ for (k = 0; k < counts[i]; ++k) {
+ js_getindex(J, -1, k);
+ if (v < nv)
+ points[v++] = js_tonumber(J, -1);
+ js_pop(J, 1);
+ }
+ js_pop(J, 1);
+ }
+ js_endtry(J);
+
+ fz_try(ctx)
+ pdf_set_annot_ink_list(ctx, annot, n, counts, points);
+ fz_catch(ctx) {
+ fz_free(ctx, counts);
+ fz_free(ctx, points);
+ rethrow(J);
+ }
+
+ fz_free(ctx, counts);
+ fz_free(ctx, points);
+}
+
+static void ffi_PDFAnnotation_updateAppearance(js_State *J)
+{
+ fz_context *ctx = js_getcontext(J);
+ pdf_annot *annot = js_touserdata(J, 0, "pdf_annot");
+ fz_try(ctx)
+ pdf_update_appearance(ctx, annot->page->doc, annot);
+ fz_catch(ctx)
+ rethrow(J);
+}
+
#endif /* FZ_ENABLE_PDF */
int murun_main(int argc, char **argv)
@@ -3907,12 +4238,30 @@ int murun_main(int argc, char **argv)
js_getregistry(J, "fz_page");
js_newobjectx(J);
{
+ jsB_propfun(J, "PDFPage.createAnnotation", ffi_PDFPage_createAnnotation, 1);
+ jsB_propfun(J, "PDFPage.deleteAnnotation", ffi_PDFPage_deleteAnnotation, 1);
}
js_setregistry(J, "pdf_page");
js_getregistry(J, "fz_annot");
js_newobjectx(J);
{
+ jsB_propfun(J, "PDFAnnotation.getType", ffi_PDFAnnotation_getType, 0);
+ jsB_propfun(J, "PDFAnnotation.getFlags", ffi_PDFAnnotation_getFlags, 0);
+ jsB_propfun(J, "PDFAnnotation.setFlags", ffi_PDFAnnotation_setFlags, 1);
+ jsB_propfun(J, "PDFAnnotation.getContents", ffi_PDFAnnotation_getContents, 0);
+ jsB_propfun(J, "PDFAnnotation.setContents", ffi_PDFAnnotation_setContents, 1);
+ jsB_propfun(J, "PDFAnnotation.getRect", ffi_PDFAnnotation_getRect, 0);
+ jsB_propfun(J, "PDFAnnotation.setRect", ffi_PDFAnnotation_setRect, 1);
+ jsB_propfun(J, "PDFAnnotation.getBorder", ffi_PDFAnnotation_getBorder, 0);
+ jsB_propfun(J, "PDFAnnotation.setBorder", ffi_PDFAnnotation_setBorder, 1);
+ jsB_propfun(J, "PDFAnnotation.getColor", ffi_PDFAnnotation_getColor, 0);
+ jsB_propfun(J, "PDFAnnotation.setColor", ffi_PDFAnnotation_setColor, 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.updateAppearance", ffi_PDFAnnotation_updateAppearance, 0);
}
js_setregistry(J, "pdf_annot");