summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Jamfile1
-rw-r--r--include/fitz/pixmap.h7
-rw-r--r--include/fitz/scanconv.h3
-rw-r--r--mupdf/interpret.c3
-rw-r--r--mupdf/nametree.c3
-rw-r--r--render/fill.c9
-rw-r--r--render/pixmap.c118
-rw-r--r--render/render.c421
-rw-r--r--render/scanconv.c49
-rw-r--r--test/pdfrip.c30
-rw-r--r--tree/debug.c6
11 files changed, 427 insertions, 223 deletions
diff --git a/Jamfile b/Jamfile
index 4adafe43..d7f69831 100644
--- a/Jamfile
+++ b/Jamfile
@@ -95,6 +95,7 @@ Library libmupdf :
mupdf/stream.c
mupdf/doctor.c
+ mupdf/nametree.c
mupdf/cmap.c
mupdf/font.c
mupdf/fontfile.c
diff --git a/include/fitz/pixmap.h b/include/fitz/pixmap.h
index f46c2c05..462b4ad6 100644
--- a/include/fitz/pixmap.h
+++ b/include/fitz/pixmap.h
@@ -3,7 +3,6 @@ typedef struct fz_colorspace_s fz_colorspace;
struct fz_pixmap_s
{
- int refcount;
int x, y, w, h;
int n, a;
int stride;
@@ -12,10 +11,10 @@ struct fz_pixmap_s
};
fz_error *fz_newpixmap(fz_pixmap **mapp, int x, int y, int w, int h, int n, int a);
-fz_pixmap *fz_keeppixmap(fz_pixmap *map);
-void fz_droppixmap(fz_pixmap *map);
+void fz_debugpixmap(fz_pixmap *map);
+void fz_freepixmap(fz_pixmap *map);
void fz_clearpixmap(fz_pixmap *map);
-void fz_blendover(fz_pixmap *dst, fz_pixmap *fg, fz_pixmap *bg);
+void fz_blendover(fz_pixmap *src, fz_pixmap *dst);
void fz_blendmask(fz_pixmap *dst, fz_pixmap *color, fz_pixmap *shape);
diff --git a/include/fitz/scanconv.h b/include/fitz/scanconv.h
index 0e073127..a3c29473 100644
--- a/include/fitz/scanconv.h
+++ b/include/fitz/scanconv.h
@@ -38,7 +38,8 @@ fz_error *fz_insertael(fz_ael *ael, fz_gel *gel, int y, int *e);
void fz_advanceael(fz_ael *ael);
void fz_freeael(fz_ael *ael);
-fz_error *fz_scanconvert(fz_gel *gel, fz_ael *ael, int eofill);
+fz_error *fz_scanconvert(fz_gel *gel, fz_ael *ael, int eofill,
+ void (*blitfunc)(int,int,int,short*,void*), void *blitdata);
fz_error *fz_fillpath(fz_gel *gel, fz_pathnode *path, fz_matrix ctm, float flatness);
fz_error *fz_strokepath(fz_gel *gel, fz_pathnode *path, fz_matrix ctm, float flatness);
diff --git a/mupdf/interpret.c b/mupdf/interpret.c
index 57d02f06..ab3b1ea5 100644
--- a/mupdf/interpret.c
+++ b/mupdf/interpret.c
@@ -50,6 +50,9 @@ pdf_newcsi(pdf_csi **csip)
csi->tree->root = node;
csi->gstate[0].head = node;
+ error = fz_newcolornode(&node, 1, 1, 1);
+ fz_insertnode(csi->tree->root, node);
+
csi->clip = nil;
csi->text = nil;
diff --git a/mupdf/nametree.c b/mupdf/nametree.c
index 73cb5553..d8179cd7 100644
--- a/mupdf/nametree.c
+++ b/mupdf/nametree.c
@@ -164,12 +164,11 @@ pdf_loadnametree(pdf_nametree **pnt, pdf_xref *xref, char* key)
fz_obj *trailer;
fz_obj *ref;
fz_obj *root = nil;
- int count;
trailer = xref->trailer;
ref = fz_dictgets(trailer, "Root");
- error = pdf_loadobject(&catalog, xref, ref, nil);
+ error = pdf_loadindirect(&catalog, xref, ref);
if (error) goto cleanup;
names = fz_dictgets(catalog, "Names");
diff --git a/render/fill.c b/render/fill.c
index fdb12205..d25f78b1 100644
--- a/render/fill.c
+++ b/render/fill.c
@@ -114,10 +114,19 @@ fz_fillpath(fz_gel *gel, fz_pathnode *path, fz_matrix ctm, float flatness)
error = line(gel, &ctm, cx, cy, bx, by);
if (error)
return error;
+ cx = bx;
+ cy = by;
break;
}
}
+ if (i && (cx != bx || cy != by))
+ {
+ error = line(gel, &ctm, cx, cy, bx, by);
+ if (error)
+ return error;
+ }
+
return nil;
}
diff --git a/render/pixmap.c b/render/pixmap.c
index ac99de80..0902c901 100644
--- a/render/pixmap.c
+++ b/render/pixmap.c
@@ -29,22 +29,11 @@ fz_newpixmap(fz_pixmap **pixp, int x, int y, int w, int h, int n, int a)
return nil;
}
-fz_pixmap *
-fz_keeppixmap(fz_pixmap *pix)
-{
- pix->refcount ++;
- return pix;
-}
-
void
-fz_droppixmap(fz_pixmap *pix)
+fz_freepixmap(fz_pixmap *pix)
{
- pix->refcount --;
- if (pix->refcount == 0)
- {
- fz_free(pix->samples);
- fz_free(pix);
- }
+ fz_free(pix->samples);
+ fz_free(pix);
}
void
@@ -57,76 +46,93 @@ void
fz_debugpixmap(fz_pixmap *pix)
{
int x, y;
- assert(pix->n == 3 && pix->a == 1);
+
FILE *f = fopen("out.ppm", "w");
- fprintf(f, "P6\n%d %d\n255\n", pix->w, pix->h);
- for (y = 0; y < pix->h; y++)
- for (x = 0; x < pix->w; x++)
- {
- int r = (pix->samples[x * 4 + y * pix->stride + 0] * 255) >> 14;
- int g = (pix->samples[x * 4 + y * pix->stride + 1] * 255) >> 14;
- int b = (pix->samples[x * 4 + y * pix->stride + 2] * 255) >> 14;
- putc(r, f);
- putc(g, f);
- putc(b, f);
- }
+
+ if (pix->n == 3 && pix->a == 1)
+ {
+ fprintf(f, "P6\n%d %d\n255\n", pix->w, pix->h);
+ for (y = 0; y < pix->h; y++)
+ for (x = 0; x < pix->w; x++)
+ {
+ int r = (pix->samples[x * 4 + y * pix->stride + 0] * 255) >> 14;
+ int g = (pix->samples[x * 4 + y * pix->stride + 1] * 255) >> 14;
+ int b = (pix->samples[x * 4 + y * pix->stride + 2] * 255) >> 14;
+ int a = (pix->samples[x * 4 + y * pix->stride + 3] * 255) >> 14;
+ putc(((r * a) / 255) + (255 - a), f);
+ putc(((g * a) / 255) + (255 - a), f);
+ putc(((b * a) / 255) + (255 - a), f);
+ // putc(a, f);
+ // putc(a, f);
+ // putc(a, f);
+ }
+ }
+ else if (pix->n == 0 && pix->a == 1)
+ {
+ fprintf(f, "P5\n%d %d\n255\n", pix->w, pix->h);
+ for (y = 0; y < pix->h; y++)
+ for (x = 0; x < pix->w; x++)
+ {
+ int a = (pix->samples[x + y * pix->stride] * 255) >> 14;
+ putc(a, f);
+ }
+ }
fclose(f);
}
void
-fz_blendover(fz_pixmap *dst, fz_pixmap *fg, fz_pixmap *bg)
+fz_blendover(fz_pixmap *src, fz_pixmap *dst)
{
- int x, y;
-
-printf("dst=%d,%d fg=%d,%d bg=%d,%d\n",
-dst->n, dst->a,
-fg->n, fg->a,
-bg->n, bg->a);
+ int x, y, k;
- assert(fg->n == bg->n);
- assert(fg->n == 3);
- assert(fg->a == 1);
- assert(bg->a == 1);
+ assert(dst->n == src->n);
+ assert(dst->a == 1);
+ assert(src->n == 3);
+ assert(src->a == 1);
for (y = 0; y < dst->h; y++)
{
- short *bgp = &fg->samples[y * fg->stride];
- short *fgp = &bg->samples[y * bg->stride];
- short *dstp = &dst->samples[y * dst->stride];
+ short *s = &src->samples[y * src->stride];
+ short *d = &dst->samples[y * dst->stride];
+
for (x = 0; x < dst->w; x++)
{
- dstp[0] = ((fgp[3] * (fgp[0] - bgp[0])) >> 14) + bgp[0];
- dstp[1] = ((fgp[3] * (fgp[1] - bgp[1])) >> 14) + bgp[1];
- dstp[2] = ((fgp[3] * (fgp[2] - bgp[2])) >> 14) + bgp[2];
- dstp[3] = ((fgp[3] * (fgp[3] - bgp[3])) >> 14) + bgp[3];
- dstp += 4;
- fgp += 4;
- bgp += 4;
+ int sa = s[3];
+ int ssa = (1 << 14) - sa;
+
+ d[0] = ((s[0] * sa) >> 14) + ((d[0] * ssa) >> 14);
+ d[1] = ((s[1] * sa) >> 14) + ((d[1] * ssa) >> 14);
+ d[2] = ((s[2] * sa) >> 14) + ((d[2] * ssa) >> 14);
+ d[3] = sa + ((ssa * d[3]) >> 14);
+
+ s += 4;
+ d += 4;
}
}
}
void
-fz_blendmask(fz_pixmap *dst, fz_pixmap *src, fz_pixmap *mask)
+fz_blendmask(fz_pixmap *dst, fz_pixmap *src, fz_pixmap *msk)
{
int x, y, k;
assert(src->n == dst->n);
- assert(src->a == 0);
- assert(mask->n == 0);
- assert(mask->a == 1);
+ assert(src->a == 1);
+ assert(msk->n == 0);
+ assert(msk->a == 1);
assert(dst->a == 1);
for (y = 0; y < dst->h; y++)
{
- short *dstp = &dst->samples[y * dst->stride];
- short *srcp = &src->samples[y * src->stride];
- short *mskp = &mask->samples[y * mask->stride];
+ short *d = &dst->samples[y * dst->stride];
+ short *s = &src->samples[y * src->stride];
+ short *m = &msk->samples[y * msk->stride];
+
for (x = 0; x < dst->w; x++)
{
for (k = 0; k < dst->n; k++)
- *dstp++ = *srcp++;
- *dstp++ = *mskp++;
+ *d++ = *s++;
+ *d++ = (*m++ * *s++) >> 14;
}
}
}
diff --git a/render/render.c b/render/render.c
index d7359d90..1e152410 100644
--- a/render/render.c
+++ b/render/render.c
@@ -11,6 +11,7 @@ struct fz_renderer_s
int x, y, w, h;
fz_pixmap *tmp;
fz_pixmap *acc;
+ short r, g, b;
};
fz_error *
@@ -66,119 +67,40 @@ fz_freerenderer(fz_renderer *gc)
if (gc->ael)
fz_freeael(gc->ael);
if (gc->tmp)
- fz_droppixmap(gc->tmp);
+ fz_freepixmap(gc->tmp);
if (gc->acc)
- fz_droppixmap(gc->acc);
+ fz_freepixmap(gc->acc);
fz_free(gc);
}
-fz_error *
-fz_renderover(fz_renderer *gc, fz_overnode *over, fz_matrix ctm)
+static void blitglyph(fz_pixmap *out, fz_glyph *gl, int xo, int yo)
{
- fz_error *error;
- fz_node *node;
- int oldmode;
-
- oldmode = gc->mode;
- gc->mode = OVER;
-
-printf("renderover ; acc=3,1\n");
-
- error = fz_newpixmap(&gc->acc, gc->x, gc->y, gc->w, gc->h, 3, 1);
- if (error)
- return error;
-
- fz_clearpixmap(gc->acc);
+ int sx, sy, dx, dy, a, b, c;
- for (node = over->super.child; node; node = node->next)
+ for (sy = 0; sy < gl->h; sy++)
{
- gc->tmp = nil;
- error = fz_rendernode(gc, node, ctm);
- if (error)
- return error;
- if (gc->tmp)
+ for (sx = 0; sx < gl->w; sx++)
{
-printf(" over -> %d,%d\n", gc->tmp->n, gc->tmp->a);
- fz_blendover(gc->acc, gc->tmp, gc->acc);
- fz_droppixmap(gc->tmp);
- }
-else printf(" -> nil\n");
- }
-
- gc->tmp = gc->acc;
- gc->acc = nil;
-
- gc->mode = oldmode;
-
- return nil;
-}
-
-fz_error *
-fz_rendermask(fz_renderer *gc, fz_masknode *mask, fz_matrix ctm)
-{
- fz_error *error;
- fz_pixmap *colorpix;
- fz_pixmap *shapepix;
- fz_node *color;
- fz_node *shape;
- int oldmode;
-
- color = mask->super.child;
- shape = color->next;
-
-// if (fz_ispathnode(shape) && fz_iscolornode(color))
-// return rcolorpath(gc, shape, color, ctm);
-// if (fz_istextnode(shape) && fz_iscolornode(color))
-// return rcolortext(gc, shape, color, ctm);
-
- oldmode = gc->mode;
- gc->mode = MASK;
-
-printf("rendermask\n");
-
- gc->tmp = nil;
- error = fz_rendernode(gc, color, ctm);
- if (error)
- return error;
- colorpix = gc->tmp;
-
-printf(" -> color %d,%d\n", colorpix->n, colorpix->a);
-
- gc->tmp = nil;
- error = fz_rendernode(gc, shape, ctm);
- if (error)
- return error;
- shapepix = gc->tmp;
-
-printf(" -> shape %d,%d\n", shapepix->n, shapepix->a);
-
- error = fz_newpixmap(&gc->tmp, gc->x, gc->y, gc->w, gc->h, colorpix->n, 1);
- if (error)
- return error;
-
-printf(" -> blend %d,%d\n", gc->tmp->n, gc->tmp->a);
-
- fz_blendmask(gc->tmp, colorpix, shapepix);
-
- fz_droppixmap(shapepix);
- fz_droppixmap(colorpix);
-
- gc->mode = oldmode;
+ dx = xo + sx + gl->lsb - out->x;
+ dy = yo - sy + gl->top - out->y;
- return nil;
-}
+ if (dx < 0) continue;
+ if (dy < 0) continue;
+ if (dx >= out->w) continue;
+ if (dy >= out->h) continue;
-fz_error *
-fz_rendertransform(fz_renderer *gc, fz_transformnode *transform, fz_matrix ctm)
-{
-printf("rendertransform\n");
- ctm = fz_concat(ctm, transform->m);
- return fz_rendernode(gc, transform->super.child, ctm);
+ a = gl->bitmap[sx + sy * gl->w] * 64;
+ b = out->samples[dx + dy * out->stride];
+ c = MAX(a, b);
+ out->samples[dx + dy * out->stride] = c;
+ }
+ }
}
-static void blitglyph(fz_pixmap *out, fz_glyph *gl, int xo, int yo)
+static void blitcolorglyph(fz_pixmap *out, fz_glyph *gl, int xo, int yo, short r, short g, short b)
{
- int sx, sy, dx, dy, a, b, c;
+ int sx, sy, dx, dy, sa, ssa;
+ short *p;
for (sy = 0; sy < gl->h; sy++)
{
@@ -192,10 +114,14 @@ static void blitglyph(fz_pixmap *out, fz_glyph *gl, int xo, int yo)
if (dx >= out->w) continue;
if (dy >= out->h) continue;
- a = gl->bitmap[sx + sy * gl->w];
- b = out->samples[dx + dy * out->stride];
- c = MAX(a, b);
- out->samples[dx + dy * out->stride] = c;
+ sa = gl->bitmap[sx + sy * gl->w] * 64;
+ ssa = (1 << 14) - sa;
+
+ p = out->samples + dx * 4 + dy * out->stride;
+ p[0] = ((r * sa) >> 14) + ((p[0] * ssa) >> 14);
+ p[1] = ((g * sa) >> 14) + ((p[1] * ssa) >> 14);
+ p[2] = ((b * sa) >> 14) + ((p[2] * ssa) >> 14);
+ p[3] = sa + ((ssa * p[3]) >> 14);
}
}
}
@@ -209,7 +135,7 @@ fz_rendertext(fz_renderer *gc, fz_textnode *text, fz_matrix ctm)
int g, i, ix, iy;
fz_matrix tm, trm;
-printf("rendertext ; tmp=0,1\n");
+puts("render text");
error = fz_newpixmap(&gc->tmp, gc->x, gc->y, gc->w, gc->h, 0, 1);
if (error)
@@ -243,10 +169,158 @@ printf("rendertext ; tmp=0,1\n");
return nil;
}
+static fz_error *
+rcolortext(fz_renderer *gc, fz_textnode *text, fz_colornode *color, fz_matrix ctm)
+{
+ fz_error *error;
+ fz_glyph gl;
+ float x, y;
+ int g, i, ix, iy;
+ fz_matrix tm, trm;
+
+puts("render (mask color text)");
+
+ gc->r = color->r * (1 << 14);
+ gc->g = color->g * (1 << 14);
+ gc->b = color->b * (1 << 14);
+
+ tm = text->trm;
+
+ for (i = 0; i < text->len; i++)
+ {
+ g = text->els[i].g;
+ x = text->els[i].x;
+ y = text->els[i].y;
+
+ tm.e = x;
+ tm.f = y;
+ trm = fz_concat(tm, ctm);
+
+ ix = floor(trm.e);
+ iy = floor(trm.f);
+
+ trm.e = (trm.e - floor(trm.e));
+ trm.f = (trm.f - floor(trm.f));
+
+ error = fz_renderglyph(gc->cache, &gl, text->font, g, trm);
+ if (error)
+ return error;
+
+ blitcolorglyph(gc->acc, &gl, ix, iy, gc->r, gc->g, gc->b);
+ }
+
+ return nil;
+}
+
+static void blitspan(int y, int x, int n, short *list, void *userdata)
+{
+ fz_pixmap *pix = (fz_pixmap*)userdata;
+
+ if (y < 0) return;
+ if (y >= pix->h) return;
+ short d = 0;
+ while (x < 0 && n) {
+ d += *list++; n--; x ++;
+ }
+ if (x + n >= pix->w)
+ n = pix->w - x;
+ short *p = pix->samples + (y - pix->y) * pix->stride + (x - pix->x);
+ while (n--)
+ {
+ d += *list++;
+ *p++ = d * 64;
+ }
+}
+
fz_error *
fz_renderpath(fz_renderer *gc, fz_pathnode *path, fz_matrix ctm)
{
-printf("renderpath ; tmp=nil\n");
+ fz_error *error;
+
+puts("render path");
+
+ fz_resetgel(gc->gel, 17, 15);
+
+ if (path->paint == FZ_STROKE)
+ {
+ if (path->dash)
+ fz_dashpath(gc->gel, path, ctm, 0.2);
+ else
+ fz_strokepath(gc->gel, path, ctm, 0.2);
+ }
+ else
+ fz_fillpath(gc->gel, path, ctm, 0.2);
+
+ fz_sortgel(gc->gel);
+
+ error = fz_newpixmap(&gc->tmp, gc->x, gc->y, gc->w, gc->h, 0, 1);
+ if (error)
+ return error;
+
+ fz_clearpixmap(gc->tmp);
+
+ fz_scanconvert(gc->gel, gc->ael, path->paint == FZ_EOFILL, blitspan, gc->tmp);
+
+ return nil;
+}
+
+static void blitcolorspan(int y, int x, int n, short *list, void *userdata)
+{
+ fz_renderer *gc = userdata;
+ fz_pixmap *pix = gc->acc;
+ short r = gc->r;
+ short g = gc->g;
+ short b = gc->b;
+ short *p;
+ short d, sa, ssa;
+
+ assert(pix->n == 3);
+ assert(pix->a == 1);
+
+ p = pix->samples + (y - pix->y) * pix->stride + (x - pix->x) * 4;
+ d = 0;
+
+ while (n --)
+ {
+ d += *list++;
+
+ sa = d * 64;
+ ssa = (1 << 14) - sa;
+
+ p[0] = ((r * sa) >> 14) + ((p[0] * ssa) >> 14);
+ p[1] = ((g * sa) >> 14) + ((p[1] * ssa) >> 14);
+ p[2] = ((b * sa) >> 14) + ((p[2] * ssa) >> 14);
+ p[3] = sa + ((ssa * p[3]) >> 14);
+
+ p += 4;
+ }
+}
+
+static fz_error *
+rcolorpath(fz_renderer *gc, fz_pathnode *path, fz_colornode *color, fz_matrix ctm)
+{
+puts("render (mask color path)");
+
+ fz_resetgel(gc->gel, 17, 15);
+
+ if (path->paint == FZ_STROKE)
+ {
+ if (path->dash)
+ fz_dashpath(gc->gel, path, ctm, 0.2);
+ else
+ fz_strokepath(gc->gel, path, ctm, 0.2);
+ }
+ else
+ fz_fillpath(gc->gel, path, ctm, 0.2);
+
+ fz_sortgel(gc->gel);
+
+ gc->r = color->r * (1 << 14);
+ gc->g = color->g * (1 << 14);
+ gc->b = color->b * (1 << 14);
+
+ fz_scanconvert(gc->gel, gc->ael, path->paint == FZ_EOFILL, blitcolorspan, gc);
+
return nil;
}
@@ -259,9 +333,9 @@ fz_rendercolor(fz_renderer *gc, fz_colornode *color, fz_matrix ctm)
short b = color->b * (1 << 14);
int x, y;
-printf("rendercolor %d %d %d ; tmp=3,0\n", r, g, b);
+puts("render color");
- error = fz_newpixmap(&gc->tmp, gc->x, gc->y, gc->w, gc->h, 3, 0);
+ error = fz_newpixmap(&gc->tmp, gc->x, gc->y, gc->w, gc->h, 3, 1);
if (error)
return error;
@@ -273,12 +347,142 @@ printf("rendercolor %d %d %d ; tmp=3,0\n", r, g, b);
*p++ = r;
*p++ = g;
*p++ = b;
+ *p++ = 1 << 14;
}
}
return nil;
}
+static fz_error *
+fz_renderoverchild(fz_renderer *gc, fz_node *node, fz_matrix ctm)
+{
+ fz_error *error;
+
+ if (node->next)
+ {
+ error = fz_renderoverchild(gc, node->next, ctm);
+ if (error)
+ return error;
+ }
+
+ gc->tmp = nil;
+ error = fz_rendernode(gc, node, ctm);
+ if (error)
+ return error;
+
+ if (gc->tmp)
+ {
+ fz_blendover(gc->tmp, gc->acc);
+ fz_freepixmap(gc->tmp);
+ gc->tmp = nil;
+ }
+
+ return nil;
+}
+
+fz_error *
+fz_renderover(fz_renderer *gc, fz_overnode *over, fz_matrix ctm)
+{
+ fz_error *error;
+ fz_pixmap *oldacc = nil;
+ int oldmode;
+
+
+ /* uh-oh! we have a new over cluster */
+ if (gc->mode != OVER)
+ {
+puts("render over");
+ oldacc = gc->acc;
+ error = fz_newpixmap(&gc->acc, gc->x, gc->y, gc->w, gc->h, 3, 1);
+ if (error)
+ return error;
+ fz_clearpixmap(gc->acc);
+ }
+
+ oldmode = gc->mode;
+ gc->mode = OVER;
+
+ gc->tmp = nil;
+
+ if (over->super.child)
+ {
+ error = fz_renderoverchild(gc, over->super.child, ctm);
+ if (error)
+ return error;
+ }
+
+ gc->mode = oldmode;
+
+ /* uh-oh! end of over cluster */
+ if (gc->mode != OVER)
+ {
+printf("end over\n");
+ gc->tmp = gc->acc;
+ gc->acc = oldacc;
+ }
+
+ return nil;
+}
+
+fz_error *
+fz_rendermask(fz_renderer *gc, fz_masknode *mask, fz_matrix ctm)
+{
+ fz_error *error;
+ fz_pixmap *colorpix;
+ fz_pixmap *shapepix;
+ fz_node *color;
+ fz_node *shape;
+ int oldmode;
+
+ color = mask->super.child;
+ shape = color->next;
+
+ if (gc->mode == OVER)
+ {
+ if (fz_ispathnode(shape) && fz_iscolornode(color))
+ return rcolorpath(gc, (fz_pathnode*)shape, (fz_colornode*)color, ctm);
+ if (fz_istextnode(shape) && fz_iscolornode(color))
+ return rcolortext(gc, (fz_textnode*)shape, (fz_colornode*)color, ctm);
+ }
+
+ oldmode = gc->mode;
+ gc->mode = MASK;
+
+ gc->tmp = nil;
+ error = fz_rendernode(gc, color, ctm);
+ if (error)
+ return error;
+ colorpix = gc->tmp;
+
+ gc->tmp = nil;
+ error = fz_rendernode(gc, shape, ctm);
+ if (error)
+ return error;
+ shapepix = gc->tmp;
+
+ error = fz_newpixmap(&gc->tmp, gc->x, gc->y, gc->w, gc->h, colorpix->n, 1);
+ if (error)
+ return error;
+
+ fz_blendmask(gc->tmp, colorpix, shapepix);
+
+ fz_freepixmap(shapepix);
+ fz_freepixmap(colorpix);
+
+ gc->mode = oldmode;
+
+ return nil;
+}
+
+fz_error *
+fz_rendertransform(fz_renderer *gc, fz_transformnode *transform, fz_matrix ctm)
+{
+puts("render transform");
+ ctm = fz_concat(transform->m, ctm);
+ return fz_rendernode(gc, transform->super.child, ctm);
+}
+
fz_error *
fz_rendernode(fz_renderer *gc, fz_node *node, fz_matrix ctm)
{
@@ -321,6 +525,7 @@ fz_rendertree(fz_pixmap **outp, fz_renderer *gc, fz_tree *tree, fz_matrix ctm, f
return error;
*outp = gc->tmp;
+ gc->tmp = nil;
return nil;
}
diff --git a/render/scanconv.c b/render/scanconv.c
index b2d32363..662c5c62 100644
--- a/render/scanconv.c
+++ b/render/scanconv.c
@@ -65,44 +65,19 @@ evenodd(fz_ael *ael, short *list, int xofs, int hs)
}
}
-/* XXX */
-
-unsigned char pixmap[1000 * 1000];
-
-void
-fz_emitdeltas(short *list, int y, int x, int n)
-{
- short a = 0;
- short d = 0;
- while (n--) {
- d = *list++;
- a += d;
- pixmap[y * 1000 + x] = 0xff - a;
- x ++;
- }
-}
-
-void
-savestuff(void)
-{
- FILE *f = fopen("out.pgm", "w");
- fprintf(f, "P5\n1000 1000\n255\n");
- fwrite(pixmap, 1, 1000 * 1000, f);
- fclose(f);
-}
-
-/* XXX */
-
+/*
void
-fz_emitdeltas0(short *list, int y, int xofs, int n)
+fz_emitdeltas(short *list, int y, int xofs, int n)
{
int d = 0;
while (n--)
d += *list++;
}
+*/
fz_error *
-fz_scanconvert(fz_gel *gel, fz_ael *ael, int eofill)
+fz_scanconvert(fz_gel *gel, fz_ael *ael, int eofill,
+ void (*blitfunc)(int,int,int,short*,void*), void *blitdata)
{
fz_error *error;
short *deltas;
@@ -121,11 +96,6 @@ fz_scanconvert(fz_gel *gel, fz_ael *ael, int eofill)
if (gel->len == 0)
return nil;
-memset(pixmap, 0xff, sizeof pixmap);
-
-printf("bbox [%d %d %d %d] samp %d/%d edges %d\n",
- xmin, ymin, xmax, ymax, hs, vs, gel->len);
-
deltas = fz_malloc(sizeof(short) * (xmax - xmin));
if (!deltas)
return fz_outofmem;
@@ -140,7 +110,7 @@ printf("bbox [%d %d %d %d] samp %d/%d edges %d\n",
{
yc = fz_idiv(y, vs);
if (yc != yd) {
- fz_emitdeltas(deltas, yd, xmin, xmax - xmin);
+ blitfunc(yd, xmin, xmax - xmin, deltas, blitdata);
memset(deltas, 0, sizeof(short) * (xmax - xmin));
}
yd = yc;
@@ -151,9 +121,6 @@ printf("bbox [%d %d %d %d] samp %d/%d edges %d\n",
return error;
}
-// { int i; for (i = 0; i < ael->len; i++)
-// pixmap[yd * 1000 + (ael->edges[i]->x / hs)] = 0; }
-
if (eofill)
evenodd(ael, deltas, xofs, hs);
else
@@ -167,9 +134,7 @@ printf("bbox [%d %d %d %d] samp %d/%d edges %d\n",
y = gel->edges[e].y;
}
- fz_emitdeltas(deltas, yd, xmin, xmax - xmin);
-
- savestuff();
+ blitfunc(yd, xmin, xmax - xmin, deltas, blitdata);
return nil;
}
diff --git a/test/pdfrip.c b/test/pdfrip.c
index 34d6a141..68276fb2 100644
--- a/test/pdfrip.c
+++ b/test/pdfrip.c
@@ -1,9 +1,11 @@
#include <fitz.h>
#include <mupdf.h>
+int showtree = 0;
+
void usage()
{
- fprintf(stderr, "usage: pdfrip [-r] [-p password] file.pdf [pages...]\n");
+ fprintf(stderr, "usage: pdfrip [-d] [-p password] file.pdf [pages...]\n");
exit(1);
}
@@ -56,7 +58,6 @@ printf(" font:\n");
fz_debugobj(rdb->font);
printf("\n extgstate:\n");
fz_debugobj(rdb->extgstate);
-printf("\nfitz tree:\n");
error = pdf_newcsi(&csi);
if (error) fz_abort(error);
@@ -78,7 +79,12 @@ printf("\nfitz tree:\n");
}
}
- fz_debugtree(csi->tree);
+
+ if (showtree)
+ {
+ printf("\nfitz tree:\n");
+ fz_debugtree(csi->tree);
+ }
{
fz_pixmap *pix;
@@ -86,24 +92,26 @@ printf("\nfitz tree:\n");
fz_matrix ctm;
fz_rect bbox;
-#define W 612
-#define H 792
+#define SCALE 1.0
+#define W 700
+#define H 900
fz_newrenderer(&gc);
bbox.min.x = 0;
bbox.min.y = 0;
- bbox.max.x = W;
- bbox.max.y = H;
+ bbox.max.x = W * SCALE;
+ bbox.max.y = H * SCALE;
- ctm = fz_concat(fz_translate(0, -H), fz_scale(1,-1));
+ //ctm = fz_scale(SCALE,SCALE);
+ ctm = fz_concat(fz_translate(0, -H), fz_scale(SCALE,-SCALE));
printf("rendering!\n");
fz_rendertree(&pix, gc, csi->tree, ctm, bbox);
printf("done!\n");
fz_debugpixmap(pix);
- fz_droppixmap(pix);
+ fz_freepixmap(pix);
fz_freerenderer(gc);
}
@@ -117,15 +125,17 @@ int main(int argc, char **argv)
char *filename;
pdf_xref *xref;
pdf_pagetree *pages;
+ int d;
int c;
char *password = "";
- while ((c = getopt(argc, argv, "p:")) != -1)
+ while ((c = getopt(argc, argv, "dp:")) != -1)
{
switch (c)
{
case 'p': password = optarg; break;
+ case 'd': ++showtree; break;
default: usage();
}
}
diff --git a/tree/debug.c b/tree/debug.c
index a70f971d..b10eacad 100644
--- a/tree/debug.c
+++ b/tree/debug.c
@@ -163,6 +163,12 @@ static void lispnode(fz_node *node, int level)
}
void
+fz_debugnode(fz_node *node)
+{
+ lispnode(node, 0);
+}
+
+void
fz_debugtree(fz_tree *tree)
{
lispnode(tree->root, 0);