diff options
author | Tor Andersson <tor@ghostscript.com> | 2004-09-27 02:15:04 +0200 |
---|---|---|
committer | Tor Andersson <tor@ghostscript.com> | 2004-09-27 02:15:04 +0200 |
commit | 6ddde92a3a45e970b05770633dc6a337d5d013c5 (patch) | |
tree | 1dec4612d7469839478e72d16d30a0da5755243c /render/scanconv.c | |
download | mupdf-6ddde92a3a45e970b05770633dc6a337d5d013c5.tar.xz |
Initial import
Diffstat (limited to 'render/scanconv.c')
-rw-r--r-- | render/scanconv.c | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/render/scanconv.c b/render/scanconv.c new file mode 100644 index 00000000..b2d32363 --- /dev/null +++ b/render/scanconv.c @@ -0,0 +1,176 @@ +#include <fitz.h> + +static inline void +addspan(short *list, int x0, int x1, int xofs, int hs) +{ + int x0pix, x0sub; + int x1pix, x1sub; + + if (x0 == x1) + return; + + /* x between 0 and width of bbox */ + x0 -= xofs; + x1 -= xofs; + + x0pix = x0 / hs; + x0sub = x0 % hs; + x1pix = x1 / hs; + x1sub = x1 % hs; + + if (x0pix == x1pix) + { + list[x0pix] += x1sub - x0sub; + list[x0pix+1] += x0sub - x1sub; + } + + else + { + list[x0pix] += hs - x0sub; + list[x0pix+1] += x0sub; + list[x1pix] += x1sub - hs; + list[x1pix+1] += -x1sub; + } +} + +static inline void +nonzerowinding(fz_ael *ael, short *list, int xofs, int hs) +{ + int winding = 0; + int x = 0; + int i; + for (i = 0; i < ael->len; i++) + { + if (!winding && (winding + ael->edges[i]->ydir)) + x = ael->edges[i]->x; + if (winding && !(winding + ael->edges[i]->ydir)) + addspan(list, x, ael->edges[i]->x, xofs, hs); + winding += ael->edges[i]->ydir; + } +} + +static inline void +evenodd(fz_ael *ael, short *list, int xofs, int hs) +{ + int even = 0; + int x = 0; + int i; + for (i = 0; i < ael->len; i++) + { + if (!even) + x = ael->edges[i]->x; + else + addspan(list, x, ael->edges[i]->x, xofs, hs); + even = !even; + } +} + +/* 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) +{ + int d = 0; + while (n--) + d += *list++; +} + +fz_error * +fz_scanconvert(fz_gel *gel, fz_ael *ael, int eofill) +{ + fz_error *error; + short *deltas; + int y, e; + int yd, yc; + + 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 xofs = xmin * gel->hs; + int hs = gel->hs; + int vs = gel->vs; + + 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; + memset(deltas, 0, sizeof(short) * (xmax - xmin)); + + e = 0; + y = gel->edges[0].y; + yc = fz_idiv(y, vs); + yd = yc; + + while (ael->len > 0 || e < gel->len) + { + yc = fz_idiv(y, vs); + if (yc != yd) { + fz_emitdeltas(deltas, yd, xmin, xmax - xmin); + memset(deltas, 0, sizeof(short) * (xmax - xmin)); + } + yd = yc; + + error = fz_insertael(ael, gel, y, &e); + if (error) { + fz_free(deltas); + 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 + nonzerowinding(ael, deltas, xofs, hs); + + fz_advanceael(ael); + + if (ael->len > 0) + y ++; + else if (e < gel->len) + y = gel->edges[e].y; + } + + fz_emitdeltas(deltas, yd, xmin, xmax - xmin); + + savestuff(); + + return nil; +} + |