summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gardiner <paul@glidos.net>2012-05-08 12:35:00 +0100
committerPaul Gardiner <paul@glidos.net>2012-05-08 12:35:00 +0100
commit50b0de6e463ebd954b1a97a2cd093731335f1671 (patch)
tree9a632a6a346a8d4c941f636ca5fcf2ffb2e6bf0c
parent6a6d2016149c731dfa3a485b1bf0b46d7127681d (diff)
downloadmupdf-50b0de6e463ebd954b1a97a2cd093731335f1671.tar.xz
Forms: handle field appearance change on mouse up/down
-rw-r--r--apps/pdfapp.c15
-rw-r--r--fitz/doc_document.c24
-rw-r--r--fitz/fitz-internal.h12
-rw-r--r--fitz/fitz.h4
-rw-r--r--pdf/mupdf-internal.h18
-rw-r--r--pdf/mupdf.h19
-rw-r--r--pdf/pdf_annot.c17
-rw-r--r--pdf/pdf_form.c59
-rw-r--r--pdf/pdf_page.c2
-rw-r--r--pdf/pdf_xref.c18
-rw-r--r--win32/libmupdf.vcproj4
11 files changed, 186 insertions, 6 deletions
diff --git a/apps/pdfapp.c b/apps/pdfapp.c
index 52bb4c48..939d4e58 100644
--- a/apps/pdfapp.c
+++ b/apps/pdfapp.c
@@ -964,6 +964,21 @@ void pdfapp_onmouse(pdfapp_t *app, int x, int y, int btn, int modifiers, int sta
p = fz_transform_point(ctm, p);
+ if (btn == 1 && (state == 1 || state == -1))
+ {
+ fz_ui_event event;
+
+ event.etype = FZ_EVENT_TYPE_POINTER;
+ event.event.pointer.pt = p;
+ if (state == 1)
+ event.event.pointer.ptype = FZ_POINTER_DOWN;
+ else /* state == -1 */
+ event.event.pointer.ptype = FZ_POINTER_UP;
+
+ if (fz_pass_event(app->doc, app->page, &event))
+ pdfapp_showpage(app, 1, 1, 1);
+ }
+
for (link = app->page_links; link; link = link->next)
{
if (p.x >= link->rect.x0 && p.x <= link->rect.x1)
diff --git a/fitz/doc_document.c b/fitz/doc_document.c
index 22229892..18b9d557 100644
--- a/fitz/doc_document.c
+++ b/fitz/doc_document.c
@@ -129,3 +129,27 @@ fz_meta(fz_document *doc, int key, void *ptr, int size)
return doc->meta(doc, key, ptr, size);
return FZ_META_UNKNOWN_KEY;
}
+
+int
+fz_pass_event(fz_document *doc, fz_page *page, fz_ui_event *ui_event)
+{
+ if (doc && doc->pass_event)
+ return doc->pass_event(doc, page, ui_event);
+ return 0;
+}
+
+fz_rect *
+fz_get_screen_update(fz_document *doc)
+{
+ if (doc && doc->get_screen_update, doc)
+ return doc->get_screen_update(doc);
+ return NULL;
+}
+
+fz_widget *
+fz_get_focussed_widget(fz_document *doc)
+{
+ if (doc && doc->get_focussed_widget)
+ return doc->get_focussed_widget(doc);
+ return NULL;
+}
diff --git a/fitz/fitz-internal.h b/fitz/fitz-internal.h
index 97bbfa5c..92896da0 100644
--- a/fitz/fitz-internal.h
+++ b/fitz/fitz-internal.h
@@ -830,6 +830,15 @@ fz_pixmap *fz_render_stroked_glyph(fz_context *ctx, fz_font*, int, fz_matrix, fz
void fz_render_t3_glyph_direct(fz_context *ctx, fz_device *dev, fz_font *font, int gid, fz_matrix trm, void *gstate);
/*
+ * Forms
+ */
+struct fz_widget
+{
+ int type;
+ fz_bbox bbox;
+};
+
+/*
* Text buffer.
*
* The trm field contains the a, b, c and d coefficients.
@@ -1085,6 +1094,9 @@ struct fz_document_s
void (*run_page)(fz_document *doc, fz_page *page, fz_device *dev, fz_matrix transform, fz_cookie *cookie);
void (*free_page)(fz_document *doc, fz_page *page);
int (*meta)(fz_document *doc, int key, void *ptr, int size);
+ int (*pass_event)(fz_document *doc, fz_page *page, fz_ui_event *ui_event);
+ fz_rect *(*get_screen_update)(fz_document *doc);
+ fz_widget *(*get_focussed_widget)(fz_document *doc);
};
#endif
diff --git a/fitz/fitz.h b/fitz/fitz.h
index 5ab7b7f1..b68090cb 100644
--- a/fitz/fitz.h
+++ b/fitz/fitz.h
@@ -2269,7 +2269,7 @@ typedef struct fz_ui_event_s
struct
{
int ptype;
- float x, y;
+ fz_point pt;
} pointer;
} event;
} fz_ui_event;
@@ -2282,7 +2282,7 @@ typedef struct fz_widget_s fz_widget;
/*
Specific types of widget
*/
-typedef struct fz_widget_text_s fz_widget_test;
+typedef struct fz_widget_text_s fz_widget_text;
/*
fz_pass_event: Pass a UI event to an interactive
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;
}
diff --git a/win32/libmupdf.vcproj b/win32/libmupdf.vcproj
index b984cc8f..ddbb9ef2 100644
--- a/win32/libmupdf.vcproj
+++ b/win32/libmupdf.vcproj
@@ -270,6 +270,10 @@
>
</File>
<File
+ RelativePath="..\pdf\pdf_form.c"
+ >
+ </File>
+ <File
RelativePath="..\pdf\pdf_function.c"
>
</File>