summaryrefslogtreecommitdiff
path: root/pdf
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2013-01-25 19:24:49 +0000
committerRobin Watts <robin.watts@artifex.com>2013-02-06 19:24:12 +0000
commitd3aa37962470253083714b5092a1ba759f674d47 (patch)
treeec60a0857cd3d44d3db5bc0c95aa69335b6b2d47 /pdf
parentc42dac496e0994c4253eb50ce67ceaec864ed379 (diff)
downloadmupdf-d3aa37962470253083714b5092a1ba759f674d47.tar.xz
Change to pass structures by reference rather than value.
This is faster on ARM in particular. The primary changes involve fz_matrix, fz_rect and fz_bbox. Rather than passing 'fz_rect r' into a function, we now consistently pass 'const fz_rect *r'. Where a rect is passed in and modified, we miss the 'const' off. Where possible, we return the pointer to the modified structure to allow 'chaining' of expressions. The basic upshot of this work is that we do far fewer copies of rectangle/matrix structures, and all the copies we do are explicit. This has opened the way to other optimisations, also performed in this commit. Rather than using expressions like: fz_concat(fz_scale(sx, sy), fz_translate(tx, ty)) we now have fz_pre_{scale,translate,rotate} functions. These can be implemented much more efficiently than doing the fully fledged matrix multiplication that fz_concat requires. We add fz_rect_{min,max} functions to return pointers to the min/max points of a rect. These can be used to in transformations to directly manipulate values. With a little casting in the path transformation code we can avoid more needless copying. We rename fz_widget_bbox to the more consistent fz_bound_widget.
Diffstat (limited to 'pdf')
-rw-r--r--pdf/mupdf-internal.h8
-rw-r--r--pdf/mupdf.h22
-rw-r--r--pdf/pdf_annot.c55
-rw-r--r--pdf/pdf_colorspace.c3
-rw-r--r--pdf/pdf_device.c66
-rw-r--r--pdf/pdf_font.c8
-rw-r--r--pdf/pdf_form.c62
-rw-r--r--pdf/pdf_interpret.c230
-rw-r--r--pdf/pdf_object.c24
-rw-r--r--pdf/pdf_page.c38
-rw-r--r--pdf/pdf_parse.c30
-rw-r--r--pdf/pdf_pattern.c4
-rw-r--r--pdf/pdf_shade.c19
-rw-r--r--pdf/pdf_type3.c9
-rw-r--r--pdf/pdf_xobject.c10
-rw-r--r--pdf/pdf_xref_aux.c4
16 files changed, 305 insertions, 287 deletions
diff --git a/pdf/mupdf-internal.h b/pdf/mupdf-internal.h
index 6ac228ef..0c070206 100644
--- a/pdf/mupdf-internal.h
+++ b/pdf/mupdf-internal.h
@@ -284,7 +284,7 @@ struct pdf_xobject_s
};
pdf_xobject *pdf_load_xobject(pdf_document *doc, pdf_obj *obj);
-pdf_obj *pdf_new_xobject(pdf_document *doc, fz_rect bbox, fz_matrix mat);
+pdf_obj *pdf_new_xobject(pdf_document *doc, const fz_rect *bbox, const fz_matrix *mat);
pdf_xobject *pdf_keep_xobject(fz_context *ctx, pdf_xobject *xobj);
void pdf_drop_xobject(fz_context *ctx, pdf_xobject *xobj);
void pdf_update_xobject_contents(pdf_document *xref, pdf_xobject *form, fz_buffer *buffer);
@@ -485,7 +485,7 @@ void pdf_drop_font(fz_context *ctx, pdf_font_desc *font);
void pdf_print_font(fz_context *ctx, pdf_font_desc *fontdesc);
#endif
-fz_rect pdf_measure_text(fz_context *ctx, pdf_font_desc *fontdesc, unsigned char *buf, int len);
+fz_rect *pdf_measure_text(fz_context *ctx, pdf_font_desc *fontdesc, unsigned char *buf, int len, fz_rect *rect);
float pdf_text_stride(fz_context *ctx, pdf_font_desc *fontdesc, float fontsize, unsigned char *buf, int len, float room, int *count);
/*
@@ -512,7 +512,7 @@ pdf_obj *pdf_lookup_dest(pdf_document *doc, pdf_obj *needle);
pdf_obj *pdf_lookup_name(pdf_document *doc, char *which, pdf_obj *needle);
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);
+fz_link *pdf_load_link_annots(pdf_document *, pdf_obj *annots, const fz_matrix *page_ctm);
pdf_annot *pdf_load_annots(pdf_document *, pdf_obj *annots, pdf_page *page);
void pdf_update_annot(pdf_document *, pdf_annot *annot);
@@ -557,7 +557,7 @@ struct pdf_page_s
* Content stream parsing
*/
-void pdf_run_glyph(pdf_document *doc, pdf_obj *resources, fz_buffer *contents, fz_device *dev, fz_matrix ctm, void *gstate, int nestedDepth);
+void pdf_run_glyph(pdf_document *doc, pdf_obj *resources, fz_buffer *contents, fz_device *dev, const fz_matrix *ctm, void *gstate, int nestedDepth);
/*
* PDF interface to store
diff --git a/pdf/mupdf.h b/pdf/mupdf.h
index 27bd1644..16a3053d 100644
--- a/pdf/mupdf.h
+++ b/pdf/mupdf.h
@@ -22,8 +22,8 @@ pdf_obj *pdf_new_string(fz_context *ctx, const char *str, int len);
pdf_obj *pdf_new_indirect(fz_context *ctx, int num, int gen, void *doc);
pdf_obj *pdf_new_array(fz_context *ctx, int initialcap);
pdf_obj *pdf_new_dict(fz_context *ctx, int initialcap);
-pdf_obj *pdf_new_rect(fz_context *ctx, fz_rect rect);
-pdf_obj *pdf_new_matrix(fz_context *ctx, fz_matrix mtx);
+pdf_obj *pdf_new_rect(fz_context *ctx, const fz_rect *rect);
+pdf_obj *pdf_new_matrix(fz_context *ctx, const fz_matrix *mtx);
pdf_obj *pdf_copy_array(fz_context *ctx, pdf_obj *array);
pdf_obj *pdf_copy_dict(fz_context *ctx, pdf_obj *dict);
@@ -95,8 +95,8 @@ unsigned short *pdf_to_ucs2(pdf_document *xref, pdf_obj *src); /* sumatrapdf */
pdf_obj *pdf_to_utf8_name(pdf_document *xref, pdf_obj *src);
char *pdf_from_ucs2(pdf_document *xref, unsigned short *str);
-fz_rect pdf_to_rect(fz_context *ctx, pdf_obj *array);
-fz_matrix pdf_to_matrix(fz_context *ctx, pdf_obj *array);
+fz_rect *pdf_to_rect(fz_context *ctx, pdf_obj *array, fz_rect *rect);
+fz_matrix *pdf_to_matrix(fz_context *ctx, pdf_obj *array, fz_matrix *mat);
int pdf_count_objects(pdf_document *doc);
pdf_obj *pdf_resolve_indirect(pdf_obj *ref);
@@ -141,7 +141,7 @@ void pdf_update_stream(pdf_document *xref, int num, fz_buffer *buf);
new pdf content. WARNING: this device is work in progress. It doesn't
currently support all rendering cases.
*/
-fz_device *pdf_new_pdf_device(pdf_document *doc, pdf_obj *contents, pdf_obj *resources, fz_matrix ctm);
+fz_device *pdf_new_pdf_device(pdf_document *doc, pdf_obj *contents, pdf_obj *resources, const fz_matrix *ctm);
/*
pdf_write_document: Write out the document to a file with all changes finalised.
@@ -235,7 +235,7 @@ fz_link *pdf_load_links(pdf_document *doc, pdf_page *page);
Does not throw exceptions.
*/
-fz_rect pdf_bound_page(pdf_document *doc, pdf_page *page);
+fz_rect *pdf_bound_page(pdf_document *doc, pdf_page *page, fz_rect *);
/*
pdf_free_page: Frees a page and its resources.
@@ -265,7 +265,7 @@ pdf_annot *pdf_next_annot(pdf_document *doc, pdf_annot *annot);
Does not throw exceptions.
*/
-fz_rect pdf_bound_annot(pdf_document *doc, pdf_annot *annot);
+fz_rect *pdf_bound_annot(pdf_document *doc, pdf_annot *annot, fz_rect *rect);
/*
pdf_run_page: Interpret a loaded page and render it on a device.
@@ -277,9 +277,9 @@ fz_rect pdf_bound_annot(pdf_document *doc, pdf_annot *annot);
ctm: A transformation matrix applied to the objects on the page,
e.g. to scale or rotate the page contents as desired.
*/
-void pdf_run_page(pdf_document *doc, pdf_page *page, fz_device *dev, fz_matrix ctm, fz_cookie *cookie);
+void pdf_run_page(pdf_document *doc, pdf_page *page, fz_device *dev, const fz_matrix *ctm, fz_cookie *cookie);
-void pdf_run_page_with_usage(pdf_document *doc, pdf_page *page, fz_device *dev, fz_matrix ctm, char *event, fz_cookie *cookie);
+void pdf_run_page_with_usage(pdf_document *doc, pdf_page *page, fz_device *dev, const fz_matrix *ctm, char *event, fz_cookie *cookie);
/*
pdf_run_page_contents: Interpret a loaded page and render it on a device.
@@ -292,7 +292,7 @@ void pdf_run_page_with_usage(pdf_document *doc, pdf_page *page, fz_device *dev,
ctm: A transformation matrix applied to the objects on the page,
e.g. to scale or rotate the page contents as desired.
*/
-void pdf_run_page_contents(pdf_document *xref, pdf_page *page, fz_device *dev, fz_matrix ctm, fz_cookie *cookie);
+void pdf_run_page_contents(pdf_document *xref, pdf_page *page, fz_device *dev, const fz_matrix *ctm, fz_cookie *cookie);
/*
pdf_run_annot: Interpret an annotation and render it on a device.
@@ -306,7 +306,7 @@ void pdf_run_page_contents(pdf_document *xref, pdf_page *page, fz_device *dev, f
ctm: A transformation matrix applied to the objects on the page,
e.g. to scale or rotate the page contents as desired.
*/
-void pdf_run_annot(pdf_document *xref, pdf_page *page, pdf_annot *annot, fz_device *dev, fz_matrix ctm, fz_cookie *cookie);
+void pdf_run_annot(pdf_document *xref, pdf_page *page, pdf_annot *annot, fz_device *dev, const fz_matrix *ctm, fz_cookie *cookie);
/*
Metadata interface.
diff --git a/pdf/pdf_annot.c b/pdf/pdf_annot.c
index 3ba37da7..32de1eb9 100644
--- a/pdf/pdf_annot.c
+++ b/pdf/pdf_annot.c
@@ -243,7 +243,7 @@ pdf_parse_action(pdf_document *xref, pdf_obj *action)
}
static fz_link *
-pdf_load_link(pdf_document *xref, pdf_obj *dict, fz_matrix page_ctm)
+pdf_load_link(pdf_document *xref, pdf_obj *dict, const fz_matrix *page_ctm)
{
pdf_obj *dest = NULL;
pdf_obj *action;
@@ -256,11 +256,11 @@ pdf_load_link(pdf_document *xref, pdf_obj *dict, fz_matrix page_ctm)
obj = pdf_dict_gets(dict, "Rect");
if (obj)
- bbox = pdf_to_rect(ctx, obj);
+ pdf_to_rect(ctx, obj, &bbox);
else
bbox = fz_empty_rect;
- bbox = fz_transform_rect(page_ctm, bbox);
+ fz_transform_rect(&bbox, page_ctm);
obj = pdf_dict_gets(dict, "Dest");
if (obj)
@@ -279,11 +279,11 @@ pdf_load_link(pdf_document *xref, pdf_obj *dict, fz_matrix page_ctm)
}
if (ld.kind == FZ_LINK_NONE)
return NULL;
- return fz_new_link(ctx, bbox, ld);
+ return fz_new_link(ctx, &bbox, ld);
}
fz_link *
-pdf_load_link_annots(pdf_document *xref, pdf_obj *annots, fz_matrix page_ctm)
+pdf_load_link_annots(pdf_document *xref, pdf_obj *annots, const fz_matrix *page_ctm)
{
fz_link *link, *head, *tail;
pdf_obj *obj;
@@ -332,12 +332,11 @@ pdf_free_annot(fz_context *ctx, pdf_annot *annot)
static void
pdf_transform_annot(pdf_annot *annot)
{
- fz_matrix matrix = annot->ap->matrix;
fz_rect bbox = annot->ap->bbox;
fz_rect rect = annot->rect;
float w, h, x, y;
- bbox = fz_transform_rect(matrix, bbox);
+ fz_transform_rect(&bbox, &annot->ap->matrix);
if (bbox.x1 == bbox.x0)
w = 0;
else
@@ -349,7 +348,7 @@ pdf_transform_annot(pdf_annot *annot)
x = rect.x0 - bbox.x0;
y = rect.y0 - bbox.y0;
- annot->matrix = fz_concat(fz_scale(w, h), fz_translate(x, y));
+ fz_pre_scale(fz_translate(&annot->matrix, x, y), w, h);
}
pdf_annot *
@@ -402,8 +401,9 @@ pdf_load_annots(pdf_document *xref, pdf_obj *annots, pdf_page *page)
annot = fz_malloc_struct(ctx, pdf_annot);
annot->page = page;
annot->obj = pdf_keep_obj(obj);
- annot->rect = pdf_to_rect(ctx, rect);
- annot->pagerect = fz_transform_rect(page->ctm, annot->rect);
+ pdf_to_rect(ctx, rect, &annot->rect);
+ annot->pagerect = annot->rect;
+ fz_transform_rect(&annot->pagerect, &page->ctm);
annot->ap = NULL;
annot->type = pdf_field_type(xref, obj);
@@ -501,12 +501,17 @@ pdf_next_annot(pdf_document *doc, pdf_annot *annot)
return annot ? annot->next : NULL;
}
-fz_rect
-pdf_bound_annot(pdf_document *doc, pdf_annot *annot)
+fz_rect *
+pdf_bound_annot(pdf_document *doc, pdf_annot *annot, fz_rect *rect)
{
+ if (rect == NULL)
+ return NULL;
+
if (annot)
- return annot->pagerect;
- return fz_empty_rect;
+ *rect = annot->pagerect;
+ else
+ *rect = fz_empty_rect;
+ return rect;
}
pdf_annot *
@@ -541,7 +546,7 @@ pdf_create_annot(pdf_document *doc, pdf_page *page, fz_annot_type type)
}
pdf_dict_puts_drop(annot_obj, "Subtype", pdf_new_name(ctx, type_str));
- pdf_dict_puts_drop(annot_obj, "Rect", pdf_new_rect(ctx, rect));
+ pdf_dict_puts_drop(annot_obj, "Rect", pdf_new_rect(ctx, &rect));
annot = fz_malloc_struct(ctx, pdf_annot);
annot->page = page;
@@ -588,20 +593,21 @@ void
pdf_set_annot_appearance(pdf_document *doc, pdf_annot *annot, fz_display_list *disp_list)
{
fz_context *ctx = doc->ctx;
- fz_matrix ctm = fz_invert_matrix(annot->page->ctm);
+ fz_matrix ctm;
fz_rect rect;
fz_matrix mat = fz_identity;
fz_device *dev = fz_new_bbox_device(ctx, &rect);
+ fz_invert_matrix(&ctm, &annot->page->ctm);
fz_try(ctx)
{
pdf_obj *ap_obj;
- fz_run_display_list(disp_list, dev, ctm, fz_infinite_rect, NULL);
+ fz_run_display_list(disp_list, dev, &ctm, &fz_infinite_rect, NULL);
fz_free_device(dev);
dev = NULL;
- pdf_dict_puts_drop(annot->obj, "Rect", pdf_new_rect(ctx, rect));
+ pdf_dict_puts_drop(annot->obj, "Rect", pdf_new_rect(ctx, &rect));
/* See if there is a current normal appearance */
ap_obj = pdf_dict_getp(annot->obj, "AP/N");
@@ -610,13 +616,13 @@ pdf_set_annot_appearance(pdf_document *doc, pdf_annot *annot, fz_display_list *d
if (ap_obj == NULL)
{
- ap_obj = pdf_new_xobject(doc, rect, mat);
+ ap_obj = pdf_new_xobject(doc, &rect, &mat);
pdf_dict_putp_drop(annot->obj, "AP/N", ap_obj);
}
else
{
- pdf_dict_puts_drop(ap_obj, "Rect", pdf_new_rect(ctx, rect));
- pdf_dict_puts_drop(ap_obj, "Matrix", pdf_new_matrix(ctx, mat));
+ pdf_dict_puts_drop(ap_obj, "Rect", pdf_new_rect(ctx, &rect));
+ pdf_dict_puts_drop(ap_obj, "Matrix", pdf_new_matrix(ctx, &mat));
}
/* Remove annot reference to the xobject and don't recreate it
@@ -625,10 +631,11 @@ pdf_set_annot_appearance(pdf_document *doc, pdf_annot *annot, fz_display_list *d
annot->ap = NULL;
annot->rect = rect;
- annot->pagerect = fz_transform_rect(annot->page->ctm, rect);
+ annot->pagerect = rect;
+ fz_transform_rect(&annot->pagerect, &annot->page->ctm);
- dev = pdf_new_pdf_device(doc, ap_obj, pdf_dict_gets(ap_obj, "Resources"), mat);
- fz_run_display_list(disp_list, dev, ctm, fz_infinite_rect, NULL);
+ dev = pdf_new_pdf_device(doc, ap_obj, pdf_dict_gets(ap_obj, "Resources"), &mat);
+ fz_run_display_list(disp_list, dev, &ctm, &fz_infinite_rect, NULL);
fz_free_device(dev);
doc->dirty = 1;
diff --git a/pdf/pdf_colorspace.c b/pdf/pdf_colorspace.c
index 1f83c906..30a45bde 100644
--- a/pdf/pdf_colorspace.c
+++ b/pdf/pdf_colorspace.c
@@ -183,6 +183,7 @@ pdf_expand_indexed_pixmap(fz_context *ctx, fz_pixmap *src)
unsigned char *s, *d;
int y, x, k, n, high;
unsigned char *lookup;
+ fz_bbox bbox;
assert(src->colorspace->to_rgb == indexed_to_rgb);
assert(src->n == 2);
@@ -192,7 +193,7 @@ pdf_expand_indexed_pixmap(fz_context *ctx, fz_pixmap *src)
lookup = idx->lookup;
n = idx->base->n;
- dst = fz_new_pixmap_with_bbox(ctx, idx->base, fz_pixmap_bbox(ctx, src));
+ dst = fz_new_pixmap_with_bbox(ctx, idx->base, fz_pixmap_bbox(ctx, src, &bbox));
s = src->samples;
d = dst->samples;
diff --git a/pdf/pdf_device.c b/pdf/pdf_device.c
index 9d76b645..aea5593f 100644
--- a/pdf/pdf_device.c
+++ b/pdf/pdf_device.c
@@ -398,16 +398,16 @@ pdf_dev_path(pdf_device *pdev, fz_path *path)
}
static void
-pdf_dev_ctm(pdf_device *pdev, fz_matrix ctm)
+pdf_dev_ctm(pdf_device *pdev, const fz_matrix *ctm)
{
fz_matrix inverse;
gstate *gs = CURRENT_GSTATE(pdev);
- if (memcmp(&gs->ctm, &ctm, sizeof(ctm)) == 0)
+ if (memcmp(&gs->ctm, ctm, sizeof(ctm)) == 0)
return;
- inverse = fz_invert_matrix(gs->ctm);
- inverse = fz_concat(ctm, inverse);
- memcpy(&gs->ctm, &ctm, sizeof(ctm));
+ fz_invert_matrix(&inverse, &gs->ctm);
+ fz_concat(&inverse, ctm, &inverse);
+ memcpy(&gs->ctm, ctm, sizeof(*ctm));
fz_buffer_printf(pdev->ctx, gs->buf, "%f %f %f %f %f %f cm\n", inverse.a, inverse.b, inverse.c, inverse.d, inverse.e, inverse.f);
}
@@ -588,7 +588,7 @@ pdf_dev_font(pdf_device *pdev, fz_font *font, float size)
}
static void
-pdf_dev_tm(pdf_device *pdev, fz_matrix *tm)
+pdf_dev_tm(pdf_device *pdev, const fz_matrix *tm)
{
gstate *gs = CURRENT_GSTATE(pdev);
@@ -662,7 +662,7 @@ pdf_dev_text(pdf_device *pdev, fz_text *text)
trunc_trm.d = trm.d;
trunc_trm.e = 0;
trunc_trm.f = 0;
- inverse = fz_invert_matrix(trunc_trm);
+ fz_invert_matrix(&inverse, &trunc_trm);
for (i=0; i < text->len; i++)
{
@@ -670,7 +670,7 @@ pdf_dev_text(pdf_device *pdev, fz_text *text)
fz_point delta;
delta.x = it->x - trm.e;
delta.y = it->y - trm.f;
- delta = fz_transform_point(inverse, delta);
+ fz_transform_point(&delta, &inverse);
if (delta.x != 0 || delta.y != 0)
{
fz_buffer_printf(pdev->ctx, gs->buf, "%g %g Td ", delta.x, delta.y);
@@ -698,7 +698,7 @@ pdf_dev_trm(pdf_device *pdev, int trm)
}
static void
-pdf_dev_begin_text(pdf_device *pdev, fz_matrix *tm, int trm)
+pdf_dev_begin_text(pdf_device *pdev, const fz_matrix *tm, int trm)
{
pdf_dev_trm(pdev, trm);
if (!pdev->in_text)
@@ -728,7 +728,7 @@ pdf_dev_end_text(pdf_device *pdev)
}
static int
-pdf_dev_new_form(pdf_obj **form_ref, pdf_device *pdev, fz_rect bbox, int isolated, int knockout, int blendmode, float alpha, fz_colorspace *colorspace)
+pdf_dev_new_form(pdf_obj **form_ref, pdf_device *pdev, const fz_rect *bbox, int isolated, int knockout, int blendmode, float alpha, fz_colorspace *colorspace)
{
fz_context *ctx = pdev->ctx;
int num;
@@ -825,7 +825,7 @@ pdf_dev_new_form(pdf_obj **form_ref, pdf_device *pdev, fz_rect bbox, int isolate
/* Entry points */
static void
-pdf_dev_fill_path(fz_device *dev, fz_path *path, int even_odd, fz_matrix ctm,
+pdf_dev_fill_path(fz_device *dev, fz_path *path, int even_odd, const fz_matrix *ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
pdf_device *pdev = dev->user;
@@ -840,7 +840,7 @@ pdf_dev_fill_path(fz_device *dev, fz_path *path, int even_odd, fz_matrix ctm,
}
static void
-pdf_dev_stroke_path(fz_device *dev, fz_path *path, fz_stroke_state *stroke, fz_matrix ctm,
+pdf_dev_stroke_path(fz_device *dev, fz_path *path, fz_stroke_state *stroke, const fz_matrix *ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
pdf_device *pdev = dev->user;
@@ -856,7 +856,7 @@ pdf_dev_stroke_path(fz_device *dev, fz_path *path, fz_stroke_state *stroke, fz_m
}
static void
-pdf_dev_clip_path(fz_device *dev, fz_path *path, fz_rect rect, int even_odd, fz_matrix ctm)
+pdf_dev_clip_path(fz_device *dev, fz_path *path, const fz_rect *rect, int even_odd, const fz_matrix *ctm)
{
pdf_device *pdev = dev->user;
gstate *gs;
@@ -870,7 +870,7 @@ pdf_dev_clip_path(fz_device *dev, fz_path *path, fz_rect rect, int even_odd, fz_
}
static void
-pdf_dev_clip_stroke_path(fz_device *dev, fz_path *path, fz_rect rect, fz_stroke_state *stroke, fz_matrix ctm)
+pdf_dev_clip_stroke_path(fz_device *dev, fz_path *path, const fz_rect *rect, fz_stroke_state *stroke, const fz_matrix *ctm)
{
pdf_device *pdev = dev->user;
gstate *gs;
@@ -888,7 +888,7 @@ pdf_dev_clip_stroke_path(fz_device *dev, fz_path *path, fz_rect rect, fz_stroke_
}
static void
-pdf_dev_fill_text(fz_device *dev, fz_text *text, fz_matrix ctm,
+pdf_dev_fill_text(fz_device *dev, fz_text *text, const fz_matrix *ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
pdf_device *pdev = dev->user;
@@ -900,7 +900,7 @@ pdf_dev_fill_text(fz_device *dev, fz_text *text, fz_matrix ctm,
}
static void
-pdf_dev_stroke_text(fz_device *dev, fz_text *text, fz_stroke_state *stroke, fz_matrix ctm,
+pdf_dev_stroke_text(fz_device *dev, fz_text *text, fz_stroke_state *stroke, const fz_matrix *ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
pdf_device *pdev = dev->user;
@@ -912,7 +912,7 @@ pdf_dev_stroke_text(fz_device *dev, fz_text *text, fz_stroke_state *stroke, fz_m
}
static void
-pdf_dev_clip_text(fz_device *dev, fz_text *text, fz_matrix ctm, int accumulate)
+pdf_dev_clip_text(fz_device *dev, fz_text *text, const fz_matrix *ctm, int accumulate)
{
pdf_device *pdev = dev->user;
gstate *gs = CURRENT_GSTATE(pdev);
@@ -923,7 +923,7 @@ pdf_dev_clip_text(fz_device *dev, fz_text *text, fz_matrix ctm, int accumulate)
}
static void
-pdf_dev_clip_stroke_text(fz_device *dev, fz_text *text, fz_stroke_state *stroke, fz_matrix ctm)
+pdf_dev_clip_stroke_text(fz_device *dev, fz_text *text, fz_stroke_state *stroke, const fz_matrix *ctm)
{
pdf_device *pdev = dev->user;
gstate *gs = CURRENT_GSTATE(pdev);
@@ -934,7 +934,7 @@ pdf_dev_clip_stroke_text(fz_device *dev, fz_text *text, fz_stroke_state *stroke,
}
static void
-pdf_dev_ignore_text(fz_device *dev, fz_text *text, fz_matrix ctm)
+pdf_dev_ignore_text(fz_device *dev, fz_text *text, const fz_matrix *ctm)
{
pdf_device *pdev = dev->user;
gstate *gs = CURRENT_GSTATE(pdev);
@@ -945,23 +945,26 @@ pdf_dev_ignore_text(fz_device *dev, fz_text *text, fz_matrix ctm)
}
static void
-pdf_dev_fill_image(fz_device *dev, fz_image *image, fz_matrix ctm, float alpha)
+pdf_dev_fill_image(fz_device *dev, fz_image *image, const fz_matrix *ctm, float alpha)
{
pdf_device *pdev = (pdf_device *)dev->user;
int num;
gstate *gs = CURRENT_GSTATE(pdev);
+ fz_matrix local_ctm = *ctm;
pdf_dev_end_text(pdev);
num = send_image(pdev, image, 0, 0);
fz_buffer_printf(dev->ctx, gs->buf, "q\n");
pdf_dev_alpha(pdev, alpha, 0);
/* PDF images are upside down, so fiddle the ctm */
- pdf_dev_ctm(pdev, fz_concat(fz_concat(fz_translate(0, -1), fz_scale(1,-1)), ctm));
+ fz_pre_scale(&local_ctm, 1, -1);
+ fz_pre_translate(&local_ctm, 0, -1);
+ pdf_dev_ctm(pdev, &local_ctm);
fz_buffer_printf(dev->ctx, gs->buf, "/Img%d Do Q\n", num);
}
static void
-pdf_dev_fill_shade(fz_device *dev, fz_shade *shade, fz_matrix ctm, float alpha)
+pdf_dev_fill_shade(fz_device *dev, fz_shade *shade, const fz_matrix *ctm, float alpha)
{
pdf_device *pdev = (pdf_device *)dev->user;
@@ -970,12 +973,13 @@ pdf_dev_fill_shade(fz_device *dev, fz_shade *shade, fz_matrix ctm, float alpha)
}
static void
-pdf_dev_fill_image_mask(fz_device *dev, fz_image *image, fz_matrix ctm,
+pdf_dev_fill_image_mask(fz_device *dev, fz_image *image, const fz_matrix *ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
pdf_device *pdev = (pdf_device *)dev->user;
gstate *gs = CURRENT_GSTATE(pdev);
int num;
+ fz_matrix local_ctm = *ctm;
pdf_dev_end_text(pdev);
num = send_image(pdev, image, 1, 0);
@@ -983,12 +987,14 @@ fz_colorspace *colorspace, float *color, float alpha)
pdf_dev_alpha(pdev, alpha, 0);
pdf_dev_color(pdev, colorspace, color, 0);
/* PDF images are upside down, so fiddle the ctm */
- pdf_dev_ctm(pdev, fz_concat(fz_concat(fz_translate(0, -1), fz_scale(1,-1)), ctm));
+ fz_pre_scale(&local_ctm, 1, -1);
+ fz_pre_translate(&local_ctm, 0, -1);
+ pdf_dev_ctm(pdev, &local_ctm);
fz_buffer_printf(dev->ctx, gs->buf, "/Img%d Do Q\n", num);
}
static void
-pdf_dev_clip_image_mask(fz_device *dev, fz_image *image, fz_rect rect, fz_matrix ctm)
+pdf_dev_clip_image_mask(fz_device *dev, fz_image *image, const fz_rect *rect, const fz_matrix *ctm)
{
pdf_device *pdev = (pdf_device *)dev->user;
@@ -1008,7 +1014,7 @@ pdf_dev_pop_clip(fz_device *dev)
}
static void
-pdf_dev_begin_mask(fz_device *dev, fz_rect bbox, int luminosity, fz_colorspace *colorspace, float *color)
+pdf_dev_begin_mask(fz_device *dev, const fz_rect *bbox, int luminosity, fz_colorspace *colorspace, float *color)
{
pdf_device *pdev = (pdf_device *)dev->user;
fz_context *ctx = pdev->ctx;
@@ -1093,7 +1099,7 @@ pdf_dev_end_mask(fz_device *dev)
}
static void
-pdf_dev_begin_group(fz_device *dev, fz_rect bbox, int isolated, int knockout, int blendmode, float alpha)
+pdf_dev_begin_group(fz_device *dev, const fz_rect *bbox, int isolated, int knockout, int blendmode, float alpha)
{
pdf_device *pdev = (pdf_device *)dev->user;
fz_context *ctx = pdev->ctx;
@@ -1132,7 +1138,7 @@ pdf_dev_end_group(fz_device *dev)
}
static void
-pdf_dev_begin_tile(fz_device *dev, fz_rect area, fz_rect view, float xstep, float ystep, fz_matrix ctm)
+pdf_dev_begin_tile(fz_device *dev, const fz_rect *area, const fz_rect *view, float xstep, float ystep, const fz_matrix *ctm)
{
pdf_device *pdev = (pdf_device *)dev->user;
@@ -1187,7 +1193,7 @@ pdf_dev_free_user(fz_device *dev)
fz_free(ctx, pdev);
}
-fz_device *pdf_new_pdf_device(pdf_document *doc, pdf_obj *contents, pdf_obj *resources, fz_matrix ctm)
+fz_device *pdf_new_pdf_device(pdf_document *doc, pdf_obj *contents, pdf_obj *resources, const fz_matrix *ctm)
{
fz_context *ctx = doc->ctx;
pdf_device *pdev = fz_malloc_struct(ctx, pdf_device);
@@ -1201,7 +1207,7 @@ fz_device *pdf_new_pdf_device(pdf_document *doc, pdf_obj *contents, pdf_obj *res
pdev->resources = pdf_keep_obj(resources);
pdev->gstates = fz_malloc_struct(ctx, gstate);
pdev->gstates[0].buf = fz_new_buffer(ctx, 256);
- pdev->gstates[0].ctm = ctm;
+ pdev->gstates[0].ctm = *ctm;
pdev->gstates[0].colorspace[0] = fz_device_gray;
pdev->gstates[0].colorspace[1] = fz_device_gray;
pdev->gstates[0].color[0][0] = 1;
diff --git a/pdf/pdf_font.c b/pdf/pdf_font.c
index ebb157b5..d3f25304 100644
--- a/pdf/pdf_font.c
+++ b/pdf/pdf_font.c
@@ -1192,23 +1192,23 @@ pdf_print_font(fz_context *ctx, pdf_font_desc *fontdesc)
}
#endif
-fz_rect pdf_measure_text(fz_context *ctx, pdf_font_desc *fontdesc, unsigned char *buf, int len)
+fz_rect *pdf_measure_text(fz_context *ctx, pdf_font_desc *fontdesc, unsigned char *buf, int len, fz_rect *acc)
{
pdf_hmtx h;
int gid;
int i;
float x = 0.0;
- fz_rect acc = fz_empty_rect;
fz_rect bbox;
+ *acc = fz_empty_rect;
for (i = 0; i < len; i++)
{
gid = pdf_font_cid_to_gid(ctx, fontdesc, buf[i]);
h = pdf_lookup_hmtx(ctx, fontdesc, buf[i]);
- bbox = fz_bound_glyph(ctx, fontdesc->font, gid, fz_identity);
+ fz_bound_glyph(ctx, fontdesc->font, gid, &fz_identity, &bbox);
bbox.x0 += x;
bbox.x1 += x;
- acc = fz_union_rect(acc, bbox);
+ fz_union_rect(acc, &bbox);
x += h.w / 1000.0;
}
diff --git a/pdf/pdf_form.c b/pdf/pdf_form.c
index e92ba738..bdab08e7 100644
--- a/pdf/pdf_form.c
+++ b/pdf/pdf_form.c
@@ -114,15 +114,15 @@ static void account_for_rot(fz_rect *rect, fz_matrix *mat, int rot)
*mat = fz_identity;
break;
case 90:
- *mat = fz_concat(fz_rotate(rot), fz_translate(width, 0));
+ fz_pre_rotate(fz_translate(mat, width, 0), rot);
rect->x1 = height;
rect->y1 = width;
break;
case 180:
- *mat = fz_concat(fz_rotate(rot), fz_translate(width, height));
+ fz_pre_rotate(fz_translate(mat, width, height), rot);
break;
case 270:
- *mat = fz_concat(fz_rotate(rot), fz_translate(0, height));
+ fz_pre_rotate(fz_translate(mat, 0, height), rot);
rect->x1 = height;
rect->y1 = width;
break;
@@ -427,14 +427,14 @@ static void fzbuf_print_da(fz_context *ctx, fz_buffer *fzbuf, da_info *di)
}
}
-static fz_rect measure_text(pdf_document *doc, font_info *font_rec, const fz_matrix *tm, char *text)
+static fz_rect *measure_text(pdf_document *doc, font_info *font_rec, const fz_matrix *tm, char *text, fz_rect *bbox)
{
- fz_rect bbox = pdf_measure_text(doc->ctx, font_rec->font, (unsigned char *)text, strlen(text));
+ pdf_measure_text(doc->ctx, font_rec->font, (unsigned char *)text, strlen(text), bbox);
- bbox.x0 *= font_rec->da_rec.font_size * tm->a;
- bbox.y0 *= font_rec->da_rec.font_size * tm->d;
- bbox.x1 *= font_rec->da_rec.font_size * tm->a;
- bbox.y1 *= font_rec->da_rec.font_size * tm->d;
+ bbox->x0 *= font_rec->da_rec.font_size * tm->a;
+ bbox->y0 *= font_rec->da_rec.font_size * tm->d;
+ bbox->x1 *= font_rec->da_rec.font_size * tm->a;
+ bbox->y1 *= font_rec->da_rec.font_size * tm->d;
return bbox;
}
@@ -463,7 +463,7 @@ static void fzbuf_print_color(fz_context *ctx, fz_buffer *fzbuf, pdf_obj *arr, i
}
}
-static void fzbuf_print_text(fz_context *ctx, fz_buffer *fzbuf, fz_rect *clip, pdf_obj *col, font_info *font_rec, fz_matrix *tm, char *text)
+static void fzbuf_print_text(fz_context *ctx, fz_buffer *fzbuf, const fz_rect *clip, pdf_obj *col, font_info *font_rec, const fz_matrix *tm, char *text)
{
fz_buffer_printf(ctx, fzbuf, fmt_q);
if (clip)
@@ -495,7 +495,7 @@ static void fzbuf_print_text(fz_context *ctx, fz_buffer *fzbuf, fz_rect *clip, p
fz_buffer_printf(ctx, fzbuf, fmt_Q);
}
-static fz_buffer *create_text_buffer(fz_context *ctx, fz_rect *clip, text_widget_info *info, fz_matrix *tm, char *text)
+static fz_buffer *create_text_buffer(fz_context *ctx, const fz_rect *clip, text_widget_info *info, const fz_matrix *tm, char *text)
{
fz_buffer *fzbuf = fz_new_buffer(ctx, 0);
@@ -514,15 +514,16 @@ static fz_buffer *create_text_buffer(fz_context *ctx, fz_rect *clip, text_widget
return fzbuf;
}
-static fz_buffer *create_aligned_text_buffer(pdf_document *doc, fz_rect *clip, text_widget_info *info, fz_matrix *tm, char *text)
+static fz_buffer *create_aligned_text_buffer(pdf_document *doc, const fz_rect *clip, text_widget_info *info, const fz_matrix *tm, char *text)
{
fz_context *ctx = doc->ctx;
fz_matrix atm = *tm;
if (info->q != Q_Left)
{
- fz_rect rect = measure_text(doc, &info->font_rec, tm, text);
+ fz_rect rect;
+ measure_text(doc, &info->font_rec, tm, text, &rect);
atm.e -= info->q == Q_Right ? rect.x1 : (rect.x1 - rect.x0) / 2;
}
@@ -545,7 +546,7 @@ static void measure_ascent_descent(pdf_document *doc, font_info *finf, char *tex
strcpy(testtext, "My");
strcat(testtext, text);
tinf.da_rec.font_size = 1;
- bbox = measure_text(doc, &tinf, &fz_identity, testtext);
+ measure_text(doc, &tinf, &fz_identity, testtext, &bbox);
*descent = -bbox.y0;
*ascent = bbox.y1;
}
@@ -725,7 +726,7 @@ static void text_splitter_retry(text_splitter *splitter)
}
}
-static void fzbuf_print_text_start(fz_context *ctx, fz_buffer *fzbuf, fz_rect *clip, pdf_obj *col, font_info *font, fz_matrix *tm)
+static void fzbuf_print_text_start(fz_context *ctx, fz_buffer *fzbuf, const fz_rect *clip, pdf_obj *col, font_info *font, const fz_matrix *tm)
{
fz_buffer_printf(ctx, fzbuf, fmt_Tx_BMC);
fz_buffer_printf(ctx, fzbuf, fmt_q);
@@ -773,7 +774,7 @@ static void fzbuf_print_text_word(fz_context *ctx, fz_buffer *fzbuf, float x, fl
fz_buffer_printf(ctx, fzbuf, ") Tj\n");
}
-static fz_buffer *create_text_appearance(pdf_document *doc, fz_rect *bbox, fz_matrix *oldtm, text_widget_info *info, char *text)
+static fz_buffer *create_text_appearance(pdf_document *doc, const fz_rect *bbox, const fz_matrix *oldtm, text_widget_info *info, char *text)
{
fz_context *ctx = doc->ctx;
int fontsize;
@@ -880,9 +881,7 @@ static fz_buffer *create_text_appearance(pdf_document *doc, fz_rect *bbox, fz_ma
float char_width = pdf_text_stride(ctx, info->font_rec.font, fontsize, (unsigned char *)"M", 1, FLT_MAX, NULL);
float init_skip = (comb_width - char_width)/2.0;
- tm = fz_identity;
- tm.e = rect.x0;
- tm.f = rect.y1 - (height+(ascent-descent)*fontsize)/2.0;
+ fz_translate(&tm, rect.x0, rect.y1 - (height+(ascent-descent)*fontsize)/2.0);
fzbuf = fz_new_buffer(ctx, 0);
@@ -901,9 +900,7 @@ static fz_buffer *create_text_appearance(pdf_document *doc, fz_rect *bbox, fz_ma
}
else
{
- tm = fz_identity;
- tm.e = rect.x0;
- tm.f = rect.y1 - (height+(ascent-descent)*fontsize)/2.0;
+ fz_translate(&tm, rect.x0, rect.y1 - (height+(ascent-descent)*fontsize)/2.0);
switch(info->q)
{
@@ -914,7 +911,7 @@ static fz_buffer *create_text_appearance(pdf_document *doc, fz_rect *bbox, fz_ma
if (variable)
{
- tbox = measure_text(doc, &info->font_rec, &tm, text);
+ measure_text(doc, &info->font_rec, &tm, text, &tbox);
if (tbox.x1 - tbox.x0 > width)
{
@@ -1082,7 +1079,8 @@ static int get_matrix(pdf_document *doc, pdf_xobject *form, int q, fz_matrix *mt
if (found)
{
- fz_rect bbox = pdf_to_rect(ctx, pdf_dict_gets(form->contents, "BBox"));
+ fz_rect bbox;
+ pdf_to_rect(ctx, pdf_dict_gets(form->contents, "BBox"), &bbox);
switch (q)
{
@@ -1163,7 +1161,7 @@ static pdf_xobject *load_or_create_form(pdf_document *doc, pdf_obj *obj, fz_rect
fz_try(ctx)
{
rot = pdf_to_int(pdf_dict_getp(obj, "MK/R"));
- *rect = pdf_to_rect(ctx, pdf_dict_gets(obj, "Rect"));
+ pdf_to_rect(ctx, pdf_dict_gets(obj, "Rect"), rect);
rect->x1 -= rect->x0;
rect->y1 -= rect->y0;
rect->x0 = rect->y0 = 0;
@@ -1179,7 +1177,7 @@ static pdf_xobject *load_or_create_form(pdf_document *doc, pdf_obj *obj, fz_rect
formobj = pdf_dict_gets(ap, dn);
if (formobj == NULL)
{
- formobj = pdf_new_xobject(doc, *rect, mat);
+ formobj = pdf_new_xobject(doc, rect, &mat);
pdf_dict_puts_drop(ap, dn, formobj);
create_form = 1;
}
@@ -1476,8 +1474,8 @@ static void update_pushbutton_appearance(pdf_document *doc, pdf_obj *obj)
clip.y1 -= btotal;
get_font_info(doc, form->resources, da, &font_rec);
- bounds = measure_text(doc, &font_rec, &fz_identity, text);
- mat = fz_translate((rect.x1 - bounds.x1)/2, (rect.y1 - bounds.y1)/2);
+ measure_text(doc, &font_rec, &fz_identity, text, &bounds);
+ fz_translate(&mat, (rect.x1 - bounds.x1)/2, (rect.y1 - bounds.y1)/2);
fzbuf_print_text(ctx, fzbuf, &clip, NULL, &font_rec, &mat, text);
}
@@ -2591,11 +2589,15 @@ void pdf_field_set_text_color(pdf_document *doc, pdf_obj *field, pdf_obj *col)
}
}
-fz_rect fz_widget_bbox(fz_widget *widget)
+fz_rect *fz_bound_widget(fz_widget *widget, fz_rect *rect)
{
pdf_annot *annot = (pdf_annot *)widget;
- return annot->pagerect;
+ if (rect == NULL)
+ return NULL;
+ *rect = annot->pagerect;
+
+ return rect;
}
char *pdf_text_widget_text(pdf_document *doc, fz_widget *tw)
diff --git a/pdf/pdf_interpret.c b/pdf/pdf_interpret.c
index 5f4fffc1..3021196c 100644
--- a/pdf/pdf_interpret.c
+++ b/pdf/pdf_interpret.c
@@ -108,8 +108,8 @@ struct pdf_csi_s
};
static void pdf_run_contents_object(pdf_csi *csi, pdf_obj *rdb, pdf_obj *contents);
-static void pdf_run_xobject(pdf_csi *csi, pdf_obj *resources, pdf_xobject *xobj, fz_matrix transform);
-static void pdf_show_pattern(pdf_csi *csi, pdf_pattern *pat, fz_rect area, int what);
+static void pdf_run_xobject(pdf_csi *csi, pdf_obj *resources, pdf_xobject *xobj, const fz_matrix *transform);
+static void pdf_show_pattern(pdf_csi *csi, pdf_pattern *pat, const fz_rect *area, int what);
static int
ocg_intents_include(pdf_ocg_descriptor *desc, char *name)
@@ -324,7 +324,7 @@ pdf_is_hidden_ocg(pdf_obj *ocg, pdf_csi *csi, pdf_obj *rdb)
*/
static void
-pdf_begin_group(pdf_csi *csi, fz_rect bbox)
+pdf_begin_group(pdf_csi *csi, const fz_rect *bbox)
{
pdf_gstate *gstate = csi->gstate + csi->gtop;
fz_context *ctx = csi->dev->ctx;
@@ -332,17 +332,18 @@ pdf_begin_group(pdf_csi *csi, fz_rect bbox)
if (gstate->softmask)
{
pdf_xobject *softmask = gstate->softmask;
- fz_rect bbox = fz_transform_rect(gstate->softmask_ctm, softmask->bbox);
+ fz_rect mask_bbox = softmask->bbox;
fz_matrix save_ctm = gstate->ctm;
+ fz_transform_rect(&mask_bbox, &gstate->softmask_ctm);
gstate->softmask = NULL;
gstate->ctm = gstate->softmask_ctm;
- fz_begin_mask(csi->dev, bbox, gstate->luminosity,
+ fz_begin_mask(csi->dev, &mask_bbox, gstate->luminosity,
softmask->colorspace, gstate->softmask_bc);
fz_try(ctx)
{
- pdf_run_xobject(csi, NULL, softmask, fz_identity);
+ pdf_run_xobject(csi, NULL, softmask, &fz_identity);
}
fz_catch(ctx)
{
@@ -385,11 +386,11 @@ pdf_show_shade(pdf_csi *csi, fz_shade *shd)
if (csi->in_hidden_ocg > 0)
return;
- bbox = fz_bound_shade(ctx, shd, gstate->ctm);
+ fz_bound_shade(ctx, shd, &gstate->ctm, &bbox);
- pdf_begin_group(csi, bbox);
+ pdf_begin_group(csi, &bbox);
- fz_fill_shade(csi->dev, shd, gstate->ctm, gstate->fill.alpha);
+ fz_fill_shade(csi->dev, shd, &gstate->ctm, gstate->fill.alpha);
pdf_end_group(csi);
}
@@ -405,20 +406,21 @@ pdf_show_image(pdf_csi *csi, fz_image *image)
return;
/* PDF has images bottom-up, so flip them right side up here */
- image_ctm = fz_concat(fz_scale(1, -1), fz_translate(0, 1));
- image_ctm = fz_concat(image_ctm, gstate->ctm);
+ image_ctm = gstate->ctm;
+ fz_pre_scale(fz_pre_translate(&image_ctm, 0, 1), 1, -1);
- bbox = fz_transform_rect(image_ctm, fz_unit_rect);
+ bbox = fz_unit_rect;
+ fz_transform_rect(&bbox, &image_ctm);
if (image->mask)
{
/* apply blend group even though we skip the soft mask */
if (gstate->blendmode)
- fz_begin_group(csi->dev, bbox, 0, 0, gstate->blendmode, 1);
- fz_clip_image_mask(csi->dev, image->mask, bbox, image_ctm);
+ fz_begin_group(csi->dev, &bbox, 0, 0, gstate->blendmode, 1);
+ fz_clip_image_mask(csi->dev, image->mask, &bbox, &image_ctm);
}
else
- pdf_begin_group(csi, bbox);
+ pdf_begin_group(csi, &bbox);
if (!image->colorspace)
{
@@ -428,22 +430,22 @@ pdf_show_image(pdf_csi *csi, fz_image *image)
case PDF_MAT_NONE:
break;
case PDF_MAT_COLOR:
- fz_fill_image_mask(csi->dev, image, image_ctm,
+ fz_fill_image_mask(csi->dev, image, &image_ctm,
gstate->fill.colorspace, gstate->fill.v, gstate->fill.alpha);
break;
case PDF_MAT_PATTERN:
if (gstate->fill.pattern)
{
- fz_clip_image_mask(csi->dev, image, bbox, image_ctm);
- pdf_show_pattern(csi, gstate->fill.pattern, bbox, PDF_FILL);
+ fz_clip_image_mask(csi->dev, image, &bbox, &image_ctm);
+ pdf_show_pattern(csi, gstate->fill.pattern, &bbox, PDF_FILL);
fz_pop_clip(csi->dev);
}
break;
case PDF_MAT_SHADE:
if (gstate->fill.shade)
{
- fz_clip_image_mask(csi->dev, image, bbox, image_ctm);
- fz_fill_shade(csi->dev, gstate->fill.shade, gstate->ctm, gstate->fill.alpha);
+ fz_clip_image_mask(csi->dev, image, &bbox, &image_ctm);
+ fz_fill_shade(csi->dev, gstate->fill.shade, &gstate->ctm, gstate->fill.alpha);
fz_pop_clip(csi->dev);
}
break;
@@ -451,7 +453,7 @@ pdf_show_image(pdf_csi *csi, fz_image *image)
}
else
{
- fz_fill_image(csi->dev, image, image_ctm, gstate->fill.alpha);
+ fz_fill_image(csi->dev, image, &image_ctm, gstate->fill.alpha);
}
if (image->mask)
@@ -493,15 +495,12 @@ pdf_show_path(pdf_csi *csi, int doclose, int dofill, int dostroke, int even_odd)
if (doclose)
fz_closepath(ctx, path);
- if (dostroke)
- bbox = fz_bound_path(ctx, path, gstate->stroke_state, gstate->ctm);
- else
- bbox = fz_bound_path(ctx, path, NULL, gstate->ctm);
+ fz_bound_path(ctx, path, (dostroke ? gstate->stroke_state : NULL), &gstate->ctm, &bbox);
if (csi->clip)
{
gstate->clip_depth++;
- fz_clip_path(csi->dev, path, fz_infinite_rect, csi->clip_even_odd, gstate->ctm);
+ fz_clip_path(csi->dev, path, NULL, csi->clip_even_odd, &gstate->ctm);
csi->clip = 0;
}
@@ -509,7 +508,7 @@ pdf_show_path(pdf_csi *csi, int doclose, int dofill, int dostroke, int even_odd)
dostroke = dofill = 0;
if (dofill || dostroke)
- pdf_begin_group(csi, bbox);
+ pdf_begin_group(csi, &bbox);
if (dofill)
{
@@ -518,22 +517,22 @@ pdf_show_path(pdf_csi *csi, int doclose, int dofill, int dostroke, int even_odd)
case PDF_MAT_NONE:
break;
case PDF_MAT_COLOR:
- fz_fill_path(csi->dev, path, even_odd, gstate->ctm,
+ fz_fill_path(csi->dev, path, even_odd, &gstate->ctm,
gstate->fill.colorspace, gstate->fill.v, gstate->fill.alpha);
break;
case PDF_MAT_PATTERN:
if (gstate->fill.pattern)
{
- fz_clip_path(csi->dev, path, fz_infinite_rect, even_odd, gstate->ctm);
- pdf_show_pattern(csi, gstate->fill.pattern, bbox, PDF_FILL);
+ fz_clip_path(csi->dev, path, NULL, even_odd, &gstate->ctm);
+ pdf_show_pattern(csi, gstate->fill.pattern, &bbox, PDF_FILL);
fz_pop_clip(csi->dev);
}
break;
case PDF_MAT_SHADE:
if (gstate->fill.shade)
{
- fz_clip_path(csi->dev, path, fz_infinite_rect, even_odd, gstate->ctm);
- fz_fill_shade(csi->dev, gstate->fill.shade, csi->top_ctm, gstate->fill.alpha);
+ fz_clip_path(csi->dev, path, NULL, even_odd, &gstate->ctm);
+ fz_fill_shade(csi->dev, gstate->fill.shade, &csi->top_ctm, gstate->fill.alpha);
fz_pop_clip(csi->dev);
}
break;
@@ -547,22 +546,22 @@ pdf_show_path(pdf_csi *csi, int doclose, int dofill, int dostroke, int even_odd)
case PDF_MAT_NONE:
break;
case PDF_MAT_COLOR:
- fz_stroke_path(csi->dev, path, gstate->stroke_state, gstate->ctm,
+ fz_stroke_path(csi->dev, path, gstate->stroke_state, &gstate->ctm,
gstate->stroke.colorspace, gstate->stroke.v, gstate->stroke.alpha);
break;
case PDF_MAT_PATTERN:
if (gstate->stroke.pattern)
{
- fz_clip_stroke_path(csi->dev, path, bbox, gstate->stroke_state, gstate->ctm);
- pdf_show_pattern(csi, gstate->stroke.pattern, bbox, PDF_STROKE);
+ fz_clip_stroke_path(csi->dev, path, &bbox, gstate->stroke_state, &gstate->ctm);
+ pdf_show_pattern(csi, gstate->stroke.pattern, &bbox, PDF_STROKE);
fz_pop_clip(csi->dev);
}
break;
case PDF_MAT_SHADE:
if (gstate->stroke.shade)
{
- fz_clip_stroke_path(csi->dev, path, bbox, gstate->stroke_state, gstate->ctm);
- fz_fill_shade(csi->dev, gstate->stroke.shade, csi->top_ctm, gstate->stroke.alpha);
+ fz_clip_stroke_path(csi->dev, path, &bbox, gstate->stroke_state, &gstate->ctm);
+ fz_fill_shade(csi->dev, gstate->stroke.shade, &csi->top_ctm, gstate->stroke.alpha);
fz_pop_clip(csi->dev);
}
break;
@@ -620,16 +619,18 @@ pdf_flush_text(pdf_csi *csi)
fz_try(ctx)
{
- fz_rect tb = fz_transform_rect(gstate->ctm, csi->text_bbox);
+ fz_rect tb = csi->text_bbox;
+
+ fz_transform_rect(&tb, &gstate->ctm);
/* Don't bother sending a text group with nothing in it */
if (text->len == 0)
break;
- pdf_begin_group(csi, tb);
+ pdf_begin_group(csi, &tb);
if (doinvisible)
- fz_ignore_text(csi->dev, text, gstate->ctm);
+ fz_ignore_text(csi->dev, text, &gstate->ctm);
if (dofill)
{
@@ -638,22 +639,22 @@ pdf_flush_text(pdf_csi *csi)
case PDF_MAT_NONE:
break;
case PDF_MAT_COLOR:
- fz_fill_text(csi->dev, text, gstate->ctm,
+ fz_fill_text(csi->dev, text, &gstate->ctm,
gstate->fill.colorspace, gstate->fill.v, gstate->fill.alpha);
break;
case PDF_MAT_PATTERN:
if (gstate->fill.pattern)
{
- fz_clip_text(csi->dev, text, gstate->ctm, 0);
- pdf_show_pattern(csi, gstate->fill.pattern, tb, PDF_FILL);
+ fz_clip_text(csi->dev, text, &gstate->ctm, 0);
+ pdf_show_pattern(csi, gstate->fill.pattern, &tb, PDF_FILL);
fz_pop_clip(csi->dev);
}
break;
case PDF_MAT_SHADE:
if (gstate->fill.shade)
{
- fz_clip_text(csi->dev, text, gstate->ctm, 0);
- fz_fill_shade(csi->dev, gstate->fill.shade, csi->top_ctm, gstate->fill.alpha);
+ fz_clip_text(csi->dev, text, &gstate->ctm, 0);
+ fz_fill_shade(csi->dev, gstate->fill.shade, &csi->top_ctm, gstate->fill.alpha);
fz_pop_clip(csi->dev);
}
break;
@@ -667,22 +668,22 @@ pdf_flush_text(pdf_csi *csi)
case PDF_MAT_NONE:
break;
case PDF_MAT_COLOR:
- fz_stroke_text(csi->dev, text, gstate->stroke_state, gstate->ctm,
+ fz_stroke_text(csi->dev, text, gstate->stroke_state, &gstate->ctm,
gstate->stroke.colorspace, gstate->stroke.v, gstate->stroke.alpha);
break;
case PDF_MAT_PATTERN:
if (gstate->stroke.pattern)
{
- fz_clip_stroke_text(csi->dev, text, gstate->stroke_state, gstate->ctm);
- pdf_show_pattern(csi, gstate->stroke.pattern, tb, PDF_STROKE);
+ fz_clip_stroke_text(csi->dev, text, gstate->stroke_state, &gstate->ctm);
+ pdf_show_pattern(csi, gstate->stroke.pattern, &tb, PDF_STROKE);
fz_pop_clip(csi->dev);
}
break;
case PDF_MAT_SHADE:
if (gstate->stroke.shade)
{
- fz_clip_stroke_text(csi->dev, text, gstate->stroke_state, gstate->ctm);
- fz_fill_shade(csi->dev, gstate->stroke.shade, csi->top_ctm, gstate->stroke.alpha);
+ fz_clip_stroke_text(csi->dev, text, gstate->stroke_state, &gstate->ctm);
+ fz_fill_shade(csi->dev, gstate->stroke.shade, &csi->top_ctm, gstate->stroke.alpha);
fz_pop_clip(csi->dev);
}
break;
@@ -693,7 +694,7 @@ pdf_flush_text(pdf_csi *csi)
{
if (csi->accumulate < 2)
gstate->clip_depth++;
- fz_clip_text(csi->dev, text, gstate->ctm, csi->accumulate);
+ fz_clip_text(csi->dev, text, &gstate->ctm, csi->accumulate);
csi->accumulate = 2;
}
@@ -756,9 +757,9 @@ pdf_show_char(pdf_csi *csi, int cid)
tsm.f -= v.y * gstate->size * 0.001f;
}
- trm = fz_concat(tsm, csi->tm);
+ fz_concat(&trm, &tsm, &csi->tm);
- bbox = fz_bound_glyph(ctx, fontdesc->font, gid, trm);
+ fz_bound_glyph(ctx, fontdesc->font, gid, &trm, &bbox);
/* Compensate for the glyph cache limited positioning precision */
bbox.x0 -= 1;
bbox.y0 -= 1;
@@ -782,7 +783,7 @@ pdf_show_char(pdf_csi *csi, int cid)
{
pdf_flush_text(csi);
- csi->text = fz_new_text(ctx, fontdesc->font, trm, fontdesc->wmode);
+ csi->text = fz_new_text(ctx, fontdesc->font, &trm, fontdesc->wmode);
csi->text->trm.e = 0;
csi->text->trm.f = 0;
csi->text_mode = gstate->render;
@@ -794,12 +795,13 @@ pdf_show_char(pdf_csi *csi, int cid)
/* Render the glyph stream direct here (only happens for
* type3 glyphs that seem to inherit current graphics
* attributes, or type 3 glyphs within type3 glyphs). */
- fz_matrix composed = fz_concat(trm, gstate->ctm);
- fz_render_t3_glyph_direct(ctx, csi->dev, fontdesc->font, gid, composed, gstate, csi->nested_depth);
+ fz_matrix composed;
+ fz_concat(&composed, &trm, &gstate->ctm);
+ fz_render_t3_glyph_direct(ctx, csi->dev, fontdesc->font, gid, &composed, gstate, csi->nested_depth);
}
else
{
- csi->text_bbox = fz_union_rect(csi->text_bbox, bbox);
+ fz_union_rect(&csi->text_bbox, &bbox);
/* add glyph to textobject */
fz_add_text(ctx, csi->text, gid, ucsbuf[0], trm.e, trm.f);
@@ -814,14 +816,14 @@ pdf_show_char(pdf_csi *csi, int cid)
h = pdf_lookup_hmtx(ctx, fontdesc, cid);
w0 = h.w * 0.001f;
tx = (w0 * gstate->size + gstate->char_space) * gstate->scale;
- csi->tm = fz_concat(fz_translate(tx, 0), csi->tm);
+ fz_pre_translate(&csi->tm, tx, 0);
}
if (fontdesc->wmode == 1)
{
w1 = v.w * 0.001f;
ty = w1 * gstate->size + gstate->char_space;
- csi->tm = fz_concat(fz_translate(0, ty), csi->tm);
+ fz_pre_translate(&csi->tm, 0, ty);
}
}
@@ -839,9 +841,9 @@ pdf_show_space(pdf_csi *csi, float tadj)
}
if (fontdesc->wmode == 0)
- csi->tm = fz_concat(fz_translate(tadj * gstate->scale, 0), csi->tm);
+ fz_pre_translate(&csi->tm, tadj * gstate->scale, 0);
else
- csi->tm = fz_concat(fz_translate(0, tadj), csi->tm);
+ fz_pre_translate(&csi->tm, 0, tadj);
}
static void
@@ -903,9 +905,9 @@ pdf_show_text(pdf_csi *csi, pdf_obj *text)
*/
static void
-pdf_init_gstate(fz_context *ctx, pdf_gstate *gs, fz_matrix ctm)
+pdf_init_gstate(fz_context *ctx, pdf_gstate *gs, const fz_matrix *ctm)
{
- gs->ctm = ctm;
+ gs->ctm = *ctm;
gs->clip_depth = 0;
gs->stroke_state = fz_new_stroke_state(ctx);
@@ -984,7 +986,7 @@ copy_state(fz_context *ctx, pdf_gstate *gs, pdf_gstate *old)
static pdf_csi *
-pdf_new_csi(pdf_document *xref, fz_device *dev, fz_matrix ctm, char *event, fz_cookie *cookie, pdf_gstate *gstate, int nested)
+pdf_new_csi(pdf_document *xref, fz_device *dev, const fz_matrix *ctm, char *event, fz_cookie *cookie, pdf_gstate *gstate, int nested)
{
pdf_csi *csi;
fz_context *ctx = dev->ctx;
@@ -1019,7 +1021,7 @@ pdf_new_csi(pdf_document *xref, fz_device *dev, fz_matrix ctm, char *event, fz_c
csi->gcap = 64;
csi->gstate = fz_malloc_array(ctx, csi->gcap, sizeof(pdf_gstate));
- csi->top_ctm = ctm;
+ csi->top_ctm = *ctm;
csi->nested_depth = nested;
pdf_init_gstate(ctx, &csi->gstate[0], ctm);
if (gstate)
@@ -1266,7 +1268,7 @@ pdf_unset_pattern(pdf_csi *csi, int what)
*/
static void
-pdf_show_pattern(pdf_csi *csi, pdf_pattern *pat, fz_rect area, int what)
+pdf_show_pattern(pdf_csi *csi, pdf_pattern *pat, const fz_rect *area, int what)
{
fz_context *ctx = csi->dev->ctx;
pdf_gstate *gstate;
@@ -1274,6 +1276,7 @@ pdf_show_pattern(pdf_csi *csi, pdf_pattern *pat, fz_rect area, int what)
fz_matrix oldtopctm;
int x0, y0, x1, y1;
int oldtop;
+ fz_rect local_area;
pdf_gsave(csi);
gstate = csi->gstate + csi->gtop;
@@ -1308,22 +1311,23 @@ pdf_show_pattern(pdf_csi *csi, pdf_pattern *pat, fz_rect area, int what)
gstate->softmask = NULL;
}
- ptm = fz_concat(pat->matrix, csi->top_ctm);
- invptm = fz_invert_matrix(ptm);
+ fz_concat(&ptm, &pat->matrix, &csi->top_ctm);
+ fz_invert_matrix(&invptm, &ptm);
/* patterns are painted using the ctm in effect at the beginning
* of the content stream. area = bbox of shape to be filled in
* device space. Map it back to pattern space. */
- area = fz_transform_rect(invptm, area);
+ local_area = *area;
+ fz_transform_rect(&local_area, &invptm);
/* When calculating the number of tiles required, we adjust by a small
* amount to allow for rounding errors. By choosing this amount to be
* smaller than 1/256, we guarantee we won't cause problems that will
* be visible even under our most extreme antialiasing. */
- x0 = floorf((area.x0 - pat->bbox.x0) / pat->xstep + 0.001);
- y0 = floorf((area.y0 - pat->bbox.y0) / pat->ystep + 0.001);
- x1 = ceilf((area.x1 - pat->bbox.x0) / pat->xstep - 0.001);
- y1 = ceilf((area.y1 - pat->bbox.y0) / pat->ystep - 0.001);
+ x0 = floorf((local_area.x0 - pat->bbox.x0) / pat->xstep + 0.001);
+ y0 = floorf((local_area.y0 - pat->bbox.y0) / pat->ystep + 0.001);
+ x1 = ceilf((local_area.x1 - pat->bbox.x0) / pat->xstep - 0.001);
+ y1 = ceilf((local_area.y1 - pat->bbox.y0) / pat->ystep - 0.001);
oldtopctm = csi->top_ctm;
oldtop = csi->gtop;
@@ -1334,7 +1338,7 @@ pdf_show_pattern(pdf_csi *csi, pdf_pattern *pat, fz_rect area, int what)
if (0)
#endif
{
- fz_begin_tile(csi->dev, area, pat->bbox, pat->xstep, pat->ystep, ptm);
+ fz_begin_tile(csi->dev, &local_area, &pat->bbox, pat->xstep, pat->ystep, &ptm);
gstate->ctm = ptm;
csi->top_ctm = gstate->ctm;
pdf_gsave(csi);
@@ -1351,7 +1355,8 @@ pdf_show_pattern(pdf_csi *csi, pdf_pattern *pat, fz_rect area, int what)
{
for (x = x0; x < x1; x++)
{
- gstate->ctm = fz_concat(fz_translate(x * pat->xstep, y * pat->ystep), ptm);
+ gstate->ctm = ptm;
+ fz_pre_translate(&gstate->ctm, x * pat->xstep, y * pat->ystep);
csi->top_ctm = gstate->ctm;
pdf_gsave(csi);
fz_try(ctx)
@@ -1378,13 +1383,14 @@ pdf_show_pattern(pdf_csi *csi, pdf_pattern *pat, fz_rect area, int what)
}
static void
-pdf_run_xobject(pdf_csi *csi, pdf_obj *resources, pdf_xobject *xobj, fz_matrix transform)
+pdf_run_xobject(pdf_csi *csi, pdf_obj *resources, pdf_xobject *xobj, const fz_matrix *transform)
{
fz_context *ctx = csi->dev->ctx;
pdf_gstate *gstate = NULL;
fz_matrix oldtopctm;
int oldtop = 0;
int popmask;
+ fz_matrix local_transform = *transform;
/* Avoid infinite recursion */
if (xobj == NULL || pdf_obj_mark(xobj->me))
@@ -1403,25 +1409,27 @@ pdf_run_xobject(pdf_csi *csi, pdf_obj *resources, pdf_xobject *xobj, fz_matrix t
popmask = 0;
/* apply xobject's transform matrix */
- transform = fz_concat(xobj->matrix, transform);
- gstate->ctm = fz_concat(transform, gstate->ctm);
+ fz_concat(&local_transform, &xobj->matrix, &local_transform);
+ fz_concat(&gstate->ctm, &local_transform, &gstate->ctm);
/* apply soft mask, create transparency group and reset state */
if (xobj->transparency)
{
+ fz_rect bbox = xobj->bbox;
+ fz_transform_rect(&bbox, &gstate->ctm);
if (gstate->softmask)
{
pdf_xobject *softmask = gstate->softmask;
- fz_rect bbox = fz_transform_rect(gstate->ctm, xobj->bbox);
+
gstate->softmask = NULL;
popmask = 1;
- fz_begin_mask(csi->dev, bbox, gstate->luminosity,
+ fz_begin_mask(csi->dev, &bbox, gstate->luminosity,
softmask->colorspace, gstate->softmask_bc);
fz_try(ctx)
{
- pdf_run_xobject(csi, resources, softmask, fz_identity);
+ pdf_run_xobject(csi, resources, softmask, &fz_identity);
}
fz_catch(ctx)
{
@@ -1436,8 +1444,7 @@ pdf_run_xobject(pdf_csi *csi, pdf_obj *resources, pdf_xobject *xobj, fz_matrix t
pdf_drop_xobject(ctx, softmask);
}
- fz_begin_group(csi->dev,
- fz_transform_rect(gstate->ctm, xobj->bbox),
+ fz_begin_group(csi->dev, &bbox,
xobj->isolated, xobj->knockout, gstate->blendmode, gstate->fill.alpha);
gstate->blendmode = 0;
@@ -1609,7 +1616,7 @@ pdf_run_extgstate(pdf_csi *csi, pdf_obj *rdb, pdf_obj *extgstate)
if (!colorspace)
colorspace = fz_device_gray;
- gstate->softmask_ctm = fz_concat(xobj->matrix, gstate->ctm);
+ fz_concat(&gstate->softmask_ctm, &xobj->matrix, &gstate->ctm);
gstate->softmask = xobj;
for (k = 0; k < colorspace->n; k++)
gstate->softmask_bc[k] = 0;
@@ -1854,7 +1861,7 @@ static void pdf_run_Do(pdf_csi *csi, pdf_obj *rdb)
fz_try(ctx)
{
- pdf_run_xobject(csi, xobj->resources, xobj, fz_identity);
+ pdf_run_xobject(csi, xobj->resources, xobj, &fz_identity);
}
fz_always(ctx)
{
@@ -2108,19 +2115,16 @@ static void pdf_run_Ts(pdf_csi *csi)
static void pdf_run_Td(pdf_csi *csi)
{
- fz_matrix m = fz_translate(csi->stack[0], csi->stack[1]);
- csi->tlm = fz_concat(m, csi->tlm);
+ fz_pre_translate(&csi->tlm, csi->stack[0], csi->stack[1]);
csi->tm = csi->tlm;
}
static void pdf_run_TD(pdf_csi *csi)
{
pdf_gstate *gstate = csi->gstate + csi->gtop;
- fz_matrix m;
gstate->leading = -csi->stack[1];
- m = fz_translate(csi->stack[0], csi->stack[1]);
- csi->tlm = fz_concat(m, csi->tlm);
+ fz_pre_translate(&csi->tlm, csi->stack[0], csi->stack[1]);
csi->tm = csi->tlm;
}
@@ -2138,8 +2142,7 @@ static void pdf_run_Tm(pdf_csi *csi)
static void pdf_run_Tstar(pdf_csi *csi)
{
pdf_gstate *gstate = csi->gstate + csi->gtop;
- fz_matrix m = fz_translate(0, -gstate->leading);
- csi->tlm = fz_concat(m, csi->tlm);
+ fz_pre_translate(&csi->tlm, 0, -gstate->leading);
csi->tm = csi->tlm;
}
@@ -2205,7 +2208,7 @@ static void pdf_run_cm(pdf_csi *csi)
m.e = csi->stack[4];
m.f = csi->stack[5];
- gstate->ctm = fz_concat(m, gstate->ctm);
+ fz_concat(&gstate->ctm, &m, &gstate->ctm);
}
static void pdf_run_d(pdf_csi *csi)
@@ -2428,11 +2431,9 @@ static void pdf_run_y(pdf_csi *csi)
static void pdf_run_squote(pdf_csi *csi)
{
- fz_matrix m;
pdf_gstate *gstate = csi->gstate + csi->gtop;
- m = fz_translate(0, -gstate->leading);
- csi->tlm = fz_concat(m, csi->tlm);
+ fz_pre_translate(&csi->tlm, 0, -gstate->leading);
csi->tm = csi->tlm;
if (csi->string_len)
@@ -2443,14 +2444,12 @@ static void pdf_run_squote(pdf_csi *csi)
static void pdf_run_dquote(pdf_csi *csi)
{
- fz_matrix m;
pdf_gstate *gstate = csi->gstate + csi->gtop;
gstate->word_space = csi->stack[0];
gstate->char_space = csi->stack[1];
- m = fz_translate(0, -gstate->leading);
- csi->tlm = fz_concat(m, csi->tlm);
+ fz_pre_translate(&csi->tlm, 0, -gstate->leading);
csi->tm = csi->tlm;
if (csi->string_len)
@@ -2866,17 +2865,21 @@ pdf_run_contents_buffer(pdf_csi *csi, pdf_obj *rdb, fz_buffer *contents)
}
}
-static void pdf_run_page_contents_with_usage(pdf_document *xref, pdf_page *page, fz_device *dev, fz_matrix ctm, char *event, fz_cookie *cookie)
+static void pdf_run_page_contents_with_usage(pdf_document *xref, pdf_page *page, fz_device *dev, const fz_matrix *ctm, char *event, fz_cookie *cookie)
{
fz_context *ctx = dev->ctx;
pdf_csi *csi;
+ fz_matrix local_ctm;
- ctm = fz_concat(page->ctm, ctm);
+ fz_concat(&local_ctm, &page->ctm, ctm);
if (page->transparency)
- fz_begin_group(dev, fz_transform_rect(ctm, page->mediabox), 1, 0, 0, 1);
+ {
+ fz_rect mediabox = page->mediabox;
+ fz_begin_group(dev, fz_transform_rect(&mediabox, &local_ctm), 1, 0, 0, 1);
+ }
- csi = pdf_new_csi(xref, dev, ctm, event, cookie, NULL, 0);
+ csi = pdf_new_csi(xref, dev, &local_ctm, event, cookie, NULL, 0);
fz_try(ctx)
{
pdf_run_contents_object(csi, page->resources, page->contents);
@@ -2894,18 +2897,19 @@ static void pdf_run_page_contents_with_usage(pdf_document *xref, pdf_page *page,
fz_end_group(dev);
}
-void pdf_run_page_contents(pdf_document *xref, pdf_page *page, fz_device *dev, fz_matrix ctm, fz_cookie *cookie)
+void pdf_run_page_contents(pdf_document *xref, pdf_page *page, fz_device *dev, const fz_matrix *ctm, fz_cookie *cookie)
{
pdf_run_page_contents_with_usage(xref, page, dev, ctm, "View", cookie);
}
-static void pdf_run_annot_with_usage(pdf_document *xref, pdf_page *page, pdf_annot *annot, fz_device *dev, fz_matrix ctm, char *event, fz_cookie *cookie)
+static void pdf_run_annot_with_usage(pdf_document *xref, pdf_page *page, pdf_annot *annot, fz_device *dev, const fz_matrix *ctm, char *event, fz_cookie *cookie)
{
fz_context *ctx = dev->ctx;
pdf_csi *csi;
int flags;
+ fz_matrix local_ctm;
- ctm = fz_concat(page->ctm, ctm);
+ fz_concat(&local_ctm, &page->ctm, ctm);
flags = pdf_to_int(pdf_dict_gets(annot->obj, "F"));
@@ -2919,12 +2923,12 @@ static void pdf_run_annot_with_usage(pdf_document *xref, pdf_page *page, pdf_ann
if (!strcmp(event, "View") && (flags & (1 << 5))) /* NoView */
return;
- csi = pdf_new_csi(xref, dev, ctm, event, cookie, NULL, 0);
+ csi = pdf_new_csi(xref, dev, &local_ctm, event, cookie, NULL, 0);
if (!pdf_is_hidden_ocg(pdf_dict_gets(annot->obj, "OC"), csi, page->resources))
{
fz_try(ctx)
{
- pdf_run_xobject(csi, page->resources, annot->ap, annot->matrix);
+ pdf_run_xobject(csi, page->resources, annot->ap, &annot->matrix);
}
fz_catch(ctx)
{
@@ -2935,12 +2939,12 @@ static void pdf_run_annot_with_usage(pdf_document *xref, pdf_page *page, pdf_ann
pdf_free_csi(csi);
}
-void pdf_run_annot(pdf_document *xref, pdf_page *page, pdf_annot *annot, fz_device *dev, fz_matrix ctm, fz_cookie *cookie)
+void pdf_run_annot(pdf_document *xref, pdf_page *page, pdf_annot *annot, fz_device *dev, const fz_matrix *ctm, fz_cookie *cookie)
{
pdf_run_annot_with_usage(xref, page, annot, dev, ctm, "View", cookie);
}
-static void pdf_run_page_annots_with_usage(pdf_document *xref, pdf_page *page, fz_device *dev, fz_matrix ctm, char *event, fz_cookie *cookie)
+static void pdf_run_page_annots_with_usage(pdf_document *xref, pdf_page *page, fz_device *dev, const fz_matrix *ctm, char *event, fz_cookie *cookie)
{
pdf_annot *annot;
@@ -2967,20 +2971,20 @@ static void pdf_run_page_annots_with_usage(pdf_document *xref, pdf_page *page, f
}
void
-pdf_run_page_with_usage(pdf_document *xref, pdf_page *page, fz_device *dev, fz_matrix ctm, char *event, fz_cookie *cookie)
+pdf_run_page_with_usage(pdf_document *xref, pdf_page *page, fz_device *dev, const fz_matrix *ctm, char *event, fz_cookie *cookie)
{
pdf_run_page_contents_with_usage(xref, page, dev, ctm, event, cookie);
pdf_run_page_annots_with_usage(xref, page, dev, ctm, event, cookie);
}
void
-pdf_run_page(pdf_document *xref, pdf_page *page, fz_device *dev, fz_matrix ctm, fz_cookie *cookie)
+pdf_run_page(pdf_document *xref, pdf_page *page, fz_device *dev, const fz_matrix *ctm, fz_cookie *cookie)
{
pdf_run_page_with_usage(xref, page, dev, ctm, "View", cookie);
}
void
-pdf_run_glyph(pdf_document *xref, pdf_obj *resources, fz_buffer *contents, fz_device *dev, fz_matrix ctm, void *gstate, int nested_depth)
+pdf_run_glyph(pdf_document *xref, pdf_obj *resources, fz_buffer *contents, fz_device *dev, const fz_matrix *ctm, void *gstate, int nested_depth)
{
pdf_csi *csi = pdf_new_csi(xref, dev, ctm, "View", NULL, gstate, nested_depth+1);
fz_context *ctx = xref->ctx;
diff --git a/pdf/pdf_object.c b/pdf/pdf_object.c
index 8a2d71fc..a2d9d37b 100644
--- a/pdf/pdf_object.c
+++ b/pdf/pdf_object.c
@@ -575,7 +575,7 @@ pdf_array_contains(pdf_obj *arr, pdf_obj *obj)
return 0;
}
-pdf_obj *pdf_new_rect(fz_context *ctx, fz_rect rect)
+pdf_obj *pdf_new_rect(fz_context *ctx, const fz_rect *rect)
{
pdf_obj *arr = NULL;
pdf_obj *item = NULL;
@@ -586,22 +586,22 @@ pdf_obj *pdf_new_rect(fz_context *ctx, fz_rect rect)
{
arr = pdf_new_array(ctx, 4);
- item = pdf_new_real(ctx, rect.x0);
+ item = pdf_new_real(ctx, rect->x0);
pdf_array_push(arr, item);
pdf_drop_obj(item);
item = NULL;
- item = pdf_new_real(ctx, rect.y0);
+ item = pdf_new_real(ctx, rect->y0);
pdf_array_push(arr, item);
pdf_drop_obj(item);
item = NULL;
- item = pdf_new_real(ctx, rect.x1);
+ item = pdf_new_real(ctx, rect->x1);
pdf_array_push(arr, item);
pdf_drop_obj(item);
item = NULL;
- item = pdf_new_real(ctx, rect.y1);
+ item = pdf_new_real(ctx, rect->y1);
pdf_array_push(arr, item);
pdf_drop_obj(item);
item = NULL;
@@ -616,7 +616,7 @@ pdf_obj *pdf_new_rect(fz_context *ctx, fz_rect rect)
return arr;
}
-pdf_obj *pdf_new_matrix(fz_context *ctx, fz_matrix mtx)
+pdf_obj *pdf_new_matrix(fz_context *ctx, const fz_matrix *mtx)
{
pdf_obj *arr = NULL;
pdf_obj *item = NULL;
@@ -627,32 +627,32 @@ pdf_obj *pdf_new_matrix(fz_context *ctx, fz_matrix mtx)
{
arr = pdf_new_array(ctx, 6);
- item = pdf_new_real(ctx, mtx.a);
+ item = pdf_new_real(ctx, mtx->a);
pdf_array_push(arr, item);
pdf_drop_obj(item);
item = NULL;
- item = pdf_new_real(ctx, mtx.b);
+ item = pdf_new_real(ctx, mtx->b);
pdf_array_push(arr, item);
pdf_drop_obj(item);
item = NULL;
- item = pdf_new_real(ctx, mtx.c);
+ item = pdf_new_real(ctx, mtx->c);
pdf_array_push(arr, item);
pdf_drop_obj(item);
item = NULL;
- item = pdf_new_real(ctx, mtx.d);
+ item = pdf_new_real(ctx, mtx->d);
pdf_array_push(arr, item);
pdf_drop_obj(item);
item = NULL;
- item = pdf_new_real(ctx, mtx.e);
+ item = pdf_new_real(ctx, mtx->e);
pdf_array_push(arr, item);
pdf_drop_obj(item);
item = NULL;
- item = pdf_new_real(ctx, mtx.f);
+ item = pdf_new_real(ctx, mtx->f);
pdf_array_push(arr, item);
pdf_drop_obj(item);
item = NULL;
diff --git a/pdf/pdf_page.c b/pdf/pdf_page.c
index a071732a..a3627176 100644
--- a/pdf/pdf_page.c
+++ b/pdf/pdf_page.c
@@ -339,8 +339,8 @@ pdf_load_page(pdf_document *xref, int number)
pdf_annot *annot;
pdf_obj *pageobj, *pageref, *obj;
fz_rect mediabox, cropbox, realbox;
- fz_matrix ctm;
float userunit;
+ fz_matrix mat;
pdf_load_page_tree(xref);
if (number < 0 || number >= xref->page_len)
@@ -363,8 +363,8 @@ pdf_load_page(pdf_document *xref, int number)
else
userunit = 1;
- mediabox = pdf_to_rect(ctx, pdf_dict_gets(pageobj, "MediaBox"));
- if (fz_is_empty_rect(mediabox))
+ pdf_to_rect(ctx, pdf_dict_gets(pageobj, "MediaBox"), &mediabox);
+ if (fz_is_empty_rect(&mediabox))
{
fz_warn(ctx, "cannot find page size for page %d", number + 1);
mediabox.x0 = 0;
@@ -373,9 +373,9 @@ pdf_load_page(pdf_document *xref, int number)
mediabox.y1 = 792;
}
- cropbox = pdf_to_rect(ctx, pdf_dict_gets(pageobj, "CropBox"));
- if (!fz_is_empty_rect(cropbox))
- mediabox = fz_intersect_rect(mediabox, cropbox);
+ pdf_to_rect(ctx, pdf_dict_gets(pageobj, "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;
@@ -398,16 +398,16 @@ pdf_load_page(pdf_document *xref, int number)
if (page->rotate > 360)
page->rotate = 0;
- ctm = fz_concat(fz_rotate(-page->rotate), fz_scale(1, -1));
- realbox = fz_transform_rect(ctm, page->mediabox);
- ctm = fz_concat(ctm, fz_scale(userunit, userunit));
- ctm = fz_concat(ctm, fz_translate(-realbox.x0, -realbox.y0));
- page->ctm = ctm;
+ 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);
obj = pdf_dict_gets(pageobj, "Annots");
if (obj)
{
- page->links = pdf_load_link_annots(xref, obj, page->ctm);
+ page->links = pdf_load_link_annots(xref, obj, &page->ctm);
page->annots = pdf_load_annots(xref, obj, page);
}
@@ -445,13 +445,15 @@ pdf_load_page(pdf_document *xref, int number)
return page;
}
-fz_rect
-pdf_bound_page(pdf_document *xref, pdf_page *page)
+fz_rect *
+pdf_bound_page(pdf_document *xref, pdf_page *page, fz_rect *bounds)
{
- fz_rect bounds, mediabox = fz_transform_rect(fz_rotate(page->rotate), page->mediabox);
- bounds.x0 = bounds.y0 = 0;
- bounds.x1 = mediabox.x1 - mediabox.x0;
- bounds.y1 = mediabox.y1 - mediabox.y0;
+ 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;
}
diff --git a/pdf/pdf_parse.c b/pdf/pdf_parse.c
index 58165894..365c9ffd 100644
--- a/pdf/pdf_parse.c
+++ b/pdf/pdf_parse.c
@@ -1,31 +1,29 @@
#include "fitz-internal.h"
#include "mupdf-internal.h"
-fz_rect
-pdf_to_rect(fz_context *ctx, pdf_obj *array)
+fz_rect *
+pdf_to_rect(fz_context *ctx, pdf_obj *array, fz_rect *r)
{
- fz_rect r;
float a = pdf_to_real(pdf_array_get(array, 0));
float b = pdf_to_real(pdf_array_get(array, 1));
float c = pdf_to_real(pdf_array_get(array, 2));
float d = pdf_to_real(pdf_array_get(array, 3));
- r.x0 = fz_min(a, c);
- r.y0 = fz_min(b, d);
- r.x1 = fz_max(a, c);
- r.y1 = fz_max(b, d);
+ r->x0 = fz_min(a, c);
+ r->y0 = fz_min(b, d);
+ r->x1 = fz_max(a, c);
+ r->y1 = fz_max(b, d);
return r;
}
-fz_matrix
-pdf_to_matrix(fz_context *ctx, pdf_obj *array)
+fz_matrix *
+pdf_to_matrix(fz_context *ctx, pdf_obj *array, fz_matrix *m)
{
- fz_matrix m;
- m.a = pdf_to_real(pdf_array_get(array, 0));
- m.b = pdf_to_real(pdf_array_get(array, 1));
- m.c = pdf_to_real(pdf_array_get(array, 2));
- m.d = pdf_to_real(pdf_array_get(array, 3));
- m.e = pdf_to_real(pdf_array_get(array, 4));
- m.f = pdf_to_real(pdf_array_get(array, 5));
+ m->a = pdf_to_real(pdf_array_get(array, 0));
+ m->b = pdf_to_real(pdf_array_get(array, 1));
+ m->c = pdf_to_real(pdf_array_get(array, 2));
+ m->d = pdf_to_real(pdf_array_get(array, 3));
+ m->e = pdf_to_real(pdf_array_get(array, 4));
+ m->f = pdf_to_real(pdf_array_get(array, 5));
return m;
}
diff --git a/pdf/pdf_pattern.c b/pdf/pdf_pattern.c
index af96c2d5..5647106b 100644
--- a/pdf/pdf_pattern.c
+++ b/pdf/pdf_pattern.c
@@ -58,11 +58,11 @@ pdf_load_pattern(pdf_document *xref, pdf_obj *dict)
pat->ystep = pdf_to_real(pdf_dict_gets(dict, "YStep"));
obj = pdf_dict_gets(dict, "BBox");
- pat->bbox = pdf_to_rect(ctx, obj);
+ pdf_to_rect(ctx, obj, &pat->bbox);
obj = pdf_dict_gets(dict, "Matrix");
if (obj)
- pat->matrix = pdf_to_matrix(ctx, obj);
+ pdf_to_matrix(ctx, obj, &pat->matrix);
else
pat->matrix = fz_identity;
diff --git a/pdf/pdf_shade.c b/pdf/pdf_shade.c
index 95726975..2eee5168 100644
--- a/pdf/pdf_shade.c
+++ b/pdf/pdf_shade.c
@@ -69,10 +69,11 @@ pdf_load_function_based_shading(fz_shade *shade, pdf_document *xref, pdf_obj *di
y1 = pdf_to_real(pdf_array_get(obj, 3));
}
- matrix = fz_identity;
obj = pdf_dict_gets(dict, "Matrix");
if (obj)
- matrix = pdf_to_matrix(ctx, obj);
+ pdf_to_matrix(ctx, obj, &matrix);
+ else
+ matrix = fz_identity;
shade->u.f.matrix = matrix;
shade->u.f.xdivs = FUNSEGS;
shade->u.f.ydivs = FUNSEGS;
@@ -312,7 +313,7 @@ pdf_load_type7_shade(fz_shade *shade, pdf_document *xref, pdf_obj *dict,
/* Load all of the shading dictionary parameters, then switch on the shading type. */
static fz_shade *
-pdf_load_shading_dict(pdf_document *xref, pdf_obj *dict, fz_matrix transform)
+pdf_load_shading_dict(pdf_document *xref, pdf_obj *dict, const fz_matrix *transform)
{
fz_shade *shade = NULL;
pdf_function *func[FZ_MAX_COLORS] = { NULL };
@@ -334,7 +335,7 @@ pdf_load_shading_dict(pdf_document *xref, pdf_obj *dict, fz_matrix transform)
shade->type = FZ_MESH_TYPE4;
shade->use_background = 0;
shade->use_function = 0;
- shade->matrix = transform;
+ shade->matrix = *transform;
shade->bbox = fz_infinite_rect;
shade->colorspace = NULL;
@@ -359,9 +360,7 @@ pdf_load_shading_dict(pdf_document *xref, pdf_obj *dict, fz_matrix transform)
obj = pdf_dict_gets(dict, "BBox");
if (pdf_is_array(obj))
- {
- shade->bbox = pdf_to_rect(ctx, obj);
- }
+ pdf_to_rect(ctx, obj, &shade->bbox);
obj = pdf_dict_gets(dict, "Function");
if (pdf_is_dict(obj))
@@ -469,7 +468,7 @@ pdf_load_shading(pdf_document *xref, pdf_obj *dict)
{
obj = pdf_dict_gets(dict, "Matrix");
if (obj)
- mat = pdf_to_matrix(ctx, obj);
+ pdf_to_matrix(ctx, obj, &mat);
else
mat = fz_identity;
@@ -486,13 +485,13 @@ pdf_load_shading(pdf_document *xref, pdf_obj *dict)
if (!obj)
fz_throw(ctx, "syntaxerror: missing shading dictionary");
- shade = pdf_load_shading_dict(xref, obj, mat);
+ shade = pdf_load_shading_dict(xref, obj, &mat);
}
/* Naked shading dictionary */
else
{
- shade = pdf_load_shading_dict(xref, dict, fz_identity);
+ shade = pdf_load_shading_dict(xref, dict, &fz_identity);
}
pdf_store_item(ctx, dict, shade, fz_shade_size(shade));
diff --git a/pdf/pdf_type3.c b/pdf/pdf_type3.c
index d96a160a..8dd780dd 100644
--- a/pdf/pdf_type3.c
+++ b/pdf/pdf_type3.c
@@ -2,7 +2,7 @@
#include "mupdf-internal.h"
static void
-pdf_run_glyph_func(void *doc, void *rdb, fz_buffer *contents, fz_device *dev, fz_matrix ctm, void *gstate, int nested_depth)
+pdf_run_glyph_func(void *doc, void *rdb, fz_buffer *contents, fz_device *dev, const fz_matrix *ctm, void *gstate, int nested_depth)
{
pdf_run_glyph(doc, (pdf_obj *)rdb, contents, dev, ctm, gstate, nested_depth);
}
@@ -44,13 +44,12 @@ pdf_load_type3_font(pdf_document *xref, pdf_obj *rdb, pdf_obj *dict)
fontdesc = pdf_new_font_desc(ctx);
obj = pdf_dict_gets(dict, "FontMatrix");
- matrix = pdf_to_matrix(ctx, obj);
+ pdf_to_matrix(ctx, obj, &matrix);
obj = pdf_dict_gets(dict, "FontBBox");
- bbox = pdf_to_rect(ctx, obj);
- bbox = fz_transform_rect(matrix, bbox);
+ fz_transform_rect(pdf_to_rect(ctx, obj, &bbox), &matrix);
- fontdesc->font = fz_new_type3_font(ctx, buf, matrix);
+ fontdesc->font = fz_new_type3_font(ctx, buf, &matrix);
fontdesc->size += sizeof(fz_font) + 256 * (sizeof(fz_buffer*) + sizeof(float));
fz_set_font_bbox(ctx, fontdesc->font, bbox.x0, bbox.y0, bbox.x1, bbox.y1);
diff --git a/pdf/pdf_xobject.c b/pdf/pdf_xobject.c
index 17d8300f..a334392f 100644
--- a/pdf/pdf_xobject.c
+++ b/pdf/pdf_xobject.c
@@ -60,11 +60,11 @@ pdf_load_xobject(pdf_document *xref, pdf_obj *dict)
fz_try(ctx)
{
obj = pdf_dict_gets(dict, "BBox");
- form->bbox = pdf_to_rect(ctx, obj);
+ pdf_to_rect(ctx, obj, &form->bbox);
obj = pdf_dict_gets(dict, "Matrix");
if (obj)
- form->matrix = pdf_to_matrix(ctx, obj);
+ pdf_to_matrix(ctx, obj, &form->matrix);
else
form->matrix = fz_identity;
@@ -111,7 +111,7 @@ pdf_load_xobject(pdf_document *xref, pdf_obj *dict)
}
pdf_obj *
-pdf_new_xobject(pdf_document *xref, fz_rect bbox, fz_matrix mat)
+pdf_new_xobject(pdf_document *xref, const fz_rect *bbox, const fz_matrix *mat)
{
int idict_num;
pdf_obj *idict = NULL;
@@ -185,9 +185,9 @@ pdf_new_xobject(pdf_document *xref, fz_rect bbox, fz_matrix mat)
form->me = NULL;
form->iteration = 0;
- form->bbox = bbox;
+ form->bbox = *bbox;
- form->matrix = mat;
+ form->matrix = *mat;
form->isolated = 0;
form->knockout = 0;
diff --git a/pdf/pdf_xref_aux.c b/pdf/pdf_xref_aux.c
index 22f21b1f..58335a4e 100644
--- a/pdf/pdf_xref_aux.c
+++ b/pdf/pdf_xref_aux.c
@@ -9,12 +9,12 @@
resulting executables.
*/
-static void pdf_run_page_contents_shim(fz_document *doc, fz_page *page, fz_device *dev, fz_matrix transform, fz_cookie *cookie)
+static void pdf_run_page_contents_shim(fz_document *doc, fz_page *page, fz_device *dev, const fz_matrix *transform, fz_cookie *cookie)
{
pdf_run_page_contents((pdf_document*)doc, (pdf_page*)page, dev, transform, cookie);
}
-static void pdf_run_annot_shim(fz_document *doc, fz_page *page, fz_annot *annot, fz_device *dev, fz_matrix transform, fz_cookie *cookie)
+static void pdf_run_annot_shim(fz_document *doc, fz_page *page, fz_annot *annot, fz_device *dev, const fz_matrix *transform, fz_cookie *cookie)
{
pdf_run_annot((pdf_document*)doc, (pdf_page*)page, (pdf_annot *)annot, dev, transform, cookie);
}