diff options
author | Paul Gardiner <paul@glidos.net> | 2012-05-08 12:35:00 +0100 |
---|---|---|
committer | Paul Gardiner <paul@glidos.net> | 2012-05-08 12:35:00 +0100 |
commit | 50b0de6e463ebd954b1a97a2cd093731335f1671 (patch) | |
tree | 9a632a6a346a8d4c941f636ca5fcf2ffb2e6bf0c /pdf | |
parent | 6a6d2016149c731dfa3a485b1bf0b46d7127681d (diff) | |
download | mupdf-50b0de6e463ebd954b1a97a2cd093731335f1671.tar.xz |
Forms: handle field appearance change on mouse up/down
Diffstat (limited to 'pdf')
-rw-r--r-- | pdf/mupdf-internal.h | 18 | ||||
-rw-r--r-- | pdf/mupdf.h | 19 | ||||
-rw-r--r-- | pdf/pdf_annot.c | 17 | ||||
-rw-r--r-- | pdf/pdf_form.c | 59 | ||||
-rw-r--r-- | pdf/pdf_page.c | 2 | ||||
-rw-r--r-- | pdf/pdf_xref.c | 18 |
6 files changed, 129 insertions, 4 deletions
diff --git a/pdf/mupdf-internal.h b/pdf/mupdf-internal.h index a66871dd..f501b916 100644 --- a/pdf/mupdf-internal.h +++ b/pdf/mupdf-internal.h @@ -156,6 +156,7 @@ struct pdf_xref_entry_s typedef struct pdf_crypt_s pdf_crypt; typedef struct pdf_ocg_descriptor_s pdf_ocg_descriptor; typedef struct pdf_ocg_entry_s pdf_ocg_entry; +typedef struct pdf_hotspot_s pdf_hotspot; struct pdf_ocg_entry_s { @@ -171,6 +172,19 @@ struct pdf_ocg_descriptor_s pdf_obj *intent; }; +enum +{ + HOTSPOT_POINTER_DOWN = 0x1, + HOTSPOT_POINTER_OVER = 0x2 +}; + +struct pdf_hotspot_s +{ + int num; + int gen; + int state; +}; + struct pdf_document_s { fz_document super; @@ -184,6 +198,7 @@ struct pdf_document_s pdf_crypt *crypt; pdf_obj *trailer; pdf_ocg_descriptor *ocg; + pdf_hotspot hotspot; int len; pdf_xref_entry *table; @@ -494,6 +509,7 @@ struct pdf_annot_s { pdf_obj *obj; fz_rect rect; + fz_rect pagerect; pdf_xobject *ap; fz_matrix matrix; pdf_annot *next; @@ -507,7 +523,7 @@ pdf_obj *pdf_load_name_tree(pdf_document *doc, char *which); fz_link *pdf_load_link_annots(pdf_document *, pdf_obj *annots, fz_matrix page_ctm); -pdf_annot *pdf_load_annots(pdf_document *, pdf_obj *annots); +pdf_annot *pdf_load_annots(pdf_document *, pdf_obj *annots, fz_matrix page_ctm); void pdf_free_annot(fz_context *ctx, pdf_annot *link); /* diff --git a/pdf/mupdf.h b/pdf/mupdf.h index 07bfa12d..e257dd5a 100644 --- a/pdf/mupdf.h +++ b/pdf/mupdf.h @@ -216,4 +216,23 @@ void pdf_run_page(pdf_document *doc, pdf_page *page, fz_device *dev, fz_matrix c void pdf_run_page_with_usage(pdf_document *doc, pdf_page *page, fz_device *dev, fz_matrix ctm, char *event, fz_cookie *cookie); +/* + pdf_pass_event: pass a UI event to a page. + + The event may activate or focus a form field. +*/ +int pdf_pass_event(pdf_document *doc, pdf_page *page, fz_ui_event *ui_event); + +/* + pdf_get_screen_update: return areas needing updating because of + appearance change. +*/ +fz_rect *pdf_get_screen_update(pdf_document *doc); + +/* + pdf_get_focussed_widget: return the currently focussed form field, + if any. +*/ +fz_widget *pdf_get_focussed_widget(pdf_document *doc); + #endif diff --git a/pdf/pdf_annot.c b/pdf/pdf_annot.c index 3864c62e..5b08990f 100644 --- a/pdf/pdf_annot.c +++ b/pdf/pdf_annot.c @@ -352,7 +352,7 @@ pdf_transform_annot(pdf_annot *annot) } pdf_annot * -pdf_load_annots(pdf_document *xref, pdf_obj *annots) +pdf_load_annots(pdf_document *xref, pdf_obj *annots, fz_matrix page_ctm) { pdf_annot *annot, *head, *tail; pdf_obj *obj, *ap, *as, *n, *rect; @@ -373,7 +373,19 @@ pdf_load_annots(pdf_document *xref, pdf_obj *annots) as = pdf_dict_gets(obj, "AS"); if (pdf_is_dict(ap)) { - n = pdf_dict_gets(ap, "N"); /* normal state */ + pdf_hotspot *hp = &xref->hotspot; + + n = NULL; + + if (hp->num == pdf_to_num(obj) + && hp->gen == pdf_to_gen(obj) + && (hp->state & HOTSPOT_POINTER_DOWN)) + { + n = pdf_dict_gets(ap, "D"); /* down state */ + } + + if (n == NULL) + n = pdf_dict_gets(ap, "N"); /* normal state */ /* lookup current state in sub-dictionary */ if (!pdf_is_stream(xref, pdf_to_num(n), pdf_to_gen(n))) @@ -394,6 +406,7 @@ pdf_load_annots(pdf_document *xref, pdf_obj *annots) annot = fz_malloc_struct(ctx, pdf_annot); annot->obj = pdf_keep_obj(obj); annot->rect = pdf_to_rect(ctx, rect); + annot->pagerect = fz_transform_rect(page_ctm, annot->rect); annot->ap = form; annot->next = NULL; diff --git a/pdf/pdf_form.c b/pdf/pdf_form.c new file mode 100644 index 00000000..ff5babeb --- /dev/null +++ b/pdf/pdf_form.c @@ -0,0 +1,59 @@ +#include "fitz-internal.h" +#include "mupdf-internal.h" + +int pdf_pass_event(pdf_document *doc, pdf_page *page, fz_ui_event *ui_event) +{ + int changed = 0; + + switch (ui_event->etype) + { + case FZ_EVENT_TYPE_POINTER: + { + pdf_hotspot *hp = &doc->hotspot; + fz_point *pt = &(ui_event->event.pointer.pt); + pdf_annot *annot; + switch (ui_event->event.pointer.ptype) + { + case FZ_POINTER_DOWN: + for (annot = page->annots; annot; annot = annot->next) + { + if (pt->x >= annot->pagerect.x0 && pt->x <= annot->pagerect.x1) + if (pt->y >= annot->pagerect.y0 && pt->y <= annot->pagerect.y1) + break; + } + + if (annot) + { + hp->num = pdf_to_num(annot->obj); + hp->gen = pdf_to_gen(annot->obj); + hp->state = HOTSPOT_POINTER_DOWN; + changed = 1; + } + break; + + case FZ_POINTER_UP: + if (hp->state != 0) + changed = 1; + + hp->num = 0; + hp->gen = 0; + hp->state = 0; + break; + } + + } + break; + } + + return changed; +} + +fz_rect *pdf_get_screen_update(pdf_document *doc) +{ + return NULL; +} + +fz_widget *pdf_get_focussed_widget(pdf_document *doc) +{ + return NULL; +} diff --git a/pdf/pdf_page.c b/pdf/pdf_page.c index 55d7ef97..3e95e9a5 100644 --- a/pdf/pdf_page.c +++ b/pdf/pdf_page.c @@ -412,7 +412,7 @@ pdf_load_page(pdf_document *xref, int number) if (obj) { page->links = pdf_load_link_annots(xref, obj, page->ctm); - page->annots = pdf_load_annots(xref, obj); + page->annots = pdf_load_annots(xref, obj, page->ctm); } page->resources = pdf_dict_gets(pageobj, "Resources"); diff --git a/pdf/pdf_xref.c b/pdf/pdf_xref.c index 30f4bd69..ea068e27 100644 --- a/pdf/pdf_xref.c +++ b/pdf/pdf_xref.c @@ -1280,6 +1280,21 @@ static int pdf_meta(fz_document *doc_, int key, void *ptr, int size) } } +static int pdf_pass_event_shim(fz_document *doc, fz_page *page, fz_ui_event *ui_event) +{ + return pdf_pass_event((pdf_document*)doc, (pdf_page*)page, ui_event); +} + +static fz_rect *pdf_get_screen_update_shim(fz_document *doc) +{ + return pdf_get_screen_update((pdf_document*)doc); +} + +static fz_widget *pdf_get_focussed_widget_shim(fz_document *doc) +{ + return pdf_get_focussed_widget((pdf_document*)doc); +} + static void pdf_init_document(pdf_document *doc) { @@ -1294,4 +1309,7 @@ pdf_init_document(pdf_document *doc) doc->super.run_page = pdf_run_page_shim; doc->super.free_page = pdf_free_page_shim; doc->super.meta = pdf_meta; + doc->super.pass_event = pdf_pass_event_shim; + doc->super.get_screen_update = pdf_get_screen_update_shim; + doc->super.get_focussed_widget = pdf_get_focussed_widget_shim; } |