summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2016-07-06 13:15:49 +0200
committerTor Andersson <tor.andersson@artifex.com>2016-07-06 15:49:55 +0200
commitf0eabc17d6ec113c6e765ac3272f19623a6cbd4e (patch)
tree873d91bfbc610d70e571358550c59d24c8b64ed2
parentc3944e2e1cfb4ac86a8580829376357e1d5bccda (diff)
downloadmupdf-f0eabc17d6ec113c6e765ac3272f19623a6cbd4e.tar.xz
Start slimming pdf_page.
We want to turn pdf_page into a thin wrapper around a pdf_obj, so that any updates to the underlying PDF objects will be reflected without having to reload the pdf_page.
-rw-r--r--include/mupdf/fitz/document.h14
-rw-r--r--include/mupdf/pdf/annot.h5
-rw-r--r--include/mupdf/pdf/page.h21
-rw-r--r--platform/x11/pdfapp.c5
-rw-r--r--source/fitz/document.c4
-rw-r--r--source/pdf/pdf-annot-edit.c40
-rw-r--r--source/pdf/pdf-annot.c13
-rw-r--r--source/pdf/pdf-appearance.c29
-rw-r--r--source/pdf/pdf-clean-file.c2
-rw-r--r--source/pdf/pdf-clean.c63
-rw-r--r--source/pdf/pdf-interpret.c2
-rw-r--r--source/pdf/pdf-page.c294
-rw-r--r--source/pdf/pdf-run.c23
-rw-r--r--source/pdf/pdf-xref.c9
-rw-r--r--source/tools/pdfmerge.c2
-rw-r--r--source/tools/pdfposter.c24
16 files changed, 269 insertions, 281 deletions
diff --git a/include/mupdf/fitz/document.h b/include/mupdf/fitz/document.h
index 1f3f474d..889b66b1 100644
--- a/include/mupdf/fitz/document.h
+++ b/include/mupdf/fitz/document.h
@@ -40,7 +40,7 @@ typedef fz_link *(fz_page_load_links_fn)(fz_context *ctx, fz_page *page);
typedef fz_rect *(fz_page_bound_page_fn)(fz_context *ctx, fz_page *page, fz_rect *);
typedef void (fz_page_run_page_contents_fn)(fz_context *ctx, fz_page *page, fz_device *dev, const fz_matrix *transform, fz_cookie *cookie);
typedef void (fz_page_drop_page_imp_fn)(fz_context *ctx, fz_page *page);
-typedef fz_transition *(fz_page_page_presentation_fn)(fz_context *ctx, fz_page *page, float *duration);
+typedef fz_transition *(fz_page_page_presentation_fn)(fz_context *ctx, fz_page *page, fz_transition *transition, float *duration);
typedef fz_annot *(fz_page_first_annot_fn)(fz_context *ctx, fz_page *page);
@@ -334,15 +334,15 @@ void *fz_new_annot(fz_context *ctx, int size);
/*
fz_page_presentation: Get the presentation details for a given page.
- duration: NULL, or a pointer to a place to set the page duration in
- seconds. (Will be set to 0 if unspecified).
+ transition: A pointer to a transition struct to fill out.
- Returns: a pointer to a transition structure, or NULL if there isn't
- one.
+ duration: A pointer to a place to set the page duration in seconds.
+ Will be set to 0 if no transition is specified for the page.
- Does not throw exceptions.
+ Returns: a pointer to a the transition structure, or NULL if there is no
+ transition specified for the page.
*/
-fz_transition *fz_page_presentation(fz_context *ctx, fz_page *page, float *duration);
+fz_transition *fz_page_presentation(fz_context *ctx, fz_page *page, fz_transition *transition, float *duration);
/*
fz_has_permission: Check permission flags on document.
diff --git a/include/mupdf/pdf/annot.h b/include/mupdf/pdf/annot.h
index ed18aae1..e6ea5b8d 100644
--- a/include/mupdf/pdf/annot.h
+++ b/include/mupdf/pdf/annot.h
@@ -59,6 +59,7 @@ struct pdf_annot_s
{
fz_annot super;
pdf_page *page;
+ fz_matrix page_ctm, inv_page_ctm;
pdf_obj *obj;
fz_rect rect;
fz_rect pagerect;
@@ -81,7 +82,7 @@ pdf_obj *pdf_load_name_tree(fz_context *ctx, pdf_document *doc, pdf_obj *which);
fz_link *pdf_load_link_annots(fz_context *ctx, pdf_document *, pdf_obj *annots, const fz_matrix *page_ctm);
void pdf_transform_annot(fz_context *ctx, pdf_annot *annot);
-void pdf_load_annots(fz_context *ctx, pdf_document *, pdf_page *page, pdf_obj *annots);
+void pdf_load_annots(fz_context *ctx, pdf_document *, pdf_page *page, pdf_obj *annots, const fz_matrix *page_transform);
void pdf_update_annot(fz_context *ctx, pdf_document *, pdf_annot *annot);
void pdf_drop_annots(fz_context *ctx, pdf_annot *annot_list);
@@ -155,6 +156,6 @@ pdf_annot *pdf_poll_changed_annot(fz_context *ctx, pdf_document *idoc, pdf_page
/*
pdf_new_annot: Internal function for creating a new pdf annotation.
*/
-pdf_annot *pdf_new_annot(fz_context *ctx, pdf_page *page);
+pdf_annot *pdf_new_annot(fz_context *ctx, pdf_page *page, const fz_matrix *page_ctm, const fz_matrix *inv_page_ctm);
#endif
diff --git a/include/mupdf/pdf/page.h b/include/mupdf/pdf/page.h
index 43634d46..e3efb1e7 100644
--- a/include/mupdf/pdf/page.h
+++ b/include/mupdf/pdf/page.h
@@ -19,7 +19,7 @@ int pdf_lookup_anchor(fz_context *ctx, pdf_document *doc, const char *name);
Copy any inheritable page keys into the actual page object, removing
any dependencies on the page tree parents.
*/
-void pdf_flatten_inheritable_page_items(fz_context *ctx, pdf_document *doc, pdf_obj *page);
+void pdf_flatten_inheritable_page_items(fz_context *ctx, pdf_obj *page);
/*
pdf_load_page: Load a page and its resources.
@@ -32,9 +32,12 @@ void pdf_flatten_inheritable_page_items(fz_context *ctx, pdf_document *doc, pdf_
number: page number, where 0 is the first page of the document.
*/
pdf_page *pdf_load_page(fz_context *ctx, pdf_document *doc, int number);
-
void pdf_drop_page(fz_context *ctx, pdf_page *page);
+void pdf_page_transform(fz_context *ctx, pdf_page *page, fz_rect *mediabox, fz_matrix *ctm);
+pdf_obj *pdf_page_resources(fz_context *ctx, pdf_page *page);
+pdf_obj *pdf_page_contents(fz_context *ctx, pdf_page *page);
+
fz_link *pdf_load_links(fz_context *ctx, pdf_page *page);
/*
@@ -159,7 +162,7 @@ void pdf_clean_annot_contents(fz_context *ctx, pdf_document *doc, pdf_annot *ann
/*
Presentation interface.
*/
-fz_transition *pdf_page_presentation(fz_context *ctx, pdf_page *page, float *duration);
+fz_transition *pdf_page_presentation(fz_context *ctx, pdf_page *page, fz_transition *transition, float *duration);
/*
* Page tree, pages and related objects
@@ -169,23 +172,17 @@ struct pdf_page_s
{
fz_page super;
pdf_document *doc;
+ pdf_obj *obj;
- fz_matrix ctm; /* calculated from mediabox and rotate */
- fz_rect mediabox;
- int rotate;
int transparency;
- pdf_obj *resources;
- pdf_obj *contents;
+
fz_link *links;
pdf_annot *annots;
pdf_annot **annot_tailp;
pdf_annot *changed_annots;
pdf_annot *deleted_annots;
pdf_annot *tmp_annots;
- pdf_obj *me;
- float duration;
- int transition_present;
- fz_transition transition;
+
int incomplete;
};
diff --git a/platform/x11/pdfapp.c b/platform/x11/pdfapp.c
index 532c217b..c3231995 100644
--- a/platform/x11/pdfapp.c
+++ b/platform/x11/pdfapp.c
@@ -907,7 +907,6 @@ static void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage, int repai
if (transition)
{
- fz_transition *new_trans;
app->new_image = app->image;
app->image = NULL;
if (app->grayscale)
@@ -916,9 +915,7 @@ static void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage, int repai
colorspace = app->colorspace;
app->image = fz_new_pixmap_with_bbox(app->ctx, colorspace, &ibounds, app->image->alpha);
app->duration = 0;
- new_trans = fz_page_presentation(app->ctx, app->page, &app->duration);
- if (new_trans)
- app->transition = *new_trans;
+ fz_page_presentation(app->ctx, app->page, &app->transition, &app->duration);
if (app->duration == 0)
app->duration = 5;
app->in_transit = fz_generate_transition(app->ctx, app->image, app->old_image, app->new_image, 0, &app->transition);
diff --git a/source/fitz/document.c b/source/fitz/document.c
index 5c913012..02c30459 100644
--- a/source/fitz/document.c
+++ b/source/fitz/document.c
@@ -398,7 +398,7 @@ fz_drop_page(fz_context *ctx, fz_page *page)
}
fz_transition *
-fz_page_presentation(fz_context *ctx, fz_page *page, float *duration)
+fz_page_presentation(fz_context *ctx, fz_page *page, fz_transition *transition, float *duration)
{
float dummy;
if (duration)
@@ -406,7 +406,7 @@ fz_page_presentation(fz_context *ctx, fz_page *page, float *duration)
else
duration = &dummy;
if (page && page->page_presentation && page)
- return page->page_presentation(ctx, page, duration);
+ return page->page_presentation(ctx, page, transition, duration);
return NULL;
}
diff --git a/source/pdf/pdf-annot-edit.c b/source/pdf/pdf-annot-edit.c
index e09a6129..4aa856b0 100644
--- a/source/pdf/pdf-annot-edit.c
+++ b/source/pdf/pdf-annot-edit.c
@@ -92,6 +92,8 @@ pdf_create_annot(fz_context *ctx, pdf_document *doc, pdf_page *page, fz_annot_ty
pdf_annot *annot = NULL;
pdf_obj *annot_obj = pdf_new_dict(ctx, doc, 0);
pdf_obj *ind_obj = NULL;
+ fz_rect mediabox;
+ fz_matrix page_ctm, inv_page_ctm;
fz_var(annot);
fz_var(ind_obj);
@@ -100,11 +102,11 @@ pdf_create_annot(fz_context *ctx, pdf_document *doc, pdf_page *page, fz_annot_ty
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_get(ctx, page->me, PDF_NAME_Annots);
+ pdf_obj *annot_arr = pdf_dict_get(ctx, page->obj, PDF_NAME_Annots);
if (annot_arr == NULL)
{
annot_arr = pdf_new_array(ctx, doc, 0);
- pdf_dict_put_drop(ctx, page->me, PDF_NAME_Annots, annot_arr);
+ pdf_dict_put_drop(ctx, page->obj, PDF_NAME_Annots, annot_arr);
}
pdf_dict_put_drop(ctx, annot_obj, PDF_NAME_Type, PDF_NAME_Annot);
@@ -115,7 +117,10 @@ pdf_create_annot(fz_context *ctx, pdf_document *doc, pdf_page *page, fz_annot_ty
/* Make printable as default */
pdf_dict_put_drop(ctx, annot_obj, PDF_NAME_F, pdf_new_int(ctx, doc, F_Print));
- annot = pdf_new_annot(ctx, page);
+ pdf_page_transform(ctx, page, &mediabox, &page_ctm);
+ fz_invert_matrix(&inv_page_ctm, &page_ctm);
+
+ annot = pdf_new_annot(ctx, page, &page_ctm, &inv_page_ctm);
annot->rect = rect;
annot->pagerect = rect;
annot->ap = NULL;
@@ -191,7 +196,7 @@ pdf_delete_annot(fz_context *ctx, pdf_document *doc, pdf_page *page, pdf_annot *
annot->ap = NULL;
/* Recreate the "Annots" array with this annot removed */
- old_annot_arr = pdf_dict_get(ctx, page->me, PDF_NAME_Annots);
+ old_annot_arr = pdf_dict_get(ctx, page->obj, PDF_NAME_Annots);
if (old_annot_arr)
{
@@ -211,7 +216,7 @@ pdf_delete_annot(fz_context *ctx, pdf_document *doc, pdf_page *page, pdf_annot *
if (pdf_is_indirect(ctx, old_annot_arr))
pdf_update_object(ctx, doc, pdf_to_num(ctx, old_annot_arr), annot_arr);
else
- pdf_dict_put(ctx, page->me, PDF_NAME_Annots, annot_arr);
+ pdf_dict_put(ctx, page->obj, PDF_NAME_Annots, annot_arr);
if (pdf_is_indirect(ctx, annot->obj))
pdf_delete_object(ctx, doc, pdf_to_num(ctx, annot->obj));
@@ -234,12 +239,9 @@ pdf_delete_annot(fz_context *ctx, pdf_document *doc, pdf_page *page, pdf_annot *
void
pdf_set_markup_annot_quadpoints(fz_context *ctx, pdf_document *doc, pdf_annot *annot, fz_point *qp, int n)
{
- fz_matrix ctm;
pdf_obj *arr = pdf_new_array(ctx, doc, n*2);
int i;
- fz_invert_matrix(&ctm, &annot->page->ctm);
-
pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_QuadPoints, arr);
for (i = 0; i < n; i++)
@@ -247,7 +249,7 @@ pdf_set_markup_annot_quadpoints(fz_context *ctx, pdf_document *doc, pdf_annot *a
fz_point pt = qp[i];
pdf_obj *r;
- fz_transform_point(&pt, &ctm);
+ fz_transform_point(&pt, &annot->inv_page_ctm);
r = pdf_new_real(ctx, doc, pt.x);
pdf_array_push_drop(ctx, arr, r);
r = pdf_new_real(ctx, doc, pt.y);
@@ -259,20 +261,17 @@ static void update_rect(fz_context *ctx, pdf_annot *annot)
{
pdf_to_rect(ctx, pdf_dict_get(ctx, annot->obj, PDF_NAME_Rect), &annot->rect);
annot->pagerect = annot->rect;
- fz_transform_rect(&annot->pagerect, &annot->page->ctm);
+ fz_transform_rect(&annot->pagerect, &annot->page_ctm);
}
void
pdf_set_ink_annot_list(fz_context *ctx, pdf_document *doc, pdf_annot *annot, fz_point *pts, int *counts, int ncount, float color[3], float thickness)
{
- fz_matrix ctm;
pdf_obj *list = pdf_new_array(ctx, doc, ncount);
pdf_obj *bs, *col;
fz_rect rect;
int i, k = 0;
- fz_invert_matrix(&ctm, &annot->page->ctm);
-
pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_InkList, list);
for (i = 0; i < ncount; i++)
@@ -286,7 +285,7 @@ pdf_set_ink_annot_list(fz_context *ctx, pdf_document *doc, pdf_annot *annot, fz_
{
fz_point pt = pts[k];
- fz_transform_point(&pt, &ctm);
+ fz_transform_point(&pt, &annot->inv_page_ctm);
if (i == 0 && j == 0)
{
@@ -346,16 +345,14 @@ static void find_free_font_name(fz_context *ctx, pdf_obj *fdict, char *buf, int
void pdf_set_text_annot_position(fz_context *ctx, 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);
+ fz_transform_rect(&rect, &annot->inv_page_ctm);
pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_Rect, pdf_new_rect(ctx, doc, &rect));
@@ -401,16 +398,13 @@ void pdf_set_free_text_details(fz_context *ctx, pdf_document *doc, pdf_annot *an
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_get(ctx, annot->page->me, PDF_NAME_Resources);
+ dr = pdf_dict_get(ctx, annot->page->obj, PDF_NAME_Resources);
if (!dr)
{
dr = pdf_new_dict(ctx, doc, 1);
- pdf_dict_put_drop(ctx, annot->page->me, PDF_NAME_Resources, dr);
+ pdf_dict_put_drop(ctx, annot->page->obj, PDF_NAME_Resources, dr);
}
/* Ensure the resource dictionary includes a font dict */
@@ -459,7 +453,7 @@ void pdf_set_free_text_details(fz_context *ctx, pdf_document *doc, pdf_annot *an
pdf_measure_text(ctx, font_desc, (unsigned char *)text, strlen(text), &bounds);
page_pos = *pos;
- fz_transform_point(&page_pos, &ctm);
+ fz_transform_point(&page_pos, &annot->inv_page_ctm);
bounds.x0 *= font_size;
bounds.x1 *= font_size;
diff --git a/source/pdf/pdf-annot.c b/source/pdf/pdf-annot.c
index a81108dc..830e2091 100644
--- a/source/pdf/pdf-annot.c
+++ b/source/pdf/pdf-annot.c
@@ -481,7 +481,7 @@ fz_annot_type pdf_annot_obj_type(fz_context *ctx, pdf_obj *obj)
return -1;
}
-pdf_annot *pdf_new_annot(fz_context *ctx, pdf_page *page)
+pdf_annot *pdf_new_annot(fz_context *ctx, pdf_page *page, const fz_matrix *page_ctm, const fz_matrix *inv_page_ctm)
{
pdf_annot *annot = fz_new_annot(ctx, sizeof(pdf_annot));
@@ -491,21 +491,26 @@ pdf_annot *pdf_new_annot(fz_context *ctx, pdf_page *page)
annot->super.next_annot = (fz_annot_next_fn*)pdf_next_annot;
annot->page = page;
+ annot->page_ctm = *page_ctm;
+ annot->inv_page_ctm = *inv_page_ctm;
return annot;
}
void
-pdf_load_annots(fz_context *ctx, pdf_document *doc, pdf_page *page, pdf_obj *annots)
+pdf_load_annots(fz_context *ctx, pdf_document *doc, pdf_page *page, pdf_obj *annots, const fz_matrix *page_ctm)
{
pdf_annot *annot, **itr;
pdf_obj *obj, *ap, *as, *n, *rect;
int i, len, keep_annot;
+ fz_matrix inv_page_ctm;
fz_var(annot);
fz_var(itr);
fz_var(keep_annot);
+ fz_invert_matrix(&inv_page_ctm, page_ctm);
+
itr = &page->annots;
len = pdf_array_len(ctx, annots);
@@ -521,7 +526,7 @@ pdf_load_annots(fz_context *ctx, pdf_document *doc, pdf_page *page, pdf_obj *ann
{
obj = pdf_array_get(ctx, annots, i);
- annot = pdf_new_annot(ctx, page);
+ annot = pdf_new_annot(ctx, page, page_ctm, &inv_page_ctm);
*itr = annot;
annot->obj = pdf_keep_obj(ctx, obj);
itr = &annot->next;
@@ -578,7 +583,7 @@ pdf_load_annots(fz_context *ctx, pdf_document *doc, pdf_page *page, pdf_obj *ann
pdf_to_rect(ctx, rect, &annot->rect);
annot->pagerect = annot->rect;
- fz_transform_rect(&annot->pagerect, &page->ctm);
+ fz_transform_rect(&annot->pagerect, page_ctm);
annot->ap = NULL;
annot->annot_type = pdf_annot_obj_type(ctx, obj);
annot->widget_type = annot->annot_type == FZ_ANNOT_WIDGET ? pdf_field_type(ctx, doc, obj) : PDF_WIDGET_TYPE_NOT_WIDGET;
diff --git a/source/pdf/pdf-appearance.c b/source/pdf/pdf-appearance.c
index 029b131d..234949b4 100644
--- a/source/pdf/pdf-appearance.c
+++ b/source/pdf/pdf-appearance.c
@@ -1568,30 +1568,25 @@ static void update_rect(fz_context *ctx, pdf_annot *annot)
{
pdf_to_rect(ctx, pdf_dict_get(ctx, annot->obj, PDF_NAME_Rect), &annot->rect);
annot->pagerect = annot->rect;
- fz_transform_rect(&annot->pagerect, &annot->page->ctm);
+ fz_transform_rect(&annot->pagerect, &annot->page_ctm);
}
void pdf_set_annot_appearance(fz_context *ctx, pdf_document *doc, pdf_annot *annot, fz_rect *rect, fz_display_list *disp_list)
{
pdf_obj *obj = annot->obj;
- const fz_matrix *page_ctm = &annot->page->ctm;
- fz_matrix ctm;
- fz_matrix mat = fz_identity;
fz_device *dev = NULL;
pdf_xobject *xobj = NULL;
pdf_obj *resources;
fz_buffer *contents;
- fz_invert_matrix(&ctm, page_ctm);
-
fz_var(dev);
fz_try(ctx)
{
pdf_obj *ap_obj;
fz_rect trect = *rect;
- fz_transform_rect(&trect, &ctm);
+ fz_transform_rect(&trect, &annot->inv_page_ctm);
pdf_dict_put_drop(ctx, obj, PDF_NAME_Rect, pdf_new_rect(ctx, doc, &trect));
@@ -1602,7 +1597,7 @@ void pdf_set_annot_appearance(fz_context *ctx, pdf_document *doc, pdf_annot *ann
if (ap_obj == NULL)
{
- ap_obj = pdf_new_xobject(ctx, doc, &trect, &mat);
+ ap_obj = pdf_new_xobject(ctx, doc, &trect, &fz_identity);
pdf_dict_putl_drop(ctx, obj, ap_obj, PDF_NAME_AP, PDF_NAME_N, NULL);
}
else
@@ -1610,7 +1605,7 @@ void pdf_set_annot_appearance(fz_context *ctx, pdf_document *doc, pdf_annot *ann
pdf_xref_ensure_incremental_object(ctx, doc, pdf_to_num(ctx, ap_obj));
/* Update bounding box and matrix in reused xobject obj */
pdf_dict_put_drop(ctx, ap_obj, PDF_NAME_BBox, pdf_new_rect(ctx, doc, &trect));
- pdf_dict_put_drop(ctx, ap_obj, PDF_NAME_Matrix, pdf_new_matrix(ctx, doc, &mat));
+ pdf_dict_put_drop(ctx, ap_obj, PDF_NAME_Matrix, pdf_new_matrix(ctx, doc, &fz_identity));
}
resources = pdf_dict_get(ctx, ap_obj, PDF_NAME_Resources);
@@ -1618,7 +1613,7 @@ void pdf_set_annot_appearance(fz_context *ctx, pdf_document *doc, pdf_annot *ann
contents = fz_new_buffer(ctx, 0);
dev = pdf_new_pdf_device(ctx, doc, &fz_identity, &trect, resources, contents);
- fz_run_display_list(ctx, disp_list, dev, &ctm, &fz_infinite_rect, NULL);
+ fz_run_display_list(ctx, disp_list, dev, &annot->inv_page_ctm, &fz_infinite_rect, NULL);
fz_drop_device(ctx, dev);
pdf_update_stream(ctx, doc, ap_obj, contents, 0);
@@ -1630,7 +1625,7 @@ void pdf_set_annot_appearance(fz_context *ctx, pdf_document *doc, pdf_annot *ann
{
/* Update bounding box and matrix also in the xobject structure */
xobj->bbox = trect;
- xobj->matrix = mat;
+ xobj->matrix = fz_identity;
xobj->iteration++;
pdf_drop_xobject(ctx, xobj);
}
@@ -1685,7 +1680,7 @@ quadpoints(fz_context *ctx, pdf_document *doc, pdf_obj *annot, int *nout)
void pdf_set_markup_appearance(fz_context *ctx, pdf_document *doc, pdf_annot *annot, float color[3], float alpha, float line_thickness, float line_height)
{
- const fz_matrix *page_ctm = &annot->page->ctm;
+ const fz_matrix *page_ctm = &annot->page_ctm;
fz_path *path = NULL;
fz_stroke_state *stroke = NULL;
fz_device *dev = NULL;
@@ -1793,7 +1788,7 @@ static fz_colorspace *pdf_to_color(fz_context *ctx, pdf_document *doc, pdf_obj *
void pdf_update_ink_appearance(fz_context *ctx, pdf_document *doc, pdf_annot *annot)
{
- const fz_matrix *page_ctm = &annot->page->ctm;
+ const fz_matrix *page_ctm = &annot->page_ctm;
fz_path *path = NULL;
fz_stroke_state *stroke = NULL;
fz_device *dev = NULL;
@@ -2090,7 +2085,7 @@ void pdf_update_text_annot_appearance(fz_context *ctx, pdf_document *doc, pdf_an
static float yellow[3] = {1.0, 1.0, 0.0};
static float black[3] = {0.0, 0.0, 0.0};
- const fz_matrix *page_ctm = &annot->page->ctm;
+ const fz_matrix *page_ctm = &annot->page_ctm;
fz_display_list *dlist = NULL;
fz_device *dev = NULL;
fz_colorspace *cs = NULL;
@@ -2156,9 +2151,9 @@ void pdf_update_text_annot_appearance(fz_context *ctx, pdf_document *doc, pdf_an
void pdf_update_free_text_annot_appearance(fz_context *ctx, pdf_document *doc, pdf_annot *annot)
{
- const fz_matrix *page_ctm = &annot->page->ctm;
+ const fz_matrix *page_ctm = &annot->page_ctm;
pdf_obj *obj = annot->obj;
- pdf_obj *dr = pdf_dict_get(ctx, annot->page->me, PDF_NAME_Resources);
+ pdf_obj *dr = pdf_dict_get(ctx, annot->page->obj, PDF_NAME_Resources);
fz_display_list *dlist = NULL;
fz_device *dev = NULL;
font_info font_rec;
@@ -2340,7 +2335,7 @@ static float logo_color[3] = {(float)0x25/(float)0xFF, (float)0x72/(float)0xFF,
void pdf_set_signature_appearance(fz_context *ctx, pdf_document *doc, pdf_annot *annot, char *name, char *dn, char *date)
{
- const fz_matrix *page_ctm = &annot->page->ctm;
+ const fz_matrix *page_ctm = &annot->page_ctm;
pdf_obj *obj = annot->obj;
pdf_obj *dr = pdf_dict_getl(ctx, pdf_trailer(ctx, doc), PDF_NAME_Root, PDF_NAME_AcroForm, PDF_NAME_DR, NULL);
fz_display_list *dlist = NULL;
diff --git a/source/pdf/pdf-clean-file.c b/source/pdf/pdf-clean-file.c
index 0464e8cc..b261aa91 100644
--- a/source/pdf/pdf-clean-file.c
+++ b/source/pdf/pdf-clean-file.c
@@ -29,7 +29,7 @@ static void retainpage(fz_context *ctx, pdf_document *doc, pdf_obj *parent, pdf_
{
pdf_obj *pageref = pdf_lookup_page_obj(ctx, doc, page-1);
- pdf_flatten_inheritable_page_items(ctx, doc, pageref);
+ pdf_flatten_inheritable_page_items(ctx, pageref);
pdf_dict_put(ctx, pageref, PDF_NAME_Parent, parent);
diff --git a/source/pdf/pdf-clean.c b/source/pdf/pdf-clean.c
index d09cc4f7..ff54e6e7 100644
--- a/source/pdf/pdf-clean.c
+++ b/source/pdf/pdf-clean.c
@@ -132,16 +132,17 @@ void pdf_clean_page_contents(fz_context *ctx, pdf_document *doc, pdf_page *page,
pdf_processor *proc_filter = NULL;
pdf_obj *new_obj = NULL;
pdf_obj *new_ref = NULL;
+ pdf_obj *res_ref = NULL;
pdf_obj *res = NULL;
- pdf_obj *ref = NULL;
pdf_obj *obj;
pdf_obj *contents;
+ pdf_obj *resources;
fz_buffer *buffer;
fz_var(new_obj);
fz_var(new_ref);
fz_var(res);
- fz_var(ref);
+ fz_var(res_ref);
fz_var(proc_buffer);
fz_var(proc_filter);
@@ -151,20 +152,23 @@ void pdf_clean_page_contents(fz_context *ctx, pdf_document *doc, pdf_page *page,
{
res = pdf_new_dict(ctx, doc, 1);
+ contents = pdf_page_contents(ctx, page);
+ resources = pdf_page_resources(ctx, page);
+
proc_buffer = pdf_new_buffer_processor(ctx, buffer, ascii);
- proc_filter = pdf_new_filter_processor(ctx, proc_buffer, doc, page->resources, res);
+ proc_filter = pdf_new_filter_processor(ctx, proc_buffer, doc, resources, res);
- pdf_process_contents(ctx, proc_filter, doc, page->resources, page->contents, cookie);
+ pdf_process_contents(ctx, proc_filter, doc, resources, contents, cookie);
+
+ /* Deal with page content stream. */
- contents = page->contents;
if (pdf_is_array(ctx, contents))
{
/* create a new object to replace the array */
new_obj = pdf_new_dict(ctx, doc, 1);
new_ref = pdf_add_object(ctx, doc, new_obj);
- pdf_drop_obj(ctx, page->contents);
- page->contents = contents = pdf_keep_obj(ctx, new_ref);
- pdf_dict_put(ctx, page->me, PDF_NAME_Contents, contents);
+ contents = new_ref;
+ pdf_dict_put(ctx, page->obj, PDF_NAME_Contents, contents);
}
else
{
@@ -172,6 +176,8 @@ void pdf_clean_page_contents(fz_context *ctx, pdf_document *doc, pdf_page *page,
pdf_dict_del(ctx, contents, PDF_NAME_DecodeParms);
}
+ pdf_update_stream(ctx, doc, contents, buffer, 0);
+
/* Now deal with resources. The spec allows for Type3 fonts and form
* XObjects to omit a resource dictionary and look in the parent.
* Avoid that by flattening here as part of the cleaning. This could
@@ -187,55 +193,45 @@ void pdf_clean_page_contents(fz_context *ctx, pdf_document *doc, pdf_page *page,
for (i = 0; i < l; i++)
{
pdf_obj *o = pdf_dict_get(ctx, pdf_dict_get_val(ctx, obj, i), PDF_NAME_SMask);
-
if (!o)
continue;
o = pdf_dict_get(ctx, o, PDF_NAME_G);
if (!o)
continue;
-
/* Transparency group XObject */
- pdf_clean_stream_object(ctx, doc, o, page->resources, cookie, 1, ascii);
+ pdf_clean_stream_object(ctx, doc, o, resources, cookie, 1, ascii);
}
}
- /* ColorSpace - no cleaning possible */
-
/* Pattern */
obj = pdf_dict_get(ctx, res, PDF_NAME_Pattern);
if (obj)
{
int i, l;
-
l = pdf_dict_len(ctx, obj);
for (i = 0; i < l; i++)
{
pdf_obj *pat = pdf_dict_get_val(ctx, obj, i);
-
if (!pat)
continue;
if (pdf_to_int(ctx, pdf_dict_get(ctx, pat, PDF_NAME_PatternType)) == 1)
- pdf_clean_stream_object(ctx, doc, pat, page->resources, cookie, 0, ascii);
+ pdf_clean_stream_object(ctx, doc, pat, resources, cookie, 0, ascii);
}
}
- /* Shading - no cleaning possible */
-
/* XObject */
obj = pdf_dict_get(ctx, res, PDF_NAME_XObject);
if (obj)
{
int i, l;
-
l = pdf_dict_len(ctx, obj);
for (i = 0; i < l; i++)
{
pdf_obj *xobj = pdf_dict_get_val(ctx, obj, i);
-
- if (!pdf_name_eq(ctx, PDF_NAME_Form, pdf_dict_get(ctx, xobj, PDF_NAME_Subtype)))
+ if (!xobj)
continue;
-
- pdf_clean_stream_object(ctx, doc, xobj, page->resources, cookie, 1, ascii);
+ if (pdf_name_eq(ctx, PDF_NAME_Form, pdf_dict_get(ctx, xobj, PDF_NAME_Subtype)))
+ pdf_clean_stream_object(ctx, doc, xobj, resources, cookie, 1, ascii);
}
}
@@ -244,34 +240,31 @@ void pdf_clean_page_contents(fz_context *ctx, pdf_document *doc, pdf_page *page,
if (obj)
{
int i, l;
-
l = pdf_dict_len(ctx, obj);
for (i = 0; i < l; i++)
{
pdf_obj *o = pdf_dict_get_val(ctx, obj, i);
-
+ if (!o)
+ continue;
if (pdf_name_eq(ctx, PDF_NAME_Type3, pdf_dict_get(ctx, o, PDF_NAME_Subtype)))
- {
- pdf_clean_type3(ctx, doc, o, page->resources, cookie, ascii);
- }
+ pdf_clean_type3(ctx, doc, o, resources, cookie, ascii);
}
}
/* ProcSet - no cleaning possible. Inherit this from the old dict. */
- obj = pdf_dict_get(ctx, page->resources, PDF_NAME_ProcSet);
+ obj = pdf_dict_get(ctx, resources, PDF_NAME_ProcSet);
if (obj)
pdf_dict_put(ctx, res, PDF_NAME_ProcSet, obj);
+ /* ColorSpace - no cleaning possible. */
/* Properties - no cleaning possible. */
if (proc_fn)
(*proc_fn)(ctx, buffer, res, proc_arg);
- pdf_update_stream(ctx, doc, contents, buffer, 0);
- pdf_drop_obj(ctx, page->resources);
- ref = pdf_add_object(ctx, doc, res);
- page->resources = pdf_keep_obj(ctx, ref);
- pdf_dict_put(ctx, page->me, PDF_NAME_Resources, ref);
+ /* Update resource dictionary */
+ res_ref = pdf_add_object(ctx, doc, res);
+ pdf_dict_put(ctx, page->obj, PDF_NAME_Resources, res_ref);
}
fz_always(ctx)
{
@@ -280,8 +273,8 @@ void pdf_clean_page_contents(fz_context *ctx, pdf_document *doc, pdf_page *page,
fz_drop_buffer(ctx, buffer);
pdf_drop_obj(ctx, new_obj);
pdf_drop_obj(ctx, new_ref);
+ pdf_drop_obj(ctx, res_ref);
pdf_drop_obj(ctx, res);
- pdf_drop_obj(ctx, ref);
}
fz_catch(ctx)
{
diff --git a/source/pdf/pdf-interpret.c b/source/pdf/pdf-interpret.c
index af5a0ed5..f3b875cd 100644
--- a/source/pdf/pdf-interpret.c
+++ b/source/pdf/pdf-interpret.c
@@ -1256,7 +1256,7 @@ pdf_process_annot(fz_context *ctx, pdf_processor *proc, pdf_document *doc, pdf_p
proc->op_cm(ctx, proc,
annot->matrix.a, annot->matrix.b, annot->matrix.c,
annot->matrix.d, annot->matrix.e, annot->matrix.f);
- proc->op_Do_form(ctx, proc, NULL, annot->ap, page->resources);
+ proc->op_Do_form(ctx, proc, NULL, annot->ap, pdf_page_resources(ctx, page));
proc->op_Q(ctx, proc);
}
}
diff --git a/source/pdf/pdf-page.c b/source/pdf/pdf-page.c
index 430c033b..6a88412d 100644
--- a/source/pdf/pdf-page.c
+++ b/source/pdf/pdf-page.c
@@ -219,7 +219,7 @@ pdf_lookup_anchor(fz_context *ctx, pdf_document *doc, const char *name)
}
static pdf_obj *
-pdf_lookup_inherited_page_item(fz_context *ctx, pdf_document *doc, pdf_obj *node, pdf_obj *key)
+pdf_lookup_inherited_page_item(fz_context *ctx, pdf_obj *node, pdf_obj *key)
{
pdf_obj *node2 = node;
pdf_obj *val;
@@ -259,28 +259,28 @@ pdf_lookup_inherited_page_item(fz_context *ctx, pdf_document *doc, pdf_obj *node
}
static void
-pdf_flatten_inheritable_page_item(fz_context *ctx, pdf_document *doc, pdf_obj *page, pdf_obj *key)
+pdf_flatten_inheritable_page_item(fz_context *ctx, pdf_obj *page, pdf_obj *key)
{
- pdf_obj *val = pdf_lookup_inherited_page_item(ctx, doc, page, key);
+ pdf_obj *val = pdf_lookup_inherited_page_item(ctx, page, key);
if (val)
pdf_dict_put(ctx, page, key, val);
}
void
-pdf_flatten_inheritable_page_items(fz_context *ctx, pdf_document *doc, pdf_obj *page)
+pdf_flatten_inheritable_page_items(fz_context *ctx, pdf_obj *page)
{
- pdf_flatten_inheritable_page_item(ctx, doc, page, PDF_NAME_MediaBox);
- pdf_flatten_inheritable_page_item(ctx, doc, page, PDF_NAME_CropBox);
- pdf_flatten_inheritable_page_item(ctx, doc, page, PDF_NAME_Rotate);
- pdf_flatten_inheritable_page_item(ctx, doc, page, PDF_NAME_Resources);
+ pdf_flatten_inheritable_page_item(ctx, page, PDF_NAME_MediaBox);
+ pdf_flatten_inheritable_page_item(ctx, page, PDF_NAME_CropBox);
+ pdf_flatten_inheritable_page_item(ctx, page, PDF_NAME_Rotate);
+ pdf_flatten_inheritable_page_item(ctx, page, PDF_NAME_Resources);
}
/* We need to know whether to install a page-level transparency group */
-static int pdf_resources_use_blending(fz_context *ctx, pdf_document *doc, pdf_obj *rdb);
+static int pdf_resources_use_blending(fz_context *ctx, pdf_obj *rdb);
static int
-pdf_extgstate_uses_blending(fz_context *ctx, pdf_document *doc, pdf_obj *dict)
+pdf_extgstate_uses_blending(fz_context *ctx, pdf_obj *dict)
{
pdf_obj *obj = pdf_dict_get(ctx, dict, PDF_NAME_BM);
if (obj && !pdf_name_eq(ctx, obj, PDF_NAME_Normal))
@@ -289,27 +289,27 @@ pdf_extgstate_uses_blending(fz_context *ctx, pdf_document *doc, pdf_obj *dict)
}
static int
-pdf_pattern_uses_blending(fz_context *ctx, pdf_document *doc, pdf_obj *dict)
+pdf_pattern_uses_blending(fz_context *ctx, pdf_obj *dict)
{
pdf_obj *obj;
obj = pdf_dict_get(ctx, dict, PDF_NAME_Resources);
- if (pdf_resources_use_blending(ctx, doc, obj))
+ if (pdf_resources_use_blending(ctx, obj))
return 1;
obj = pdf_dict_get(ctx, dict, PDF_NAME_ExtGState);
- return pdf_extgstate_uses_blending(ctx, doc, obj);
+ return pdf_extgstate_uses_blending(ctx, obj);
}
static int
-pdf_xobject_uses_blending(fz_context *ctx, pdf_document *doc, pdf_obj *dict)
+pdf_xobject_uses_blending(fz_context *ctx, pdf_obj *dict)
{
pdf_obj *obj = pdf_dict_get(ctx, dict, PDF_NAME_Resources);
if (pdf_name_eq(ctx, pdf_dict_getp(ctx, dict, "Group/S"), PDF_NAME_Transparency))
return 1;
- return pdf_resources_use_blending(ctx, doc, obj);
+ return pdf_resources_use_blending(ctx, obj);
}
static int
-pdf_resources_use_blending(fz_context *ctx, pdf_document *doc, pdf_obj *rdb)
+pdf_resources_use_blending(fz_context *ctx, pdf_obj *rdb)
{
pdf_obj *obj;
int i, n, useBM = 0;
@@ -330,19 +330,19 @@ pdf_resources_use_blending(fz_context *ctx, pdf_document *doc, pdf_obj *rdb)
obj = pdf_dict_get(ctx, rdb, PDF_NAME_ExtGState);
n = pdf_dict_len(ctx, obj);
for (i = 0; i < n; i++)
- if (pdf_extgstate_uses_blending(ctx, doc, pdf_dict_get_val(ctx, obj, i)))
+ if (pdf_extgstate_uses_blending(ctx, pdf_dict_get_val(ctx, obj, i)))
goto found;
obj = pdf_dict_get(ctx, rdb, PDF_NAME_Pattern);
n = pdf_dict_len(ctx, obj);
for (i = 0; i < n; i++)
- if (pdf_pattern_uses_blending(ctx, doc, pdf_dict_get_val(ctx, obj, i)))
+ if (pdf_pattern_uses_blending(ctx, pdf_dict_get_val(ctx, obj, i)))
goto found;
obj = pdf_dict_get(ctx, rdb, PDF_NAME_XObject);
n = pdf_dict_len(ctx, obj);
for (i = 0; i < n; i++)
- if (pdf_xobject_uses_blending(ctx, doc, pdf_dict_get_val(ctx, obj, i)))
+ if (pdf_xobject_uses_blending(ctx, pdf_dict_get_val(ctx, obj, i)))
goto found;
if (0)
{
@@ -363,62 +363,65 @@ found:
return useBM;
}
-static void
-pdf_load_transition(fz_context *ctx, pdf_document *doc, pdf_page *page, pdf_obj *transdict)
+fz_transition *
+pdf_page_presentation(fz_context *ctx, pdf_page *page, fz_transition *transition, float *duration)
{
- pdf_obj *name;
- pdf_obj *obj;
- int type;
+ pdf_obj *obj, *transdict;
+
+ *duration = pdf_to_real(ctx, pdf_dict_get(ctx, page->obj, PDF_NAME_Dur));
+
+ transdict = pdf_dict_get(ctx, page->obj, PDF_NAME_Trans);
+ if (!transdict)
+ return NULL;
obj = pdf_dict_get(ctx, transdict, PDF_NAME_D);
- page->transition.duration = (obj ? pdf_to_real(ctx, obj) : 1);
- page->transition.vertical = !pdf_name_eq(ctx, pdf_dict_get(ctx, transdict, PDF_NAME_Dm), PDF_NAME_H);
- page->transition.outwards = !pdf_name_eq(ctx, pdf_dict_get(ctx, transdict, PDF_NAME_M), PDF_NAME_I);
+ transition->duration = (obj ? pdf_to_real(ctx, obj) : 1);
+
+ transition->vertical = !pdf_name_eq(ctx, pdf_dict_get(ctx, transdict, PDF_NAME_Dm), PDF_NAME_H);
+ transition->outwards = !pdf_name_eq(ctx, pdf_dict_get(ctx, transdict, PDF_NAME_M), PDF_NAME_I);
/* FIXME: If 'Di' is None, it should be handled differently, but
* this only affects Fly, and we don't implement that currently. */
- page->transition.direction = (pdf_to_int(ctx, pdf_dict_get(ctx, transdict, PDF_NAME_Di)));
+ transition->direction = (pdf_to_int(ctx, pdf_dict_get(ctx, transdict, PDF_NAME_Di)));
/* FIXME: Read SS for Fly when we implement it */
/* FIXME: Read B for Fly when we implement it */
- name = pdf_dict_get(ctx, transdict, PDF_NAME_S);
- if (pdf_name_eq(ctx, name, PDF_NAME_Split))
- type = FZ_TRANSITION_SPLIT;
- else if (pdf_name_eq(ctx, name, PDF_NAME_Blinds))
- type = FZ_TRANSITION_BLINDS;
- else if (pdf_name_eq(ctx, name, PDF_NAME_Box))
- type = FZ_TRANSITION_BOX;
- else if (pdf_name_eq(ctx, name, PDF_NAME_Wipe))
- type = FZ_TRANSITION_WIPE;
- else if (pdf_name_eq(ctx, name, PDF_NAME_Dissolve))
- type = FZ_TRANSITION_DISSOLVE;
- else if (pdf_name_eq(ctx, name, PDF_NAME_Glitter))
- type = FZ_TRANSITION_GLITTER;
- else if (pdf_name_eq(ctx, name, PDF_NAME_Fly))
- type = FZ_TRANSITION_FLY;
- else if (pdf_name_eq(ctx, name, PDF_NAME_Push))
- type = FZ_TRANSITION_PUSH;
- else if (pdf_name_eq(ctx, name, PDF_NAME_Cover))
- type = FZ_TRANSITION_COVER;
- else if (pdf_name_eq(ctx, name, PDF_NAME_Uncover))
- type = FZ_TRANSITION_UNCOVER;
- else if (pdf_name_eq(ctx, name, PDF_NAME_Fade))
- type = FZ_TRANSITION_FADE;
+ obj = pdf_dict_get(ctx, transdict, PDF_NAME_S);
+ if (pdf_name_eq(ctx, obj, PDF_NAME_Split))
+ transition->type = FZ_TRANSITION_SPLIT;
+ else if (pdf_name_eq(ctx, obj, PDF_NAME_Blinds))
+ transition->type = FZ_TRANSITION_BLINDS;
+ else if (pdf_name_eq(ctx, obj, PDF_NAME_Box))
+ transition->type = FZ_TRANSITION_BOX;
+ else if (pdf_name_eq(ctx, obj, PDF_NAME_Wipe))
+ transition->type = FZ_TRANSITION_WIPE;
+ else if (pdf_name_eq(ctx, obj, PDF_NAME_Dissolve))
+ transition->type = FZ_TRANSITION_DISSOLVE;
+ else if (pdf_name_eq(ctx, obj, PDF_NAME_Glitter))
+ transition->type = FZ_TRANSITION_GLITTER;
+ else if (pdf_name_eq(ctx, obj, PDF_NAME_Fly))
+ transition->type = FZ_TRANSITION_FLY;
+ else if (pdf_name_eq(ctx, obj, PDF_NAME_Push))
+ transition->type = FZ_TRANSITION_PUSH;
+ else if (pdf_name_eq(ctx, obj, PDF_NAME_Cover))
+ transition->type = FZ_TRANSITION_COVER;
+ else if (pdf_name_eq(ctx, obj, PDF_NAME_Uncover))
+ transition->type = FZ_TRANSITION_UNCOVER;
+ else if (pdf_name_eq(ctx, obj, PDF_NAME_Fade))
+ transition->type = FZ_TRANSITION_FADE;
else
- type = FZ_TRANSITION_NONE;
- page->transition.type = type;
+ transition->type = FZ_TRANSITION_NONE;
+
+ return transition;
}
fz_rect *
-pdf_bound_page(fz_context *ctx, pdf_page *page, fz_rect *bounds)
+pdf_bound_page(fz_context *ctx, pdf_page *page, fz_rect *mediabox)
{
- fz_matrix mtx;
- fz_rect mediabox = page->mediabox;
- fz_transform_rect(&mediabox, fz_rotate(&mtx, page->rotate));
- bounds->x0 = bounds->y0 = 0;
- bounds->x1 = mediabox.x1 - mediabox.x0;
- bounds->y1 = mediabox.y1 - mediabox.y0;
- return bounds;
+ fz_matrix page_ctm;
+ pdf_page_transform(ctx, page, mediabox, &page_ctm);
+ fz_transform_rect(mediabox, &page_ctm);
+ return mediabox;
}
fz_link *
@@ -427,6 +430,72 @@ pdf_load_links(fz_context *ctx, pdf_page *page)
return fz_keep_link(ctx, page->links);
}
+pdf_obj *
+pdf_page_resources(fz_context *ctx, pdf_page *page)
+{
+ return pdf_lookup_inherited_page_item(ctx, page->obj, PDF_NAME_Resources);
+}
+
+pdf_obj *
+pdf_page_contents(fz_context *ctx, pdf_page *page)
+{
+ return pdf_dict_get(ctx, page->obj, PDF_NAME_Contents);
+}
+
+void
+pdf_page_transform(fz_context *ctx, pdf_page *page, fz_rect *page_mediabox, fz_matrix *page_ctm)
+{
+ pdf_obj *pageobj = page->obj;
+ pdf_obj *obj;
+ fz_rect mediabox, cropbox, realbox;
+ float userunit = 1;
+ int rotate;
+
+ obj = pdf_dict_get(ctx, pageobj, PDF_NAME_UserUnit);
+ if (pdf_is_real(ctx, obj))
+ userunit = pdf_to_real(ctx, obj);
+
+ pdf_to_rect(ctx, pdf_lookup_inherited_page_item(ctx, pageobj, PDF_NAME_MediaBox), &mediabox);
+ if (fz_is_empty_rect(&mediabox))
+ {
+ mediabox.x0 = 0;
+ mediabox.y0 = 0;
+ mediabox.x1 = 612;
+ mediabox.y1 = 792;
+ }
+
+ pdf_to_rect(ctx, pdf_lookup_inherited_page_item(ctx, pageobj, PDF_NAME_CropBox), &cropbox);
+ if (!fz_is_empty_rect(&cropbox))
+ fz_intersect_rect(&mediabox, &cropbox);
+
+ page_mediabox->x0 = fz_min(mediabox.x0, mediabox.x1);
+ page_mediabox->y0 = fz_min(mediabox.y0, mediabox.y1);
+ page_mediabox->x1 = fz_max(mediabox.x0, mediabox.x1);
+ page_mediabox->y1 = fz_max(mediabox.y0, mediabox.y1);
+
+ if (page_mediabox->x1 - page_mediabox->x0 < 1 || page_mediabox->y1 - page_mediabox->y0 < 1)
+ *page_mediabox = fz_unit_rect;
+
+ rotate = pdf_to_int(ctx, pdf_lookup_inherited_page_item(ctx, pageobj, PDF_NAME_Rotate));
+
+ /* Snap page rotation to 0, 90, 180 or 270 */
+ if (rotate < 0)
+ rotate = 360 - ((-rotate) % 360);
+ if (rotate >= 360)
+ rotate = rotate % 360;
+ rotate = 90*((rotate + 45)/90);
+ if (rotate >= 360)
+ rotate = 0;
+
+ /* Compute transform from fitz' page space (upper left page origin, y descending, 72 dpi)
+ * to PDF user space (arbitary page origin, y ascending, UserUnit dpi). */
+ fz_rotate(page_ctm, -rotate);
+ realbox = *page_mediabox;
+ fz_transform_rect(&realbox, page_ctm);
+ fz_pre_translate(page_ctm, -realbox.x0, -realbox.y1);
+ fz_post_scale(page_ctm, userunit, -userunit);
+}
+
static void
pdf_drop_page_imp(fz_context *ctx, pdf_page *page)
{
@@ -435,8 +504,6 @@ pdf_drop_page_imp(fz_context *ctx, pdf_page *page)
if (page == NULL)
return;
- pdf_drop_obj(ctx, page->resources);
- pdf_drop_obj(ctx, page->contents);
if (page->links)
fz_drop_link(ctx, page->links);
if (page->annots)
@@ -450,7 +517,8 @@ pdf_drop_page_imp(fz_context *ctx, pdf_page *page)
* annotations are destroyed. doc->focus_obj
* keeps track of the actual annotation object. */
doc->focus = NULL;
- pdf_drop_obj(ctx, page->me);
+
+ pdf_drop_obj(ctx, page->obj);
fz_drop_document(ctx, &page->doc->super);
}
@@ -474,8 +542,8 @@ pdf_new_page(fz_context *ctx, pdf_document *doc)
page->super.run_page_contents = (fz_page_run_page_contents_fn *)pdf_run_page_contents;
page->super.page_presentation = (fz_page_page_presentation_fn *)pdf_page_presentation;
- page->resources = NULL;
- page->contents = NULL;
+ page->obj = NULL;
+
page->transparency = 0;
page->links = NULL;
page->annots = NULL;
@@ -483,7 +551,6 @@ pdf_new_page(fz_context *ctx, pdf_document *doc)
page->deleted_annots = NULL;
page->tmp_annots = NULL;
page->incomplete = 0;
- page->me = NULL;
return page;
}
@@ -493,78 +560,31 @@ pdf_load_page(fz_context *ctx, pdf_document *doc, int number)
{
pdf_page *page;
pdf_annot *annot;
- pdf_obj *pageobj, *pageref, *obj;
- fz_rect mediabox, cropbox, realbox;
- float userunit;
- fz_matrix mat;
+ pdf_obj *pageobj, *obj;
if (doc->file_reading_linearly)
{
- pageref = pdf_progressive_advance(ctx, doc, number);
- if (pageref == NULL)
+ pageobj = pdf_progressive_advance(ctx, doc, number);
+ if (pageobj == NULL)
fz_throw(ctx, FZ_ERROR_TRYLATER, "page %d not available yet", number);
}
else
- pageref = pdf_lookup_page_obj(ctx, doc, number);
- pageobj = pdf_resolve_indirect_chain(ctx, pageref);
+ pageobj = pdf_lookup_page_obj(ctx, doc, number);
page = pdf_new_page(ctx, doc);
- page->me = pdf_keep_obj(ctx, pageobj);
-
- obj = pdf_dict_get(ctx, pageobj, PDF_NAME_UserUnit);
- if (pdf_is_real(ctx, obj))
- userunit = pdf_to_real(ctx, obj);
- else
- userunit = 1;
-
- pdf_to_rect(ctx, pdf_lookup_inherited_page_item(ctx, doc, pageobj, PDF_NAME_MediaBox), &mediabox);
- if (fz_is_empty_rect(&mediabox))
- {
- fz_warn(ctx, "cannot find page size for page %d", number + 1);
- mediabox.x0 = 0;
- mediabox.y0 = 0;
- mediabox.x1 = 612;
- mediabox.y1 = 792;
- }
-
- pdf_to_rect(ctx, pdf_lookup_inherited_page_item(ctx, doc, pageobj, PDF_NAME_CropBox), &cropbox);
- if (!fz_is_empty_rect(&cropbox))
- fz_intersect_rect(&mediabox, &cropbox);
-
- page->mediabox.x0 = fz_min(mediabox.x0, mediabox.x1) * userunit;
- page->mediabox.y0 = fz_min(mediabox.y0, mediabox.y1) * userunit;
- page->mediabox.x1 = fz_max(mediabox.x0, mediabox.x1) * userunit;
- page->mediabox.y1 = fz_max(mediabox.y0, mediabox.y1) * userunit;
-
- if (page->mediabox.x1 - page->mediabox.x0 < 1 || page->mediabox.y1 - page->mediabox.y0 < 1)
- {
- fz_warn(ctx, "invalid page size in page %d", number + 1);
- page->mediabox = fz_unit_rect;
- }
-
- page->rotate = pdf_to_int(ctx, pdf_lookup_inherited_page_item(ctx, doc, pageobj, PDF_NAME_Rotate));
- /* Snap page->rotate to 0, 90, 180 or 270 */
- if (page->rotate < 0)
- page->rotate = 360 - ((-page->rotate) % 360);
- if (page->rotate >= 360)
- page->rotate = page->rotate % 360;
- page->rotate = 90*((page->rotate + 45)/90);
- if (page->rotate > 360)
- page->rotate = 0;
-
- fz_pre_rotate(fz_scale(&page->ctm, 1, -1), -page->rotate);
- realbox = page->mediabox;
- fz_transform_rect(&realbox, &page->ctm);
- fz_pre_scale(fz_translate(&mat, -realbox.x0, -realbox.y0), userunit, userunit);
- fz_concat(&page->ctm, &page->ctm, &mat);
+ page->obj = pdf_keep_obj(ctx, pageobj);
+ /* Pre-load annotations and links */
fz_try(ctx)
{
obj = pdf_dict_get(ctx, pageobj, PDF_NAME_Annots);
if (obj)
{
- page->links = pdf_load_link_annots(ctx, doc, obj, &page->ctm);
- pdf_load_annots(ctx, doc, page, obj);
+ fz_rect page_mediabox;
+ fz_matrix page_ctm;
+ pdf_page_transform(ctx, page, &page_mediabox, &page_ctm);
+ page->links = pdf_load_link_annots(ctx, doc, obj, &page_ctm);
+ pdf_load_annots(ctx, doc, page, obj, &page_ctm);
}
}
fz_catch(ctx)
@@ -576,32 +596,16 @@ pdf_load_page(fz_context *ctx, pdf_document *doc, int number)
page->links = NULL;
}
- page->duration = pdf_to_real(ctx, pdf_dict_get(ctx, pageobj, PDF_NAME_Dur));
-
- obj = pdf_dict_get(ctx, pageobj, PDF_NAME_Trans);
- page->transition_present = (obj != NULL);
- if (obj)
- {
- pdf_load_transition(ctx, doc, page, obj);
- }
-
- // TODO: inherit
- page->resources = pdf_lookup_inherited_page_item(ctx, doc, pageobj, PDF_NAME_Resources);
- if (page->resources)
- pdf_keep_obj(ctx, page->resources);
-
- obj = pdf_dict_get(ctx, pageobj, PDF_NAME_Contents);
+ /* Scan for transparency */
fz_try(ctx)
{
- page->contents = pdf_keep_obj(ctx, obj);
-
- if (pdf_resources_use_blending(ctx, doc, page->resources))
+ pdf_obj *resources = pdf_page_resources(ctx, page);
+ if (pdf_resources_use_blending(ctx, resources))
page->transparency = 1;
else if (pdf_name_eq(ctx, pdf_dict_getp(ctx, pageobj, "Group/S"), PDF_NAME_Transparency))
page->transparency = 1;
-
for (annot = page->annots; annot && !page->transparency; annot = annot->next)
- if (annot->ap && pdf_resources_use_blending(ctx, doc, annot->ap->resources))
+ if (annot->ap && pdf_resources_use_blending(ctx, annot->ap->resources))
page->transparency = 1;
}
fz_catch(ctx)
diff --git a/source/pdf/pdf-run.c b/source/pdf/pdf-run.c
index e84604fb..f806b120 100644
--- a/source/pdf/pdf-run.c
+++ b/source/pdf/pdf-run.c
@@ -3,10 +3,12 @@
static void
pdf_run_annot_with_usage(fz_context *ctx, pdf_document *doc, pdf_page *page, pdf_annot *annot, fz_device *dev, const fz_matrix *ctm, char *event, fz_cookie *cookie)
{
- fz_matrix local_ctm;
+ fz_matrix local_ctm, page_ctm;
+ fz_rect mediabox;
pdf_processor *proc;
- fz_concat(&local_ctm, &page->ctm, ctm);
+ pdf_page_transform(ctx, page, &mediabox, &page_ctm);
+ fz_concat(&local_ctm, &page_ctm, ctm);
proc = pdf_new_run_processor(ctx, dev, &local_ctm, event, NULL, 0);
fz_try(ctx)
@@ -19,21 +21,24 @@ pdf_run_annot_with_usage(fz_context *ctx, pdf_document *doc, pdf_page *page, pdf
static void pdf_run_page_contents_with_usage(fz_context *ctx, pdf_document *doc, pdf_page *page, fz_device *dev, const fz_matrix *ctm, char *event, fz_cookie *cookie)
{
- fz_matrix local_ctm;
+ fz_matrix local_ctm, page_ctm;
+ pdf_obj *resources;
+ pdf_obj *contents;
+ fz_rect mediabox;
pdf_processor *proc;
- fz_concat(&local_ctm, &page->ctm, ctm);
+ pdf_page_transform(ctx, page, &mediabox, &page_ctm);
+ fz_concat(&local_ctm, &page_ctm, ctm);
+
+ resources = pdf_page_resources(ctx, page);
+ contents = pdf_page_contents(ctx, page);
if (page->transparency)
- {
- fz_rect mediabox = page->mediabox;
fz_begin_group(ctx, dev, fz_transform_rect(&mediabox, &local_ctm), 1, 0, 0, 1);
- }
proc = pdf_new_run_processor(ctx, dev, &local_ctm, event, NULL, 0);
-
fz_try(ctx)
- pdf_process_contents(ctx, proc, doc, page->resources, page->contents, cookie);
+ pdf_process_contents(ctx, proc, doc, resources, contents, cookie);
fz_always(ctx)
pdf_drop_processor(ctx, proc);
fz_catch(ctx)
diff --git a/source/pdf/pdf-xref.c b/source/pdf/pdf-xref.c
index 82fe7db1..48a5d316 100644
--- a/source/pdf/pdf-xref.c
+++ b/source/pdf/pdf-xref.c
@@ -2284,15 +2284,6 @@ pdf_lookup_metadata(fz_context *ctx, pdf_document *doc, const char *key, char *b
return -1;
}
-fz_transition *
-pdf_page_presentation(fz_context *ctx, pdf_page *page, float *duration)
-{
- *duration = page->duration;
- if (!page->transition_present)
- return NULL;
- return &page->transition;
-}
-
/*
Initializers for the fz_document interface.
diff --git a/source/tools/pdfmerge.c b/source/tools/pdfmerge.c
index bda2ffb7..6874e8b9 100644
--- a/source/tools/pdfmerge.c
+++ b/source/tools/pdfmerge.c
@@ -41,7 +41,7 @@ static void page_merge(int page_from, int page_to, pdf_graft_map *graft_map)
fz_try(ctx)
{
page_ref = pdf_lookup_page_obj(ctx, doc_src, page_from - 1);
- pdf_flatten_inheritable_page_items(ctx, doc_src, page_ref);
+ pdf_flatten_inheritable_page_items(ctx, page_ref);
/* Make a new page object dictionary to hold the items we copy from the source page. */
page_dict = pdf_new_dict(ctx, doc_des, 4);
diff --git a/source/tools/pdfposter.c b/source/tools/pdfposter.c
index 81ca0d75..66eaa3a5 100644
--- a/source/tools/pdfposter.c
+++ b/source/tools/pdfposter.c
@@ -58,6 +58,8 @@ static void decimatepages(fz_context *ctx, pdf_document *doc)
pdf_obj *oldroot, *root, *pages, *kids;
int num_pages = pdf_count_pages(ctx, doc);
int page, kidcount;
+ fz_rect mediabox;
+ fz_matrix page_ctm;
oldroot = pdf_dict_get(ctx, pdf_trailer(ctx, doc), PDF_NAME_Root);
pages = pdf_dict_get(ctx, oldroot, PDF_NAME_Pages);
@@ -78,9 +80,13 @@ static void decimatepages(fz_context *ctx, pdf_document *doc)
{
pdf_page *page_details = pdf_load_page(ctx, doc, page);
int xf = x_factor, yf = y_factor;
+ float w, h;
int x, y;
- float w = page_details->mediabox.x1 - page_details->mediabox.x0;
- float h = page_details->mediabox.y1 - page_details->mediabox.y0;
+
+ pdf_page_transform(ctx, page_details, &mediabox, &page_ctm);
+
+ w = mediabox.x1 - mediabox.x0;
+ h = mediabox.y1 - mediabox.y0;
if (xf == 0 && yf == 0)
{
@@ -103,21 +109,21 @@ static void decimatepages(fz_context *ctx, pdf_document *doc)
fz_rect mb;
newpageobj = pdf_copy_dict(ctx, pdf_lookup_page_obj(ctx, doc, page));
- pdf_flatten_inheritable_page_items(ctx, doc, newpageobj);
+ pdf_flatten_inheritable_page_items(ctx, newpageobj);
newpageref = pdf_add_object(ctx, doc, newpageobj);
newmediabox = pdf_new_array(ctx, doc, 4);
- mb.x0 = page_details->mediabox.x0 + (w/xf)*x;
+ mb.x0 = mediabox.x0 + (w/xf)*x;
if (x == xf-1)
- mb.x1 = page_details->mediabox.x1;
+ mb.x1 = mediabox.x1;
else
- mb.x1 = page_details->mediabox.x0 + (w/xf)*(x+1);
- mb.y0 = page_details->mediabox.y0 + (h/yf)*y;
+ mb.x1 = mediabox.x0 + (w/xf)*(x+1);
+ mb.y0 = mediabox.y0 + (h/yf)*y;
if (y == yf-1)
- mb.y1 = page_details->mediabox.y1;
+ mb.y1 = mediabox.y1;
else
- mb.y1 = page_details->mediabox.y0 + (h/yf)*(y+1);
+ mb.y1 = mediabox.y0 + (h/yf)*(y+1);
pdf_array_push(ctx, newmediabox, pdf_new_real(ctx, doc, mb.x0));
pdf_array_push(ctx, newmediabox, pdf_new_real(ctx, doc, mb.y0));