summaryrefslogtreecommitdiff
path: root/fitz
diff options
context:
space:
mode:
authorTor Andersson <tor@ghostscript.com>2010-07-17 01:41:20 +0000
committerTor Andersson <tor@ghostscript.com>2010-07-17 01:41:20 +0000
commit3ac42a2ad5c49724d4972bac4f729d1a2ed57423 (patch)
treecf685c23608d4d06df7b93f2391da97a012f8009 /fitz
parent2c79e6f2ccb72e8115aa51089f69be2560603016 (diff)
downloadmupdf-3ac42a2ad5c49724d4972bac4f729d1a2ed57423.tar.xz
Support SMasks for general graphics (incomplete).
Diffstat (limited to 'fitz')
-rw-r--r--fitz/dev_draw.c278
-rw-r--r--fitz/dev_trace.c7
-rw-r--r--fitz/fitz.h10
-rw-r--r--fitz/res_font.c2
-rw-r--r--fitz/res_pixmap.c38
5 files changed, 222 insertions, 113 deletions
diff --git a/fitz/dev_draw.c b/fitz/dev_draw.c
index 3148360e..5c2445ae 100644
--- a/fitz/dev_draw.c
+++ b/fitz/dev_draw.c
@@ -4,32 +4,27 @@
#define HSUBPIX 5.0
#define VSUBPIX 5.0
-#define MAXCLIP 64
+#define STACKSIZE 96
typedef struct fz_drawdevice_s fz_drawdevice;
struct fz_drawdevice_s
{
- fz_colorspace *model;
fz_glyphcache *cache;
fz_gel *gel;
fz_ael *ael;
- fz_pixmap *dest;
+ fz_pixmap *dest;
fz_bbox scissor;
- struct {
- fz_pixmap *dest;
- fz_pixmap *mask;
- fz_bbox scissor;
- } clipstack[MAXCLIP];
- int cliptop;
struct {
+ fz_bbox scissor;
fz_pixmap *dest;
+ fz_pixmap *mask;
fz_blendmode blendmode;
- fz_bbox scissor;
- } groupstack[MAXCLIP];
- int grouptop;
+ int luminosity;
+ } stack[STACKSIZE];
+ int top;
};
static void
@@ -84,6 +79,7 @@ fz_drawfillpath(void *user, fz_path *path, int evenodd, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
fz_drawdevice *dev = user;
+ fz_colorspace *model = dev->dest->colorspace;
float expansion = fz_matrixexpansion(ctm);
float flatness = 0.3f / expansion;
unsigned char colorbv[FZ_MAXCOLORS + 1];
@@ -101,10 +97,10 @@ fz_drawfillpath(void *user, fz_path *path, int evenodd, fz_matrix ctm,
if (fz_isemptyrect(bbox))
return;
- if (dev->model)
+ if (model)
{
- fz_convertcolor(colorspace, color, dev->model, colorfv);
- for (i = 0; i < dev->model->n; i++)
+ fz_convertcolor(colorspace, color, model, colorfv);
+ for (i = 0; i < model->n; i++)
colorbv[i] = colorfv[i] * 255;
colorbv[i] = alpha * 255;
fz_scanconvert(dev->gel, dev->ael, evenodd, bbox, dev->dest, colorbv, nil, nil);
@@ -120,6 +116,7 @@ fz_drawstrokepath(void *user, fz_path *path, fz_strokestate *stroke, fz_matrix c
fz_colorspace *colorspace, float *color, float alpha)
{
fz_drawdevice *dev = user;
+ fz_colorspace *model = dev->dest->colorspace;
float expansion = fz_matrixexpansion(ctm);
float flatness = 0.3f / expansion;
float linewidth = stroke->linewidth;
@@ -144,10 +141,10 @@ fz_drawstrokepath(void *user, fz_path *path, fz_strokestate *stroke, fz_matrix c
if (fz_isemptyrect(bbox))
return;
- if (dev->model)
+ if (model)
{
- fz_convertcolor(colorspace, color, dev->model, colorfv);
- for (i = 0; i < dev->model->n; i++)
+ fz_convertcolor(colorspace, color, model, colorfv);
+ for (i = 0; i < model->n; i++)
colorbv[i] = colorfv[i] * 255;
colorbv[i] = alpha * 255;
fz_scanconvert(dev->gel, dev->ael, 0, bbox, dev->dest, colorbv, nil, nil);
@@ -162,14 +159,15 @@ static void
fz_drawclippath(void *user, fz_path *path, int evenodd, fz_matrix ctm)
{
fz_drawdevice *dev = user;
+ fz_colorspace *model = dev->dest->colorspace;
float expansion = fz_matrixexpansion(ctm);
float flatness = 0.3f / expansion;
fz_pixmap *mask, *dest;
fz_bbox bbox;
- if (dev->cliptop == MAXCLIP)
+ if (dev->top == STACKSIZE)
{
- fz_warn("assert: too many clip masks on stack");
+ fz_warn("assert: too many buffers on stack");
return;
}
@@ -182,43 +180,44 @@ fz_drawclippath(void *user, fz_path *path, int evenodd, fz_matrix ctm)
if (fz_isemptyrect(bbox) || fz_isrectgel(dev->gel))
{
- dev->clipstack[dev->cliptop].scissor = dev->scissor;
- dev->clipstack[dev->cliptop].mask = nil;
- dev->clipstack[dev->cliptop].dest = nil;
+ dev->stack[dev->top].scissor = dev->scissor;
+ dev->stack[dev->top].mask = nil;
+ dev->stack[dev->top].dest = nil;
dev->scissor = bbox;
- dev->cliptop++;
+ dev->top++;
return;
}
mask = fz_newpixmapwithrect(nil, bbox);
- dest = fz_newpixmapwithrect(dev->model, bbox);
+ dest = fz_newpixmapwithrect(model, bbox);
fz_clearpixmap(mask, 0);
fz_clearpixmap(dest, 0);
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;
- dev->clipstack[dev->cliptop].dest = dev->dest;
+ dev->stack[dev->top].scissor = dev->scissor;
+ dev->stack[dev->top].mask = mask;
+ dev->stack[dev->top].dest = dev->dest;
dev->scissor = bbox;
dev->dest = dest;
- dev->cliptop++;
+ dev->top++;
}
static void
fz_drawclipstrokepath(void *user, fz_path *path, fz_strokestate *stroke, fz_matrix ctm)
{
fz_drawdevice *dev = user;
+ fz_colorspace *model = dev->dest->colorspace;
float expansion = fz_matrixexpansion(ctm);
float flatness = 0.3f / expansion;
float linewidth = stroke->linewidth;
fz_pixmap *mask, *dest;
fz_bbox bbox;
- if (dev->cliptop == MAXCLIP)
+ if (dev->top == STACKSIZE)
{
- fz_warn("assert: too many clip masks on stack");
+ fz_warn("assert: too many buffers on stack");
return;
}
@@ -236,7 +235,7 @@ fz_drawclipstrokepath(void *user, fz_path *path, fz_strokestate *stroke, fz_matr
bbox = fz_intersectbbox(bbox, dev->scissor);
mask = fz_newpixmapwithrect(nil, bbox);
- dest = fz_newpixmapwithrect(dev->model, bbox);
+ dest = fz_newpixmapwithrect(model, bbox);
fz_clearpixmap(mask, 0);
fz_clearpixmap(dest, 0);
@@ -244,12 +243,12 @@ fz_drawclipstrokepath(void *user, fz_path *path, fz_strokestate *stroke, fz_matr
if (!fz_isemptyrect(bbox))
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;
- dev->clipstack[dev->cliptop].dest = dev->dest;
+ dev->stack[dev->top].scissor = dev->scissor;
+ dev->stack[dev->top].mask = mask;
+ dev->stack[dev->top].dest = dev->dest;
dev->scissor = bbox;
dev->dest = dest;
- dev->cliptop++;
+ dev->top++;
}
static void
@@ -311,16 +310,17 @@ fz_drawfilltext(void *user, fz_text *text, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
fz_drawdevice *dev = user;
+ fz_colorspace *model = dev->dest->colorspace;
unsigned char colorbv[FZ_MAXCOLORS + 1];
float colorfv[FZ_MAXCOLORS];
fz_matrix tm, trm;
fz_pixmap *glyph;
int i, x, y, gid;
- if (dev->model)
+ if (model)
{
- fz_convertcolor(colorspace, color, dev->model, colorfv);
- for (i = 0; i < dev->model->n; i++)
+ fz_convertcolor(colorspace, color, model, colorfv);
+ for (i = 0; i < model->n; i++)
colorbv[i] = colorfv[i] * 255;
colorbv[i] = alpha * 255;
}
@@ -344,7 +344,7 @@ fz_drawfilltext(void *user, fz_text *text, fz_matrix ctm,
glyph = fz_renderglyph(dev->cache, text->font, gid, trm);
if (glyph)
{
- if (dev->model)
+ if (model)
drawglyph(colorbv, dev->dest, glyph, x, y, dev->scissor);
else
drawglyph(nil, dev->dest, glyph, x, y, dev->scissor);
@@ -358,16 +358,17 @@ fz_drawstroketext(void *user, fz_text *text, fz_strokestate *stroke, fz_matrix c
fz_colorspace *colorspace, float *color, float alpha)
{
fz_drawdevice *dev = user;
+ fz_colorspace *model = dev->dest->colorspace;
unsigned char colorbv[FZ_MAXCOLORS + 1];
float colorfv[FZ_MAXCOLORS];
fz_matrix tm, trm;
fz_pixmap *glyph;
int i, x, y, gid;
- if (dev->model)
+ if (model)
{
- fz_convertcolor(colorspace, color, dev->model, colorfv);
- for (i = 0; i < dev->model->n; i++)
+ fz_convertcolor(colorspace, color, model, colorfv);
+ for (i = 0; i < model->n; i++)
colorbv[i] = colorfv[i] * 255;
colorbv[i] = alpha * 255;
}
@@ -391,7 +392,7 @@ fz_drawstroketext(void *user, fz_text *text, fz_strokestate *stroke, fz_matrix c
glyph = fz_renderstrokedglyph(dev->cache, text->font, gid, trm, ctm, stroke);
if (glyph)
{
- if (dev->model)
+ if (model)
drawglyph(colorbv, dev->dest, glyph, x, y, dev->scissor);
else
drawglyph(nil, dev->dest, glyph, x, y, dev->scissor);
@@ -404,6 +405,7 @@ static void
fz_drawcliptext(void *user, fz_text *text, fz_matrix ctm, int accumulate)
{
fz_drawdevice *dev = user;
+ fz_colorspace *model = dev->dest->colorspace;
fz_bbox bbox;
fz_pixmap *mask, *dest;
fz_matrix tm, trm;
@@ -414,9 +416,9 @@ fz_drawcliptext(void *user, fz_text *text, fz_matrix ctm, int accumulate)
/* If accumulate == 1 then this text object is the first (or only) in a sequence */
/* If accumulate == 2 then this text object is a continuation */
- if (dev->cliptop == MAXCLIP)
+ if (dev->top == STACKSIZE)
{
- fz_warn("assert: too many clip masks on stack");
+ fz_warn("assert: too many buffers on stack");
return;
}
@@ -435,21 +437,21 @@ fz_drawcliptext(void *user, fz_text *text, fz_matrix ctm, int accumulate)
if (accumulate == 0 || accumulate == 1)
{
mask = fz_newpixmapwithrect(nil, bbox);
- dest = fz_newpixmapwithrect(dev->model, bbox);
+ dest = fz_newpixmapwithrect(model, bbox);
fz_clearpixmap(mask, 0);
fz_clearpixmap(dest, 0);
- dev->clipstack[dev->cliptop].scissor = dev->scissor;
- dev->clipstack[dev->cliptop].mask = mask;
- dev->clipstack[dev->cliptop].dest = dev->dest;
+ dev->stack[dev->top].scissor = dev->scissor;
+ dev->stack[dev->top].mask = mask;
+ dev->stack[dev->top].dest = dev->dest;
dev->scissor = bbox;
dev->dest = dest;
- dev->cliptop++;
+ dev->top++;
}
else
{
- mask = dev->clipstack[dev->cliptop-1].mask;
+ mask = dev->stack[dev->top-1].mask;
}
if (!fz_isemptyrect(bbox))
@@ -484,15 +486,16 @@ static void
fz_drawclipstroketext(void *user, fz_text *text, fz_strokestate *stroke, fz_matrix ctm)
{
fz_drawdevice *dev = user;
+ fz_colorspace *model = dev->dest->colorspace;
fz_bbox bbox;
fz_pixmap *mask, *dest;
fz_matrix tm, trm;
fz_pixmap *glyph;
int i, x, y, gid;
- if (dev->cliptop == MAXCLIP)
+ if (dev->top == STACKSIZE)
{
- fz_warn("assert: too many clip masks on stack");
+ fz_warn("assert: too many buffers on stack");
return;
}
@@ -501,17 +504,17 @@ fz_drawclipstroketext(void *user, fz_text *text, fz_strokestate *stroke, fz_matr
bbox = fz_intersectbbox(bbox, dev->scissor);
mask = fz_newpixmapwithrect(nil, bbox);
- dest = fz_newpixmapwithrect(dev->model, bbox);
+ dest = fz_newpixmapwithrect(model, bbox);
fz_clearpixmap(mask, 0);
fz_clearpixmap(dest, 0);
- dev->clipstack[dev->cliptop].scissor = dev->scissor;
- dev->clipstack[dev->cliptop].mask = mask;
- dev->clipstack[dev->cliptop].dest = dev->dest;
+ dev->stack[dev->top].scissor = dev->scissor;
+ dev->stack[dev->top].mask = mask;
+ dev->stack[dev->top].dest = dev->dest;
dev->scissor = bbox;
dev->dest = dest;
- dev->cliptop++;
+ dev->top++;
if (!fz_isemptyrect(bbox))
{
@@ -550,6 +553,7 @@ static void
fz_drawfillshade(void *user, fz_shade *shade, fz_matrix ctm)
{
fz_drawdevice *dev = user;
+ fz_colorspace *model = dev->dest->colorspace;
fz_pixmap *dest = dev->dest;
fz_rect bounds;
fz_bbox bbox;
@@ -569,7 +573,7 @@ fz_drawfillshade(void *user, fz_shade *shade, fz_matrix ctm)
if (fz_isemptyrect(bbox))
return;
- if (!dev->model)
+ if (!model)
{
fz_warn("cannot render shading directly to an alpha mask");
return;
@@ -579,8 +583,8 @@ fz_drawfillshade(void *user, fz_shade *shade, fz_matrix ctm)
{
unsigned char *s;
int x, y, n, i;
- fz_convertcolor(shade->cs, shade->background, dev->model, colorfv);
- for (i = 0; i < dev->model->n; i++)
+ fz_convertcolor(shade->cs, shade->background, model, colorfv);
+ for (i = 0; i < model->n; i++)
colorbv[i] = colorfv[i] * 255;
colorbv[i] = 255;
@@ -655,13 +659,14 @@ static void
fz_drawfillimage(void *user, fz_pixmap *image, fz_matrix ctm)
{
fz_drawdevice *dev = user;
+ fz_colorspace *model = dev->dest->colorspace;
fz_bbox bbox;
int dx, dy;
fz_pixmap *scaled = nil;
fz_pixmap *converted = nil;
fz_matrix invmat;
- if (!dev->model)
+ if (!model)
{
fz_warn("cannot render image directly to an alpha mask");
return;
@@ -678,9 +683,9 @@ fz_drawfillimage(void *user, fz_pixmap *image, fz_matrix ctm)
image = scaled;
}
- if (image->colorspace != dev->model)
+ if (image->colorspace != model)
{
- converted = fz_newpixmap(dev->model, image->x, image->y, image->w, image->h);
+ converted = fz_newpixmap(model, image->x, image->y, image->w, image->h);
fz_convertpixmap(image, converted);
image = converted;
}
@@ -698,6 +703,7 @@ fz_drawfillimagemask(void *user, fz_pixmap *image, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
fz_drawdevice *dev = user;
+ fz_colorspace *model = dev->dest->colorspace;
unsigned char colorbv[FZ_MAXCOLORS + 1];
float colorfv[FZ_MAXCOLORS];
fz_bbox bbox;
@@ -719,8 +725,8 @@ fz_drawfillimagemask(void *user, fz_pixmap *image, fz_matrix ctm,
if (dev->dest->colorspace)
{
- fz_convertcolor(colorspace, color, dev->model, colorfv);
- for (i = 0; i < dev->model->n; i++)
+ fz_convertcolor(colorspace, color, model, colorfv);
+ for (i = 0; i < model->n; i++)
colorbv[i] = colorfv[i] * 255;
colorbv[i] = alpha * 255;
fz_scanconvert(dev->gel, dev->ael, 0, bbox, dev->dest, colorbv, image, &invmat);
@@ -738,15 +744,16 @@ static void
fz_drawclipimagemask(void *user, fz_pixmap *image, fz_matrix ctm)
{
fz_drawdevice *dev = user;
+ fz_colorspace *model = dev->dest->colorspace;
fz_bbox bbox;
fz_pixmap *mask, *dest;
int dx, dy;
fz_pixmap *scaled = nil;
fz_matrix invmat;
- if (dev->cliptop == MAXCLIP)
+ if (dev->top == STACKSIZE)
{
- fz_warn("assert: too many clip masks on stack");
+ fz_warn("assert: too many buffers on stack");
return;
}
@@ -754,11 +761,11 @@ fz_drawclipimagemask(void *user, fz_pixmap *image, fz_matrix ctm)
if (fz_isemptyrect(bbox) || image->w == 0 || image->h == 0)
{
- dev->clipstack[dev->cliptop].scissor = dev->scissor;
- dev->clipstack[dev->cliptop].mask = nil;
- dev->clipstack[dev->cliptop].dest = nil;
+ dev->stack[dev->top].scissor = dev->scissor;
+ dev->stack[dev->top].mask = nil;
+ dev->stack[dev->top].dest = nil;
dev->scissor = bbox;
- dev->cliptop++;
+ dev->top++;
return;
}
@@ -769,19 +776,19 @@ fz_drawclipimagemask(void *user, fz_pixmap *image, fz_matrix ctm)
}
mask = fz_newpixmapwithrect(nil, bbox);
- dest = fz_newpixmapwithrect(dev->model, bbox);
+ dest = fz_newpixmapwithrect(model, bbox);
fz_clearpixmap(mask, 0);
fz_clearpixmap(dest, 0);
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;
- dev->clipstack[dev->cliptop].dest = dev->dest;
+ dev->stack[dev->top].scissor = dev->scissor;
+ dev->stack[dev->top].mask = mask;
+ dev->stack[dev->top].dest = dev->dest;
dev->scissor = bbox;
dev->dest = dest;
- dev->cliptop++;
+ dev->top++;
if (scaled)
fz_droppixmap(scaled);
@@ -792,12 +799,12 @@ fz_drawpopclip(void *user)
{
fz_drawdevice *dev = user;
fz_pixmap *mask, *dest;
- if (dev->cliptop > 0)
+ if (dev->top > 0)
{
- dev->cliptop--;
- dev->scissor = dev->clipstack[dev->cliptop].scissor;
- mask = dev->clipstack[dev->cliptop].mask;
- dest = dev->clipstack[dev->cliptop].dest;
+ dev->top--;
+ dev->scissor = dev->stack[dev->top].scissor;
+ mask = dev->stack[dev->top].mask;
+ dest = dev->stack[dev->top].dest;
if (mask && dest)
{
fz_pixmap *scratch = dev->dest;
@@ -812,38 +819,106 @@ fz_drawpopclip(void *user)
static void
fz_drawbeginmask(void *user, fz_rect rect, int luminosity, fz_colorspace *colorspace, float *colorfv)
{
+ fz_drawdevice *dev = user;
+ fz_pixmap *dest;
+ fz_bbox bbox;
+
fz_warn("fz_drawbeginmask");
+
+ if (dev->top == STACKSIZE)
+ {
+ fz_warn("assert: too many buffers on stack");
+ return;
+ }
+
+ bbox = fz_roundrect(rect);
+ bbox = fz_intersectbbox(bbox, dev->scissor);
+ dest = fz_newpixmapwithrect(pdf_devicegray, bbox);
+
+ if (luminosity)
+ fz_clearpixmap(dest, 255);
+ else
+ fz_clearpixmap(dest, 0);
+
+ dev->stack[dev->top].scissor = dev->scissor;
+ dev->stack[dev->top].dest = dev->dest;
+ dev->stack[dev->top].luminosity = luminosity;
+ dev->top++;
+
+ dev->scissor = bbox;
+ dev->dest = dest;
}
static void
fz_drawendmask(void *user)
{
+ fz_drawdevice *dev = user;
+ fz_pixmap *mask = dev->dest;
+ fz_pixmap *temp, *dest;
+ fz_bbox bbox;
+ int luminosity;
+
fz_warn("fz_drawendmask");
+
+ if (dev->top == STACKSIZE)
+ {
+ fz_warn("assert: too many buffers on stack");
+ return;
+ }
+
+ if (dev->top > 0)
+ {
+ /* pop soft mask buffer */
+ dev->top--;
+ luminosity = dev->stack[dev->top].luminosity;
+ dev->scissor = dev->stack[dev->top].scissor;
+ dev->dest = dev->stack[dev->top].dest;
+
+ /* convert to alpha mask */
+ temp = fz_alphafromgray(mask, luminosity);
+fz_writepng(mask, "softmask-1.png", 1);
+fz_writepng(temp, "softmask-2.png", 1);
+ fz_droppixmap(mask);
+
+ /* create new dest scratch buffer */
+ bbox = fz_boundpixmap(temp);
+ dest = fz_newpixmapwithrect(dev->dest->colorspace, bbox);
+ fz_clearpixmap(dest, 0);
+
+ /* push soft mask as clip mask */
+ dev->stack[dev->top].scissor = dev->scissor;
+ dev->stack[dev->top].mask = temp;
+ dev->stack[dev->top].dest = dev->dest;
+ dev->scissor = bbox;
+ dev->dest = dest;
+ dev->top++;
+ }
}
static void
fz_drawbegingroup(void *user, fz_rect rect, int isolated, int knockout, fz_blendmode blendmode)
{
fz_drawdevice *dev = user;
+ fz_colorspace *model = dev->dest->colorspace;
fz_bbox bbox;
fz_pixmap *dest;
- if (dev->cliptop == MAXCLIP)
+ if (dev->top == STACKSIZE)
{
- fz_warn("assert: too many clip masks on stack");
+ fz_warn("assert: too many buffers on stack");
return;
}
bbox = fz_roundrect(rect);
bbox = fz_intersectbbox(bbox, dev->scissor);
- dest = fz_newpixmapwithrect(dev->model, bbox);
+ dest = fz_newpixmapwithrect(model, bbox);
fz_clearpixmap(dest, 0);
- dev->groupstack[dev->grouptop].blendmode = blendmode;
- dev->groupstack[dev->grouptop].scissor = dev->scissor;
- dev->groupstack[dev->grouptop].dest = dev->dest;
- dev->grouptop++;
+ dev->stack[dev->top].blendmode = blendmode;
+ dev->stack[dev->top].scissor = dev->scissor;
+ dev->stack[dev->top].dest = dev->dest;
+ dev->top++;
dev->scissor = bbox;
dev->dest = dest;
@@ -856,24 +931,22 @@ fz_drawendgroup(void *user)
fz_pixmap *group = dev->dest;
fz_blendmode blendmode;
- if (dev->grouptop > 0)
+ if (dev->top > 0)
{
- dev->grouptop--;
- blendmode = dev->groupstack[dev->grouptop].blendmode;
- dev->dest = dev->groupstack[dev->grouptop].dest;
- dev->scissor = dev->groupstack[dev->grouptop].scissor;
+ dev->top--;
+ blendmode = dev->stack[dev->top].blendmode;
+ dev->dest = dev->stack[dev->top].dest;
+ dev->scissor = dev->stack[dev->top].scissor;
fz_blendpixmaps(group, dev->dest, blendmode);
+ fz_droppixmap(group);
}
-
- fz_droppixmap(group);
}
static void
fz_drawfreeuser(void *user)
{
fz_drawdevice *dev = user;
- if (dev->model)
- fz_dropcolorspace(dev->model);
+ /* TODO: pop and free the stacks */
fz_freegel(dev->gel);
fz_freeael(dev->ael);
fz_free(dev);
@@ -884,16 +957,11 @@ fz_newdrawdevice(fz_glyphcache *cache, fz_pixmap *dest)
{
fz_device *dev;
fz_drawdevice *ddev = fz_malloc(sizeof(fz_drawdevice));
- if (dest->colorspace)
- ddev->model = fz_keepcolorspace(dest->colorspace);
- else
- ddev->model = nil;
ddev->cache = cache;
ddev->gel = fz_newgel();
ddev->ael = fz_newael();
ddev->dest = dest;
- ddev->cliptop = 0;
- ddev->grouptop = 0;
+ ddev->top = 0;
ddev->scissor.x0 = dest->x;
ddev->scissor.y0 = dest->y;
diff --git a/fitz/dev_trace.c b/fitz/dev_trace.c
index 6941ec40..84aaff50 100644
--- a/fitz/dev_trace.c
+++ b/fitz/dev_trace.c
@@ -230,10 +230,11 @@ fz_tracepopclip(void *user)
static void
fz_tracebeginmask(void *user, fz_rect bbox, int luminosity, fz_colorspace *colorspace, float *color)
{
+ printf("<gsave>\n");
printf("<mask bbox=\"%g %g %g %g\" s=\"%s\" ",
bbox.x0, bbox.y0, bbox.x1, bbox.y1,
luminosity ? "luminosity" : "alpha");
- fz_tracecolor(colorspace, color, 1);
+// fz_tracecolor(colorspace, color, 1);
printf(">\n");
}
@@ -246,9 +247,9 @@ fz_traceendmask(void *user)
static void
fz_tracebegingroup(void *user, fz_rect bbox, int isolated, int knockout, fz_blendmode blendmode)
{
- printf("<group bbox=\"%g %g %g %g\" isolated=\"%d\" knockout=\"%d\" blendmode=\"%d\">\n",
+ printf("<group bbox=\"%g %g %g %g\" isolated=\"%d\" knockout=\"%d\" blendmode=\"%s\">\n",
bbox.x0, bbox.y0, bbox.x1, bbox.y1,
- isolated, knockout, blendmode);
+ isolated, knockout, fz_blendnames[blendmode]);
}
static void
diff --git a/fitz/fitz.h b/fitz/fitz.h
index 3d7c5cb8..215b9437 100644
--- a/fitz/fitz.h
+++ b/fitz/fitz.h
@@ -676,6 +676,8 @@ typedef enum fz_blendmode_e
FZ_BLUMINOSITY,
} fz_blendmode;
+extern const char *fz_blendnames[];
+
/*
* Pixmaps have n components per pixel. the last is always alpha.
* premultiplied alpha when rendering, but non-premultiplied for colorspace
@@ -695,10 +697,12 @@ struct fz_pixmap_s
fz_pixmap * fz_newpixmapwithrect(fz_colorspace *, fz_bbox bbox);
fz_pixmap * fz_newpixmap(fz_colorspace *, int x, int y, int w, int h);
-fz_pixmap *fz_keeppixmap(fz_pixmap *map);
-void fz_droppixmap(fz_pixmap *map);
-void fz_clearpixmap(fz_pixmap *map, unsigned char value);
+fz_pixmap *fz_keeppixmap(fz_pixmap *pix);
+void fz_droppixmap(fz_pixmap *pix);
+void fz_clearpixmap(fz_pixmap *pix, int value);
void fz_gammapixmap(fz_pixmap *pix, float gamma);
+fz_pixmap *fz_alphafromgray(fz_pixmap *gray, int luminosity);
+fz_bbox fz_boundpixmap(fz_pixmap *pix);
fz_pixmap * fz_scalepixmap(fz_pixmap *src, int xdenom, int ydenom);
diff --git a/fitz/res_font.c b/fitz/res_font.c
index 368c4919..8dc06902 100644
--- a/fitz/res_font.c
+++ b/fitz/res_font.c
@@ -472,7 +472,7 @@ fz_rendert3glyph(fz_font *font, int gid, fz_matrix trm)
fz_freedevice(dev);
glyph = fz_newpixmap(nil, bbox.x0-1, bbox.y0-1, bbox.x1 - bbox.x0 + 1, bbox.y1 - bbox.y0 + 1);
- fz_clearpixmap(glyph, 0x00);
+ fz_clearpixmap(glyph, 0);
cache = fz_newglyphcache();
dev = fz_newdrawdevice(cache, glyph);
diff --git a/fitz/res_pixmap.c b/fitz/res_pixmap.c
index e1184fff..4599fb0c 100644
--- a/fitz/res_pixmap.c
+++ b/fitz/res_pixmap.c
@@ -51,11 +51,22 @@ fz_droppixmap(fz_pixmap *pix)
}
void
-fz_clearpixmap(fz_pixmap *pix, unsigned char value)
+fz_clearpixmap(fz_pixmap *pix, int value)
{
memset(pix->samples, value, pix->w * pix->h * pix->n);
}
+fz_bbox
+fz_boundpixmap(fz_pixmap *pix)
+{
+ fz_bbox bbox;
+ bbox.x0 = pix->x;
+ bbox.y0 = pix->y;
+ bbox.x1 = pix->x + pix->w;
+ bbox.y1 = pix->y + pix->h;
+ return bbox;
+}
+
void
fz_gammapixmap(fz_pixmap *pix, float gamma)
{
@@ -72,6 +83,31 @@ fz_gammapixmap(fz_pixmap *pix, float gamma)
}
}
+fz_pixmap *
+fz_alphafromgray(fz_pixmap *gray, int luminosity)
+{
+ fz_pixmap *alpha;
+ unsigned char *sp, *dp;
+ int len;
+
+ assert(gray->n == 2);
+
+ alpha = fz_newpixmap(nil, gray->x, gray->y, gray->w, gray->h);
+ dp = alpha->samples;
+ sp = gray->samples;
+ if (!luminosity)
+ sp ++;
+
+ len = gray->w * gray->h;
+ while (len--)
+ {
+ *dp++ = sp[0];
+ sp += 2;
+ }
+
+ return alpha;
+}
+
/*
* Write pixmap to PNM file (without alpha channel)
*/