summaryrefslogtreecommitdiff
path: root/source/pdf/pdf-annot.c
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2014-03-20 15:20:25 +0100
committerRobin Watts <robin.watts@artifex.com>2014-03-25 16:44:42 +0000
commit95361b7f10880776f0db3030030842d94ba341a9 (patch)
tree4d14b9474d0f3a970349b4ff722b86822a7330e4 /source/pdf/pdf-annot.c
parentdb6353067cf545f4ca6fd854c8e8b4c4145dc537 (diff)
downloadmupdf-95361b7f10880776f0db3030030842d94ba341a9.tar.xz
Break dependency of pdf-annot.c to graphics library.
Diffstat (limited to 'source/pdf/pdf-annot.c')
-rw-r--r--source/pdf/pdf-annot.c481
1 files changed, 1 insertions, 480 deletions
diff --git a/source/pdf/pdf-annot.c b/source/pdf/pdf-annot.c
index 1fcbbcf4..c3440c63 100644
--- a/source/pdf/pdf-annot.c
+++ b/source/pdf/pdf-annot.c
@@ -1,7 +1,5 @@
#include "mupdf/pdf.h"
-#define TEXT_ANNOT_SIZE (25.0)
-
static pdf_obj *
resolve_dest_rec(pdf_document *doc, pdf_obj *dest, fz_link_kind kind, int depth)
{
@@ -383,7 +381,7 @@ pdf_free_annot(fz_context *ctx, pdf_annot *annot)
}
}
-static void
+void
pdf_transform_annot(pdf_annot *annot)
{
fz_rect bbox = annot->ap->bbox;
@@ -462,39 +460,6 @@ fz_annot_type pdf_annot_obj_type(pdf_obj *obj)
return -1;
}
-static const char *annot_type_str(fz_annot_type type)
-{
- switch (type)
- {
- case FZ_ANNOT_TEXT: return "Text";
- case FZ_ANNOT_LINK: return "Link";
- case FZ_ANNOT_FREETEXT: return "FreeText";
- case FZ_ANNOT_LINE: return "Line";
- case FZ_ANNOT_SQUARE: return "Square";
- case FZ_ANNOT_CIRCLE: return "Circle";
- case FZ_ANNOT_POLYGON: return "Polygon";
- case FZ_ANNOT_POLYLINE: return "PolyLine";
- case FZ_ANNOT_HIGHLIGHT: return "Highlight";
- case FZ_ANNOT_UNDERLINE: return "Underline";
- case FZ_ANNOT_SQUIGGLY: return "Squiggly";
- case FZ_ANNOT_STRIKEOUT: return "StrikeOut";
- case FZ_ANNOT_STAMP: return "Stamp";
- case FZ_ANNOT_CARET: return "Caret";
- case FZ_ANNOT_INK: return "Ink";
- case FZ_ANNOT_POPUP: return "Popup";
- case FZ_ANNOT_FILEATTACHMENT: return "FileAttachment";
- case FZ_ANNOT_SOUND: return "Sound";
- case FZ_ANNOT_MOVIE: return "Movie";
- case FZ_ANNOT_WIDGET: return "Widget";
- case FZ_ANNOT_SCREEN: return "Screen";
- case FZ_ANNOT_PRINTERMARK: return "PrinterMark";
- case FZ_ANNOT_TRAPNET: return "TrapNet";
- case FZ_ANNOT_WATERMARK: return "Watermark";
- case FZ_ANNOT_3D: return "3D";
- default: return "";
- }
-}
-
void
pdf_load_annots(pdf_document *doc, pdf_page *page, pdf_obj *annots)
{
@@ -624,60 +589,6 @@ pdf_load_annots(pdf_document *doc, pdf_page *page, pdf_obj *annots)
page->annot_tailp = itr;
}
-void
-pdf_update_annot(pdf_document *doc, pdf_annot *annot)
-{
- pdf_obj *obj, *ap, *as, *n;
- fz_context *ctx = doc->ctx;
-
- if (doc->update_appearance)
- doc->update_appearance(doc, annot);
-
- obj = annot->obj;
-
- ap = pdf_dict_gets(obj, "AP");
- as = pdf_dict_gets(obj, "AS");
-
- if (pdf_is_dict(ap))
- {
- pdf_hotspot *hp = &doc->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(doc, pdf_to_num(n), pdf_to_gen(n)))
- n = pdf_dict_get(n, as);
-
- pdf_drop_xobject(ctx, annot->ap);
- annot->ap = NULL;
-
- if (pdf_is_stream(doc, pdf_to_num(n), pdf_to_gen(n)))
- {
- fz_try(ctx)
- {
- annot->ap = pdf_load_xobject(doc, n);
- pdf_transform_annot(annot);
- annot->ap_iteration = annot->ap->iteration;
- }
- fz_catch(ctx)
- {
- fz_rethrow_if(ctx, FZ_ERROR_TRYLATER);
- fz_warn(ctx, "ignoring broken annotation");
- }
- }
- }
-}
-
pdf_annot *
pdf_first_annot(pdf_document *doc, pdf_page *page)
{
@@ -708,393 +619,3 @@ pdf_annot_type(pdf_annot *annot)
{
return annot->annot_type;
}
-
-pdf_annot *
-pdf_create_annot(pdf_document *doc, pdf_page *page, fz_annot_type type)
-{
- fz_context *ctx = doc->ctx;
- pdf_annot *annot = NULL;
- pdf_obj *annot_obj = pdf_new_dict(doc, 0);
- pdf_obj *ind_obj = NULL;
-
- fz_var(annot);
- fz_var(ind_obj);
- fz_try(ctx)
- {
- int ind_obj_num;
- fz_rect rect = {0.0, 0.0, 0.0, 0.0};
- const char *type_str = annot_type_str(type);
- pdf_obj *annot_arr = pdf_dict_gets(page->me, "Annots");
- if (annot_arr == NULL)
- {
- annot_arr = pdf_new_array(doc, 0);
- pdf_dict_puts_drop(page->me, "Annots", annot_arr);
- }
-
- pdf_dict_puts_drop(annot_obj, "Type", pdf_new_name(doc, "Annot"));
-
- pdf_dict_puts_drop(annot_obj, "Subtype", pdf_new_name(doc, type_str));
- pdf_dict_puts_drop(annot_obj, "Rect", pdf_new_rect(doc, &rect));
-
- /* Make printable as default */
- pdf_dict_puts_drop(annot_obj, "F", pdf_new_int(doc, F_Print));
-
- annot = fz_malloc_struct(ctx, pdf_annot);
- annot->page = page;
- annot->rect = rect;
- annot->pagerect = rect;
- annot->ap = NULL;
- annot->widget_type = PDF_WIDGET_TYPE_NOT_WIDGET;
- annot->annot_type = type;
-
- /*
- Both annotation object and annotation structure are now created.
- Insert the object in the hierarchy and the structure in the
- page's array.
- */
- ind_obj_num = pdf_create_object(doc);
- pdf_update_object(doc, ind_obj_num, annot_obj);
- ind_obj = pdf_new_indirect(doc, ind_obj_num, 0);
- pdf_array_push(annot_arr, ind_obj);
- annot->obj = pdf_keep_obj(ind_obj);
-
- /*
- Linking must be done after any call that might throw because
- pdf_free_annot below actually frees a list. Put the new annot
- at the end of the list, so that it will be drawn last.
- */
- *page->annot_tailp = annot;
- page->annot_tailp = &annot->next;
-
- doc->dirty = 1;
- }
- fz_always(ctx)
- {
- pdf_drop_obj(annot_obj);
- pdf_drop_obj(ind_obj);
- }
- fz_catch(ctx)
- {
- pdf_free_annot(ctx, annot);
- fz_rethrow(ctx);
- }
-
- return annot;
-}
-
-void
-pdf_delete_annot(pdf_document *doc, pdf_page *page, pdf_annot *annot)
-{
- fz_context *ctx = doc->ctx;
- pdf_annot **annotptr;
- pdf_obj *old_annot_arr;
- pdf_obj *annot_arr;
-
- if (annot == NULL)
- return;
-
- /* Remove annot from page's list */
- for (annotptr = &page->annots; *annotptr; annotptr = &(*annotptr)->next)
- {
- if (*annotptr == annot)
- break;
- }
-
- /* Check the passed annotation was of this page */
- if (*annotptr == NULL)
- return;
-
- *annotptr = annot->next;
- /* If the removed annotation was the last in the list adjust the end pointer */
- if (*annotptr == NULL)
- page->annot_tailp = annotptr;
-
- /* Stick it in the deleted list */
- annot->next = page->deleted_annots;
- page->deleted_annots = annot;
-
- pdf_drop_xobject(ctx, annot->ap);
- annot->ap = NULL;
-
- /* Recreate the "Annots" array with this annot removed */
- old_annot_arr = pdf_dict_gets(page->me, "Annots");
-
- if (old_annot_arr)
- {
- int i, n = pdf_array_len(old_annot_arr);
- annot_arr = pdf_new_array(doc, n?(n-1):0);
-
- fz_try(ctx)
- {
- for (i = 0; i < n; i++)
- {
- pdf_obj *obj = pdf_array_get(old_annot_arr, i);
-
- if (obj != annot->obj)
- pdf_array_push(annot_arr, obj);
- }
-
- if (pdf_is_indirect(old_annot_arr))
- pdf_update_object(doc, pdf_to_num(old_annot_arr), annot_arr);
- else
- pdf_dict_puts(page->me, "Annots", annot_arr);
-
- if (pdf_is_indirect(annot->obj))
- pdf_delete_object(doc, pdf_to_num(annot->obj));
- }
- fz_always(ctx)
- {
- pdf_drop_obj(annot_arr);
- }
- fz_catch(ctx)
- {
- fz_rethrow(ctx);
- }
- }
-
- pdf_drop_obj(annot->obj);
- annot->obj = NULL;
- doc->dirty = 1;
-}
-
-void
-pdf_set_markup_annot_quadpoints(pdf_document *doc, pdf_annot *annot, fz_point *qp, int n)
-{
- fz_matrix ctm;
- pdf_obj *arr = pdf_new_array(doc, n*2);
- int i;
-
- fz_invert_matrix(&ctm, &annot->page->ctm);
-
- pdf_dict_puts_drop(annot->obj, "QuadPoints", arr);
-
- for (i = 0; i < n; i++)
- {
- fz_point pt = qp[i];
- pdf_obj *r;
-
- fz_transform_point(&pt, &ctm);
- r = pdf_new_real(doc, pt.x);
- pdf_array_push_drop(arr, r);
- r = pdf_new_real(doc, pt.y);
- pdf_array_push_drop(arr, r);
- }
-}
-
-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(doc, 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(doc, 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(doc, pt.x));
- pdf_array_push_drop(arc, pdf_new_real(doc, pt.y));
- k++;
- }
- }
-
- /*
- 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;
- }
-
- pdf_dict_puts_drop(annot->obj, "Rect", pdf_new_rect(doc, &rect));
- update_rect(ctx, annot);
-
- bs = pdf_new_dict(doc, 1);
- pdf_dict_puts_drop(annot->obj, "BS", bs);
- pdf_dict_puts_drop(bs, "W", pdf_new_real(doc, thickness));
-
- col = pdf_new_array(doc, 3);
- pdf_dict_puts_drop(annot->obj, "C", col);
- for (i = 0; i < 3; i++)
- pdf_array_push_drop(col, pdf_new_real(doc, color[i]));
-}
-
-static void find_free_font_name(pdf_obj *fdict, char *buf, int buf_size)
-{
- int i;
-
- /* Find a number X such that /FX doesn't occur as a key in fdict */
- for (i = 0; 1; i++)
- {
- snprintf(buf, buf_size, "F%d", i);
-
- if (!pdf_dict_gets(fdict, buf))
- break;
- }
-}
-
-void pdf_set_text_annot_position(pdf_document *doc, pdf_annot *annot, fz_point pt)
-{
- fz_matrix ctm;
- fz_rect rect;
- int flags;
-
- fz_invert_matrix(&ctm, &annot->page->ctm);
- rect.x0 = pt.x;
- rect.x1 = pt.x + TEXT_ANNOT_SIZE;
- rect.y0 = pt.y;
- rect.y1 = pt.y + TEXT_ANNOT_SIZE;
- fz_transform_rect(&rect, &ctm);
-
- pdf_dict_puts_drop(annot->obj, "Rect", pdf_new_rect(doc, &rect));
-
- flags = pdf_to_int(pdf_dict_gets(annot->obj, "F"));
- flags |= (F_NoZoom|F_NoRotate);
- pdf_dict_puts_drop(annot->obj, "F", pdf_new_int(doc, flags));
-
- update_rect(doc->ctx, annot);
-}
-
-void pdf_set_annot_contents(pdf_document *doc, pdf_annot *annot, char *text)
-{
- pdf_dict_puts_drop(annot->obj, "Contents", pdf_new_string(doc, text, strlen(text)));
-}
-
-char *pdf_annot_contents(pdf_document *doc, pdf_annot *annot)
-{
- return pdf_to_str_buf(pdf_dict_getp(annot->obj, "Contents"));
-}
-
-void pdf_set_free_text_details(pdf_document *doc, pdf_annot *annot, fz_point *pos, char *text, char *font_name, float font_size, float color[3])
-{
- fz_context *ctx = doc->ctx;
- char nbuf[32];
- pdf_obj *dr;
- pdf_obj *form_fonts;
- pdf_obj *font = NULL;
- pdf_obj *ref;
- pdf_font_desc *font_desc = NULL;
- pdf_da_info da_info;
- fz_buffer *fzbuf = NULL;
- fz_matrix ctm;
- fz_point page_pos;
-
- fz_invert_matrix(&ctm, &annot->page->ctm);
-
- dr = pdf_dict_gets(annot->page->me, "Resources");
- if (!dr)
- {
- dr = pdf_new_dict(doc, 1);
- pdf_dict_putp_drop(annot->page->me, "Resources", dr);
- }
-
- /* Ensure the resource dictionary includes a font dict */
- form_fonts = pdf_dict_gets(dr, "Font");
- if (!form_fonts)
- {
- form_fonts = pdf_new_dict(doc, 1);
- pdf_dict_puts_drop(dr, "Font", form_fonts);
- /* form_fonts is still valid if execution continues past the above call */
- }
-
- fz_var(fzbuf);
- fz_var(font);
- fz_try(ctx)
- {
- unsigned char *da_str;
- int da_len;
- fz_rect bounds;
-
- find_free_font_name(form_fonts, nbuf, sizeof(nbuf));
-
- font = pdf_new_dict(doc, 5);
- ref = pdf_new_ref(doc, font);
- pdf_dict_puts_drop(form_fonts, nbuf, ref);
-
- pdf_dict_puts_drop(font, "Type", pdf_new_name(doc, "Font"));
- pdf_dict_puts_drop(font, "Subtype", pdf_new_name(doc, "Type1"));
- pdf_dict_puts_drop(font, "BaseFont", pdf_new_name(doc, font_name));
- pdf_dict_puts_drop(font, "Encoding", pdf_new_name(doc, "WinAnsiEncoding"));
-
- memcpy(da_info.col, color, sizeof(float)*3);
- da_info.col_size = 3;
- da_info.font_name = nbuf;
- da_info.font_size = font_size;
-
- fzbuf = fz_new_buffer(ctx, 0);
- pdf_fzbuf_print_da(ctx, fzbuf, &da_info);
-
- da_len = fz_buffer_storage(ctx, fzbuf, &da_str);
- pdf_dict_puts_drop(annot->obj, "DA", pdf_new_string(doc, (char *)da_str, da_len));
-
- /* FIXME: should convert to WinAnsiEncoding */
- pdf_dict_puts_drop(annot->obj, "Contents", pdf_new_string(doc, text, strlen(text)));
-
- font_desc = pdf_load_font(doc, NULL, font, 0);
- pdf_measure_text(ctx, font_desc, (unsigned char *)text, strlen(text), &bounds);
-
- page_pos = *pos;
- fz_transform_point(&page_pos, &ctm);
-
- bounds.x0 *= font_size;
- bounds.x1 *= font_size;
- bounds.y0 *= font_size;
- bounds.y1 *= font_size;
-
- bounds.x0 += page_pos.x;
- bounds.x1 += page_pos.x;
- bounds.y0 += page_pos.y;
- bounds.y1 += page_pos.y;
-
- pdf_dict_puts_drop(annot->obj, "Rect", pdf_new_rect(doc, &bounds));
- update_rect(ctx, annot);
- }
- fz_always(ctx)
- {
- pdf_drop_obj(font);
- fz_drop_buffer(ctx, fzbuf);
- pdf_drop_font(ctx, font_desc);
- }
- fz_catch(ctx)
- {
- fz_rethrow(ctx);
- }
-}