summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gardiner <paul@glidos.net>2012-04-09 14:58:21 +0100
committerPaul Gardiner <paul@glidos.net>2012-05-08 15:07:48 +0100
commit1ee037cf638874f8f726bcde8c79ef135cedc755 (patch)
treeb4c89223e40feb6e5382848734422de60358c066
parent7eebd3b6d6f3287ce642ff7e1be9cafc5cfe329f (diff)
downloadmupdf-1ee037cf638874f8f726bcde8c79ef135cedc755.tar.xz
Forms: replace the marked content rather than the entire stream
-rw-r--r--pdf/pdf_form.c90
1 files changed, 89 insertions, 1 deletions
diff --git a/pdf/pdf_form.c b/pdf/pdf_form.c
index e7e5caec..bee28ece 100644
--- a/pdf/pdf_form.c
+++ b/pdf/pdf_form.c
@@ -360,6 +360,94 @@ fz_buffer *create_text_appearance(pdf_document *doc, fz_rect *bbox, pdf_obj *dr,
return fzbuf;
}
+static void update_marked_content(fz_context *ctx, pdf_xobject *form, fz_buffer *fzbuf)
+{
+ int tok;
+ pdf_lexbuf lbuf;
+ fz_stream *str_outer = NULL;
+ fz_stream *str_inner = NULL;
+ unsigned char *buf;
+ int len;
+ fz_buffer *newbuf = NULL;
+
+ memset(lbuf.scratch, 0, sizeof(lbuf.scratch));
+ lbuf.size = sizeof(lbuf.scratch);
+
+ fz_var(str_outer);
+ fz_var(str_inner);
+ fz_var(newbuf);
+ fz_try(ctx)
+ {
+ int bmc_found;
+ int first = 1;
+
+ newbuf = fz_new_buffer(ctx, 0);
+ len = fz_buffer_storage(ctx, form->contents, &buf);
+ str_outer = fz_open_memory(ctx, buf, len);
+ len = fz_buffer_storage(ctx, fzbuf, &buf);
+ str_inner = fz_open_memory(ctx, buf, len);
+
+ /* Copy the existing appearance stream to newbuf while looking for BMC */
+ for (tok = pdf_lex(str_outer, &lbuf); tok != PDF_TOK_EOF; tok = pdf_lex(str_outer, &lbuf))
+ {
+ if (first)
+ first = 0;
+ else
+ fz_buffer_printf(ctx, newbuf, " ");
+
+ pdf_print_token(ctx, newbuf, tok, &lbuf);
+ if (tok == PDF_TOK_KEYWORD && !strcmp(lbuf.scratch, "BMC"))
+ break;
+ }
+
+ bmc_found = (tok != PDF_TOK_EOF);
+
+ if (bmc_found)
+ {
+ /* Drop Tx BMC from the replacement appearance stream */
+ (void)pdf_lex(str_inner, &lbuf);
+ (void)pdf_lex(str_inner, &lbuf);
+ }
+
+ /* Copy the replacement appearance stream to newbuf */
+ for (tok = pdf_lex(str_inner, &lbuf); tok != PDF_TOK_EOF; tok = pdf_lex(str_inner, &lbuf))
+ {
+ fz_buffer_printf(ctx, newbuf, " ");
+ pdf_print_token(ctx, newbuf, tok, &lbuf);
+ }
+
+ if (bmc_found)
+ {
+ /* Drop the rest of the existing appearance stream until EMC found */
+ for (tok = pdf_lex(str_outer, &lbuf); tok != PDF_TOK_EOF; tok = pdf_lex(str_outer, &lbuf))
+ {
+ if (tok == PDF_TOK_KEYWORD && !strcmp(lbuf.scratch, "EMC"))
+ break;
+ }
+
+ /* Copy the rest of the existing appearance stream to newbuf */
+ for (tok = pdf_lex(str_outer, &lbuf); tok != PDF_TOK_EOF; tok = pdf_lex(str_outer, &lbuf))
+ {
+ fz_buffer_printf(ctx, newbuf, " ");
+ pdf_print_token(ctx, newbuf, tok, &lbuf);
+ }
+ }
+
+ /* Use newbuf in place of the existing appearance stream */
+ pdf_xobject_set_contents(ctx, form, newbuf);
+ }
+ fz_always(ctx)
+ {
+ fz_close(str_outer);
+ fz_close(str_inner);
+ fz_drop_buffer(ctx, newbuf);
+ }
+ fz_catch(ctx)
+ {
+ fz_rethrow(ctx);
+ }
+}
+
static void update_text_appearance(pdf_document *doc, pdf_obj *obj, char *text)
{
fz_context *ctx = doc->ctx;
@@ -395,7 +483,7 @@ static void update_text_appearance(pdf_document *doc, pdf_obj *obj, char *text)
}
fzbuf = create_text_appearance(doc, &form->bbox, dr, pdf_to_str_buf(da), text);
- pdf_xobject_set_contents(ctx, form, fzbuf);
+ update_marked_content(ctx, form, fzbuf);
}
}
}