summaryrefslogtreecommitdiff
path: root/apps
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 /apps
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 'apps')
-rw-r--r--apps/mudraw.c46
-rw-r--r--apps/pdfapp.c89
-rw-r--r--apps/pdfapp.h2
-rw-r--r--apps/pdfinfo.c2
-rw-r--r--apps/win_main.c4
-rw-r--r--apps/x11_main.c4
6 files changed, 77 insertions, 70 deletions
diff --git a/apps/mudraw.c b/apps/mudraw.c
index 30ebda57..dd9386be 100644
--- a/apps/mudraw.c
+++ b/apps/mudraw.c
@@ -221,12 +221,13 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum)
}
for (;widget; widget = fz_next_widget(inter, widget))
{
- fz_rect rect = fz_widget_bbox(widget);
- int w = (rect.x1-rect.x0);
- int h = (rect.y1-rect.y0);
- int len;
+ fz_rect rect;
+ int w, h, len;
int type = fz_widget_get_type(widget);
+ fz_bound_widget(widget, &rect);
+ w = (rect.x1 - rect.x0);
+ h = (rect.y1 - rect.y0);
++mujstest_count;
switch (type)
{
@@ -312,7 +313,7 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum)
{
list = fz_new_display_list(ctx);
dev = fz_new_list_device(ctx, list);
- fz_run_page(doc, page, dev, fz_identity, &cookie);
+ fz_run_page(doc, page, dev, &fz_identity, &cookie);
}
fz_always(ctx)
{
@@ -334,9 +335,9 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum)
dev = fz_new_trace_device(ctx);
fz_printf(out, "<page number=\"%d\">\n", pagenum);
if (list)
- fz_run_display_list(list, dev, fz_identity, fz_infinite_rect, &cookie);
+ fz_run_display_list(list, dev, &fz_identity, &fz_infinite_rect, &cookie);
else
- fz_run_page(doc, page, dev, fz_identity, &cookie);
+ fz_run_page(doc, page, dev, &fz_identity, &cookie);
fz_printf(out, "</page>\n");
}
fz_always(ctx)
@@ -360,12 +361,13 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum)
fz_try(ctx)
{
- text = fz_new_text_page(ctx, fz_bound_page(doc, page));
+ fz_rect bounds;
+ text = fz_new_text_page(ctx, fz_bound_page(doc, page, &bounds));
dev = fz_new_text_device(ctx, sheet, text);
if (list)
- fz_run_display_list(list, dev, fz_identity, fz_infinite_rect, &cookie);
+ fz_run_display_list(list, dev, &fz_identity, &fz_infinite_rect, &cookie);
else
- fz_run_page(doc, page, dev, fz_identity, &cookie);
+ fz_run_page(doc, page, dev, &fz_identity, &cookie);
fz_free_device(dev);
dev = NULL;
if (showtext == TEXT_XML)
@@ -410,12 +412,11 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum)
fz_var(pix);
- bounds = fz_bound_page(doc, page);
+ fz_bound_page(doc, page, &bounds);
zoom = resolution / 72;
- ctm = fz_scale(zoom, zoom);
- ctm = fz_concat(ctm, fz_rotate(rotation));
- tbounds = fz_transform_rect(ctm, bounds);
- ibounds = fz_round_rect(tbounds); /* convert to integers */
+ fz_pre_scale(fz_rotate(&ctm, rotation), zoom, zoom);
+ tbounds = bounds;
+ fz_round_rect(&ibounds, fz_transform_rect(&tbounds, &ctm));
/* Make local copies of our width/height */
w = width;
@@ -439,6 +440,7 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum)
{
float scalex = w / (tbounds.x1 - tbounds.x0);
float scaley = h / (tbounds.y1 - tbounds.y0);
+ fz_matrix scale_mat;
if (fit)
{
@@ -461,16 +463,18 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum)
else
scaley = scalex;
}
- ctm = fz_concat(ctm, fz_scale(scalex, scaley));
- tbounds = fz_transform_rect(ctm, bounds);
+ fz_scale(&scale_mat, scalex, scaley);
+ fz_concat(&ctm, &ctm, &scale_mat);
+ tbounds = bounds;
+ fz_transform_rect(&tbounds, &ctm);
}
- ibounds = fz_round_rect(tbounds);
+ fz_round_rect(&ibounds, &tbounds);
/* TODO: banded rendering and multi-page ppm */
fz_try(ctx)
{
- pix = fz_new_pixmap_with_bbox(ctx, colorspace, ibounds);
+ pix = fz_new_pixmap_with_bbox(ctx, colorspace, &ibounds);
if (savealpha)
fz_clear_pixmap(ctx, pix);
@@ -479,9 +483,9 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum)
dev = fz_new_draw_device(ctx, pix);
if (list)
- fz_run_display_list(list, dev, ctm, tbounds, &cookie);
+ fz_run_display_list(list, dev, &ctm, &tbounds, &cookie);
else
- fz_run_page(doc, page, dev, ctm, &cookie);
+ fz_run_page(doc, page, dev, &ctm, &cookie);
fz_free_device(dev);
dev = NULL;
diff --git a/apps/pdfapp.c b/apps/pdfapp.c
index 143a18c4..f9ee5406 100644
--- a/apps/pdfapp.c
+++ b/apps/pdfapp.c
@@ -98,9 +98,10 @@ void pdfapp_init(fz_context *ctx, pdfapp_t *app)
#endif
}
-void pdfapp_invert(pdfapp_t *app, fz_rect rect)
+void pdfapp_invert(pdfapp_t *app, const fz_rect *rect)
{
- fz_invert_pixmap_rect(app->image, fz_round_rect(rect));
+ fz_bbox b;
+ fz_invert_pixmap_rect(app->image, fz_round_rect(&b, rect));
}
static void event_cb(fz_doc_event *event, void *data)
@@ -390,12 +391,9 @@ int pdfapp_preclose(pdfapp_t *app)
return 1;
}
-static fz_matrix pdfapp_viewctm(pdfapp_t *app)
+static void pdfapp_viewctm(fz_matrix *mat, pdfapp_t *app)
{
- fz_matrix ctm;
- ctm = fz_scale(app->resolution/72.0f, app->resolution/72.0f);
- ctm = fz_concat(ctm, fz_rotate(app->rotate));
- return ctm;
+ fz_pre_rotate(fz_scale(mat, app->resolution/72.0f, app->resolution/72.0f), app->rotate);
}
static void pdfapp_panview(pdfapp_t *app, int newx, int newy)
@@ -461,7 +459,7 @@ static void pdfapp_loadpage(pdfapp_t *app)
{
app->page = fz_load_page(app->doc, app->pageno - 1);
- app->page_bbox = fz_bound_page(app->doc, app->page);
+ fz_bound_page(app->doc, app->page, &app->page_bbox);
}
fz_catch(app->ctx)
{
@@ -475,13 +473,13 @@ static void pdfapp_loadpage(pdfapp_t *app)
/* Create display lists */
app->page_list = fz_new_display_list(app->ctx);
mdev = fz_new_list_device(app->ctx, app->page_list);
- fz_run_page_contents(app->doc, app->page, mdev, fz_identity, &cookie);
+ fz_run_page_contents(app->doc, app->page, mdev, &fz_identity, &cookie);
fz_free_device(mdev);
mdev = NULL;
app->annotations_list = fz_new_display_list(app->ctx);
mdev = fz_new_list_device(app->ctx, app->annotations_list);
for (annot = fz_first_annot(app->doc, app->page); annot; annot = fz_next_annot(app->doc, annot))
- fz_run_annot(app->doc, app->page, annot, mdev, fz_identity, &cookie);
+ fz_run_annot(app->doc, app->page, annot, mdev, &fz_identity, &cookie);
if (cookie.errors)
{
pdfapp_warn(app, "Errors found on page");
@@ -532,7 +530,7 @@ static void pdfapp_recreate_annotationslist(pdfapp_t *app)
app->annotations_list = fz_new_display_list(app->ctx);
mdev = fz_new_list_device(app->ctx, app->annotations_list);
for (annot = fz_first_annot(app->doc, app->page); annot; annot = fz_next_annot(app->doc, annot))
- fz_run_annot(app->doc, app->page, annot, mdev, fz_identity, &cookie);
+ fz_run_annot(app->doc, app->page, annot, mdev, &fz_identity, &cookie);
if (cookie.errors)
{
pdfapp_warn(app, "Errors found on page");
@@ -558,23 +556,26 @@ static void pdfapp_updatepage(pdfapp_t *app)
{
fz_interactive *idoc = fz_interact(app->doc);
fz_device *idev;
- fz_matrix ctm = pdfapp_viewctm(app);
+ fz_matrix ctm;
fz_annot *annot;
+ pdfapp_viewctm(&ctm, app);
fz_update_page(idoc, app->page);
pdfapp_recreate_annotationslist(app);
while ((annot = fz_poll_changed_annot(idoc, app->page)) != NULL)
{
- fz_rect bounds = fz_transform_rect(ctm, fz_bound_annot(app->doc, annot));
- fz_bbox bbox = fz_round_rect(bounds);
- fz_clear_pixmap_rect_with_value(app->ctx, app->image, 255, bbox);
- idev = fz_new_draw_device_with_bbox(app->ctx, app->image, bbox);
+ fz_rect bounds;
+ fz_bbox ibounds;
+ fz_transform_rect(fz_bound_annot(app->doc, annot, &bounds), &ctm);
+ fz_round_rect(&ibounds, &bounds);
+ fz_clear_pixmap_rect_with_value(app->ctx, app->image, 255, &ibounds);
+ idev = fz_new_draw_device_with_bbox(app->ctx, app->image, &ibounds);
if (app->page_list)
- fz_run_display_list(app->page_list, idev, ctm, bounds, NULL);
+ fz_run_display_list(app->page_list, idev, &ctm, &bounds, NULL);
if (app->annotations_list)
- fz_run_display_list(app->annotations_list, idev, ctm, bounds, NULL);
+ fz_run_display_list(app->annotations_list, idev, &ctm, &bounds, NULL);
fz_free_device(idev);
}
@@ -591,7 +592,7 @@ static void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage, int repai
fz_colorspace *colorspace;
fz_matrix ctm;
fz_rect bounds;
- fz_bbox bbox;
+ fz_bbox ibounds;
fz_cookie cookie = { 0 };
if (!app->nowaitcursor)
@@ -616,15 +617,15 @@ static void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage, int repai
/* Extract text */
app->page_sheet = fz_new_text_sheet(app->ctx);
- app->page_text = fz_new_text_page(app->ctx, app->page_bbox);
+ app->page_text = fz_new_text_page(app->ctx, &app->page_bbox);
if (app->page_list || app->annotations_list)
{
tdev = fz_new_text_device(app->ctx, app->page_sheet, app->page_text);
if (app->page_list)
- fz_run_display_list(app->page_list, tdev, fz_identity, fz_infinite_rect, &cookie);
+ fz_run_display_list(app->page_list, tdev, &fz_identity, &fz_infinite_rect, &cookie);
if (app->annotations_list)
- fz_run_display_list(app->annotations_list, tdev, fz_identity, fz_infinite_rect, &cookie);
+ fz_run_display_list(app->annotations_list, tdev, &fz_identity, &fz_infinite_rect, &cookie);
fz_free_device(tdev);
}
}
@@ -647,9 +648,9 @@ static void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage, int repai
sprintf(buf, "%s%s", app->doctitle, buf2);
wintitle(app, buf);
- ctm = pdfapp_viewctm(app);
- bounds = fz_transform_rect(ctm, app->page_bbox);
- bbox = fz_round_rect(bounds);
+ pdfapp_viewctm(&ctm, app);
+ bounds = app->page_bbox;
+ fz_round_rect(&ibounds, fz_transform_rect(&bounds, &ctm));
/* Draw */
if (app->image)
@@ -659,15 +660,15 @@ static void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage, int repai
else
colorspace = app->colorspace;
app->image = NULL;
- app->image = fz_new_pixmap_with_bbox(app->ctx, colorspace, bbox);
+ app->image = fz_new_pixmap_with_bbox(app->ctx, colorspace, &ibounds);
fz_clear_pixmap_with_value(app->ctx, app->image, 255);
if (app->page_list || app->annotations_list)
{
idev = fz_new_draw_device(app->ctx, app->image);
if (app->page_list)
- fz_run_display_list(app->page_list, idev, ctm, bounds, &cookie);
+ fz_run_display_list(app->page_list, idev, &ctm, &bounds, &cookie);
if (app->annotations_list)
- fz_run_display_list(app->annotations_list, idev, ctm, bounds, &cookie);
+ fz_run_display_list(app->annotations_list, idev, &ctm, &bounds, &cookie);
fz_free_device(idev);
}
if (app->invert)
@@ -679,7 +680,7 @@ static void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage, int repai
fz_transition *new_trans;
app->new_image = app->image;
app->image = NULL;
- app->image = fz_new_pixmap_with_bbox(app->ctx, colorspace, bbox);
+ app->image = fz_new_pixmap_with_bbox(app->ctx, colorspace, &ibounds);
app->duration = 0;
new_trans = fz_page_presentation(app->doc, app->page, &app->duration);
if (new_trans)
@@ -825,25 +826,25 @@ void pdfapp_inverthit(pdfapp_t *app)
return;
hitbox = fz_empty_rect;
- ctm = pdfapp_viewctm(app);
+ pdfapp_viewctm(&ctm, app);
for (i = app->hit; i < app->hit + app->hitlen; i++)
{
bbox = bboxcharat(app->page_text, i);
- if (fz_is_empty_rect(bbox))
+ if (fz_is_empty_rect(&bbox))
{
- if (!fz_is_empty_rect(hitbox))
- pdfapp_invert(app, fz_transform_rect(ctm, hitbox));
+ if (!fz_is_empty_rect(&hitbox))
+ pdfapp_invert(app, fz_transform_rect(&hitbox, &ctm));
hitbox = fz_empty_rect;
}
else
{
- hitbox = fz_union_rect(hitbox, bbox);
+ fz_union_rect(&hitbox, &bbox);
}
}
- if (!fz_is_empty_rect(hitbox))
- pdfapp_invert(app, fz_transform_rect(ctm, hitbox));
+ if (!fz_is_empty_rect(&hitbox))
+ pdfapp_invert(app, fz_transform_rect(&hitbox, &ctm));
}
static int match(char *s, fz_text_page *page, int n)
@@ -1339,19 +1340,20 @@ void pdfapp_onkey(pdfapp_t *app, int c)
void pdfapp_onmouse(pdfapp_t *app, int x, int y, int btn, int modifiers, int state)
{
fz_context *ctx = app->ctx;
- fz_bbox rect = fz_pixmap_bbox(app->ctx, app->image);
+ fz_bbox rect;
fz_link *link;
fz_matrix ctm;
fz_point p;
int processed = 0;
+ fz_pixmap_bbox(app->ctx, app->image, &rect);
p.x = x - app->panx + rect.x0;
p.y = y - app->pany + rect.y0;
- ctm = pdfapp_viewctm(app);
- ctm = fz_invert_matrix(ctm);
+ pdfapp_viewctm(&ctm, app);
+ fz_invert_matrix(&ctm, &ctm);
- p = fz_transform_point(ctm, p);
+ fz_transform_point(&p, &ctm);
if (btn == 1 && (state == 1 || state == -1))
{
@@ -1466,7 +1468,8 @@ void pdfapp_onmouse(pdfapp_t *app, int x, int y, int btn, int modifiers, int sta
fz_annot *annot;
for (annot = fz_first_annot(app->doc, app->page); annot; annot = fz_next_annot(app->doc, annot))
{
- fz_rect rect = fz_bound_annot(app->doc, annot);
+ fz_rect rect;
+ fz_bound_annot(app->doc, annot, &rect);
if (x >= rect.x0 && x < rect.x1)
if (y >= rect.y0 && y < rect.y1)
break;
@@ -1625,7 +1628,7 @@ void pdfapp_oncopy(pdfapp_t *app, unsigned short *ucsbuf, int ucslen)
int y0 = app->selr.y0;
int y1 = app->selr.y1;
- ctm = pdfapp_viewctm(app);
+ pdfapp_viewctm(&ctm, app);
p = 0;
@@ -1650,7 +1653,7 @@ void pdfapp_oncopy(pdfapp_t *app, unsigned short *ucsbuf, int ucslen)
for (i = 0; i < span->len; i++)
{
hitbox = span->text[i].bbox;
- hitbox = fz_transform_rect(ctm, hitbox);
+ fz_transform_rect(&hitbox, &ctm);
c = span->text[i].c;
if (c < 32)
c = '?';
diff --git a/apps/pdfapp.h b/apps/pdfapp.h
index 425ba93a..1ee51d45 100644
--- a/apps/pdfapp.h
+++ b/apps/pdfapp.h
@@ -139,7 +139,7 @@ void pdfapp_oncopy(pdfapp_t *app, unsigned short *ucsbuf, int ucslen);
void pdfapp_onresize(pdfapp_t *app, int w, int h);
void pdfapp_gotopage(pdfapp_t *app, int number);
-void pdfapp_invert(pdfapp_t *app, fz_rect rect);
+void pdfapp_invert(pdfapp_t *app, const fz_rect *rect);
void pdfapp_inverthit(pdfapp_t *app);
void pdfapp_postblit(pdfapp_t *app);
diff --git a/apps/pdfinfo.c b/apps/pdfinfo.c
index 3fab99c7..2d47456c 100644
--- a/apps/pdfinfo.c
+++ b/apps/pdfinfo.c
@@ -200,7 +200,7 @@ gatherdimensions(int page, pdf_obj *pageref, pdf_obj *pageobj)
if (!pdf_is_array(obj))
return;
- bbox = pdf_to_rect(ctx, obj);
+ pdf_to_rect(ctx, obj, &bbox);
obj = pdf_dict_gets(pageobj, "UserUnit");
if (pdf_is_real(obj))
diff --git a/apps/win_main.c b/apps/win_main.c
index 3ae482ec..18c110eb 100644
--- a/apps/win_main.c
+++ b/apps/win_main.c
@@ -707,7 +707,7 @@ void winblit()
{
if (gapp.iscopying || justcopied)
{
- pdfapp_invert(&gapp, gapp.selr);
+ pdfapp_invert(&gapp, &gapp.selr);
justcopied = 1;
}
@@ -747,7 +747,7 @@ void winblit()
if (gapp.iscopying || justcopied)
{
- pdfapp_invert(&gapp, gapp.selr);
+ pdfapp_invert(&gapp, &gapp.selr);
justcopied = 1;
}
}
diff --git a/apps/x11_main.c b/apps/x11_main.c
index 9e35dafe..364013c8 100644
--- a/apps/x11_main.c
+++ b/apps/x11_main.c
@@ -444,7 +444,7 @@ static void winblit(pdfapp_t *app)
if (gapp.iscopying || justcopied)
{
- pdfapp_invert(&gapp, gapp.selr);
+ pdfapp_invert(&gapp, &gapp.selr);
justcopied = 1;
}
@@ -487,7 +487,7 @@ static void winblit(pdfapp_t *app)
if (gapp.iscopying || justcopied)
{
- pdfapp_invert(&gapp, gapp.selr);
+ pdfapp_invert(&gapp, &gapp.selr);
justcopied = 1;
}