summaryrefslogtreecommitdiff
path: root/fitz/dev_draw.c
diff options
context:
space:
mode:
authorTor Andersson <tor@ghostscript.com>2010-05-20 23:49:12 +0200
committerTor Andersson <tor@ghostscript.com>2010-05-20 23:49:12 +0200
commit20191dcca2bde592da73db125193bb773c62f502 (patch)
treea11da9f79a120cbbfabe6e80605abe49a09a7b33 /fitz/dev_draw.c
parent30b8e3187fed0ad8f4c879cbe08fdd75f496e693 (diff)
downloadmupdf-20191dcca2bde592da73db125193bb773c62f502.tar.xz
Draw images with anti-aliased edges.
Diffstat (limited to 'fitz/dev_draw.c')
-rw-r--r--fitz/dev_draw.c197
1 files changed, 60 insertions, 137 deletions
diff --git a/fitz/dev_draw.c b/fitz/dev_draw.c
index cc7bdc0c..1b2b4ded 100644
--- a/fitz/dev_draw.c
+++ b/fitz/dev_draw.c
@@ -133,11 +133,11 @@ fz_drawfillpath(void *user, fz_path *path, int evenodd, fz_matrix ctm,
argb[1] = rgb[0] * 255;
argb[2] = rgb[1] * 255;
argb[3] = rgb[2] * 255;
- fz_scanconvert(dev->gel, dev->ael, evenodd, bbox, dev->dest, argb, 1);
+ fz_scanconvert(dev->gel, dev->ael, evenodd, bbox, dev->dest, argb, nil, nil);
}
else
{
- fz_scanconvert(dev->gel, dev->ael, evenodd, bbox, dev->dest, nil, 1);
+ fz_scanconvert(dev->gel, dev->ael, evenodd, bbox, dev->dest, nil, nil, nil);
}
}
@@ -176,11 +176,11 @@ fz_drawstrokepath(void *user, fz_path *path, fz_strokestate *stroke, fz_matrix c
argb[1] = rgb[0] * 255;
argb[2] = rgb[1] * 255;
argb[3] = rgb[2] * 255;
- fz_scanconvert(dev->gel, dev->ael, 0, bbox, dev->dest, argb, 1);
+ fz_scanconvert(dev->gel, dev->ael, 0, bbox, dev->dest, argb, nil, nil);
}
else
{
- fz_scanconvert(dev->gel, dev->ael, 0, bbox, dev->dest, nil, 1);
+ fz_scanconvert(dev->gel, dev->ael, 0, bbox, dev->dest, nil, nil, nil);
}
}
@@ -222,7 +222,7 @@ fz_drawclippath(void *user, fz_path *path, int evenodd, fz_matrix ctm)
memset(mask->samples, 0, mask->w * mask->h * mask->n);
memset(dest->samples, 0, dest->w * dest->h * dest->n);
- fz_scanconvert(dev->gel, dev->ael, evenodd, bbox, mask, nil, 1);
+ fz_scanconvert(dev->gel, dev->ael, evenodd, bbox, mask, nil, nil, nil);
dev->clipstack[dev->cliptop].scissor = dev->scissor;
dev->clipstack[dev->cliptop].mask = mask;
@@ -268,7 +268,7 @@ fz_drawclipstrokepath(void *user, fz_path *path, fz_strokestate *stroke, fz_matr
memset(dest->samples, 0, dest->w * dest->h * dest->n);
if (!fz_isemptyrect(bbox))
- fz_scanconvert(dev->gel, dev->ael, 0, bbox, mask, nil, 1);
+ fz_scanconvert(dev->gel, dev->ael, 0, bbox, mask, nil, nil, nil);
dev->clipstack[dev->cliptop].scissor = dev->scissor;
dev->clipstack[dev->cliptop].mask = mask;
@@ -515,49 +515,66 @@ fz_drawfillshade(void *user, fz_shade *shade, fz_matrix ctm)
}
static inline void
-calcimagescale(fz_matrix ctm, int w, int h, int *odx, int *ody)
+calcimagestate(fz_drawdevice *dev, fz_pixmap *image, fz_matrix ctm,
+ fz_bbox *bbox, fz_matrix *invmat, int *dx, int *dy)
{
- float sx = w / sqrt(ctm.a * ctm.a + ctm.b * ctm.b);
- float sy = h / sqrt(ctm.c * ctm.c + ctm.d * ctm.d);
+ float sx, sy;
+ fz_path *path;
+ fz_matrix mat;
+ int w, h;
+
+ sx = image->w / sqrt(ctm.a * ctm.a + ctm.b * ctm.b);
+ sy = image->h / sqrt(ctm.c * ctm.c + ctm.d * ctm.d);
if (sx < 1.0)
- *odx = 1;
+ *dx = 1;
else
- *odx = sx;
+ *dx = sx;
if (sy < 1.0)
- *ody = 1;
+ *dy = 1;
else
- *ody = sy;
-}
+ *dy = sy;
+
+ w = image->w / *dx;
+ h = image->h / *dy;
+
+ path = fz_newpath();
+ fz_moveto(path, 0.0, 0.0);
+ fz_lineto(path, 1.0, 0.0);
+ fz_lineto(path, 1.0, 1.0);
+ fz_lineto(path, 0.0, 1.0);
+ fz_closepath(path);
-#define PDST(p) p->samples + ((y0-p->y) * p->w + (x0-p->x)) * p->n, p->w * p->n
+ fz_resetgel(dev->gel, dev->scissor);
+ fz_fillpath(dev->gel, path, ctm, 1.0);
+ fz_sortgel(dev->gel);
+
+ fz_freepath(path);
+
+ *bbox = fz_boundgel(dev->gel);
+ *bbox = fz_intersectbbox(*bbox, dev->scissor);
+
+ mat.a = 1.0 / w;
+ mat.b = 0.0;
+ mat.c = 0.0;
+ mat.d = -1.0 / h;
+ mat.e = 0.0;
+ mat.f = 1.0;
+ *invmat = fz_invertmatrix(fz_concat(mat, ctm));
+ invmat->e -= 0.5;
+ invmat->f -= 0.5;
+}
static void
fz_drawfillimage(void *user, fz_pixmap *image, fz_matrix ctm)
{
fz_drawdevice *dev = user;
- fz_rect bounds;
fz_bbox bbox;
int dx, dy;
fz_pixmap *scaled = nil;
fz_pixmap *converted = nil;
- fz_matrix imgmat;
fz_matrix invmat;
- int fa, fb, fc, fd;
- int u0, v0;
- int x0, y0;
- int w, h;
-
- bounds = fz_transformrect(ctm, fz_unitrect);
- bbox = fz_roundrect(bounds);
- bbox = fz_intersectbbox(bbox, dev->scissor);
-
- if (fz_isemptyrect(bbox))
- return;
-
- if (image->w == 0 || image->h == 0)
- return;
if (!dev->model)
{
@@ -565,7 +582,10 @@ fz_drawfillimage(void *user, fz_pixmap *image, fz_matrix ctm)
return;
}
- calcimagescale(ctm, image->w, image->h, &dx, &dy);
+ calcimagestate(dev, image, ctm, &bbox, &invmat, &dx, &dy);
+
+ if (fz_isemptyrect(bbox) || image->w == 0 || image->h == 0)
+ return;
if (dx != 1 || dy != 1)
{
@@ -580,34 +600,7 @@ fz_drawfillimage(void *user, fz_pixmap *image, fz_matrix ctm)
image = converted;
}
- imgmat.a = 1.0 / image->w;
- imgmat.b = 0.0;
- imgmat.c = 0.0;
- imgmat.d = -1.0 / image->h;
- imgmat.e = 0.0;
- imgmat.f = 1.0;
- invmat = fz_invertmatrix(fz_concat(imgmat, ctm));
-
- invmat.e -= 0.5;
- invmat.f -= 0.5;
-
- w = bbox.x1 - bbox.x0;
- h = bbox.y1 - bbox.y0;
- x0 = bbox.x0;
- y0 = bbox.y0;
- u0 = (invmat.a * (x0+0.5) + invmat.c * (y0+0.5) + invmat.e) * 65536;
- v0 = (invmat.b * (x0+0.5) + invmat.d * (y0+0.5) + invmat.f) * 65536;
- fa = invmat.a * 65536;
- fb = invmat.b * 65536;
- fc = invmat.c * 65536;
- fd = invmat.d * 65536;
-
- if (dev->dest->colorspace)
- fz_img_4o4(image->samples, image->w, image->h, PDST(dev->dest),
- u0, v0, fa, fb, fc, fd, w, h);
- else
- fz_img_1o1(image->samples, image->w, image->h, PDST(dev->dest),
- u0, v0, fa, fb, fc, fd, w, h);
+ fz_scanconvert(dev->gel, dev->ael, 0, bbox, dev->dest, nil, image, &invmat);
if (scaled)
fz_droppixmap(scaled);
@@ -620,57 +613,22 @@ fz_drawfillimagemask(void *user, fz_pixmap *image, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
fz_drawdevice *dev = user;
- fz_rect bounds;
fz_bbox bbox;
int dx, dy;
fz_pixmap *scaled = nil;
- fz_matrix imgmat;
fz_matrix invmat;
- int fa, fb, fc, fd;
- int u0, v0;
- int x0, y0;
- int w, h;
- bounds = fz_transformrect(ctm, fz_unitrect);
- bbox = fz_roundrect(bounds);
- bbox = fz_intersectbbox(bbox, dev->scissor);
+ calcimagestate(dev, image, ctm, &bbox, &invmat, &dx, &dy);
- if (fz_isemptyrect(bbox))
+ if (fz_isemptyrect(bbox) || image->w == 0 || image->h == 0)
return;
- if (image->w == 0 || image->h == 0)
- return;
-
- calcimagescale(ctm, image->w, image->h, &dx, &dy);
-
if (dx != 1 || dy != 1)
{
scaled = fz_scalepixmap(image, dx, dy);
image = scaled;
}
- imgmat.a = 1.0 / image->w;
- imgmat.b = 0.0;
- imgmat.c = 0.0;
- imgmat.d = -1.0 / image->h;
- imgmat.e = 0.0;
- imgmat.f = 1.0;
- invmat = fz_invertmatrix(fz_concat(imgmat, ctm));
-
- invmat.e -= 0.5;
- invmat.f -= 0.5;
-
- w = bbox.x1 - bbox.x0;
- h = bbox.y1 - bbox.y0;
- x0 = bbox.x0;
- y0 = bbox.y0;
- u0 = (invmat.a * (x0+0.5) + invmat.c * (y0+0.5) + invmat.e) * 65536;
- v0 = (invmat.b * (x0+0.5) + invmat.d * (y0+0.5) + invmat.f) * 65536;
- fa = invmat.a * 65536;
- fb = invmat.b * 65536;
- fc = invmat.c * 65536;
- fd = invmat.d * 65536;
-
if (dev->dest->colorspace)
{
unsigned char argb[4];
@@ -680,13 +638,11 @@ fz_drawfillimagemask(void *user, fz_pixmap *image, fz_matrix ctm,
argb[1] = rgb[0] * 255;
argb[2] = rgb[1] * 255;
argb[3] = rgb[2] * 255;
- fz_img_w4i1o4(argb, image->samples, image->w, image->h, PDST(dev->dest),
- u0, v0, fa, fb, fc, fd, w, h);
+ fz_scanconvert(dev->gel, dev->ael, 0, bbox, dev->dest, argb, image, &invmat);
}
else
{
- fz_img_1o1(image->samples, image->w, image->h, PDST(dev->dest),
- u0, v0, fa, fb, fc, fd, w, h);
+ fz_scanconvert(dev->gel, dev->ael, 0, bbox, dev->dest, nil, image, &invmat);
}
if (scaled)
@@ -697,17 +653,11 @@ static void
fz_drawclipimagemask(void *user, fz_pixmap *image, fz_matrix ctm)
{
fz_drawdevice *dev = user;
- fz_rect bounds;
fz_bbox bbox;
fz_pixmap *mask, *dest;
int dx, dy;
fz_pixmap *scaled = nil;
- fz_matrix imgmat;
fz_matrix invmat;
- int fa, fb, fc, fd;
- int u0, v0;
- int x0, y0;
- int w, h;
if (dev->cliptop == MAXCLIP)
{
@@ -715,11 +665,9 @@ fz_drawclipimagemask(void *user, fz_pixmap *image, fz_matrix ctm)
return;
}
- bounds = fz_transformrect(ctm, fz_unitrect);
- bbox = fz_roundrect(bounds);
- bbox = fz_intersectbbox(bbox, dev->scissor);
+ calcimagestate(dev, image, ctm, &bbox, &invmat, &dx, &dy);
- if (fz_isemptyrect(bbox) || (image->w == 0 || image->h == 0))
+ if (fz_isemptyrect(bbox) || image->w == 0 || image->h == 0)
{
dev->clipstack[dev->cliptop].scissor = dev->scissor;
dev->clipstack[dev->cliptop].mask = nil;
@@ -729,44 +677,19 @@ fz_drawclipimagemask(void *user, fz_pixmap *image, fz_matrix ctm)
return;
}
- calcimagescale(ctm, image->w, image->h, &dx, &dy);
-
if (dx != 1 || dy != 1)
{
scaled = fz_scalepixmap(image, dx, dy);
image = scaled;
}
- imgmat.a = 1.0 / image->w;
- imgmat.b = 0.0;
- imgmat.c = 0.0;
- imgmat.d = -1.0 / image->h;
- imgmat.e = 0.0;
- imgmat.f = 1.0;
- invmat = fz_invertmatrix(fz_concat(imgmat, ctm));
-
- invmat.e -= 0.5;
- invmat.f -= 0.5;
-
- w = bbox.x1 - bbox.x0;
- h = bbox.y1 - bbox.y0;
- x0 = bbox.x0;
- y0 = bbox.y0;
- u0 = (invmat.a * (x0+0.5) + invmat.c * (y0+0.5) + invmat.e) * 65536;
- v0 = (invmat.b * (x0+0.5) + invmat.d * (y0+0.5) + invmat.f) * 65536;
- fa = invmat.a * 65536;
- fb = invmat.b * 65536;
- fc = invmat.c * 65536;
- fd = invmat.d * 65536;
-
mask = fz_newpixmapwithrect(nil, bbox);
dest = fz_newpixmapwithrect(dev->model, bbox);
memset(mask->samples, 0, mask->w * mask->h * mask->n);
memset(dest->samples, 0, dest->w * dest->h * dest->n);
- fz_img_1o1(image->samples, image->w, image->h, PDST(mask),
- u0, v0, fa, fb, fc, fd, w, h);
+ fz_scanconvert(dev->gel, dev->ael, 0, bbox, mask, nil, image, &invmat);
dev->clipstack[dev->cliptop].scissor = dev->scissor;
dev->clipstack[dev->cliptop].mask = mask;