#include 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; }