diff options
-rw-r--r-- | draw/draw_device.c | 32 | ||||
-rw-r--r-- | draw/draw_scale.c | 59 | ||||
-rw-r--r-- | fitz/fitz.h | 2 | ||||
-rw-r--r-- | fitz/res_font.c | 2 |
4 files changed, 88 insertions, 7 deletions
diff --git a/draw/draw_device.c b/draw/draw_device.c index 46a3fa2b..52393081 100644 --- a/draw/draw_device.c +++ b/draw/draw_device.c @@ -8,6 +8,10 @@ typedef struct fz_draw_device_s fz_draw_device; +enum { + FZ_DRAWDEV_FLAGS_TYPE3 = 1, +}; + struct fz_draw_device_s { fz_glyph_cache *cache; @@ -17,6 +21,7 @@ struct fz_draw_device_s fz_pixmap *shape; fz_bbox scissor; + int flags; int top; int blendmode; struct { @@ -737,14 +742,14 @@ fz_draw_fill_shade(void *user, fz_shade *shade, fz_matrix ctm, float alpha) } static fz_pixmap * -fz_transform_pixmap(fz_pixmap *image, fz_matrix *ctm, int x, int y, int dx, int dy) +fz_transform_pixmap(fz_pixmap *image, fz_matrix *ctm, int x, int y, int dx, int dy, int gridfit) { fz_pixmap *scaled; if (ctm->a != 0 && ctm->b == 0 && ctm->c == 0 && ctm->d != 0) { /* Unrotated or X flip or Yflip or XYflip */ - scaled = fz_scale_pixmap(image, ctm->e, ctm->f, ctm->a, ctm->d); + scaled = fz_scale_pixmap_gridfit(image, ctm->e, ctm->f, ctm->a, ctm->d, gridfit); if (scaled == NULL) return NULL; ctm->a = scaled->w; @@ -756,7 +761,7 @@ fz_transform_pixmap(fz_pixmap *image, fz_matrix *ctm, int x, int y, int dx, int if (ctm->a == 0 && ctm->b != 0 && ctm->c != 0 && ctm->d == 0) { /* Other orthogonal flip/rotation cases */ - scaled = fz_scale_pixmap(image, ctm->f, ctm->e, ctm->b, ctm->c); + scaled = fz_scale_pixmap_gridfit(image, ctm->f, ctm->e, ctm->b, ctm->c, gridfit); if (scaled == NULL) return NULL; ctm->b = scaled->w; @@ -815,7 +820,7 @@ fz_draw_fill_image(void *user, fz_pixmap *image, fz_matrix ctm, float alpha) dy = sqrtf(ctm.c * ctm.c + ctm.d * ctm.d); if (dx < image->w && dy < image->h) { - scaled = fz_transform_pixmap(image, &ctm, dev->dest->x, dev->dest->y, dx, dy); + scaled = fz_transform_pixmap(image, &ctm, dev->dest->x, dev->dest->y, dx, dy, (alpha == 1.0f) && ((dev->flags & FZ_DRAWDEV_FLAGS_TYPE3) == 0)); if (scaled == NULL) { if (dx < 1) @@ -876,7 +881,7 @@ fz_draw_fill_image_mask(void *user, fz_pixmap *image, fz_matrix ctm, dy = sqrtf(ctm.c * ctm.c + ctm.d * ctm.d); if (dx < image->w && dy < image->h) { - scaled = fz_transform_pixmap(image, &ctm, dev->dest->x, dev->dest->y, dx, dy); + scaled = fz_transform_pixmap(image, &ctm, dev->dest->x, dev->dest->y, dx, dy, (alpha == 1.0f) && ((dev->flags & FZ_DRAWDEV_FLAGS_TYPE3) == 0)); if (scaled == NULL) { if (dx < 1) @@ -951,7 +956,7 @@ fz_draw_clip_image_mask(void *user, fz_pixmap *image, fz_rect *rect, fz_matrix c dy = sqrtf(ctm.c * ctm.c + ctm.d * ctm.d); if (dx < image->w && dy < image->h) { - scaled = fz_transform_pixmap(image, &ctm, dev->dest->x, dev->dest->y, dx, dy); + scaled = fz_transform_pixmap(image, &ctm, dev->dest->x, dev->dest->y, dx, dy, (dev->flags & FZ_DRAWDEV_FLAGS_TYPE3) == 0); if (scaled == NULL) { if (dx < 1) @@ -1307,6 +1312,7 @@ fz_new_draw_device(fz_glyph_cache *cache, fz_pixmap *dest) ddev->shape = NULL; ddev->top = 0; ddev->blendmode = 0; + ddev->flags = 0; ddev->scissor.x0 = dest->x; ddev->scissor.y0 = dest->y; @@ -1344,3 +1350,17 @@ fz_new_draw_device(fz_glyph_cache *cache, fz_pixmap *dest) return dev; } + +fz_device * +fz_new_draw_device_type3(fz_glyph_cache *cache, fz_pixmap *dest) +{ + fz_device *dev = fz_new_draw_device(cache, dest); + + if (dev) + { + fz_draw_device *ddev = (fz_draw_device *)dev->user; + + ddev->flags |= FZ_DRAWDEV_FLAGS_TYPE3; + } + return dev; +} diff --git a/draw/draw_scale.c b/draw/draw_scale.c index 9b94702e..40a5deff 100644 --- a/draw/draw_scale.c +++ b/draw/draw_scale.c @@ -989,6 +989,65 @@ scale_single_col(unsigned char *dst, unsigned char *src, fz_weights *weights, in #endif /* SINGLE_PIXEL_SPECIALS */ fz_pixmap * +fz_scale_pixmap_gridfit(fz_pixmap *src, float x, float y, float w, float h, int gridfit) +{ + if (gridfit) { + float n; + if (w > 0) { + /* Adjust the left hand edge, leftwards to a pixel boundary */ + n = (float)(int)x; /* n is now on a pixel boundary */ + if (n > x) /* Ensure it's the pixel boundary BELOW x */ + n -= 1.0f; + w += x-n; /* width gets wider as x >= n */ + x = n; + /* Adjust the right hand edge rightwards to a pixel boundary */ + n = (float)(int)w; /* n is now the integer width <= w */ + if (n != w) /* If w isn't an integer already, bump it */ + w = 1.0f + n;/* up to the next integer. */ + } else { + /* Adjust the right hand edge, rightwards to a pixel boundary */ + n = (float)(int)x; /* n is now on a pixel boundary */ + if (n > x) /* Ensure it's the pixel boundary <= x */ + n -= 1.0f; + if (n != x) /* If x isn't on a pixel boundary already, */ + n += 1.0f; /* make n be the pixel boundary above x. */ + w -= n-x; /* Expand width (more negative!) as n >= x */ + x = n; + /* Adjust the left hand edge leftwards to a pixel boundary */ + n = (float)(int)w; + if (n != w) + w = n - 1.0f; + } + if (h > 0) { + /* Adjust the bottom edge, downwards to a pixel boundary */ + n = (float)(int)y; /* n is now on a pixel boundary */ + if (n > y) /* Ensure it's the pixel boundary BELOW y */ + n -= 1.0f; + h += y-n; /* height gets larger as y >= n */ + y = n; + /* Adjust the top edge upwards to a pixel boundary */ + n = (float)(int)h; /* n is now the integer height <= h */ + if (n != h) /* If h isn't an integer already, bump it */ + h = 1.0f + n;/* up to the next integer. */ + } else { + /* Adjust the top edge, upwards to a pixel boundary */ + n = (float)(int)y; /* n is now on a pixel boundary */ + if (n > y) /* Ensure it's the pixel boundary <= y */ + n -= 1.0f; + if (n != y) /* If y isn't on a pixel boundary already, */ + n += 1.0f; /* make n be the pixel boundary above y. */ + h -= n-y; /* Expand height (more negative!) as n >= y */ + y = n; + /* Adjust the bottom edge downwards to a pixel boundary */ + n = (float)(int)h; + if (n != h) + h = n - 1.0f; + } + } + return fz_scale_pixmap(src, x, y, w, h); +} + +fz_pixmap * fz_scale_pixmap(fz_pixmap *src, float x, float y, float w, float h) { fz_scale_filter *filter = &fz_scale_filter_simple; diff --git a/fitz/fitz.h b/fitz/fitz.h index 028c6325..7fe8b297 100644 --- a/fitz/fitz.h +++ b/fitz/fitz.h @@ -627,6 +627,7 @@ fz_pixmap *fz_alpha_from_gray(fz_pixmap *gray, int luminosity); fz_bbox fz_bound_pixmap(fz_pixmap *pix); fz_pixmap *fz_scale_pixmap(fz_pixmap *src, float x, float y, float w, float h); +fz_pixmap *fz_scale_pixmap_gridfit(fz_pixmap *src, float x, float y, float w, float h, int gridfit); fz_error fz_write_pnm(fz_pixmap *pixmap, char *filename); fz_error fz_write_pam(fz_pixmap *pixmap, char *filename, int savealpha); @@ -1010,6 +1011,7 @@ void fz_free_device(fz_device *dev); fz_device *fz_new_trace_device(void); fz_device *fz_new_bbox_device(fz_bbox *bboxp); fz_device *fz_new_draw_device(fz_glyph_cache *cache, fz_pixmap *dest); +fz_device *fz_new_draw_device_type3(fz_glyph_cache *cache, fz_pixmap *dest); /* * Text extraction device diff --git a/fitz/res_font.c b/fitz/res_font.c index 948b2bdd..e5027d5b 100644 --- a/fitz/res_font.c +++ b/fitz/res_font.c @@ -546,7 +546,7 @@ fz_render_t3_glyph(fz_font *font, int gid, fz_matrix trm) fz_clear_pixmap(glyph); cache = fz_new_glyph_cache(); - dev = fz_new_draw_device(cache, glyph); + dev = fz_new_draw_device_type3(cache, glyph); error = font->t3run(font->t3xref, font->t3resources, contents, dev, ctm); if (error) fz_catch(error, "cannot draw type3 glyph"); |