summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2013-01-30 13:54:39 +0100
committerTor Andersson <tor.andersson@artifex.com>2013-01-30 14:13:01 +0100
commit594c64f744862b993bcad12e05217f3d43e7d547 (patch)
tree5328ba05eb7c360c25bdc1849604839ce8d99762
parent29f09279714f4f9b81d9b5488072860142f86f24 (diff)
downloadmupdf-594c64f744862b993bcad12e05217f3d43e7d547.tar.xz
Introduce fz_irect where the old fz_bbox was useful.
Inside the renderer we often deal with integer sized areas, for pixmaps and scissoring regions. Use a new fz_irect type in these places.
-rw-r--r--apps/mudraw.c5
-rw-r--r--apps/pdfapp.c21
-rw-r--r--doc/example.c5
-rw-r--r--doc/multi-threaded.c2
-rw-r--r--draw/draw_affine.c13
-rw-r--r--draw/draw_blend.c4
-rw-r--r--draw/draw_device.c108
-rw-r--r--draw/draw_edge.c20
-rw-r--r--draw/draw_glyph.c6
-rw-r--r--draw/draw_mesh.c6
-rw-r--r--draw/draw_paint.c16
-rw-r--r--draw/draw_scale.c4
-rw-r--r--draw/draw_simple_scale.c4
-rw-r--r--fitz/base_geometry.c110
-rw-r--r--fitz/fitz-internal.h28
-rw-r--r--fitz/fitz.h34
-rw-r--r--fitz/res_font.c16
-rw-r--r--fitz/res_pixmap.c29
18 files changed, 256 insertions, 175 deletions
diff --git a/apps/mudraw.c b/apps/mudraw.c
index 84c02682..cf9864ec 100644
--- a/apps/mudraw.c
+++ b/apps/mudraw.c
@@ -402,7 +402,8 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum)
{
float zoom;
fz_matrix ctm;
- fz_rect bounds, tbounds, ibounds;
+ fz_rect bounds, tbounds;
+ fz_irect ibounds;
fz_pixmap *pix = NULL;
int w, h;
@@ -477,7 +478,7 @@ 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, ibounds, &cookie);
+ fz_run_display_list(list, dev, ctm, tbounds, &cookie);
else
fz_run_page(doc, page, dev, ctm, &cookie);
fz_free_device(dev);
diff --git a/apps/pdfapp.c b/apps/pdfapp.c
index 167c118d..1d2a2fa2 100644
--- a/apps/pdfapp.c
+++ b/apps/pdfapp.c
@@ -100,7 +100,7 @@ void pdfapp_init(fz_context *ctx, pdfapp_t *app)
void pdfapp_invert(pdfapp_t *app, fz_rect rect)
{
- fz_invert_pixmap_rect(app->image, rect);
+ fz_invert_pixmap_rect(app->image, fz_round_rect(rect));
}
static void event_cb(fz_doc_event *event, void *data)
@@ -566,14 +566,15 @@ static void pdfapp_updatepage(pdfapp_t *app)
while ((annot = fz_poll_changed_annot(idoc, app->page)) != NULL)
{
- fz_rect bbox = fz_transform_rect(ctm, fz_bound_annot(app->doc, annot));
+ fz_rect bounds = fz_transform_rect(ctm, fz_bound_annot(app->doc, annot));
+ fz_irect 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);
if (app->page_list)
- fz_run_display_list(app->page_list, idev, ctm, bbox, 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, bbox, NULL);
+ fz_run_display_list(app->annotations_list, idev, ctm, bounds, NULL);
fz_free_device(idev);
}
@@ -589,7 +590,8 @@ static void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage, int repai
fz_device *tdev;
fz_colorspace *colorspace;
fz_matrix ctm;
- fz_rect bbox;
+ fz_rect bounds;
+ fz_irect bbox;
fz_cookie cookie = { 0 };
if (!app->nowaitcursor)
@@ -646,7 +648,8 @@ static void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage, int repai
wintitle(app, buf);
ctm = pdfapp_viewctm(app);
- bbox = fz_transform_rect(ctm, app->page_bbox);
+ bounds = fz_transform_rect(ctm, app->page_bbox);
+ bbox = fz_round_rect(bounds);
/* Draw */
if (app->image)
@@ -662,9 +665,9 @@ static void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage, int repai
{
idev = fz_new_draw_device(app->ctx, app->image);
if (app->page_list)
- fz_run_display_list(app->page_list, idev, ctm, bbox, &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, bbox, &cookie);
+ fz_run_display_list(app->annotations_list, idev, ctm, bounds, &cookie);
fz_free_device(idev);
}
if (app->invert)
@@ -1336,7 +1339,7 @@ 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_rect rect = fz_pixmap_bbox(app->ctx, app->image);
+ fz_irect rect = fz_pixmap_bbox(app->ctx, app->image);
fz_link *link;
fz_matrix ctm;
fz_point p;
diff --git a/doc/example.c b/doc/example.c
index b834e3ff..d1e4798f 100644
--- a/doc/example.c
+++ b/doc/example.c
@@ -41,8 +41,8 @@ render(char *filename, int pagenumber, int zoom, int rotation)
// Take the page bounds and transform them by the same matrix that
// we will use to render the page.
- fz_rect bbox = fz_bound_page(doc, page);
- bbox = fz_transform_rect(transform, rect);
+ fz_rect bounds = fz_bound_page(doc, page);
+ bounds = fz_transform_rect(transform, rect);
// Create a blank pixmap to hold the result of rendering. The
// pixmap bounds used here are the same as the transformed page
@@ -50,6 +50,7 @@ render(char *filename, int pagenumber, int zoom, int rotation)
// space has the origin at the top left corner and the x axis
// extends to the right and the y axis extends down.
+ fz_irect bbox = fz_round_rect(bounds);
fz_pixmap *pix = fz_new_pixmap_with_bbox(ctx, fz_device_rgb, bbox);
fz_clear_pixmap_with_value(ctx, pix, 0xff);
diff --git a/doc/multi-threaded.c b/doc/multi-threaded.c
index b54beb81..af4bab97 100644
--- a/doc/multi-threaded.c
+++ b/doc/multi-threaded.c
@@ -201,7 +201,7 @@ int main(int argc, char **argv)
// Create a white pixmap using the correct dimensions.
- fz_pixmap *pix = fz_new_pixmap_with_bbox(ctx, fz_device_rgb, bbox);
+ fz_pixmap *pix = fz_new_pixmap_with_bbox(ctx, fz_device_rgb, fz_round_rect(bbox));
fz_clear_pixmap_with_value(ctx, pix, 0xff);
// Populate the data structure to be sent to the
diff --git a/draw/draw_affine.c b/draw/draw_affine.c
index 347346b9..a824c874 100644
--- a/draw/draw_affine.c
+++ b/draw/draw_affine.c
@@ -597,14 +597,14 @@ fz_gridfit_matrix(fz_matrix *m)
/* Draw an image with an affine transform on destination */
static void
-fz_paint_image_imp(fz_pixmap *dst, fz_rect scissor, fz_pixmap *shape, fz_pixmap *img, fz_matrix ctm, byte *color, int alpha)
+fz_paint_image_imp(fz_pixmap *dst, fz_irect scissor, fz_pixmap *shape, fz_pixmap *img, fz_matrix ctm, byte *color, int alpha)
{
byte *dp, *sp, *hp;
int u, v, fa, fb, fc, fd;
int x, y, w, h;
int sw, sh, n, hw;
fz_matrix inv;
- fz_rect bbox;
+ fz_irect bbox;
int dolerp;
void (*paintfn)(byte *dp, byte *sp, int sw, int sh, int u, int v, int fa, int fb, int w, int n, int alpha, byte *color, byte *hp);
@@ -629,9 +629,8 @@ fz_paint_image_imp(fz_pixmap *dst, fz_rect scissor, fz_pixmap *shape, fz_pixmap
dolerp = 0;
}
- bbox = fz_transform_rect(ctm, fz_unit_rect);
- bbox = fz_intersect_rect(bbox, scissor);
- bbox = fz_rect_covering_rect(bbox);
+ bbox = fz_rect_covering_rect(fz_transform_rect(ctm, fz_unit_rect));
+ bbox = fz_intersect_irect(bbox, scissor);
x = bbox.x0;
if (shape && shape->x > x)
@@ -731,14 +730,14 @@ fz_paint_image_imp(fz_pixmap *dst, fz_rect scissor, fz_pixmap *shape, fz_pixmap
}
void
-fz_paint_image_with_color(fz_pixmap *dst, fz_rect scissor, fz_pixmap *shape, fz_pixmap *img, fz_matrix ctm, byte *color)
+fz_paint_image_with_color(fz_pixmap *dst, fz_irect scissor, fz_pixmap *shape, fz_pixmap *img, fz_matrix ctm, byte *color)
{
assert(img->n == 1);
fz_paint_image_imp(dst, scissor, shape, img, ctm, color, 255);
}
void
-fz_paint_image(fz_pixmap *dst, fz_rect scissor, fz_pixmap *shape, fz_pixmap *img, fz_matrix ctm, int alpha)
+fz_paint_image(fz_pixmap *dst, fz_irect scissor, fz_pixmap *shape, fz_pixmap *img, fz_matrix ctm, int alpha)
{
assert(dst->n == img->n || (dst->n == 4 && img->n == 2));
fz_paint_image_imp(dst, scissor, shape, img, ctm, NULL, alpha);
diff --git a/draw/draw_blend.c b/draw/draw_blend.c
index 3e5dd932..27888cfe 100644
--- a/draw/draw_blend.c
+++ b/draw/draw_blend.c
@@ -574,7 +574,7 @@ void
fz_blend_pixmap(fz_pixmap *dst, fz_pixmap *src, int alpha, int blendmode, int isolated, fz_pixmap *shape)
{
unsigned char *sp, *dp;
- fz_rect bbox;
+ fz_irect bbox;
int x, y, w, h, n;
/* TODO: fix this hack! */
@@ -590,7 +590,7 @@ fz_blend_pixmap(fz_pixmap *dst, fz_pixmap *src, int alpha, int blendmode, int is
}
bbox = fz_pixmap_bbox_no_ctx(dst);
- bbox = fz_intersect_rect(bbox, fz_pixmap_bbox_no_ctx(src));
+ bbox = fz_intersect_irect(bbox, fz_pixmap_bbox_no_ctx(src));
x = bbox.x0;
y = bbox.y0;
diff --git a/draw/draw_device.c b/draw/draw_device.c
index 196e9bdb..0e2697e4 100644
--- a/draw/draw_device.c
+++ b/draw/draw_device.c
@@ -22,7 +22,7 @@ enum {
typedef struct fz_draw_state_s fz_draw_state;
struct fz_draw_state_s {
- fz_rect scissor;
+ fz_irect scissor;
fz_pixmap *dest;
fz_pixmap *mask;
fz_pixmap *shape;
@@ -31,7 +31,7 @@ struct fz_draw_state_s {
float alpha;
fz_matrix ctm;
float xstep, ystep;
- fz_rect area;
+ fz_irect area;
};
struct fz_draw_device_s
@@ -127,7 +127,7 @@ static fz_draw_state *
fz_knockout_begin(fz_draw_device *dev)
{
fz_context *ctx = dev->ctx;
- fz_rect bbox;
+ fz_irect bbox;
fz_pixmap *dest, *shape;
fz_draw_state *state = &dev->stack[dev->top];
int isolated = state->blendmode & FZ_BLEND_ISOLATED;
@@ -138,7 +138,7 @@ fz_knockout_begin(fz_draw_device *dev)
state = push_stack(dev);
bbox = fz_pixmap_bbox(dev->ctx, state->dest);
- bbox = fz_intersect_rect(bbox, state->scissor);
+ bbox = fz_intersect_irect(bbox, state->scissor);
dest = fz_new_pixmap_with_bbox(dev->ctx, state->dest->colorspace, bbox);
if (isolated)
@@ -246,7 +246,7 @@ fz_draw_fill_path(fz_device *devp, fz_path *path, int even_odd, fz_matrix ctm,
float flatness = 0.3f / expansion;
unsigned char colorbv[FZ_MAX_COLORS + 1];
float colorfv[FZ_MAX_COLORS];
- fz_rect bbox;
+ fz_irect bbox;
int i;
fz_draw_state *state = &dev->stack[dev->top];
fz_colorspace *model = state->dest->colorspace;
@@ -259,7 +259,7 @@ fz_draw_fill_path(fz_device *devp, fz_path *path, int even_odd, fz_matrix ctm,
fz_sort_gel(dev->gel);
bbox = fz_bound_gel(dev->gel);
- bbox = fz_intersect_rect(bbox, state->scissor);
+ bbox = fz_intersect_irect(bbox, state->scissor);
if (fz_is_empty_rect(bbox))
return;
@@ -297,7 +297,7 @@ fz_draw_stroke_path(fz_device *devp, fz_path *path, fz_stroke_state *stroke, fz_
float linewidth = stroke->linewidth;
unsigned char colorbv[FZ_MAX_COLORS + 1];
float colorfv[FZ_MAX_COLORS];
- fz_rect bbox;
+ fz_irect bbox;
int i;
fz_draw_state *state = &dev->stack[dev->top];
fz_colorspace *model = state->dest->colorspace;
@@ -316,7 +316,7 @@ fz_draw_stroke_path(fz_device *devp, fz_path *path, fz_stroke_state *stroke, fz_
fz_sort_gel(dev->gel);
bbox = fz_bound_gel(dev->gel);
- bbox = fz_intersect_rect(bbox, state->scissor);
+ bbox = fz_intersect_irect(bbox, state->scissor);
if (fz_is_empty_rect(bbox))
return;
@@ -353,7 +353,7 @@ fz_draw_clip_path(fz_device *devp, fz_path *path, fz_rect rect, int even_odd, fz
fz_draw_device *dev = devp->user;
float expansion = fz_matrix_expansion(ctm);
float flatness = 0.3f / expansion;
- fz_rect bbox;
+ fz_irect bbox;
fz_draw_state *state = &dev->stack[dev->top];
fz_colorspace *model;
fz_context *ctx = dev->ctx;
@@ -366,8 +366,8 @@ fz_draw_clip_path(fz_device *devp, fz_path *path, fz_rect rect, int even_odd, fz
model = state->dest->colorspace;
bbox = fz_bound_gel(dev->gel);
- bbox = fz_intersect_rect(bbox, state->scissor);
- bbox = fz_intersect_rect(bbox, fz_rect_covering_rect(rect));
+ bbox = fz_intersect_irect(bbox, state->scissor);
+ bbox = fz_intersect_irect(bbox, fz_rect_covering_rect(rect));
if (fz_is_empty_rect(bbox) || fz_is_rect_gel(dev->gel))
{
@@ -412,7 +412,7 @@ fz_draw_clip_stroke_path(fz_device *devp, fz_path *path, fz_rect rect, fz_stroke
float expansion = fz_matrix_expansion(ctm);
float flatness = 0.3f / expansion;
float linewidth = stroke->linewidth;
- fz_rect bbox;
+ fz_irect bbox;
fz_draw_state *state = &dev->stack[dev->top];
fz_colorspace *model;
fz_context *ctx = dev->ctx;
@@ -431,8 +431,8 @@ fz_draw_clip_stroke_path(fz_device *devp, fz_path *path, fz_rect rect, fz_stroke
model = state->dest->colorspace;
bbox = fz_bound_gel(dev->gel);
- bbox = fz_intersect_rect(bbox, state->scissor);
- bbox = fz_intersect_rect(bbox, fz_rect_covering_rect(rect));
+ bbox = fz_intersect_irect(bbox, state->scissor);
+ bbox = fz_intersect_irect(bbox, fz_rect_covering_rect(rect));
fz_try(ctx)
{
@@ -463,15 +463,15 @@ fz_draw_clip_stroke_path(fz_device *devp, fz_path *path, fz_rect rect, fz_stroke
static void
draw_glyph(unsigned char *colorbv, fz_pixmap *dst, fz_pixmap *msk,
- int xorig, int yorig, fz_rect scissor)
+ int xorig, int yorig, fz_irect scissor)
{
unsigned char *dp, *mp;
- fz_rect bbox;
+ fz_irect bbox;
int x, y, w, h;
bbox = fz_pixmap_bbox_no_ctx(msk);
- bbox = fz_translate_rect(bbox, xorig, yorig);
- bbox = fz_intersect_rect(bbox, scissor); /* scissor < dst */
+ bbox = fz_translate_irect(bbox, xorig, yorig);
+ bbox = fz_intersect_irect(bbox, scissor); /* scissor < dst */
x = bbox.x0;
y = bbox.y0;
w = bbox.x1 - bbox.x0;
@@ -506,7 +506,7 @@ fz_draw_fill_text(fz_device *devp, fz_text *text, fz_matrix ctm,
int i, x, y, gid;
fz_draw_state *state = &dev->stack[dev->top];
fz_colorspace *model = state->dest->colorspace;
- fz_rect scissor = state->scissor;
+ fz_irect scissor = state->scissor;
if (state->blendmode & FZ_BLEND_KNOCKOUT)
state = fz_knockout_begin(dev);
@@ -585,7 +585,7 @@ fz_draw_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke, fz_
int i, x, y, gid;
fz_draw_state *state = &dev->stack[dev->top];
fz_colorspace *model = state->dest->colorspace;
- fz_rect scissor = state->scissor;
+ fz_irect scissor = state->scissor;
if (state->blendmode & FZ_BLEND_KNOCKOUT)
state = fz_knockout_begin(dev);
@@ -648,7 +648,7 @@ fz_draw_clip_text(fz_device *devp, fz_text *text, fz_matrix ctm, int accumulate)
{
fz_draw_device *dev = devp->user;
fz_context *ctx = dev->ctx;
- fz_rect bbox;
+ fz_irect bbox;
fz_pixmap *mask, *dest, *shape;
fz_matrix tm, trm, trunc_trm;
fz_pixmap *glyph;
@@ -667,7 +667,7 @@ fz_draw_clip_text(fz_device *devp, fz_text *text, fz_matrix ctm, int accumulate)
{
/* make the mask the exact size needed */
bbox = fz_rect_covering_rect(fz_bound_text(dev->ctx, text, ctm));
- bbox = fz_intersect_rect(bbox, state->scissor);
+ bbox = fz_intersect_irect(bbox, state->scissor);
}
else
{
@@ -782,7 +782,7 @@ fz_draw_clip_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke
{
fz_draw_device *dev = devp->user;
fz_context *ctx = dev->ctx;
- fz_rect bbox;
+ fz_irect bbox;
fz_pixmap *mask, *dest, *shape;
fz_matrix tm, trm, trunc_trm;
fz_pixmap *glyph;
@@ -792,7 +792,7 @@ fz_draw_clip_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke
/* make the mask the exact size needed */
bbox = fz_rect_covering_rect(fz_bound_text(dev->ctx, text, ctm));
- bbox = fz_intersect_rect(bbox, state->scissor);
+ bbox = fz_intersect_irect(bbox, state->scissor);
fz_try(ctx)
{
@@ -893,7 +893,7 @@ fz_draw_fill_shade(fz_device *devp, fz_shade *shade, fz_matrix ctm, float alpha)
{
fz_draw_device *dev = devp->user;
fz_rect bounds;
- fz_rect bbox, scissor;
+ fz_irect bbox, scissor;
fz_pixmap *dest, *shape;
float colorfv[FZ_MAX_COLORS];
unsigned char colorbv[FZ_MAX_COLORS + 1];
@@ -902,7 +902,7 @@ fz_draw_fill_shade(fz_device *devp, fz_shade *shade, fz_matrix ctm, float alpha)
bounds = fz_bound_shade(dev->ctx, shade, ctm);
scissor = state->scissor;
- bbox = fz_intersect_rect(fz_rect_covering_rect(bounds), scissor);
+ bbox = fz_intersect_irect(fz_rect_covering_rect(bounds), scissor);
if (fz_is_empty_rect(bbox))
return;
@@ -982,7 +982,7 @@ fz_draw_fill_shade(fz_device *devp, fz_shade *shade, fz_matrix ctm, float alpha)
}
static fz_pixmap *
-fz_transform_pixmap(fz_draw_device *dev, fz_pixmap *image, fz_matrix *ctm, int x, int y, int dx, int dy, int gridfit, fz_rect *clip)
+fz_transform_pixmap(fz_draw_device *dev, fz_pixmap *image, fz_matrix *ctm, int x, int y, int dx, int dy, int gridfit, fz_irect *clip)
{
fz_pixmap *scaled;
fz_context *ctx = dev->ctx;
@@ -1007,7 +1007,7 @@ fz_transform_pixmap(fz_draw_device *dev, fz_pixmap *image, fz_matrix *ctm, int x
{
/* Other orthogonal flip/rotation cases */
fz_matrix m = *ctm;
- fz_rect rclip;
+ fz_irect rclip;
if (gridfit)
fz_gridfit_matrix(&m);
if (clip)
@@ -1050,9 +1050,9 @@ fz_draw_fill_image(fz_device *devp, fz_image *image, fz_matrix ctm, float alpha)
fz_context *ctx = dev->ctx;
fz_draw_state *state = &dev->stack[dev->top];
fz_colorspace *model = state->dest->colorspace;
- fz_rect clip = fz_pixmap_bbox(ctx, state->dest);
+ fz_irect clip = fz_pixmap_bbox(ctx, state->dest);
- clip = fz_intersect_rect(clip, state->scissor);
+ clip = fz_intersect_irect(clip, state->scissor);
fz_var(scaled);
@@ -1154,9 +1154,9 @@ fz_draw_fill_image_mask(fz_device *devp, fz_image *image, fz_matrix ctm,
fz_context *ctx = dev->ctx;
fz_draw_state *state = &dev->stack[dev->top];
fz_colorspace *model = state->dest->colorspace;
- fz_rect clip = fz_pixmap_bbox(ctx, state->dest);
+ fz_irect clip = fz_pixmap_bbox(ctx, state->dest);
- clip = fz_intersect_rect(clip, state->scissor);
+ clip = fz_intersect_irect(clip, state->scissor);
if (image->w == 0 || image->h == 0)
return;
@@ -1215,7 +1215,7 @@ fz_draw_clip_image_mask(fz_device *devp, fz_image *image, fz_rect rect, fz_matri
{
fz_draw_device *dev = devp->user;
fz_context *ctx = dev->ctx;
- fz_rect bbox;
+ fz_irect bbox;
fz_pixmap *mask = NULL;
fz_pixmap *dest = NULL;
fz_pixmap *shape = NULL;
@@ -1225,9 +1225,9 @@ fz_draw_clip_image_mask(fz_device *devp, fz_image *image, fz_rect rect, fz_matri
int dx, dy;
fz_draw_state *state = push_stack(dev);
fz_colorspace *model = state->dest->colorspace;
- fz_rect clip = fz_pixmap_bbox(ctx, state->dest);
+ fz_irect clip = fz_pixmap_bbox(ctx, state->dest);
- clip = fz_intersect_rect(clip, state->scissor);
+ clip = fz_intersect_irect(clip, state->scissor);
fz_var(mask);
fz_var(dest);
@@ -1240,7 +1240,7 @@ fz_draw_clip_image_mask(fz_device *devp, fz_image *image, fz_rect rect, fz_matri
#ifdef DUMP_GROUP_BLENDS
dump_spaces(dev->top-1, "Clip (image mask) (empty) begin\n");
#endif
- state[1].scissor = fz_empty_rect;
+ state[1].scissor = fz_empty_irect;
state[1].mask = NULL;
return;
}
@@ -1250,8 +1250,8 @@ fz_draw_clip_image_mask(fz_device *devp, fz_image *image, fz_rect rect, fz_matri
#endif
bbox = fz_rect_covering_rect(fz_transform_rect(ctm, fz_unit_rect));
- bbox = fz_intersect_rect(bbox, state->scissor);
- bbox = fz_intersect_rect(bbox, fz_rect_covering_rect(rect));
+ bbox = fz_intersect_irect(bbox, state->scissor);
+ bbox = fz_intersect_irect(bbox, fz_rect_covering_rect(rect));
dx = sqrtf(ctm.a * ctm.a + ctm.b * ctm.b);
dy = sqrtf(ctm.c * ctm.c + ctm.d * ctm.d);
@@ -1360,13 +1360,13 @@ fz_draw_begin_mask(fz_device *devp, fz_rect rect, int luminosity, fz_colorspace
{
fz_draw_device *dev = devp->user;
fz_pixmap *dest;
- fz_rect bbox;
+ fz_irect bbox;
fz_draw_state *state = push_stack(dev);
fz_pixmap *shape = state->shape;
fz_context *ctx = dev->ctx;
bbox = fz_rect_covering_rect(rect);
- bbox = fz_intersect_rect(bbox, state->scissor);
+ bbox = fz_intersect_irect(bbox, state->scissor);
fz_try(ctx)
{
@@ -1416,7 +1416,7 @@ fz_draw_end_mask(fz_device *devp)
{
fz_draw_device *dev = devp->user;
fz_pixmap *temp, *dest;
- fz_rect bbox;
+ fz_irect bbox;
int luminosity;
fz_context *ctx = dev->ctx;
fz_draw_state *state;
@@ -1468,7 +1468,7 @@ static void
fz_draw_begin_group(fz_device *devp, fz_rect rect, int isolated, int knockout, int blendmode, float alpha)
{
fz_draw_device *dev = devp->user;
- fz_rect bbox;
+ fz_irect bbox;
fz_pixmap *dest, *shape;
fz_context *ctx = dev->ctx;
fz_draw_state *state = &dev->stack[dev->top];
@@ -1479,7 +1479,7 @@ fz_draw_begin_group(fz_device *devp, fz_rect rect, int isolated, int knockout, i
state = push_stack(dev);
bbox = fz_rect_covering_rect(rect);
- bbox = fz_intersect_rect(bbox, state->scissor);
+ bbox = fz_intersect_irect(bbox, state->scissor);
fz_try(ctx)
{
@@ -1591,7 +1591,7 @@ fz_draw_begin_tile(fz_device *devp, fz_rect area, fz_rect view, float xstep, flo
fz_draw_device *dev = devp->user;
fz_pixmap *dest = NULL;
fz_pixmap *shape;
- fz_rect bbox;
+ fz_irect bbox;
fz_context *ctx = dev->ctx;
fz_draw_state *state = &dev->stack[dev->top];
fz_colorspace *model = state->dest->colorspace;
@@ -1624,7 +1624,7 @@ fz_draw_begin_tile(fz_device *devp, fz_rect area, fz_rect view, float xstep, flo
state[1].blendmode |= FZ_BLEND_ISOLATED;
state[1].xstep = xstep;
state[1].ystep = ystep;
- state[1].area = area;
+ state[1].area = fz_rect_covering_rect(area);
state[1].ctm = ctm;
#ifdef DUMP_GROUP_BLENDS
dump_spaces(dev->top-1, "Tile begin\n");
@@ -1645,8 +1645,8 @@ fz_draw_end_tile(fz_device *devp)
fz_draw_device *dev = devp->user;
float xstep, ystep;
fz_matrix ttm, ctm, shapectm;
- fz_rect area, scissor;
- fz_rect scissor_box;
+ fz_irect area, scissor;
+ fz_rect scissor_tmp;
int x0, y0, x1, y1, x, y;
fz_context *ctx = dev->ctx;
fz_draw_state *state;
@@ -1665,13 +1665,11 @@ fz_draw_end_tile(fz_device *devp)
/* Fudge the scissor bbox a little to allow for inaccuracies in the
* matrix inversion. */
- scissor_box = fz_expand_rect(state[0].scissor, 1);
- scissor.x0 = (float)scissor_box.x0;
- scissor.y0 = (float)scissor_box.y0;
- scissor.x1 = (float)scissor_box.x1;
- scissor.y1 = (float)scissor_box.y1;
- scissor = fz_transform_rect(fz_invert_matrix(ctm), scissor);
- area = fz_intersect_rect(area, scissor);
+ scissor_tmp = fz_rect_from_irect(state[0].scissor);
+ scissor_tmp = fz_expand_rect(scissor_tmp, 1);
+ scissor_tmp = fz_transform_rect(fz_invert_matrix(ctm), scissor_tmp);
+ scissor = fz_rect_covering_rect(scissor_tmp);
+ area = fz_intersect_irect(area, scissor);
x0 = floorf(area.x0 / xstep);
y0 = floorf(area.y0 / ystep);
@@ -1831,7 +1829,7 @@ fz_new_draw_device(fz_context *ctx, fz_pixmap *dest)
}
fz_device *
-fz_new_draw_device_with_bbox(fz_context *ctx, fz_pixmap *dest, fz_rect clip)
+fz_new_draw_device_with_bbox(fz_context *ctx, fz_pixmap *dest, fz_irect clip)
{
fz_device *dev = fz_new_draw_device(ctx, dest);
fz_draw_device *ddev = dev->user;
diff --git a/draw/draw_edge.c b/draw/draw_edge.c
index df59ba14..c5438ffe 100644
--- a/draw/draw_edge.c
+++ b/draw/draw_edge.c
@@ -203,7 +203,7 @@ fz_new_gel(fz_context *ctx)
}
void
-fz_reset_gel(fz_gel *gel, fz_rect clip)
+fz_reset_gel(fz_gel *gel, fz_irect clip)
{
fz_aa_context *ctxaa = gel->ctx->aa;
@@ -235,13 +235,13 @@ fz_free_gel(fz_gel *gel)
fz_free(gel->ctx, gel);
}
-fz_rect
+fz_irect
fz_bound_gel(fz_gel *gel)
{
- fz_rect bbox;
+ fz_irect bbox;
fz_aa_context *ctxaa = gel->ctx->aa;
if (gel->len == 0)
- return fz_empty_rect;
+ return fz_empty_irect;
bbox.x0 = fz_idiv(gel->bbox.x0, fz_aa_hscale);
bbox.y0 = fz_idiv(gel->bbox.y0, fz_aa_vscale);
bbox.x1 = fz_idiv(gel->bbox.x1, fz_aa_hscale) + 1;
@@ -666,7 +666,7 @@ static inline void blit_aa(fz_pixmap *dst, int x, int y,
}
static void
-fz_scan_convert_aa(fz_gel *gel, int eofill, fz_rect clip,
+fz_scan_convert_aa(fz_gel *gel, int eofill, fz_irect clip,
fz_pixmap *dst, unsigned char *color)
{
unsigned char *alphas;
@@ -851,7 +851,7 @@ clip_ended:
*/
static inline void blit_sharp(int x0, int x1, int y,
- fz_rect clip, fz_pixmap *dst, unsigned char *color)
+ fz_irect clip, fz_pixmap *dst, unsigned char *color)
{
unsigned char *dp;
x0 = fz_clampi(x0, dst->x, dst->x + dst->w);
@@ -867,7 +867,7 @@ static inline void blit_sharp(int x0, int x1, int y,
}
static inline void non_zero_winding_sharp(fz_gel *gel, int y,
- fz_rect clip, fz_pixmap *dst, unsigned char *color)
+ fz_irect clip, fz_pixmap *dst, unsigned char *color)
{
int winding = 0;
int x = 0;
@@ -883,7 +883,7 @@ static inline void non_zero_winding_sharp(fz_gel *gel, int y,
}
static inline void even_odd_sharp(fz_gel *gel, int y,
- fz_rect clip, fz_pixmap *dst, unsigned char *color)
+ fz_irect clip, fz_pixmap *dst, unsigned char *color)
{
int even = 0;
int x = 0;
@@ -899,7 +899,7 @@ static inline void even_odd_sharp(fz_gel *gel, int y,
}
static void
-fz_scan_convert_sharp(fz_gel *gel, int eofill, fz_rect clip,
+fz_scan_convert_sharp(fz_gel *gel, int eofill, fz_irect clip,
fz_pixmap *dst, unsigned char *color)
{
int e = 0;
@@ -955,7 +955,7 @@ fz_scan_convert_sharp(fz_gel *gel, int eofill, fz_rect clip,
}
void
-fz_scan_convert(fz_gel *gel, int eofill, fz_rect clip,
+fz_scan_convert(fz_gel *gel, int eofill, fz_irect clip,
fz_pixmap *dst, unsigned char *color)
{
fz_aa_context *ctxaa = gel->ctx->aa;
diff --git a/draw/draw_glyph.c b/draw/draw_glyph.c
index 40c71241..93caf478 100644
--- a/draw/draw_glyph.c
+++ b/draw/draw_glyph.c
@@ -95,7 +95,7 @@ fz_keep_glyph_cache(fz_context *ctx)
}
fz_pixmap *
-fz_render_stroked_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, fz_matrix ctm, fz_stroke_state *stroke, fz_rect scissor)
+fz_render_stroked_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, fz_matrix ctm, fz_stroke_state *stroke, fz_irect scissor)
{
if (font->ft_face)
{
@@ -116,7 +116,7 @@ fz_render_stroked_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm,
This must not be inserted into the cache.
*/
fz_pixmap *
-fz_render_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix ctm, fz_colorspace *model, fz_rect scissor)
+fz_render_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix ctm, fz_colorspace *model, fz_irect scissor)
{
fz_glyph_cache *cache;
fz_glyph_key key;
@@ -126,7 +126,7 @@ fz_render_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix ctm, fz_color
if (size <= MAX_GLYPH_SIZE)
{
- scissor = fz_infinite_rect;
+ scissor = fz_infinite_irect;
do_cache = 1;
}
else
diff --git a/draw/draw_mesh.c b/draw/draw_mesh.c
index 98669e17..bbd3dc02 100644
--- a/draw/draw_mesh.c
+++ b/draw/draw_mesh.c
@@ -213,7 +213,7 @@ static inline void step_edge(int *ael, int *del, int n)
}
static void
-fz_paint_triangle(fz_pixmap *pix, float *av, float *bv, float *cv, int n, fz_rect bbox)
+fz_paint_triangle(fz_pixmap *pix, float *av, float *bv, float *cv, int n, fz_irect bbox)
{
float poly[MAXV][MAXN];
float temp[MAXV][MAXN];
@@ -307,7 +307,7 @@ struct paint_tri_data
fz_context *ctx;
fz_shade *shade;
fz_pixmap *dest;
- fz_rect bbox;
+ fz_irect bbox;
};
static void
@@ -349,7 +349,7 @@ do_paint_tri(void *arg, fz_vertex *av, fz_vertex *bv, fz_vertex *cv)
}
void
-fz_paint_shade(fz_context *ctx, fz_shade *shade, fz_matrix ctm, fz_pixmap *dest, fz_rect bbox)
+fz_paint_shade(fz_context *ctx, fz_shade *shade, fz_matrix ctm, fz_pixmap *dest, fz_irect bbox)
{
unsigned char clut[256][FZ_MAX_COLORS];
fz_pixmap *temp = NULL;
diff --git a/draw/draw_paint.c b/draw/draw_paint.c
index 2f6ef368..de0f1d34 100644
--- a/draw/draw_paint.c
+++ b/draw/draw_paint.c
@@ -375,15 +375,15 @@ fz_paint_span(byte * restrict dp, byte * restrict sp, int n, int w, int alpha)
*/
void
-fz_paint_pixmap_with_bbox(fz_pixmap *dst, fz_pixmap *src, int alpha, fz_rect bbox)
+fz_paint_pixmap_with_bbox(fz_pixmap *dst, fz_pixmap *src, int alpha, fz_irect bbox)
{
unsigned char *sp, *dp;
int x, y, w, h, n;
assert(dst->n == src->n);
- bbox = fz_intersect_rect(bbox, fz_pixmap_bbox_no_ctx(dst));
- bbox = fz_intersect_rect(bbox, fz_pixmap_bbox_no_ctx(src));
+ bbox = fz_intersect_irect(bbox, fz_pixmap_bbox_no_ctx(dst));
+ bbox = fz_intersect_irect(bbox, fz_pixmap_bbox_no_ctx(src));
x = bbox.x0;
y = bbox.y0;
@@ -408,13 +408,13 @@ void
fz_paint_pixmap(fz_pixmap *dst, fz_pixmap *src, int alpha)
{
unsigned char *sp, *dp;
- fz_rect bbox;
+ fz_irect bbox;
int x, y, w, h, n;
assert(dst->n == src->n);
bbox = fz_pixmap_bbox_no_ctx(dst);
- bbox = fz_intersect_rect(bbox, fz_pixmap_bbox_no_ctx(src));
+ bbox = fz_intersect_irect(bbox, fz_pixmap_bbox_no_ctx(src));
x = bbox.x0;
y = bbox.y0;
@@ -439,15 +439,15 @@ void
fz_paint_pixmap_with_mask(fz_pixmap *dst, fz_pixmap *src, fz_pixmap *msk)
{
unsigned char *sp, *dp, *mp;
- fz_rect bbox;
+ fz_irect bbox;
int x, y, w, h, n;
assert(dst->n == src->n);
assert(msk->n == 1);
bbox = fz_pixmap_bbox_no_ctx(dst);
- bbox = fz_intersect_rect(bbox, fz_pixmap_bbox_no_ctx(src));
- bbox = fz_intersect_rect(bbox, fz_pixmap_bbox_no_ctx(msk));
+ bbox = fz_intersect_irect(bbox, fz_pixmap_bbox_no_ctx(src));
+ bbox = fz_intersect_irect(bbox, fz_pixmap_bbox_no_ctx(msk));
x = bbox.x0;
y = bbox.y0;
diff --git a/draw/draw_scale.c b/draw/draw_scale.c
index a2439216..8cb99166 100644
--- a/draw/draw_scale.c
+++ b/draw/draw_scale.c
@@ -1238,13 +1238,13 @@ scale_single_col(unsigned char *dst, unsigned char *src, fz_weights *weights, in
#endif /* SINGLE_PIXEL_SPECIALS */
fz_pixmap *
-fz_scale_pixmap(fz_context *ctx, fz_pixmap *src, float x, float y, float w, float h, fz_rect *clip)
+fz_scale_pixmap(fz_context *ctx, fz_pixmap *src, float x, float y, float w, float h, fz_irect *clip)
{
return fz_scale_pixmap_cached(ctx, src, x, y, w, h, clip, NULL, NULL);
}
fz_pixmap *
-fz_scale_pixmap_cached(fz_context *ctx, fz_pixmap *src, float x, float y, float w, float h, fz_rect *clip, fz_scale_cache *cache_x, fz_scale_cache *cache_y)
+fz_scale_pixmap_cached(fz_context *ctx, fz_pixmap *src, float x, float y, float w, float h, fz_irect *clip, fz_scale_cache *cache_x, fz_scale_cache *cache_y)
{
fz_scale_filter *filter = &fz_scale_filter_simple;
fz_weights *contrib_rows = NULL;
diff --git a/draw/draw_simple_scale.c b/draw/draw_simple_scale.c
index d2b69cf9..60914e52 100644
--- a/draw/draw_simple_scale.c
+++ b/draw/draw_simple_scale.c
@@ -1214,13 +1214,13 @@ scale_single_col(unsigned char *dst, unsigned char *src, fz_weights *weights, in
#endif /* SINGLE_PIXEL_SPECIALS */
fz_pixmap *
-fz_scale_pixmap(fz_context *ctx, fz_pixmap *src, float x, float y, float w, float h, fz_rect *clip)
+fz_scale_pixmap(fz_context *ctx, fz_pixmap *src, float x, float y, float w, float h, fz_irect *clip)
{
return fz_scale_pixmap_cached(ctx, src, x, y, w, h, clip, NULL, NULL);
}
fz_pixmap *
-fz_scale_pixmap_cached(fz_context *ctx, fz_pixmap *src, float x, float y, float w, float h, fz_rect *clip, fz_scale_cache *cache_x, fz_scale_cache *cache_y)
+fz_scale_pixmap_cached(fz_context *ctx, fz_pixmap *src, float x, float y, float w, float h, fz_irect *clip, fz_scale_cache *cache_x, fz_scale_cache *cache_y)
{
fz_scale_filter *filter = &fz_scale_filter_simple;
fz_weights *contrib_rows = NULL;
diff --git a/fitz/base_geometry.c b/fitz/base_geometry.c
index 1486279f..317c8df1 100644
--- a/fitz/base_geometry.c
+++ b/fitz/base_geometry.c
@@ -3,6 +3,24 @@
#define MAX4(a,b,c,d) fz_max(fz_max(a,b), fz_max(c,d))
#define MIN4(a,b,c,d) fz_min(fz_min(a,b), fz_min(c,d))
+/* A useful macro to add with overflow detection and clamping.
+
+ We want to do "b = a + x", but to allow for overflow. Consider the
+ top bits, and the cases in which overflow occurs:
+
+ overflow a x b ~a^x a^b (~a^x)&(a^b)
+ no 0 0 0 1 0 0
+ yes 0 0 1 1 1 1
+ no 0 1 0 0 0 0
+ no 0 1 1 0 1 0
+ no 1 0 0 0 1 0
+ no 1 0 1 0 0 0
+ yes 1 1 0 1 1 1
+ no 1 1 1 1 0 0
+*/
+#define ADD_WITH_SAT(b,a,x) \
+ ((b) = (a) + (x), (b) = (((~(a)^(x))&((a)^(b))) < 0 ? ((x) < 0 ? INT_MIN : INT_MAX) : (b)))
+
/* Matrices, points and affine transformations */
const fz_matrix fz_identity = { 1, 0, 0, 1, 0, 0 };
@@ -170,36 +188,57 @@ const fz_rect fz_infinite_rect = { 1, 1, -1, -1 };
const fz_rect fz_empty_rect = { 0, 0, 0, 0 };
const fz_rect fz_unit_rect = { 0, 0, 1, 1 };
-fz_rect
-fz_rect_covering_rect(fz_rect f)
+const fz_irect fz_infinite_irect = { 1, 1, -1, -1 };
+const fz_irect fz_empty_irect = { 0, 0, 0, 0 };
+const fz_irect fz_unit_irect = { 0, 0, 1, 1 };
+
+fz_irect
+fz_rect_covering_rect(fz_rect a)
{
- f.x0 = floorf(f.x0);
- f.y0 = floorf(f.y0);
- f.x1 = ceilf(f.x1);
- f.y1 = ceilf(f.y1);
+ fz_irect b;
+
+ a.x0 = floorf(a.x0);
+ a.y0 = floorf(a.y0);
+ a.x1 = ceilf(a.x1);
+ a.y1 = ceilf(a.y1);
/* check for integer overflow */
- f.x0 = fz_clamp(f.x0, MIN_SAFE_INT, MAX_SAFE_INT);
- f.y0 = fz_clamp(f.y0, MIN_SAFE_INT, MAX_SAFE_INT);
- f.x1 = fz_clamp(f.x1, MIN_SAFE_INT, MAX_SAFE_INT);
- f.y1 = fz_clamp(f.y1, MIN_SAFE_INT, MAX_SAFE_INT);
- return f;
+ b.x0 = fz_clamp(a.x0, MIN_SAFE_INT, MAX_SAFE_INT);
+ b.y0 = fz_clamp(a.y0, MIN_SAFE_INT, MAX_SAFE_INT);
+ b.x1 = fz_clamp(a.x1, MIN_SAFE_INT, MAX_SAFE_INT);
+ b.y1 = fz_clamp(a.y1, MIN_SAFE_INT, MAX_SAFE_INT);
+
+ return b;
}
fz_rect
-fz_round_rect(fz_rect f)
+fz_rect_from_irect(fz_irect a)
{
- f.x0 = floorf(f.x0 + 0.001);
- f.y0 = floorf(f.y0 + 0.001);
- f.x1 = ceilf(f.x1 - 0.001);
- f.y1 = ceilf(f.y1 - 0.001);
+ fz_rect b;
+ b.x0 = a.x0;
+ b.y0 = a.y0;
+ b.x1 = a.x1;
+ b.y1 = a.y1;
+ return b;
+}
+
+fz_irect
+fz_round_rect(fz_rect a)
+{
+ fz_irect b;
+
+ a.x0 = floorf(a.x0 + 0.001);
+ a.y0 = floorf(a.y0 + 0.001);
+ a.x1 = ceilf(a.x1 - 0.001);
+ a.y1 = ceilf(a.y1 - 0.001);
/* check for integer overflow */
- f.x0 = fz_clamp(f.x0, MIN_SAFE_INT, MAX_SAFE_INT);
- f.y0 = fz_clamp(f.y0, MIN_SAFE_INT, MAX_SAFE_INT);
- f.x1 = fz_clamp(f.x1, MIN_SAFE_INT, MAX_SAFE_INT);
- f.y1 = fz_clamp(f.y1, MIN_SAFE_INT, MAX_SAFE_INT);
- return f;
+ b.x0 = fz_clamp(a.x0, MIN_SAFE_INT, MAX_SAFE_INT);
+ b.y0 = fz_clamp(a.y0, MIN_SAFE_INT, MAX_SAFE_INT);
+ b.x1 = fz_clamp(a.x1, MIN_SAFE_INT, MAX_SAFE_INT);
+ b.y1 = fz_clamp(a.y1, MIN_SAFE_INT, MAX_SAFE_INT);
+
+ return b;
}
fz_rect
@@ -218,6 +257,22 @@ fz_intersect_rect(fz_rect a, fz_rect b)
return (r.x1 < r.x0 || r.y1 < r.y0) ? fz_empty_rect : r;
}
+fz_irect
+fz_intersect_irect(fz_irect a, fz_irect b)
+{
+ fz_irect r;
+ /* Check for empty box before infinite box */
+ if (fz_is_empty_rect(a)) return fz_empty_irect;
+ if (fz_is_empty_rect(b)) return fz_empty_irect;
+ if (fz_is_infinite_rect(a)) return b;
+ if (fz_is_infinite_rect(b)) return a;
+ r.x0 = fz_maxi(a.x0, b.x0);
+ r.y0 = fz_maxi(a.y0, b.y0);
+ r.x1 = fz_mini(a.x1, b.x1);
+ r.y1 = fz_mini(a.y1, b.y1);
+ return (r.x1 < r.x0 || r.y1 < r.y0) ? fz_empty_irect : r;
+}
+
fz_rect
fz_union_rect(fz_rect a, fz_rect b)
{
@@ -270,6 +325,19 @@ fz_translate_rect(fz_rect a, float xoff, float yoff)
return b;
}
+fz_irect
+fz_translate_irect(fz_irect a, int xoff, int yoff)
+{
+ fz_irect b;
+ if (fz_is_empty_rect(a)) return a;
+ if (fz_is_infinite_rect(a)) return a;
+ ADD_WITH_SAT(b.x0, a.x0, xoff);
+ ADD_WITH_SAT(b.y0, a.y0, yoff);
+ ADD_WITH_SAT(b.x1, a.x1, xoff);
+ ADD_WITH_SAT(b.y1, a.y1, yoff);
+ return b;
+}
+
fz_rect
fz_expand_rect(fz_rect a, float expand)
{
diff --git a/fitz/fitz-internal.h b/fitz/fitz-internal.h
index e7e7ca3b..518ed8c2 100644
--- a/fitz/fitz-internal.h
+++ b/fitz/fitz-internal.h
@@ -872,22 +872,22 @@ struct fz_pixmap_s
void fz_free_pixmap_imp(fz_context *ctx, fz_storable *pix);
-void fz_copy_pixmap_rect(fz_context *ctx, fz_pixmap *dest, fz_pixmap *src, fz_rect r);
+void fz_copy_pixmap_rect(fz_context *ctx, fz_pixmap *dest, fz_pixmap *src, fz_irect r);
void fz_premultiply_pixmap(fz_context *ctx, fz_pixmap *pix);
fz_pixmap *fz_alpha_from_gray(fz_context *ctx, fz_pixmap *gray, int luminosity);
unsigned int fz_pixmap_size(fz_context *ctx, fz_pixmap *pix);
-fz_pixmap *fz_scale_pixmap(fz_context *ctx, fz_pixmap *src, float x, float y, float w, float h, fz_rect *clip);
+fz_pixmap *fz_scale_pixmap(fz_context *ctx, fz_pixmap *src, float x, float y, float w, float h, fz_irect *clip);
typedef struct fz_scale_cache_s fz_scale_cache;
fz_scale_cache *fz_new_scale_cache(fz_context *ctx);
void fz_free_scale_cache(fz_context *ctx, fz_scale_cache *cache);
-fz_pixmap *fz_scale_pixmap_cached(fz_context *ctx, fz_pixmap *src, float x, float y, float w, float h, fz_rect *clip, fz_scale_cache *cache_x, fz_scale_cache *cache_y);
+fz_pixmap *fz_scale_pixmap_cached(fz_context *ctx, fz_pixmap *src, float x, float y, float w, float h, fz_irect *clip, fz_scale_cache *cache_x, fz_scale_cache *cache_y);
void fz_subsample_pixmap(fz_context *ctx, fz_pixmap *tile, int factor);
-fz_rect fz_pixmap_bbox_no_ctx(fz_pixmap *src);
+fz_irect fz_pixmap_bbox_no_ctx(fz_pixmap *src);
typedef struct fz_compression_params_s fz_compression_params;
@@ -1187,10 +1187,10 @@ void fz_purge_glyph_cache(fz_context *ctx);
fz_path *fz_outline_ft_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm);
fz_path *fz_outline_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix ctm);
fz_pixmap *fz_render_ft_glyph(fz_context *ctx, fz_font *font, int cid, fz_matrix trm, int aa);
-fz_pixmap *fz_render_t3_glyph(fz_context *ctx, fz_font *font, int cid, fz_matrix trm, fz_colorspace *model, fz_rect scissor);
+fz_pixmap *fz_render_t3_glyph(fz_context *ctx, fz_font *font, int cid, fz_matrix trm, fz_colorspace *model, fz_irect scissor);
fz_pixmap *fz_render_ft_stroked_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, fz_matrix ctm, fz_stroke_state *state);
-fz_pixmap *fz_render_glyph(fz_context *ctx, fz_font*, int, fz_matrix, fz_colorspace *model, fz_rect scissor);
-fz_pixmap *fz_render_stroked_glyph(fz_context *ctx, fz_font*, int, fz_matrix, fz_matrix, fz_stroke_state *stroke, fz_rect scissor);
+fz_pixmap *fz_render_glyph(fz_context *ctx, fz_font*, int, fz_matrix, fz_colorspace *model, fz_irect scissor);
+fz_pixmap *fz_render_stroked_glyph(fz_context *ctx, fz_font*, int, fz_matrix, fz_matrix, fz_stroke_state *stroke, fz_irect scissor);
void fz_render_t3_glyph_direct(fz_context *ctx, fz_device *dev, fz_font *font, int gid, fz_matrix trm, void *gstate, int nestedDepth);
void fz_prepare_t3_glyph(fz_context *ctx, fz_font *font, int gid, int nestedDepth);
@@ -1300,7 +1300,7 @@ void fz_drop_shade(fz_context *ctx, fz_shade *shade);
void fz_free_shade_imp(fz_context *ctx, fz_storable *shade);
fz_rect fz_bound_shade(fz_context *ctx, fz_shade *shade, fz_matrix ctm);
-void fz_paint_shade(fz_context *ctx, fz_shade *shade, fz_matrix ctm, fz_pixmap *dest, fz_rect bbox);
+void fz_paint_shade(fz_context *ctx, fz_shade *shade, fz_matrix ctm, fz_pixmap *dest, fz_irect bbox);
/*
* Handy routine for processing mesh based shades
@@ -1339,13 +1339,13 @@ typedef struct fz_gel_s fz_gel;
fz_gel *fz_new_gel(fz_context *ctx);
void fz_insert_gel(fz_gel *gel, float x0, float y0, float x1, float y1);
-void fz_reset_gel(fz_gel *gel, fz_rect clip);
+void fz_reset_gel(fz_gel *gel, fz_irect clip);
void fz_sort_gel(fz_gel *gel);
-fz_rect fz_bound_gel(fz_gel *gel);
+fz_irect fz_bound_gel(fz_gel *gel);
void fz_free_gel(fz_gel *gel);
int fz_is_rect_gel(fz_gel *gel);
-void fz_scan_convert(fz_gel *gel, int eofill, fz_rect clip, fz_pixmap *pix, unsigned char *colorbv);
+void fz_scan_convert(fz_gel *gel, int eofill, fz_irect clip, fz_pixmap *pix, unsigned char *colorbv);
void fz_flatten_fill_path(fz_gel *gel, fz_path *path, fz_matrix ctm, float flatness);
void fz_flatten_stroke_path(fz_gel *gel, fz_path *path, fz_stroke_state *stroke, fz_matrix ctm, float flatness, float linewidth);
@@ -1458,12 +1458,12 @@ void fz_paint_solid_color(unsigned char * restrict dp, int n, int w, unsigned ch
void fz_paint_span(unsigned char * restrict dp, unsigned char * restrict sp, int n, int w, int alpha);
void fz_paint_span_with_color(unsigned char * restrict dp, unsigned char * restrict mp, int n, int w, unsigned char *color);
-void fz_paint_image(fz_pixmap *dst, fz_rect scissor, fz_pixmap *shape, fz_pixmap *img, fz_matrix ctm, int alpha);
-void fz_paint_image_with_color(fz_pixmap *dst, fz_rect scissor, fz_pixmap *shape, fz_pixmap *img, fz_matrix ctm, unsigned char *colorbv);
+void fz_paint_image(fz_pixmap *dst, fz_irect scissor, fz_pixmap *shape, fz_pixmap *img, fz_matrix ctm, int alpha);
+void fz_paint_image_with_color(fz_pixmap *dst, fz_irect scissor, fz_pixmap *shape, fz_pixmap *img, fz_matrix ctm, unsigned char *colorbv);
void fz_paint_pixmap(fz_pixmap *dst, fz_pixmap *src, int alpha);
void fz_paint_pixmap_with_mask(fz_pixmap *dst, fz_pixmap *src, fz_pixmap *msk);
-void fz_paint_pixmap_with_bbox(fz_pixmap *dst, fz_pixmap *src, int alpha, fz_rect bbox);
+void fz_paint_pixmap_with_bbox(fz_pixmap *dst, fz_pixmap *src, int alpha, fz_irect bbox);
void fz_blend_pixmap(fz_pixmap *dst, fz_pixmap *src, int alpha, int blendmode, int isolated, fz_pixmap *shape);
void fz_blend_pixel(unsigned char dp[3], unsigned char bp[3], unsigned char sp[3], int blendmode);
diff --git a/fitz/fitz.h b/fitz/fitz.h
index 7243c341..0e025e44 100644
--- a/fitz/fitz.h
+++ b/fitz/fitz.h
@@ -748,6 +748,18 @@ struct fz_rect_s
};
/*
+ fz_irect is a rectangle using integers instead of floats.
+
+ It's used in the draw device and for pixmap dimensions.
+*/
+typedef struct fz_irect_s fz_irect;
+struct fz_irect_s
+{
+ int x0, y0;
+ int x1, y1;
+};
+
+/*
A rectangle with sides of length one.
The bottom left corner is at (0, 0) and the top right corner
@@ -761,6 +773,7 @@ extern const fz_rect fz_unit_rect;
Both the top left and bottom right corner are at (0, 0).
*/
extern const fz_rect fz_empty_rect;
+extern const fz_irect fz_empty_irect;
/*
An infinite rectangle with negative area.
@@ -769,6 +782,7 @@ extern const fz_rect fz_empty_rect;
at (-1, -1).
*/
extern const fz_rect fz_infinite_rect;
+extern const fz_irect fz_infinite_irect;
/*
fz_is_empty_rect: Check if rectangle is empty.
@@ -912,6 +926,7 @@ float fz_matrix_expansion(fz_matrix m); /* sumatrapdf */
Does not throw exceptions.
*/
fz_rect fz_intersect_rect(fz_rect a, fz_rect b);
+fz_irect fz_intersect_irect(fz_irect a, fz_irect b);
/*
fz_union_rect: Compute union of two rectangles.
@@ -938,7 +953,7 @@ fz_rect fz_union_rect(fz_rect a, fz_rect b);
Does not throw exceptions.
*/
-fz_rect fz_rect_covering_rect(fz_rect rect);
+fz_irect fz_rect_covering_rect(fz_rect rect);
/*
fz_round_rect: Round rectangle coordinates.
@@ -956,7 +971,9 @@ fz_rect fz_rect_covering_rect(fz_rect rect);
Does not throw exceptions.
*/
-fz_rect fz_round_rect(fz_rect rect);
+fz_irect fz_round_rect(fz_rect rect);
+
+fz_rect fz_rect_from_irect(fz_irect rect);
/*
fz_expand_rect: Expand a bbox by a given amount in all directions.
@@ -973,6 +990,7 @@ fz_rect fz_expand_rect(fz_rect b, float expand);
Does not throw exceptions.
*/
fz_rect fz_translate_rect(fz_rect a, float xoff, float yoff);
+fz_irect fz_translate_irect(fz_irect a, int xoff, int yoff);
/*
fz_transform_point: Apply a transformation to a point.
@@ -1245,7 +1263,7 @@ typedef struct fz_pixmap_s fz_pixmap;
/*
fz_pixmap_bbox: Return the bounding box for a pixmap.
*/
-fz_rect fz_pixmap_bbox(fz_context *ctx, fz_pixmap *pix);
+fz_irect fz_pixmap_bbox(fz_context *ctx, fz_pixmap *pix);
/*
fz_pixmap_width: Return the width of the pixmap in pixels.
@@ -1289,7 +1307,7 @@ fz_pixmap *fz_new_pixmap(fz_context *ctx, fz_colorspace *cs, int w, int h);
Returns a pointer to the new pixmap. Throws exception on failure to
allocate.
*/
-fz_pixmap *fz_new_pixmap_with_bbox(fz_context *ctx, fz_colorspace *colorspace, fz_rect bbox);
+fz_pixmap *fz_new_pixmap_with_bbox(fz_context *ctx, fz_colorspace *colorspace, fz_irect bbox);
/*
fz_new_pixmap_with_data: Create a new pixmap, with it's origin at
@@ -1328,7 +1346,7 @@ fz_pixmap *fz_new_pixmap_with_data(fz_context *ctx, fz_colorspace *colorspace, i
Returns a pointer to the new pixmap. Throws exception on failure to
allocate.
*/
-fz_pixmap *fz_new_pixmap_with_bbox_and_data(fz_context *ctx, fz_colorspace *colorspace, fz_rect rect, unsigned char *samples);
+fz_pixmap *fz_new_pixmap_with_bbox_and_data(fz_context *ctx, fz_colorspace *colorspace, fz_irect rect, unsigned char *samples);
/*
fz_keep_pixmap: Take a reference to a pixmap.
@@ -1396,7 +1414,7 @@ void fz_clear_pixmap_with_value(fz_context *ctx, fz_pixmap *pix, int value);
Does not throw exceptions.
*/
-void fz_clear_pixmap_rect_with_value(fz_context *ctx, fz_pixmap *pix, int value, fz_rect r);
+void fz_clear_pixmap_rect_with_value(fz_context *ctx, fz_pixmap *pix, int value, fz_irect r);
/*
fz_clear_pixmap_with_value: Sets all components (including alpha) of
@@ -1423,7 +1441,7 @@ void fz_invert_pixmap(fz_context *ctx, fz_pixmap *pix);
Does not throw exceptions.
*/
-void fz_invert_pixmap_rect(fz_pixmap *image, fz_rect rect);
+void fz_invert_pixmap_rect(fz_pixmap *image, fz_irect rect);
/*
fz_gamma_pixmap: Apply gamma correction to a pixmap. All components
@@ -1624,7 +1642,7 @@ fz_device *fz_new_draw_device(fz_context *ctx, fz_pixmap *dest);
clip: Bounding box to restrict any marking operations of the
draw device.
*/
-fz_device *fz_new_draw_device_with_bbox(fz_context *ctx, fz_pixmap *dest, fz_rect clip);
+fz_device *fz_new_draw_device_with_bbox(fz_context *ctx, fz_pixmap *dest, fz_irect clip);
/*
Text extraction device: Used for searching, format conversion etc.
diff --git a/fitz/res_font.c b/fitz/res_font.c
index 1b07d060..56481962 100644
--- a/fitz/res_font.c
+++ b/fitz/res_font.c
@@ -887,11 +887,12 @@ fz_bound_t3_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm)
}
fz_pixmap *
-fz_render_t3_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, fz_colorspace *model, fz_rect scissor)
+fz_render_t3_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, fz_colorspace *model, fz_irect scissor)
{
fz_display_list *list;
fz_matrix ctm;
- fz_rect bbox;
+ fz_rect bounds;
+ fz_irect bbox;
fz_device *dev;
fz_pixmap *glyph;
fz_pixmap *result;
@@ -920,13 +921,10 @@ fz_render_t3_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, fz_co
model = NULL; /* Treat as masked */
}
- bbox = fz_bound_glyph(ctx, font, gid, trm);
- bbox.x0 -= 1;
- bbox.y0 -= 1;
- bbox.x1 += 1;
- bbox.y1 += 1;
-
- bbox = fz_intersect_rect(bbox, scissor);
+ bounds = fz_bound_glyph(ctx, font, gid, trm);
+ bounds = fz_expand_rect(bounds, 1);
+ bbox = fz_rect_covering_rect(bounds);
+ bbox = fz_intersect_irect(bbox, scissor);
glyph = fz_new_pixmap_with_bbox(ctx, model ? model : fz_device_gray, bbox);
fz_clear_pixmap(ctx, glyph);
diff --git a/fitz/res_pixmap.c b/fitz/res_pixmap.c
index eb5d58ef..60e615ec 100644
--- a/fitz/res_pixmap.c
+++ b/fitz/res_pixmap.c
@@ -83,9 +83,8 @@ fz_new_pixmap(fz_context *ctx, fz_colorspace *colorspace, int w, int h)
}
fz_pixmap *
-fz_new_pixmap_with_bbox(fz_context *ctx, fz_colorspace *colorspace, fz_rect rf)
+fz_new_pixmap_with_bbox(fz_context *ctx, fz_colorspace *colorspace, fz_irect r)
{
- fz_rect r = fz_round_rect(rf);
fz_pixmap *pixmap = fz_new_pixmap(ctx, colorspace, r.x1 - r.x0, r.y1 - r.y0);
pixmap->x = r.x0;
pixmap->y = r.y0;
@@ -93,19 +92,18 @@ fz_new_pixmap_with_bbox(fz_context *ctx, fz_colorspace *colorspace, fz_rect rf)
}
fz_pixmap *
-fz_new_pixmap_with_bbox_and_data(fz_context *ctx, fz_colorspace *colorspace, fz_rect rf, unsigned char *samples)
+fz_new_pixmap_with_bbox_and_data(fz_context *ctx, fz_colorspace *colorspace, fz_irect r, unsigned char *samples)
{
- fz_rect r = fz_round_rect(rf);
fz_pixmap *pixmap = fz_new_pixmap_with_data(ctx, colorspace, r.x1 - r.x0, r.y1 - r.y0, samples);
pixmap->x = r.x0;
pixmap->y = r.y0;
return pixmap;
}
-fz_rect
+fz_irect
fz_pixmap_bbox(fz_context *ctx, fz_pixmap *pix)
{
- fz_rect bbox;
+ fz_irect bbox;
bbox.x0 = pix->x;
bbox.y0 = pix->y;
bbox.x1 = pix->x + pix->w;
@@ -113,10 +111,10 @@ fz_pixmap_bbox(fz_context *ctx, fz_pixmap *pix)
return bbox;
}
-fz_rect
+fz_irect
fz_pixmap_bbox_no_ctx(fz_pixmap *pix)
{
- fz_rect bbox;
+ fz_irect bbox;
bbox.x0 = pix->x;
bbox.y0 = pix->y;
bbox.x1 = pix->x + pix->w;
@@ -166,15 +164,14 @@ fz_clear_pixmap_with_value(fz_context *ctx, fz_pixmap *pix, int value)
}
void
-fz_copy_pixmap_rect(fz_context *ctx, fz_pixmap *dest, fz_pixmap *src, fz_rect r)
+fz_copy_pixmap_rect(fz_context *ctx, fz_pixmap *dest, fz_pixmap *src, fz_irect r)
{
const unsigned char *srcp;
unsigned char *destp;
int x, y, w, destspan, srcspan;
- r = fz_round_rect(r);
- r = fz_intersect_rect(r, fz_pixmap_bbox(ctx, dest));
- r = fz_intersect_rect(r, fz_pixmap_bbox(ctx, src));
+ r = fz_intersect_irect(r, fz_pixmap_bbox(ctx, dest));
+ r = fz_intersect_irect(r, fz_pixmap_bbox(ctx, src));
w = r.x1 - r.x0;
y = r.y1 - r.y0;
if (w <= 0 || y <= 0)
@@ -267,13 +264,12 @@ fz_copy_pixmap_rect(fz_context *ctx, fz_pixmap *dest, fz_pixmap *src, fz_rect r)
}
void
-fz_clear_pixmap_rect_with_value(fz_context *ctx, fz_pixmap *dest, int value, fz_rect r)
+fz_clear_pixmap_rect_with_value(fz_context *ctx, fz_pixmap *dest, int value, fz_irect r)
{
unsigned char *destp;
int x, y, w, k, destspan;
- r = fz_round_rect(r);
- r = fz_intersect_rect(r, fz_pixmap_bbox(ctx, dest));
+ r = fz_intersect_irect(r, fz_pixmap_bbox(ctx, dest));
w = r.x1 - r.x0;
y = r.y1 - r.y0;
if (w <= 0 || y <= 0)
@@ -384,13 +380,12 @@ fz_invert_pixmap(fz_context *ctx, fz_pixmap *pix)
}
}
-void fz_invert_pixmap_rect(fz_pixmap *image, fz_rect r)
+void fz_invert_pixmap_rect(fz_pixmap *image, fz_irect r)
{
unsigned char *p;
int x0, x1, y0, y1;
int x, y, n;
- r = fz_round_rect(r);
x0 = fz_clampi(r.x0 - image->x, 0, image->w - 1);
x1 = fz_clampi(r.x1 - image->x, 0, image->w - 1);
y0 = fz_clampi(r.y0 - image->y, 0, image->h - 1);