diff options
author | Paul Gardiner <paulg.artifex@glidos.net> | 2013-03-25 12:50:19 +0000 |
---|---|---|
committer | Paul Gardiner <paulg.artifex@glidos.net> | 2013-03-25 12:50:19 +0000 |
commit | 41f10c71dbae05fb538f51a495ef7aaa1861fd5d (patch) | |
tree | 40a9b0ce7a528f95db71f5c1e3cf165032d927a9 | |
parent | f031719c18e610269e85aa1d1b83a619ddc7fec7 (diff) | |
download | mupdf-41f10c71dbae05fb538f51a495ef7aaa1861fd5d.tar.xz |
Support creation of Ink annotations in MuPDF library
-rw-r--r-- | fitz/doc_interactive.c | 5 | ||||
-rw-r--r-- | fitz/fitz-internal.h | 6 | ||||
-rw-r--r-- | pdf/mupdf-internal.h | 2 | ||||
-rw-r--r-- | pdf/pdf_annot.c | 182 | ||||
-rw-r--r-- | pdf/pdf_form.c | 3 |
5 files changed, 191 insertions, 7 deletions
diff --git a/fitz/doc_interactive.c b/fitz/doc_interactive.c index fb9d6cb4..10d48129 100644 --- a/fitz/doc_interactive.c +++ b/fitz/doc_interactive.c @@ -111,6 +111,11 @@ void fz_set_markup_appearance(fz_interactive *idoc, fz_annot *annot, float color pdf_set_markup_appearance((pdf_document *)idoc, (pdf_annot *)annot, color, alpha, line_thickness, line_height); } +void fz_set_ink_annot_list(fz_interactive *idoc, fz_annot *annot, fz_point *pts, int *counts, int ncount, float color[3], float thickness) +{ + pdf_set_ink_annot_list((pdf_document *)idoc, (pdf_annot *)annot, pts, counts, ncount, color, thickness); +} + void fz_set_doc_event_callback(fz_interactive *idoc, fz_doc_event_cb *event_cb, void *data) { pdf_set_doc_event_callback((pdf_document *)idoc, event_cb, data); diff --git a/fitz/fitz-internal.h b/fitz/fitz-internal.h index 0436bfcd..19e0a493 100644 --- a/fitz/fitz-internal.h +++ b/fitz/fitz-internal.h @@ -1228,6 +1228,12 @@ void fz_set_markup_annot_quadpoints(fz_interactive *idoc, fz_annot *annot, fz_po void fz_set_markup_appearance(fz_interactive *idoc, fz_annot *annot, float color[3], float alpha, float line_thickness, float line_height); /* + fz_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 fz_set_ink_annot_list(fz_interactive *idoc, fz_annot *annot, fz_point *pts, int *counts, int ncount, float color[3], float thickness); + +/* * Text buffer. * * The trm field contains the a, b, c and d coefficients. diff --git a/pdf/mupdf-internal.h b/pdf/mupdf-internal.h index 667f996a..164b0c81 100644 --- a/pdf/mupdf-internal.h +++ b/pdf/mupdf-internal.h @@ -614,6 +614,8 @@ void pdf_set_annot_appearance(pdf_document *doc, pdf_annot *annot, fz_rect *rect void pdf_set_markup_annot_quadpoints(pdf_document *doc, pdf_annot *annot, fz_point *qp, int n); void pdf_set_markup_obj_appearance(pdf_document *doc, pdf_obj *annot, float color[3], float alpha, float line_thickness, float line_height); void pdf_set_markup_appearance(pdf_document *doc, pdf_annot *annot, float color[3], float alpha, float line_thickness, float line_height); +void pdf_set_ink_annot_list(pdf_document *doc, pdf_annot *annot, fz_point *pts, int *counts, int ncount, float color[3], float thickness); +void pdf_set_ink_obj_appearance(pdf_document *doc, pdf_obj *annot); void pdf_set_doc_event_callback(pdf_document *doc, fz_doc_event_cb *event_cb, void *data); void pdf_event_issue_alert(pdf_document *doc, fz_alert_event *event); diff --git a/pdf/pdf_annot.c b/pdf/pdf_annot.c index 5252ce9a..0c2128a7 100644 --- a/pdf/pdf_annot.c +++ b/pdf/pdf_annot.c @@ -768,6 +768,25 @@ pdf_delete_annot(pdf_document *doc, pdf_page *page, pdf_annot *annot) doc->dirty = 1; } +static fz_colorspace *pdf_to_color(pdf_obj *col, float color[4]) +{ + fz_colorspace *cs; + int i, ncol = pdf_array_len(col); + + switch (ncol) + { + case 1: cs = fz_device_gray; break; + case 3: cs = fz_device_rgb; break; + case 4: cs = fz_device_cmyk; break; + default: return NULL; + } + + for (i = 0; i < ncol; i++) + color[i] = pdf_to_real(pdf_array_get(col, i)); + + return cs; +} + static fz_point * quadpoints(pdf_document *doc, pdf_obj *annot, int *nout) { @@ -831,6 +850,70 @@ pdf_set_markup_annot_quadpoints(pdf_document *doc, pdf_annot *annot, fz_point *q } } +static void update_rect(fz_context *ctx, pdf_annot *annot) +{ + pdf_to_rect(ctx, pdf_dict_gets(annot->obj, "Rect"), &annot->rect); + annot->pagerect = annot->rect; + fz_transform_rect(&annot->pagerect, &annot->page->ctm); +} + +void +pdf_set_ink_annot_list(pdf_document *doc, pdf_annot *annot, fz_point *pts, int *counts, int ncount, float color[3], float thickness) +{ + fz_context *ctx = doc->ctx; + fz_matrix ctm; + pdf_obj *list = pdf_new_array(ctx, ncount); + pdf_obj *bs, *col; + fz_rect rect; + int i, k = 0; + + fz_invert_matrix(&ctm, &annot->page->ctm); + + pdf_dict_puts_drop(annot->obj, "InkList", list); + + for (i = 0; i < ncount; i++) + { + int j; + pdf_obj *arc = pdf_new_array(ctx, counts[i]); + + pdf_array_push_drop(list, arc); + + for (j = 0; j < counts[i]; j++) + { + fz_point pt = pts[k]; + + fz_transform_point(&pt, &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(arc, pdf_new_real(ctx, pt.x)); + pdf_array_push_drop(arc, pdf_new_real(ctx, pt.y)); + k++; + } + } + + fz_expand_rect(&rect, thickness); + pdf_dict_puts_drop(annot->obj, "Rect", pdf_new_rect(ctx, &rect)); + update_rect(ctx, annot); + + bs = pdf_new_dict(ctx, 1); + pdf_dict_puts_drop(annot->obj, "BS", bs); + pdf_dict_puts_drop(bs, "W", pdf_new_real(ctx, thickness)); + + col = pdf_new_array(ctx, 3); + pdf_dict_puts_drop(annot->obj, "C", col); + for (i = 0; i < 3; i++) + pdf_array_push_drop(col, pdf_new_real(ctx, color[i])); +} + void pdf_set_annot_obj_appearance(pdf_document *doc, pdf_obj *obj, const fz_matrix *page_ctm, fz_rect *rect, fz_display_list *disp_list) { @@ -889,13 +972,6 @@ pdf_set_annot_obj_appearance(pdf_document *doc, pdf_obj *obj, const fz_matrix *p } } -static void update_rect(fz_context *ctx, pdf_annot *annot) -{ - pdf_to_rect(ctx, pdf_dict_gets(annot->obj, "Rect"), &annot->rect); - annot->pagerect = annot->rect; - fz_transform_rect(&annot->pagerect, &annot->page->ctm); -} - void pdf_set_annot_appearance(pdf_document *doc, pdf_annot *annot, fz_rect *rect, fz_display_list *disp_list) { @@ -993,6 +1069,98 @@ pdf_set_markup_obj_appearance(pdf_document *doc, pdf_obj *annot, float color[3], } void +pdf_set_ink_obj_appearance(pdf_document *doc, pdf_obj *annot) +{ + fz_context *ctx = doc->ctx; + fz_path *path = NULL; + fz_stroke_state *stroke = NULL; + fz_device *dev = NULL; + fz_display_list *strike_list = NULL; + + fz_var(path); + fz_var(stroke); + fz_var(dev); + fz_var(strike_list); + fz_try(ctx) + { + fz_rect rect = fz_empty_rect; + fz_colorspace *cs; + float color[4]; + float width; + pdf_obj *list; + int n, m, i, j; + + cs = pdf_to_color(pdf_dict_gets(annot, "C"), color); + if (!cs) + { + cs = fz_device_rgb; + color[0] = 1.0f; + color[1] = 0.0f; + color[2] = 0.0f; + } + + width = pdf_to_real(pdf_dict_gets(pdf_dict_gets(annot, "BS"), "W")); + if (width == 0.0f) + width = 1.0f; + + list = pdf_dict_gets(annot, "InkList"); + + n = pdf_array_len(list); + + strike_list = fz_new_display_list(ctx); + dev = fz_new_list_device(ctx, strike_list); + path = fz_new_path(ctx); + stroke = fz_new_stroke_state(ctx); + stroke->linewidth = width; + + for (i = 0; i < n; i ++) + { + pdf_obj *arc = pdf_array_get(list, i); + m = pdf_array_len(arc); + + for (j = 0; j < m-1; j += 2) + { + fz_point pt; + pt.x = pdf_to_real(pdf_array_get(arc, j)); + pt.y = pdf_to_real(pdf_array_get(arc, j+1)); + + 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); + } + + if (j == 0) + fz_moveto(ctx, path, pt.x, pt.y); + else + fz_lineto(ctx, path, pt.x, pt.y); + } + } + + fz_stroke_path(dev, path, stroke, &fz_identity, cs, color, 1.0f); + + fz_expand_rect(&rect, width); + + pdf_set_annot_obj_appearance(doc, annot, &fz_identity, &rect, strike_list); + } + fz_always(ctx) + { + fz_free_device(dev); + fz_drop_stroke_state(ctx, stroke); + fz_free_path(ctx, path); + fz_free_display_list(ctx, strike_list); + } + fz_catch(ctx) + { + fz_rethrow(ctx); + } +} + +void pdf_set_markup_appearance(pdf_document *doc, pdf_annot *annot, float color[3], float alpha, float line_thickness, float line_height) { pdf_set_markup_obj_appearance(doc, annot->obj, color, alpha, line_thickness, line_height); diff --git a/pdf/pdf_form.c b/pdf/pdf_form.c index 01f82d74..9e02f2d0 100644 --- a/pdf/pdf_form.c +++ b/pdf/pdf_form.c @@ -1806,6 +1806,9 @@ void pdf_update_appearance(pdf_document *doc, pdf_obj *obj) case FZ_ANNOT_HIGHLIGHT: update_text_markup_appearance(doc, obj, type); break; + case FZ_ANNOT_INK: + pdf_set_ink_obj_appearance(doc, obj); + break; default: break; } |