diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/fitz/device.c | 7 | ||||
-rw-r--r-- | source/fitz/draw-affine.c | 71 | ||||
-rw-r--r-- | source/fitz/draw-device.c | 24 | ||||
-rw-r--r-- | source/fitz/draw-imp.h | 4 | ||||
-rw-r--r-- | source/fitz/list-device.c | 45 | ||||
-rw-r--r-- | source/gprf/gprf-doc.c | 2 |
6 files changed, 132 insertions, 21 deletions
diff --git a/source/fitz/device.c b/source/fitz/device.c index 5e3bb61a..6df650f4 100644 --- a/source/fitz/device.c +++ b/source/fitz/device.c @@ -488,3 +488,10 @@ fz_end_tile(fz_context *ctx, fz_device *dev) if (dev->end_tile) dev->end_tile(ctx, dev); } + +void +fz_render_flags(fz_context *ctx, fz_device *dev, int set, int clear) +{ + if (dev->render_flags) + dev->render_flags(ctx, dev, set, clear); +} diff --git a/source/fitz/draw-affine.c b/source/fitz/draw-affine.c index ec19d936..1c6c26d1 100644 --- a/source/fitz/draw-affine.c +++ b/source/fitz/draw-affine.c @@ -807,12 +807,31 @@ fz_paint_affine_color_near(byte *dp, byte *sp, int sw, int sh, int u, int v, int */ #define MY_EPSILON 0.001 +/* We have 2 possible ways of gridfitting images. The first way, considered + * 'safe' in all cases, is to expand an image out to fill a box that entirely + * covers all the pixels touched by the current image. This is our 'standard' + * mechanism. + * The alternative, used when we know images are tiled across a page, is to + * round the edge of each image to the closest integer pixel boundary. This + * would not be safe in the general case, but gives less distortion across + * neighbouring images when tiling is used. We use this for .gproof files. + */ void -fz_gridfit_matrix(fz_matrix *m) +fz_gridfit_matrix(int as_tiled, fz_matrix *m) { if (fabsf(m->b) < FLT_EPSILON && fabsf(m->c) < FLT_EPSILON) { - if (m->a > 0) + if (as_tiled) + { + float f; + /* Nearest boundary for left */ + f = (float)(int)(m->e + 0.5); + m->a += m->e - f; /* Adjust width for change */ + m->e = f; + /* Nearest boundary for right (width really) */ + m->a = (float)(int)(m->a + 0.5); + } + else if (m->a > 0) { float f; /* Adjust left hand side onto pixel boundary */ @@ -842,7 +861,17 @@ fz_gridfit_matrix(fz_matrix *m) f -= 1.0; /* Ensure it moves left */ m->a = f; } - if (m->d > 0) + if (as_tiled) + { + float f; + /* Nearest boundary for top */ + f = (float)(int)(m->f + 0.5); + m->d += m->f - f; /* Adjust width for change */ + m->f = f; + /* Nearest boundary for bottom (height really) */ + m->d = (float)(int)(m->d + 0.5); + } + else if (m->d > 0) { float f; /* Adjust top onto pixel boundary */ @@ -875,7 +904,17 @@ fz_gridfit_matrix(fz_matrix *m) } else if (fabsf(m->a) < FLT_EPSILON && fabsf(m->d) < FLT_EPSILON) { - if (m->b > 0) + if (as_tiled) + { + float f; + /* Nearest boundary for left */ + f = (float)(int)(m->e + 0.5); + m->b += m->e - f; /* Adjust width for change */ + m->e = f; + /* Nearest boundary for right (width really) */ + m->b = (float)(int)(m->b + 0.5); + } + else if (m->b > 0) { float f; /* Adjust left hand side onto pixel boundary */ @@ -905,7 +944,17 @@ fz_gridfit_matrix(fz_matrix *m) f -= 1.0; /* Ensure it moves left */ m->b = f; } - if (m->c > 0) + if (as_tiled) + { + float f; + /* Nearest boundary for left */ + f = (float)(int)(m->f + 0.5); + m->c += m->f - f; /* Adjust width for change */ + m->f = f; + /* Nearest boundary for right (width really) */ + m->c = (float)(int)(m->c + 0.5); + } + else if (m->c > 0) { float f; /* Adjust top onto pixel boundary */ @@ -941,7 +990,7 @@ fz_gridfit_matrix(fz_matrix *m) /* Draw an image with an affine transform on destination */ static void -fz_paint_image_imp(fz_pixmap *dst, const fz_irect *scissor, fz_pixmap *shape, fz_pixmap *img, const fz_matrix *ctm, byte *color, int alpha, int lerp_allowed) +fz_paint_image_imp(fz_pixmap *dst, const fz_irect *scissor, fz_pixmap *shape, fz_pixmap *img, const fz_matrix *ctm, byte *color, int alpha, int lerp_allowed, int as_tiled) { byte *dp, *sp, *hp; int u, v, fa, fb, fc, fd; @@ -955,7 +1004,7 @@ fz_paint_image_imp(fz_pixmap *dst, const fz_irect *scissor, fz_pixmap *shape, fz int is_rectilinear; /* grid fit the image */ - fz_gridfit_matrix(&local_ctm); + fz_gridfit_matrix(as_tiled, &local_ctm); /* turn on interpolation for upscaled and non-rectilinear transforms */ dolerp = 0; @@ -1084,15 +1133,15 @@ fz_paint_image_imp(fz_pixmap *dst, const fz_irect *scissor, fz_pixmap *shape, fz } void -fz_paint_image_with_color(fz_pixmap *dst, const fz_irect *scissor, fz_pixmap *shape, fz_pixmap *img, const fz_matrix *ctm, byte *color, int lerp_allowed) +fz_paint_image_with_color(fz_pixmap *dst, const fz_irect *scissor, fz_pixmap *shape, fz_pixmap *img, const fz_matrix *ctm, byte *color, int lerp_allowed, int as_tiled) { assert(img->n == 1); - fz_paint_image_imp(dst, scissor, shape, img, ctm, color, 255, lerp_allowed); + fz_paint_image_imp(dst, scissor, shape, img, ctm, color, 255, lerp_allowed, as_tiled); } void -fz_paint_image(fz_pixmap *dst, const fz_irect *scissor, fz_pixmap *shape, fz_pixmap *img, const fz_matrix *ctm, int alpha, int lerp_allowed) +fz_paint_image(fz_pixmap *dst, const fz_irect *scissor, fz_pixmap *shape, fz_pixmap *img, const fz_matrix *ctm, int alpha, int lerp_allowed, int as_tiled) { assert(dst->n == img->n || (dst->n == 4 && img->n == 2)); - fz_paint_image_imp(dst, scissor, shape, img, ctm, NULL, alpha, lerp_allowed); + fz_paint_image_imp(dst, scissor, shape, img, ctm, NULL, alpha, lerp_allowed, as_tiled); } diff --git a/source/fitz/draw-device.c b/source/fitz/draw-device.c index a2499016..fdb631f4 100644 --- a/source/fitz/draw-device.c +++ b/source/fitz/draw-device.c @@ -610,7 +610,7 @@ fz_draw_fill_text(fz_context *ctx, fz_device *devp, fz_text *text, const fz_matr fz_matrix mat; mat.a = pixmap->w; mat.b = mat.c = 0; mat.d = pixmap->h; mat.e = x + pixmap->x; mat.f = y + pixmap->y; - fz_paint_image(state->dest, &state->scissor, state->shape, pixmap, &mat, alpha * 255, !(devp->hints & FZ_DONT_INTERPOLATE_IMAGES)); + fz_paint_image(state->dest, &state->scissor, state->shape, pixmap, &mat, alpha * 255, !(devp->hints & FZ_DONT_INTERPOLATE_IMAGES), devp->flags & FZ_DEVFLAG_GRIDFIT_AS_TILED); } fz_drop_glyph(ctx, glyph); } @@ -1040,7 +1040,9 @@ fz_transform_pixmap(fz_context *ctx, fz_draw_device *dev, fz_pixmap *image, fz_m /* Unrotated or X-flip or Y-flip or XY-flip */ fz_matrix m = *ctm; if (gridfit) - fz_gridfit_matrix(&m); + { + fz_gridfit_matrix(dev->flags & FZ_DEVFLAG_GRIDFIT_AS_TILED, &m); + } scaled = fz_scale_pixmap_cached(ctx, image, m.e, m.f, m.a, m.d, clip, dev->cache_x, dev->cache_y); if (!scaled) return NULL; @@ -1057,7 +1059,7 @@ fz_transform_pixmap(fz_context *ctx, fz_draw_device *dev, fz_pixmap *image, fz_m fz_matrix m = *ctm; fz_irect rclip; if (gridfit) - fz_gridfit_matrix(&m); + fz_gridfit_matrix(dev->flags & FZ_DEVFLAG_GRIDFIT_AS_TILED, &m); if (clip) { rclip.x0 = clip->y0; @@ -1174,7 +1176,7 @@ fz_draw_fill_image(fz_context *ctx, fz_device *devp, fz_image *image, const fz_m } } - fz_paint_image(state->dest, &state->scissor, state->shape, pixmap, &local_ctm, alpha * 255, !(devp->hints & FZ_DONT_INTERPOLATE_IMAGES)); + fz_paint_image(state->dest, &state->scissor, state->shape, pixmap, &local_ctm, alpha * 255, !(devp->hints & FZ_DONT_INTERPOLATE_IMAGES), devp->flags & FZ_DEVFLAG_GRIDFIT_AS_TILED); if (state->blendmode & FZ_BLEND_KNOCKOUT) fz_knockout_end(ctx, dev); @@ -1245,7 +1247,7 @@ fz_draw_fill_image_mask(fz_context *ctx, fz_device *devp, fz_image *image, const colorbv[i] = colorfv[i] * 255; colorbv[i] = alpha * 255; - fz_paint_image_with_color(state->dest, &state->scissor, state->shape, pixmap, &local_ctm, colorbv, !(devp->hints & FZ_DONT_INTERPOLATE_IMAGES)); + fz_paint_image_with_color(state->dest, &state->scissor, state->shape, pixmap, &local_ctm, colorbv, !(devp->hints & FZ_DONT_INTERPOLATE_IMAGES), devp->flags & FZ_DEVFLAG_GRIDFIT_AS_TILED); if (scaled) fz_drop_pixmap(ctx, scaled); @@ -1351,7 +1353,7 @@ fz_draw_clip_image_mask(fz_context *ctx, fz_device *devp, fz_image *image, const if (scaled) pixmap = scaled; } - fz_paint_image(mask, &bbox, state->shape, pixmap, &local_ctm, 255, !(devp->hints & FZ_DONT_INTERPOLATE_IMAGES)); + fz_paint_image(mask, &bbox, state->shape, pixmap, &local_ctm, 255, !(devp->hints & FZ_DONT_INTERPOLATE_IMAGES), devp->flags & FZ_DEVFLAG_GRIDFIT_AS_TILED); } fz_always(ctx) { @@ -2040,6 +2042,14 @@ fz_draw_drop_imp(fz_context *ctx, fz_device *devp) fz_drop_gel(ctx, gel); } +static void +fz_draw_render_flags(fz_context *ctx, fz_device *devp, int set, int clear) +{ + fz_draw_device *dev = (fz_draw_device*)devp; + + dev->flags = (dev->flags | set ) & ~clear; +} + fz_device * fz_new_draw_device(fz_context *ctx, fz_pixmap *dest) { @@ -2073,6 +2083,8 @@ fz_new_draw_device(fz_context *ctx, fz_pixmap *dest) dev->super.begin_tile = fz_draw_begin_tile; dev->super.end_tile = fz_draw_end_tile; + dev->super.render_flags = fz_draw_render_flags; + dev->flags = 0; dev->top = 0; dev->stack = &dev->init_stack[0]; diff --git a/source/fitz/draw-imp.h b/source/fitz/draw-imp.h index 3a1ddbd2..8a750860 100644 --- a/source/fitz/draw-imp.h +++ b/source/fitz/draw-imp.h @@ -35,8 +35,8 @@ 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, const fz_irect *scissor, fz_pixmap *shape, fz_pixmap *img, const fz_matrix *ctm, int alpha, int lerp_allowed); -void fz_paint_image_with_color(fz_pixmap *dst, const fz_irect *scissor, fz_pixmap *shape, fz_pixmap *img, const fz_matrix *ctm, unsigned char *colorbv, int lerp_allowed); +void fz_paint_image(fz_pixmap *dst, const fz_irect *scissor, fz_pixmap *shape, fz_pixmap *img, const fz_matrix *ctm, int alpha, int lerp_allowed, int gridfit_as_tiled); +void fz_paint_image_with_color(fz_pixmap *dst, const fz_irect *scissor, fz_pixmap *shape, fz_pixmap *img, const fz_matrix *ctm, unsigned char *colorbv, int lerp_allowed, int gridfit_as_tiled); 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); diff --git a/source/fitz/list-device.c b/source/fitz/list-device.c index 038517b4..0a282018 100644 --- a/source/fitz/list-device.c +++ b/source/fitz/list-device.c @@ -28,7 +28,8 @@ typedef enum fz_display_command_e FZ_CMD_BEGIN_GROUP, FZ_CMD_END_GROUP, FZ_CMD_BEGIN_TILE, - FZ_CMD_END_TILE + FZ_CMD_END_TILE, + FZ_CMD_RENDER_FLAGS } fz_display_command; /* The display list is a list of nodes. @@ -1212,6 +1213,37 @@ fz_list_end_tile(fz_context *ctx, fz_device *dev) } static void +fz_list_render_flags(fz_context *ctx, fz_device *dev, int set, int clear) +{ + int flags; + + /* Pack the options down */ + if (set == FZ_DEVFLAG_GRIDFIT_AS_TILED && clear == 0) + flags = 1; + else if (set == 0 && clear == FZ_DEVFLAG_GRIDFIT_AS_TILED) + flags = 0; + else + { + assert("Unsupported flags combination" == NULL); + return; + } + fz_append_display_node( + ctx, + dev, + FZ_CMD_RENDER_FLAGS, + flags, /* flags */ + NULL, + NULL, /* path */ + NULL, /* color */ + NULL, /* colorspace */ + NULL, /* alpha */ + NULL, /* ctm */ + NULL, /* stroke */ + NULL, /* private_data */ + 0); /* private_data_len */ +} + +static void drop_writer(fz_context *ctx, fz_device *dev) { fz_list_device *writer = (fz_list_device *)dev; @@ -1257,6 +1289,8 @@ fz_new_list_device(fz_context *ctx, fz_display_list *list) dev->super.begin_tile = fz_list_begin_tile; dev->super.end_tile = fz_list_end_tile; + dev->super.render_flags = fz_list_render_flags; + dev->super.drop_imp = drop_writer; dev->list = list; @@ -1570,7 +1604,8 @@ fz_run_display_list(fz_context *ctx, fz_display_list *list, fz_device *dev, cons if (tiled || n.cmd == FZ_CMD_BEGIN_TILE || n.cmd == FZ_CMD_END_TILE || - n.cmd == FZ_CMD_BEGIN_PAGE || n.cmd == FZ_CMD_END_PAGE) + n.cmd == FZ_CMD_BEGIN_PAGE || n.cmd == FZ_CMD_END_PAGE || + n.cmd == FZ_CMD_RENDER_FLAGS) { empty = 0; } @@ -1700,6 +1735,12 @@ visible: tiled--; fz_end_tile(ctx, dev); break; + case FZ_CMD_RENDER_FLAGS: + if (n.flags == 0) + fz_render_flags(ctx, dev, 0, FZ_DEVFLAG_GRIDFIT_AS_TILED); + else if (n.flags == 1) + fz_render_flags(ctx, dev, FZ_DEVFLAG_GRIDFIT_AS_TILED, 0); + break; } } fz_catch(ctx) diff --git a/source/gprf/gprf-doc.c b/source/gprf/gprf-doc.c index bcd631ad..e9638340 100644 --- a/source/gprf/gprf-doc.c +++ b/source/gprf/gprf-doc.c @@ -596,6 +596,7 @@ gprf_run_page(fz_context *ctx, fz_page *page_, fz_device *dev, const fz_matrix * page_rect.y0 = 0; page_rect.x1 = 72.0 * page->width / doc->res; page_rect.y1 = 72.0 * page->height / doc->res; + fz_render_flags(ctx, dev, FZ_DEVFLAG_GRIDFIT_AS_TILED, 0); fz_begin_page(ctx, dev, &page_rect, ctm); i = 0; @@ -618,6 +619,7 @@ gprf_run_page(fz_context *ctx, fz_page *page_, fz_device *dev, const fz_matrix * } } fz_end_page(ctx, dev); + fz_render_flags(ctx, dev, 0, FZ_DEVFLAG_GRIDFIT_AS_TILED); } |