summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--draw/draw_device.c32
-rw-r--r--draw/draw_scale.c59
-rw-r--r--fitz/fitz.h2
-rw-r--r--fitz/res_font.c2
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");