diff options
-rw-r--r-- | Jamfile | 2 | ||||
-rw-r--r-- | include/fitz/pixmap.h | 2 | ||||
-rw-r--r-- | include/fitz/render.h | 15 | ||||
-rw-r--r-- | include/fitz/scanconv.h | 2 | ||||
-rw-r--r-- | mupdf/colorspace.c | 16 | ||||
-rw-r--r-- | mupdf/interpret.c | 5 | ||||
-rw-r--r-- | render/pixmap.c | 70 | ||||
-rw-r--r-- | render/render.c | 307 | ||||
-rw-r--r-- | render/renderpath.c | 139 | ||||
-rw-r--r-- | render/rendertext.c | 139 | ||||
-rw-r--r-- | render/scanconv.c | 33 | ||||
-rw-r--r-- | tree/colorspace.c | 10 |
12 files changed, 392 insertions, 348 deletions
@@ -82,6 +82,8 @@ Library libfitz : render/fill.c render/stroke.c render/render.c + render/renderpath.c + render/rendertext.c ; Library libmupdf : diff --git a/include/fitz/pixmap.h b/include/fitz/pixmap.h index f7bab833..24584f30 100644 --- a/include/fitz/pixmap.h +++ b/include/fitz/pixmap.h @@ -6,7 +6,7 @@ struct fz_pixmap_s int x, y, w, h; int n, a; int stride; - short *samples; + unsigned char *samples; }; fz_error *fz_newpixmap(fz_pixmap **mapp, fz_colorspace *cs, int x, int y, int w, int h, int n, int a); diff --git a/include/fitz/render.h b/include/fitz/render.h index 7f4e08db..dc2f116a 100644 --- a/include/fitz/render.h +++ b/include/fitz/render.h @@ -1,5 +1,20 @@ typedef struct fz_renderer_s fz_renderer; +enum { FZ_RNONE, FZ_ROVER, FZ_RMASK }; + +struct fz_renderer_s +{ + fz_colorspace *model; + fz_glyphcache *cache; + fz_gel *gel; + fz_ael *ael; + int mode; + int x, y, w, h; + fz_pixmap *tmp; + fz_pixmap *acc; + unsigned char r, g, b; +}; + fz_error *fz_newrenderer(fz_renderer **gcp, fz_colorspace *pcm); void fz_freerenderer(fz_renderer *gc); diff --git a/include/fitz/scanconv.h b/include/fitz/scanconv.h index a3c29473..794b9ba2 100644 --- a/include/fitz/scanconv.h +++ b/include/fitz/scanconv.h @@ -38,7 +38,7 @@ 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, int y0, int y1, void (*blitfunc)(int,int,int,short*,void*), void *blitdata); fz_error *fz_fillpath(fz_gel *gel, fz_pathnode *path, fz_matrix ctm, float flatness); diff --git a/mupdf/colorspace.c b/mupdf/colorspace.c index 4ec7e26e..05a4535c 100644 --- a/mupdf/colorspace.c +++ b/mupdf/colorspace.c @@ -379,14 +379,14 @@ printf("\n"); float black[3]; float gamma; - tmp = fz_dictgets(dict, "White"); + tmp = fz_dictgets(dict, "WhitePoint"); if (!fz_isarray(tmp)) - return fz_throw("syntaxerror: CalGray missing White"); + return fz_throw("syntaxerror: CalGray missing WhitePoint"); white[0] = fz_toreal(fz_arrayget(tmp, 0)); white[1] = fz_toreal(fz_arrayget(tmp, 1)); white[2] = fz_toreal(fz_arrayget(tmp, 2)); - tmp = fz_dictgets(dict, "Black"); + tmp = fz_dictgets(dict, "BlackPoint"); if (fz_isarray(tmp)) { black[0] = fz_toreal(fz_arrayget(tmp, 0)); @@ -419,14 +419,14 @@ printf("\n"); float gamma[3]; float matrix[9]; - tmp = fz_dictgets(dict, "White"); + tmp = fz_dictgets(dict, "WhitePoint"); if (!fz_isarray(tmp)) return fz_throw("syntaxerror: CalRGB missing White"); white[0] = fz_toreal(fz_arrayget(tmp, 0)); white[1] = fz_toreal(fz_arrayget(tmp, 1)); white[2] = fz_toreal(fz_arrayget(tmp, 2)); - tmp = fz_dictgets(dict, "Black"); + tmp = fz_dictgets(dict, "BlackPoint"); if (fz_isarray(tmp)) { black[0] = fz_toreal(fz_arrayget(tmp, 0)); @@ -486,14 +486,14 @@ printf("\n"); float black[3]; float range[4]; - tmp = fz_dictgets(dict, "White"); + tmp = fz_dictgets(dict, "WhitePoint"); if (!fz_isarray(tmp)) - return fz_throw("syntaxerror: Lab missing White"); + return fz_throw("syntaxerror: Lab missing WhitePoint"); white[0] = fz_toreal(fz_arrayget(tmp, 0)); white[1] = fz_toreal(fz_arrayget(tmp, 1)); white[2] = fz_toreal(fz_arrayget(tmp, 2)); - tmp = fz_dictgets(dict, "Black"); + tmp = fz_dictgets(dict, "BlackPoint"); if (fz_isarray(tmp)) { black[0] = fz_toreal(fz_arrayget(tmp, 0)); diff --git a/mupdf/interpret.c b/mupdf/interpret.c index 14aae160..fdf367b5 100644 --- a/mupdf/interpret.c +++ b/mupdf/interpret.c @@ -21,6 +21,7 @@ pdf_newcsi(pdf_csi **csip) fz_error *error; pdf_csi *csi; fz_node *node; + float white = 1.0; csi = *csip = fz_malloc(sizeof(pdf_csi)); if (!csi) @@ -50,8 +51,8 @@ pdf_newcsi(pdf_csi **csip) csi->tree->root = node; csi->gstate[0].head = node; -// error = fz_newcolornode(&node, pdf_devicegray, 1); -// fz_insertnode(csi->tree->root, node); + error = fz_newcolornode(&node, pdf_devicegray, 1, &white); + fz_insertnode(csi->tree->root, node); csi->clip = nil; diff --git a/render/pixmap.c b/render/pixmap.c index 5dd8bcda..84a542b9 100644 --- a/render/pixmap.c +++ b/render/pixmap.c @@ -18,13 +18,13 @@ fz_newpixmap(fz_pixmap **pixp, fz_colorspace *cs, int x, int y, int w, int h, in pix->a = a; pix->stride = (pix->n + pix->a) * pix->w; - pix->samples = fz_malloc(sizeof(short) * pix->stride * pix->h); + pix->samples = fz_malloc(sizeof(unsigned char) * pix->stride * pix->h); if (!pix->samples) { fz_free(pix); return fz_outofmem; } - memset(pix->samples, 0, sizeof(short) * pix->stride * pix->h); + memset(pix->samples, 0, sizeof(unsigned char) * pix->stride * pix->h); return nil; } @@ -39,7 +39,7 @@ fz_freepixmap(fz_pixmap *pix) void fz_clearpixmap(fz_pixmap *pix) { - memset(pix->samples, 0, sizeof(short) * pix->stride * pix->h); + memset(pix->samples, 0, sizeof(unsigned char) * pix->stride * pix->h); } void @@ -47,37 +47,47 @@ fz_debugpixmap(fz_pixmap *pix) { int x, y; - FILE *f = fopen("out.ppm", "w"); + FILE *ppm = fopen("out.ppm", "w"); + FILE *pgm = fopen("out.pgm", "w"); + + fprintf(ppm, "P6\n%d %d\n255\n", pix->w, pix->h); + fprintf(pgm, "P5\n%d %d\n255\n", pix->w, pix->h); 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); + int r = pix->samples[x * 4 + y * pix->stride + 0]; + int g = pix->samples[x * 4 + y * pix->stride + 1]; + int b = pix->samples[x * 4 + y * pix->stride + 2]; + int a = pix->samples[x * 4 + y * pix->stride + 3]; + + //putc(r, ppm); + //putc(g, ppm); + //putc(b, ppm); + putc(((r * a) / 255) + (255 - a), ppm); + putc(((g * a) / 255) + (255 - a), ppm); + putc(((b * a) / 255) + (255 - a), ppm); + + putc(a, pgm); } } 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); + int a = pix->samples[x + y * pix->stride]; + putc(0, ppm); + putc(0, ppm); + putc(0, ppm); + putc(a, pgm); } } - fclose(f); + + fclose(ppm); + fclose(pgm); } void @@ -92,18 +102,18 @@ fz_blendover(fz_pixmap *src, fz_pixmap *dst) for (y = 0; y < dst->h; y++) { - short *s = &src->samples[y * src->stride]; - short *d = &dst->samples[y * dst->stride]; + unsigned char *s = &src->samples[y * src->stride]; + unsigned char *d = &dst->samples[y * dst->stride]; for (x = 0; x < dst->w; x++) { int sa = s[3]; - int ssa = (1 << 14) - sa; + int ssa = 255 - 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); + d[0] = fz_mul255(s[0], sa) + fz_mul255(d[0], ssa); + d[1] = fz_mul255(s[1], sa) + fz_mul255(d[1], ssa); + d[2] = fz_mul255(s[2], sa) + fz_mul255(d[2], ssa); + d[3] = sa + fz_mul255(d[3], ssa); s += 4; d += 4; @@ -124,15 +134,15 @@ fz_blendmask(fz_pixmap *dst, fz_pixmap *src, fz_pixmap *msk) for (y = 0; y < dst->h; y++) { - short *d = &dst->samples[y * dst->stride]; - short *s = &src->samples[y * src->stride]; - short *m = &msk->samples[y * msk->stride]; + unsigned char *d = &dst->samples[y * dst->stride]; + unsigned char *s = &src->samples[y * src->stride]; + unsigned char *m = &msk->samples[y * msk->stride]; for (x = 0; x < dst->w; x++) { for (k = 0; k < dst->n; k++) *d++ = *s++; - *d++ = (*m++ * *s++) >> 14; + *d++ = fz_mul255(*m++, *s++); } } } diff --git a/render/render.c b/render/render.c index fab6262d..d46d5b71 100644 --- a/render/render.c +++ b/render/render.c @@ -1,19 +1,9 @@ #include <fitz.h> -enum { NONE, OVER, MASK }; - -struct fz_renderer_s -{ - fz_colorspace *model; - fz_glyphcache *cache; - fz_gel *gel; - fz_ael *ael; - int mode; - int x, y, w, h; - fz_pixmap *tmp; - fz_pixmap *acc; - short r, g, b; -}; +fz_error *fz_rendercolortext(fz_renderer*, fz_textnode*, fz_colornode*, fz_matrix); +fz_error *fz_rendercolorpath(fz_renderer*, fz_pathnode*, fz_colornode*, fz_matrix); +fz_error *fz_rendertext(fz_renderer*, fz_textnode*, fz_matrix); +fz_error *fz_renderpath(fz_renderer*, fz_pathnode*, fz_matrix); fz_error * fz_newrenderer(fz_renderer **gcp, fz_colorspace *processcolormodel) @@ -29,7 +19,7 @@ fz_newrenderer(fz_renderer **gcp, fz_colorspace *processcolormodel) gc->cache = nil; gc->gel = nil; gc->ael = nil; - gc->mode = NONE; + gc->mode = FZ_RNONE; gc->tmp = nil; gc->acc = nil; @@ -75,263 +65,6 @@ fz_freerenderer(fz_renderer *gc) fz_free(gc); } -static void blitglyph(fz_pixmap *out, fz_glyph *gl, int xo, int yo) -{ - int sx, sy, dx, dy, a, b, c; - - for (sy = 0; sy < gl->h; sy++) - { - for (sx = 0; sx < gl->w; sx++) - { - dx = xo + sx + gl->lsb - out->x; - dy = yo - sy + gl->top - out->y; - - if (dx < 0) continue; - if (dy < 0) continue; - if (dx >= out->w) continue; - if (dy >= out->h) continue; - - 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 blitcolorglyph(fz_pixmap *out, fz_glyph *gl, int xo, int yo, fz_renderer *gc) -{ - int sx, sy, dx, dy, sa, ssa; - short *p; - - for (sy = 0; sy < gl->h; sy++) - { - for (sx = 0; sx < gl->w; sx++) - { - dx = xo + sx + gl->lsb - out->x; - dy = yo - sy + gl->top - out->y; - - if (dx < 0) continue; - if (dy < 0) continue; - if (dx >= out->w) continue; - if (dy >= out->h) continue; - - sa = gl->bitmap[sx + sy * gl->w] * 64; - ssa = (1 << 14) - sa; - - p = out->samples + dx * 4 + dy * out->stride; - p[0] = ((gc->r * sa) >> 14) + ((p[0] * ssa) >> 14); - p[1] = ((gc->g * sa) >> 14) + ((p[1] * ssa) >> 14); - p[2] = ((gc->b * sa) >> 14) + ((p[2] * ssa) >> 14); - p[3] = sa + ((ssa * p[3]) >> 14); - } - } -} - -fz_error * -fz_rendertext(fz_renderer *gc, fz_textnode *text, fz_matrix ctm) -{ - fz_error *error; - fz_glyph gl; - float x, y; - int g, i, ix, iy; - fz_matrix tm, trm; - -puts("render text"); - - error = fz_newpixmap(&gc->tmp, nil, gc->x, gc->y, gc->w, gc->h, 0, 1); - if (error) - return error; - - tm = text->trm; - - for (i = 0; i < text->len; i++) - { - g = text->els[i].cid; - 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; - - blitglyph(gc->tmp, &gl, ix, iy); - } - - 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; - float rgb[3]; - -puts("render (mask color text)"); - - fz_convertcolor(color->cs, color->samples, gc->model, rgb); - gc->r = rgb[0] * (1 << 14); - gc->g = rgb[1] * (1 << 14); - gc->b = rgb[2] * (1 << 14); - - tm = text->trm; - - for (i = 0; i < text->len; i++) - { - g = text->els[i].cid; - 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); - } - - 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) -{ - fz_error *error; - -puts("render path"); - - float flatness = 0.3 / ctm.a; - - fz_resetgel(gc->gel, 16, 16); - - if (path->paint == FZ_STROKE) - { - if (path->dash) - fz_dashpath(gc->gel, path, ctm, flatness); - else - fz_strokepath(gc->gel, path, ctm, flatness); - } - else - fz_fillpath(gc->gel, path, ctm, flatness); - - fz_sortgel(gc->gel); - - error = fz_newpixmap(&gc->tmp, nil, 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 *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] = ((gc->r * sa) >> 14) + ((p[0] * ssa) >> 14); - p[1] = ((gc->g * sa) >> 14) + ((p[1] * ssa) >> 14); - p[2] = ((gc->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) -{ - float rgb[3]; - -puts("render (mask color path)"); - - float flatness = 0.3 / ctm.a; - - fz_resetgel(gc->gel, 17, 15); - - if (path->paint == FZ_STROKE) - { - if (path->dash) - fz_dashpath(gc->gel, path, ctm, flatness); - else - fz_strokepath(gc->gel, path, ctm, flatness); - } - else - fz_fillpath(gc->gel, path, ctm, flatness); - - fz_sortgel(gc->gel); - - fz_convertcolor(color->cs, color->samples, gc->model, rgb); - gc->r = rgb[0] * (1 << 14); - gc->g = rgb[1] * (1 << 14); - gc->b = rgb[2] * (1 << 14); - - fz_scanconvert(gc->gel, gc->ael, path->paint == FZ_EOFILL, blitcolorspan, gc); - - return nil; -} - fz_error * fz_rendercolor(fz_renderer *gc, fz_colornode *color, fz_matrix ctm) { @@ -340,9 +73,9 @@ fz_rendercolor(fz_renderer *gc, fz_colornode *color, fz_matrix ctm) float rgb[3]; fz_convertcolor(color->cs, color->samples, gc->model, rgb); - gc->r = rgb[0] * (1 << 14); - gc->g = rgb[1] * (1 << 14); - gc->b = rgb[2] * (1 << 14); + gc->r = rgb[0] * 255; + gc->g = rgb[1] * 255; + gc->b = rgb[2] * 255; puts("render color"); @@ -352,13 +85,13 @@ puts("render color"); for (y = 0; y < gc->tmp->h; y++) { - short *p = &gc->tmp->samples[y * gc->tmp->stride]; + unsigned char *p = &gc->tmp->samples[y * gc->tmp->stride]; for (x = 0; x < gc->tmp->w; x++) { *p++ = gc->r; *p++ = gc->g; *p++ = gc->b; - *p++ = 1 << 14; + *p++ = 255; } } @@ -398,12 +131,11 @@ fz_renderover(fz_renderer *gc, fz_overnode *over, fz_matrix ctm) fz_error *error; fz_pixmap *oldacc = nil; int oldmode; - +int i; /* uh-oh! we have a new over cluster */ - if (gc->mode != OVER) + if (gc->mode != FZ_ROVER) { -puts("render over"); oldacc = gc->acc; error = fz_newpixmap(&gc->acc, gc->model, gc->x, gc->y, gc->w, gc->h, 3, 1); if (error) @@ -412,7 +144,7 @@ puts("render over"); } oldmode = gc->mode; - gc->mode = OVER; + gc->mode = FZ_ROVER; gc->tmp = nil; @@ -426,9 +158,8 @@ puts("render over"); gc->mode = oldmode; /* uh-oh! end of over cluster */ - if (gc->mode != OVER) + if (gc->mode != FZ_ROVER) { -printf("end over\n"); gc->tmp = gc->acc; gc->acc = oldacc; } @@ -449,16 +180,16 @@ fz_rendermask(fz_renderer *gc, fz_masknode *mask, fz_matrix ctm) color = mask->super.child; shape = color->next; - if (gc->mode == OVER) + if (gc->mode == FZ_ROVER) { if (fz_ispathnode(shape) && fz_iscolornode(color)) - return rcolorpath(gc, (fz_pathnode*)shape, (fz_colornode*)color, ctm); + return fz_rendercolorpath(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); + return fz_rendercolortext(gc, (fz_textnode*)shape, (fz_colornode*)color, ctm); } oldmode = gc->mode; - gc->mode = MASK; + gc->mode = FZ_RMASK; gc->tmp = nil; error = fz_rendernode(gc, color, ctm); @@ -489,7 +220,6 @@ fz_rendermask(fz_renderer *gc, fz_masknode *mask, fz_matrix ctm) 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); } @@ -537,7 +267,6 @@ fz_rendertree(fz_pixmap **outp, fz_renderer *gc, fz_tree *tree, fz_matrix ctm, f *outp = gc->tmp; gc->tmp = nil; - return nil; } diff --git a/render/renderpath.c b/render/renderpath.c new file mode 100644 index 00000000..9e805a53 --- /dev/null +++ b/render/renderpath.c @@ -0,0 +1,139 @@ +#include <fitz.h> + +enum { HS = 17, VS = 15 }; + +static fz_error *pathtogel(fz_gel *gel, fz_pathnode *path, fz_matrix ctm) +{ + float flatness = 0.3 / ctm.a; + if (flatness < 0.1) + flatness = 0.1; + + if (path->paint == FZ_STROKE) + { + if (path->dash) + return fz_dashpath(gel, path, ctm, flatness); + return fz_strokepath(gel, path, ctm, flatness); + } + return fz_fillpath(gel, path, ctm, flatness); +} + +static void blitcolorspan(int y, int x0, int n, short *list, void *userdata) +{ + fz_renderer *gc = userdata; + fz_pixmap *pix = gc->acc; + unsigned char sa; + unsigned char ssa; + unsigned char *p; + unsigned char r = gc->r; + unsigned char g = gc->g; + unsigned char b = gc->b; + + sa = 0; + + while (x0 < pix->x) + { + sa += *list++; + x0 ++; + n --; + } + + if (n > pix->w) + n = pix->w; + + p = &pix->samples[(y - pix->y) * pix->stride + (x0 - pix->x) * 4]; + + while (n--) + { + sa += *list++; + ssa = 255 - sa; + + p[0] = fz_mul255(r, sa) + fz_mul255(p[0], ssa); + p[1] = fz_mul255(g, sa) + fz_mul255(p[1], ssa); + p[2] = fz_mul255(b, sa) + fz_mul255(p[2], ssa); + p[3] = sa + fz_mul255(p[3], ssa); + + p += 4; + } +} + +static void blitalphaspan(int y, int x0, int n, short *list, void *userdata) +{ + fz_pixmap *pix = userdata; + unsigned char a; + unsigned char *p; + + a = 0; + + while (x0 < pix->x) + { + a += *list++; + x0 ++; + n --; + } + + if (n > pix->w) + n = pix->w; + + p = &pix->samples[(y - pix->y) * pix->stride + (x0 - pix->x) * 4]; + + while (n--) + { + a += *list++; + *p++ = a; + } +} + +fz_error * +fz_rendercolorpath(fz_renderer *gc, fz_pathnode *path, fz_colornode *color, fz_matrix ctm) +{ + fz_error *error; + float rgb[3]; + + fz_resetgel(gc->gel, HS, VS); + + error = pathtogel(gc->gel, path, ctm); + if (error) + return error; + + fz_sortgel(gc->gel); + + fz_convertcolor(color->cs, color->samples, gc->model, rgb); + gc->r = rgb[0] * 255; + gc->g = rgb[1] * 255; + gc->b = rgb[2] * 255; + + fz_scanconvert(gc->gel, gc->ael, + path->paint == FZ_EOFILL, + gc->y, gc->y + gc->h, + blitcolorspan, gc); + + return nil; +} + +fz_error * +fz_renderpath(fz_renderer *gc, fz_pathnode *path, fz_matrix ctm) +{ + fz_error *error; + + fz_resetgel(gc->gel, HS, VS); + + error = pathtogel(gc->gel, path, ctm); + if (error) + return error; + + fz_sortgel(gc->gel); + + error = fz_newpixmap(&gc->tmp, nil, 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, + gc->y, gc->y + gc->h, + blitalphaspan, gc->tmp); + + return nil; +} + diff --git a/render/rendertext.c b/render/rendertext.c new file mode 100644 index 00000000..cc181657 --- /dev/null +++ b/render/rendertext.c @@ -0,0 +1,139 @@ +#include <fitz.h> + +static void blitalphaglyph(fz_pixmap *out, fz_glyph *gl, int xo, int yo) +{ + int sx, sy, dx, dy, a, b, c; + + for (sy = 0; sy < gl->h; sy++) + { + for (sx = 0; sx < gl->w; sx++) + { + dx = xo + sx + gl->lsb - out->x; + dy = yo - sy + gl->top - out->y; + + if (dx < 0) continue; + if (dy < 0) continue; + 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; + } + } +} + +static void blitcolorglyph(fz_pixmap *out, fz_glyph *gl, int xo, int yo, fz_renderer *gc) +{ + int sx, sy, dx, dy, sa, ssa; + unsigned char *p; + + for (sy = 0; sy < gl->h; sy++) + { + for (sx = 0; sx < gl->w; sx++) + { + dx = xo + sx + gl->lsb - out->x; + dy = yo - sy + gl->top - out->y; + + if (dx < 0) continue; + if (dy < 0) continue; + if (dx >= out->w) continue; + if (dy >= out->h) continue; + + sa = gl->bitmap[sx + sy * gl->w]; + ssa = 255 - sa; + + p = out->samples + dx * 4 + dy * out->stride; + p[0] = fz_mul255(gc->r, sa) + fz_mul255(p[0], ssa); + p[1] = fz_mul255(gc->g, sa) + fz_mul255(p[1], ssa); + p[2] = fz_mul255(gc->b, sa) + fz_mul255(p[2], ssa); + p[3] = sa + fz_mul255(ssa, p[3]); + } + } +} + +fz_error * +fz_rendertext(fz_renderer *gc, fz_textnode *text, fz_matrix ctm) +{ + fz_error *error; + fz_glyph gl; + float x, y; + int g, i, ix, iy; + fz_matrix tm, trm; + + error = fz_newpixmap(&gc->tmp, nil, gc->x, gc->y, gc->w, gc->h, 0, 1); + if (error) + return error; + + tm = text->trm; + + for (i = 0; i < text->len; i++) + { + g = text->els[i].cid; + 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; + + blitalphaglyph(gc->tmp, &gl, ix, iy); + } + + return nil; +} + +fz_error * +fz_rendercolortext(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; + float rgb[3]; + + fz_convertcolor(color->cs, color->samples, gc->model, rgb); + gc->r = rgb[0] * 255; + gc->g = rgb[1] * 255; + gc->b = rgb[2] * 255; + + tm = text->trm; + + for (i = 0; i < text->len; i++) + { + g = text->els[i].cid; + 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); + } + + return nil; +} + diff --git a/render/scanconv.c b/render/scanconv.c index 662c5c62..b2689ae2 100644 --- a/render/scanconv.c +++ b/render/scanconv.c @@ -76,7 +76,7 @@ fz_emitdeltas(short *list, int y, int xofs, int n) */ fz_error * -fz_scanconvert(fz_gel *gel, fz_ael *ael, int eofill, +fz_scanconvert(fz_gel *gel, fz_ael *ael, int eofill, int y0, int y1, void (*blitfunc)(int,int,int,short*,void*), void *blitdata) { fz_error *error; @@ -86,8 +86,8 @@ fz_scanconvert(fz_gel *gel, fz_ael *ael, int eofill, int xmin = fz_idiv(gel->xmin, gel->hs); int xmax = fz_idiv(gel->xmax, gel->hs) + 1; - int ymin = fz_idiv(gel->ymin, gel->vs); - int ymax = fz_idiv(gel->ymax, gel->vs) + 1; + // int ymin = fz_idiv(gel->ymin, gel->vs); + // int ymax = fz_idiv(gel->ymax, gel->vs) + 1; int xofs = xmin * gel->hs; int hs = gel->hs; @@ -96,10 +96,11 @@ fz_scanconvert(fz_gel *gel, fz_ael *ael, int eofill, if (gel->len == 0) return nil; - deltas = fz_malloc(sizeof(short) * (xmax - xmin)); + deltas = fz_malloc(sizeof(short) * (xmax - xmin + 1)); if (!deltas) return fz_outofmem; - memset(deltas, 0, sizeof(short) * (xmax - xmin)); + + memset(deltas, 0, sizeof(short) * (xmax - xmin + 1)); e = 0; y = gel->edges[0].y; @@ -110,8 +111,11 @@ fz_scanconvert(fz_gel *gel, fz_ael *ael, int eofill, { yc = fz_idiv(y, vs); if (yc != yd) { - blitfunc(yd, xmin, xmax - xmin, deltas, blitdata); - memset(deltas, 0, sizeof(short) * (xmax - xmin)); + if (yd >= y0 && yd < y1) + { + blitfunc(yd, xmin, xmax - xmin, deltas, blitdata); + memset(deltas, 0, sizeof(short) * (xmax - xmin + 1)); + } } yd = yc; @@ -121,10 +125,13 @@ fz_scanconvert(fz_gel *gel, fz_ael *ael, int eofill, return error; } - if (eofill) - evenodd(ael, deltas, xofs, hs); - else - nonzerowinding(ael, deltas, xofs, hs); + if (yd >= y0 && yd < y1) + { + if (eofill) + evenodd(ael, deltas, xofs, hs); + else + nonzerowinding(ael, deltas, xofs, hs); + } fz_advanceael(ael); @@ -134,8 +141,10 @@ fz_scanconvert(fz_gel *gel, fz_ael *ael, int eofill, y = gel->edges[e].y; } - blitfunc(yd, xmin, xmax - xmin, deltas, blitdata); + if (yd >= y0 && yd < y1) + blitfunc(yd, xmin, xmax - xmin, deltas, blitdata); + fz_free(deltas); return nil; } diff --git a/tree/colorspace.c b/tree/colorspace.c index 6ff61d3e..57fa9ac5 100644 --- a/tree/colorspace.c +++ b/tree/colorspace.c @@ -14,15 +14,15 @@ void fz_convertcolor(fz_colorspace *srcs, float *srcv, fz_colorspace *dsts, float *dstv) { float xyz[3]; - int i; +//int i; if (srcs != dsts) { -printf("convert color from %s to %s\n ", srcs->name, dsts->name); -for(i=0;i<srcs->n;i++)printf("%g ", srcv[i]);printf("\n"); +//printf("convert color from %s to %s\n ", srcs->name, dsts->name); +//for(i=0;i<srcs->n;i++)printf("%g ", srcv[i]);printf("\n"); srcs->toxyz(srcs, srcv, xyz); -printf(" %g %g %g\n ", xyz[0], xyz[1], xyz[2]); +//printf(" %g %g %g\n ", xyz[0], xyz[1], xyz[2]); dsts->fromxyz(dsts, xyz, dstv); -for(i=0;i<dsts->n;i++)printf("%g ", dstv[i]);printf("\n"); +//for(i=0;i<dsts->n;i++)printf("%g ", dstv[i]);printf("\n"); } else { |