diff options
author | Tor Andersson <tor@ghostscript.com> | 2004-12-06 05:57:13 +0100 |
---|---|---|
committer | Tor Andersson <tor@ghostscript.com> | 2004-12-06 05:57:13 +0100 |
commit | 6162dc43d376fce8906160d51e3ab076d83632aa (patch) | |
tree | 61a17e608638b8164b2ca50e7837723f5af37d29 | |
parent | 1dfbba0a2142c0786714c1d476fc2736044a02ac (diff) | |
download | mupdf-6162dc43d376fce8906160d51e3ab076d83632aa.tar.xz |
mesh based shadings
-rw-r--r-- | Jamfile | 2 | ||||
-rw-r--r-- | include/fitz/shade.h | 32 | ||||
-rw-r--r-- | include/mupdf/rsrc.h | 5 | ||||
-rw-r--r-- | mupdf/shade.c | 113 | ||||
-rw-r--r-- | mupdf/shade1.c | 36 | ||||
-rw-r--r-- | mupdf/shade2.c | 96 | ||||
-rw-r--r-- | mupdf/shade3.c | 115 | ||||
-rw-r--r-- | render/rastshade.c | 355 | ||||
-rw-r--r-- | render/render.c | 2 | ||||
-rw-r--r-- | tree/shade.c | 4 |
10 files changed, 393 insertions, 367 deletions
@@ -127,6 +127,8 @@ Library libmupdf : mupdf/image.c mupdf/pattern.c mupdf/shade.c + mupdf/shade2.c + mupdf/shade3.c mupdf/cmap.c mupdf/unicode.c mupdf/fontagl.c diff --git a/include/fitz/shade.h b/include/fitz/shade.h index c8a47ffd..6687d42c 100644 --- a/include/fitz/shade.h +++ b/include/fitz/shade.h @@ -3,25 +3,27 @@ typedef struct fz_shade_s fz_shade; struct fz_shade_s { int refs; - fz_colorspace *cs; - fz_obj *background; - fz_rect *bbox; - int antialias; - - int type; - fz_obj *coords; - fz_obj *domain; - fz_matrix matrix; - fz_matrix matrix2; - void *function; - fz_obj *extend; - - /* ... */ + + fz_rect bbox; /* can be fz_infiniterect */ + fz_colorspace *colorspace; + + /* used by build.c -- not used in drawshade.c */ + fz_matrix matrix; /* matrix from pattern dict */ + int usebackground; /* background color for fills but not 'sh' */ + float background[FZ_MAXCOLORS]; + + int usefunction; + float function[512][FZ_MAXCOLORS]; + + int meshlen; + int meshcap; + float *mesh; /* [x y t] or [x y c1 ... cn] * 3 * meshlen */ }; + fz_shade *fz_keepshade(fz_shade *shade); void fz_dropshade(fz_shade *shade); fz_rect fz_boundshade(fz_shade *shade, fz_matrix ctm); -fz_error *fz_rendershade(fz_shade *shade, fz_matrix ctm, fz_colorspace *dsts, fz_pixmap *dstp, int over); +fz_error *fz_rendershade(fz_shade *shade, fz_matrix ctm, fz_colorspace *dsts, fz_pixmap *dstp); diff --git a/include/mupdf/rsrc.h b/include/mupdf/rsrc.h index e840ccec..82a201c9 100644 --- a/include/mupdf/rsrc.h +++ b/include/mupdf/rsrc.h @@ -80,6 +80,11 @@ fz_error *pdf_loadpattern(pdf_pattern **patp, pdf_xref *xref, fz_obj *obj, fz_ob pdf_pattern *pdf_keeppattern(pdf_pattern *pat); void pdf_droppattern(pdf_pattern *pat); +/* + * Shading + */ + +void pdf_setmeshvalue(float *mesh, int i, float x, float y, float t); fz_error *pdf_loadshade(fz_shade **shadep, pdf_xref *xref, fz_obj *obj, fz_obj *ref); /* diff --git a/mupdf/shade.c b/mupdf/shade.c index 0473e33f..b80453d5 100644 --- a/mupdf/shade.c +++ b/mupdf/shade.c @@ -2,11 +2,33 @@ #include <mupdf.h> fz_error * +pdf_loadshadefunction(fz_shade *shade, pdf_xref *xref, fz_obj *shading, float t0, float t1) +{ + fz_error *error; + float t; + fz_obj *obj; + pdf_function *func; + + obj = fz_dictgets(shading, "Function"); + error = pdf_loadfunction(&func, xref, obj); + if (error) return error; + + for (int i=0; i<512; ++i) { + t = t0 + (i / 511.) * (t1 - t0); + error = pdf_evalfunction(func, &t, 1, shade->function[i], 0); + } + if (error) return error; + + return nil; +} + +fz_error * pdf_loadshadedict(fz_shade **shadep, pdf_xref *xref, fz_obj *shading, fz_obj *ref, fz_matrix mat) { fz_error *error; fz_shade *shade; pdf_function *func; + fz_obj *obj; fz_colorspace *cs = nil; @@ -17,11 +39,11 @@ pdf_loadshadedict(fz_shade **shadep, pdf_xref *xref, fz_obj *shading, fz_obj *re shade->matrix = mat; + pdf_logshade("load shade dict {\n"); + sobj = fz_dictgets(shading, "ShadingType"); type = fz_toint(sobj); - shade->type = type; - sobj = fz_dictgets(shading, "ColorSpace"); if (sobj) { @@ -45,44 +67,48 @@ pdf_loadshadedict(fz_shade **shadep, pdf_xref *xref, fz_obj *shading, fz_obj *re fz_dropobj(sobj); } - shade->cs = cs; + shade->colorspace = cs; - shade->background = fz_dictgets(shading, "Background"); + pdf_logshade("colorspace %s\n", shade->colorspace->name); - //shade->bbox = fz_torect(fz_dictgets(shading, "BBox")); - shade->antialias = fz_toint(fz_dictgets(shading, "AntiAlias")); +// shade->background = fz_dictgets(shading, "Background"); - switch(type) { + obj = fz_dictgets(shading, "BBox"); + if (fz_isarray(obj)) + { + shade->bbox = pdf_torect(obj); + pdf_logshade("bbox [%g %g %g %g]\n", + shade->bbox.min.x, shade->bbox.min.y, + shade->bbox.max.x, shade->bbox.max.y); + } + + switch(type) + { case 1: - shade->domain = fz_dictgets(shading, "Domain"); -// shade->matrix = fz_dictgets(shading, "Matrix"); /* NYI */ - sobj = fz_dictgets(shading, "Function"); - error = pdf_loadfunction(&shade->function, xref, sobj); +// error = pdf_loadtype1shade(shade, xref, shading, ref, mat); if (error) goto cleanup; - break; case 2: + error = pdf_loadtype2shade(shade, xref, shading, ref, mat); + if (error) goto cleanup; + break; case 3: - shade->coords = fz_dictgets(shading, "Coords"); - shade->domain = fz_dictgets(shading, "Domain"); - sobj = fz_dictgets(shading, "Function"); -// if (fz_isindirect(sobj)) { -// error = pdf_loadindirect(&sobj, xref, sobj); -// } - error = pdf_loadfunction(&shade->function, xref, sobj); + error = pdf_loadtype3shade(shade, xref, shading, ref, mat); if (error) goto cleanup; - - shade->extend = fz_dictgets(shading, "Extend"); break; case 4: break; default: + break; }; + pdf_logshade("}\n"); + *shadep = shade; return nil; cleanup: + pdf_logshade("have an error: %s\n", error->msg); return error; } @@ -90,17 +116,16 @@ fz_error * pdf_loadshade(fz_shade **shadep, pdf_xref *xref, fz_obj *obj, fz_obj *ref) { fz_error *error = fz_throw("NYI"); - fz_shade *shade; fz_obj *shading; fz_matrix mat; fz_obj *extgstate; - shade = fz_malloc(sizeof(fz_shade)); - if (!shade) - return fz_outofmem; + if ((*shadep = pdf_finditem(xref->store, PDF_KSHADE, ref))) + return nil; + + pdf_logshade("loading shade %d %d {\n", fz_tonum(ref), fz_togen(ref)); -printf("loading shade pattern\n"); shading = fz_dictgets(obj, "Shading"); if (fz_isindirect(shading)) { @@ -109,31 +134,39 @@ printf("loading shade pattern\n"); } obj = fz_dictgets(obj, "Matrix"); - if (obj) { - mat.a = fz_toreal(fz_arrayget(obj, 0)); - mat.b = fz_toreal(fz_arrayget(obj, 1)); - mat.c = fz_toreal(fz_arrayget(obj, 2)); - mat.d = fz_toreal(fz_arrayget(obj, 3)); - mat.e = fz_toreal(fz_arrayget(obj, 4)); - mat.f = fz_toreal(fz_arrayget(obj, 5)); - } - else { + if (obj) + mat = pdf_tomatrix(obj); + else mat = fz_identity(); - } if (fz_isdict(shading)) { - pdf_loadshadedict(&shade, xref, shading, ref, mat); + pdf_loadshadedict(shadep, xref, shading, ref, mat); } else if (pdf_isstream(xref, fz_tonum(shading), fz_togen(shading))) { - goto cleanup; /* NYI */ } - else + else { + } + + pdf_logshade("}\n"); + + if (*shadep) + { + error = pdf_storeitem(xref->store, PDF_KSHADE, ref, *shadep); + if (error) goto cleanup; + } - *shadep = shade; return nil; cleanup: return error; } +void +pdf_setmeshvalue(float *mesh, int i, float x, float y, float t) +{ + pdf_logshade("mesh %d: %g %g %g\n", i, x, y, t); + mesh[i*3+0] = x; + mesh[i*3+1] = y; + mesh[i*3+2] = t; +} diff --git a/mupdf/shade1.c b/mupdf/shade1.c new file mode 100644 index 00000000..5ce3ee95 --- /dev/null +++ b/mupdf/shade1.c @@ -0,0 +1,36 @@ +#include <fitz.h> +#include <mupdf.h> + +fz_error * +pdf_buildt1shademesh(fz_shade *shade, pdf_xref *xref, fz_obj *shading, + fz_obj *ref, fz_matrix mat) +{ + fz_error *error; + + shade->meshlen = 2; + shade->mesh = (float*) malloc(sizeof(float) * 9 * meshlen); + + pdf_setmeshvalue(mesh, 0, shade-> +cleanup: + return error; +} + +fz_error * +pdf_loadtype1shade(fz_shade *shade, pdf_xref *xref, fz_obj *shading, + fz_obj *ref, fz_matrix mat) +{ + fz_error *error; + fz_obj *obj; + + obj = fz_dictgets(shading, "Domain"); + if (obj) { + t0 = fz_toreal(fz_arrayget(obj, 0)); + t1 = fz_toreal(fz_arrayget(obj, 1)); + } else { + t0 = 0.; + t1 = 1.; + } + + pdf_loadshadefunction(shade, xref, shading); + pdf_buildt1shademesh(shade, xref, shading, ref, mat); +} diff --git a/mupdf/shade2.c b/mupdf/shade2.c new file mode 100644 index 00000000..b9f86d5f --- /dev/null +++ b/mupdf/shade2.c @@ -0,0 +1,96 @@ +#include <fitz.h> +#include <mupdf.h> + +fz_error * +pdf_buildt2shademesh(fz_shade *shade, pdf_xref *xref, fz_obj *shading, + fz_obj *ref, fz_matrix mat) +{ + fz_error *error; + float x0, y0, x1, y1; + float t0, t1; + fz_obj *obj; + pdf_function *func; + + pdf_logshade("loading type2 shade {\n"); + + obj = fz_dictgets(shading, "Coords"); + x0 = fz_toreal(fz_arrayget(obj, 0)); + y0 = fz_toreal(fz_arrayget(obj, 1)); + x1 = fz_toreal(fz_arrayget(obj, 2)); + y1 = fz_toreal(fz_arrayget(obj, 3)); + + pdf_logshade("coords %g %g %g %g\n", x0, y0, x1, y1); + + obj = fz_dictgets(shading, "Domain"); + if (obj) { + t0 = fz_toreal(fz_arrayget(obj, 0)); + t1 = fz_toreal(fz_arrayget(obj, 1)); + } else { + t0 = 0.; + t1 = 1.; + } + + pdf_logshade("domain %g %g\n", t0, t1); + + pdf_loadshadefunction(shade, xref, shading, t0, t1); + + shade->meshlen = 2; + shade->mesh = (float*) malloc(sizeof(float) * 3*3 * shade->meshlen); + + float theta; + theta = atan2(x1 - x0, y1 - y0); + + pdf_logshade("theta=%g\n", theta); + + fz_point p1, p2, p3, p4; + + p1.x = x0 + 100 * cos(theta); + p1.y = y0 + 100 * sin(theta); + p2.x = x1 + 100 * cos(theta); + p2.y = y1 + 100 * sin(theta); + p3.x = x0 - 100 * cos(theta); + p3.y = y0 - 100 * sin(theta); + p4.x = x1 - 100 * cos(theta); + p4.y = y1 - 100 * sin(theta); + + pdf_logshade("p1 %g %g\n", p1.x, p1.y); + pdf_logshade("p2 %g %g\n", p2.x, p2.y); + pdf_logshade("p3 %g %g\n", p3.x, p3.y); + pdf_logshade("p4 %g %g\n", p4.x, p4.y); + + pdf_setmeshvalue(shade->mesh, 0, p1.x, p1.y, 0); + pdf_setmeshvalue(shade->mesh, 1, p2.x, p2.y, 511); + pdf_setmeshvalue(shade->mesh, 2, p4.x, p4.y, 511); + pdf_setmeshvalue(shade->mesh, 3, p1.x, p1.y, 0); + pdf_setmeshvalue(shade->mesh, 4, p4.x, p4.y, 511); + pdf_setmeshvalue(shade->mesh, 5, p3.x, p3.y, 0); + + /* + if (shade->extend) { + e0 = fz_toint(fz_arrayget(shade->extend, 0)); + e1 = fz_toint(fz_arrayget(shade->extend, 1)); + } else { + e0 = 0; + e1 = 0; + } + */ + + pdf_logshade("}\n"); + + return nil; + +cleanup: + return error; +} + +fz_error * +pdf_loadtype2shade(fz_shade *shade, pdf_xref *xref, fz_obj *shading, + fz_obj *ref, fz_matrix mat) +{ + fz_error *error; + fz_obj *obj; + + pdf_buildt2shademesh(shade, xref, shading, ref, mat); + + return nil; +} diff --git a/mupdf/shade3.c b/mupdf/shade3.c new file mode 100644 index 00000000..c77fbec6 --- /dev/null +++ b/mupdf/shade3.c @@ -0,0 +1,115 @@ +#include <fitz.h> +#include <mupdf.h> + +fz_error * +fz_buildannulusmesh(float* mesh, + int x0, int y0, int r0, int x1, int y1, int r1, + float c0, float c1, int nsegs) +{ + fz_error *error; + fz_point pt1, pt2, pt3, pt4; + float step; + float theta; + + theta = 0.; + step = 3.1415921 * 2. / (float)nsegs; + + for (int n=0; theta < step*nsegs; theta += step) { + pt1.x = cos (theta) * r1 + x1; + pt1.y = sin (theta) * r1 + y1; + pt2.x = cos (theta) * r0 + x0; + pt2.y = sin (theta) * r0 + y0; + pt3.x = cos (theta+step) * r1 + x1; + pt3.y = sin (theta+step) * r1 + y1; + pt4.x = cos (theta+step) * r0 + x0; + pt4.y = sin (theta+step) * r0 + y0; + + pdf_setmeshvalue(mesh, n, pt1.x, pt1.y, c1); + ++n; + pdf_setmeshvalue(mesh, n, pt2.x, pt2.y, c0); + ++n; + pdf_setmeshvalue(mesh, n, pt4.x, pt4.y, c0); + ++n; + + pdf_setmeshvalue(mesh, n, pt1.x, pt1.y, c1); + ++n; + pdf_setmeshvalue(mesh, n, pt3.x, pt3.y, c1); + ++n; + pdf_setmeshvalue(mesh, n, pt4.x, pt4.y, c0); + ++n; + } + + return error; +} + +fz_error * +pdf_buildt3shademesh(fz_shade *shade, pdf_xref *xref, fz_obj *shading, + fz_obj *ref, fz_matrix mat) +{ + fz_error *error; + float x0, y0, r0, x1, y1, r1; + float t0, t1; + fz_obj *obj; + pdf_function *func; + + obj = fz_dictgets(shading, "Coords"); + x0 = fz_toreal(fz_arrayget(obj, 0)); + y0 = fz_toreal(fz_arrayget(obj, 1)); + r0 = fz_toreal(fz_arrayget(obj, 2)); + x1 = fz_toreal(fz_arrayget(obj, 3)); + y1 = fz_toreal(fz_arrayget(obj, 4)); + r1 = fz_toreal(fz_arrayget(obj, 5)); + + obj = fz_dictgets(shading, "Domain"); + if (obj) { + t0 = fz_toreal(fz_arrayget(obj, 0)); + t1 = fz_toreal(fz_arrayget(obj, 1)); + } else { + t0 = 0.; + t1 = 1.; + } + + pdf_loadshadefunction(shade, xref, shading, t0, t1); + + shade->meshlen = 36 * 10 * 2; + shade->mesh = (float*) malloc(sizeof(float) * 9 * shade->meshlen); + + float tn, tn1; + float tstep = (t1 - t0) / 10.; + tn = t0; + tn1 = t0 + tstep; + + for (int i = 0; i < 10; ++i) { + float tx0, ty0, tr0; + float tx1, ty1, tr1; + int c0, c1; + + tx0 = x0 + (x1 - x0) * i / 10.; + ty0 = y0 + (y1 - y0) * i / 10.; + tr0 = r0 + (r1 - r0) * i / 10.; + tx1 = x0 + (x1 - x0) * (i + 1) / 10.; + ty1 = y0 + (y1 - y0) * (i + 1) / 10.; + tr1 = r0 + (r1 - r0) * (i + 1) / 10.; + c0 = 511. * i / 10; + c1 = 511. * (i + 1) / 10.; + + fz_buildannulusmesh(&(shade->mesh[i*36*2*9]), tx0, ty0, tr0, tx1, ty1, tr1, c0, c1, 36); + } + + return nil; + +cleanup: + return error; +} + +fz_error * +pdf_loadtype3shade(fz_shade *shade, pdf_xref *xref, fz_obj *shading, + fz_obj *ref, fz_matrix mat) +{ + fz_error *error; + fz_obj *obj; + + error = pdf_buildt3shademesh(shade, xref, shading, ref, mat); + + return error; +} diff --git a/render/rastshade.c b/render/rastshade.c index 4affae36..b002de82 100644 --- a/render/rastshade.c +++ b/render/rastshade.c @@ -1,127 +1,15 @@ #include <fitz.h> -fz_error * -fz_rendershade1(fz_shade *shade, fz_matrix ctm, fz_colorspace *dsts, fz_pixmap *dstp, int over) +typedef struct fz_vertex { - fz_error *error; - int x, y; - int dx, dy, dw, dh; - float x0, y0, x1, y1; - float xp; - float yp; - // pdf_function *func; - - dx = dstp->x; - dy = dstp->y; - dw = dstp->w; - dh = dstp->h; - - x0 = 0; - y0 = 0; - x1 = 0; - y1 = 0; - - for (int y = 0; y < dh; ++y) { - for (int x = 0; x < dw; ++x) { - float outcol[16], outn; - float destcol[16]; - xp = ((x1 - x0) * (x - x0) + (y1 - y0) * (y - y0)) - / ((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0)); - - error = pdf_evalfunction(shade->function, &xp, 1, outcol, outn); - shade->cs->convcolor(shade->cs, outcol, dsts, destcol); - dstp->samples[(x+y*dw)*4+0] = 255; - dstp->samples[(x+y*dw)*4+1] = destcol[0] * 255; - dstp->samples[(x+y*dw)*4+2] = destcol[1] * 255; - dstp->samples[(x+y*dw)*4+3] = destcol[2] * 255; - } - } - - return error; -} + float x, y; + float l; +} fz_vertex; -fz_error * -fz_rendershade2(fz_shade *shade, fz_matrix ctm, fz_colorspace *dsts, fz_pixmap *dstp, int over) +typedef struct fz_triangle { - fz_error *error; - int x, y; - int dx, dy, dw, dh; - float x0, y0, x1, y1; - float t0, t1; - int e0, e1; - float xp; - float yp; - // pdf_function *func; - int destcol[512][4]; - - ctm = fz_concat(shade->matrix, ctm); - - dx = dstp->x; - dy = dstp->y; - dw = dstp->w; - dh = dstp->h; - - x0 = fz_toreal(fz_arrayget(shade->coords, 0)); - y0 = fz_toreal(fz_arrayget(shade->coords, 1)); - x1 = fz_toreal(fz_arrayget(shade->coords, 2)); - y1 = fz_toreal(fz_arrayget(shade->coords, 3)); - - if (shade->domain) { - t0 = fz_toreal(fz_arrayget(shade->domain, 0)); - t1 = fz_toreal(fz_arrayget(shade->domain, 1)); - } else { - t0 = 0.; - t1 = 1.; - } - - if (shade->extend) { - e0 = fz_toint(fz_arrayget(shade->extend, 0)); - e1 = fz_toint(fz_arrayget(shade->extend, 1)); - } else { - e0 = 0; - e1 = 0; - } - - /* build color table */ - for (int i=0; i<512; ++i) { - float destc[4]; - float outcol[4]; - float t = (i / 511.) / (t1 - t0) - t0; - error = pdf_evalfunction(shade->function, &t, 1, outcol, 3); - shade->cs->convcolor(shade->cs, outcol, dsts, destc); - destcol[i][0] = destc[0]*255.; - destcol[i][1] = destc[1]*255.; - destcol[i][2] = destc[2]*255.; - } - - for (int y = 0; y < dh; ++y) { - for (int x = 0; x < dw; ++x) { - int cidx; - float t; - float ix, iy; - - xp = x + dx; - yp = y + dy; - - ix = (xp * ctm.d - yp * ctm.c + ctm.c * ctm.f - ctm.e*ctm.d) - / (ctm.a * ctm.d - ctm.b * ctm.c); /* inverse */ - iy = (xp * ctm.b - yp * ctm.a + ctm.a * ctm.f - ctm.b*ctm.e) - / (ctm.b * ctm.c - ctm.a * ctm.d); /* inverse */ - - t = ((x1 - x0) * (ix - x0) + (y1 - y0) * (iy - y0)) - / ((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0)); - - cidx = ((t + t0) * (t1 - t0)) * 511; - - dstp->samples[(x+y*dw)*4+0] = 255; - dstp->samples[(x+y*dw)*4+1] = destcol[cidx][0]; - dstp->samples[(x+y*dw)*4+2] = destcol[cidx][1]; - dstp->samples[(x+y*dw)*4+3] = destcol[cidx][2]; - } - } - - return error; -} + fz_vertex vertex[3]; +} fz_triangle; #define putpixel(x, y, c) \ if (x >= 0 && x < dstp->w && y >= 0 && y < dstp->h) { \ @@ -130,18 +18,6 @@ fz_rendershade2(fz_shade *shade, fz_matrix ctm, fz_colorspace *dsts, fz_pixmap * dstp->samples[((x)+(y)*(dstp->w))*4+2] = c[1]; \ dstp->samples[((x)+(y)*(dstp->w))*4+3] = c[2]; \ } \ - - -typedef struct fz_vertex -{ - float x, y; - float l; -} fz_vertex; - -typedef struct fz_triangle -{ - fz_vertex vertex[3]; -} fz_triangle; void fz_swapvertex(fz_vertex *a, fz_vertex *b) { @@ -151,17 +27,11 @@ void fz_swapvertex(fz_vertex *a, fz_vertex *b) *b = temp; } -int fz_pointinrect(fz_point point, fz_rect rect) -{ - if (point.x < rect.min.x || point.x > rect.max.x) return 0; - if (point.y < rect.min.y || point.y > rect.max.y) return 0; - - return 1; -} - -void fz_drawgouraudtriangle(fz_triangle triangle, fz_pixmap *dstp, int destcol[512][4], +fz_error * +fz_drawgouraudtriangle(fz_triangle triangle, fz_pixmap *dstp, int destcol[512][4], int bx0, int by0, int bx1, int by1) { + fz_error *error; fz_vertex a, b, c; a = triangle.vertex[0]; @@ -173,10 +43,10 @@ void fz_drawgouraudtriangle(fz_triangle triangle, fz_pixmap *dstp, int destcol[5 fz_rect bb1; fz_rect bb2; - bb1.min.x = min(min(a.x, b.x), c.x); - bb1.min.y = min(min(a.y, b.y), c.y); - bb1.max.x = max(max(a.x, b.x), c.x); - bb1.max.y = max(max(a.y, b.y), c.y); + bb1.min.x = MIN(MIN(a.x, b.x), c.x); + bb1.min.y = MIN(MIN(a.y, b.y), c.y); + bb1.max.x = MAX(MAX(a.x, b.x), c.x); + bb1.max.y = MAX(MAX(a.y, b.y), c.y); bb2.min.x = bx0; bb2.min.y = by0; @@ -184,7 +54,7 @@ void fz_drawgouraudtriangle(fz_triangle triangle, fz_pixmap *dstp, int destcol[5 bb2.max.y = by1; if (fz_isemptyrect(fz_intersectrects(bb1, bb2))) - return; + return nil; } if(a.y > b.y) fz_swapvertex(&a, &b); @@ -216,8 +86,9 @@ void fz_drawgouraudtriangle(fz_triangle triangle, fz_pixmap *dstp, int destcol[5 for(int x = (int)(xab); x != maxx+incx; x += incx) { - if (l >= 0 && l <= 511) - putpixel(x, y, destcol[(int)(l)]); + if (l < 0) l = 0; + if (l > 511) l = 511; + putpixel(x, y, destcol[(int)(l)]); l += slope_l; } @@ -243,8 +114,9 @@ void fz_drawgouraudtriangle(fz_triangle triangle, fz_pixmap *dstp, int destcol[5 float l = lbc; for(int x = (int)(xbc); x != maxx+incx; x += incx) { - if (l >= 0 && l <= 511) - putpixel(x, y, destcol[(int)(l)]); + if (l < 0) l = 0; + if (l > 511) l = 511; + putpixel(x, y, destcol[(int)(l)]); l += slope_l; } @@ -253,179 +125,44 @@ void fz_drawgouraudtriangle(fz_triangle triangle, fz_pixmap *dstp, int destcol[5 xbc += slopebc_x; lbc += slopebc_l; } -} - -fz_error * -fz_renderannulus(int x0, int y0, int r0, int x1, int y1, int r1, int t0, int t1, - fz_matrix ctm, fz_pixmap *dstp, int destcol[512][4]) -{ - fz_point pt1, pt2, pt3, pt4; - fz_triangle triangle; - float step; - float theta; - - ctm = fz_concat(ctm, fz_translate(-dstp->x, -dstp->y)); - - /* - theta = atan((y1 - y0) / (x1 - x0)); - if ((x1 - x0) < 0) theta += M_PI; - theta -= (M_PI / 2.); - */ - theta = 0; - step = 3.1415921 * 2 / 36.; - for (; theta < step*36; theta += step) { - pt1.x = cos (theta) * r1 + x1; - pt1.y = sin (theta) * r1 + y1; - pt2.x = cos (theta) * r0 + x0; - pt2.y = sin (theta) * r0 + y0; - pt3.x = cos (theta+step) * r1 + x1; - pt3.y = sin (theta+step) * r1 + y1; - pt4.x = cos (theta+step) * r0 + x0; - pt4.y = sin (theta+step) * r0 + y0; - - pt1 = fz_transformpoint(ctm, pt1); - pt2 = fz_transformpoint(ctm, pt2); - pt3 = fz_transformpoint(ctm, pt3); - pt4 = fz_transformpoint(ctm, pt4); - - triangle.vertex[0].x = pt1.x; - triangle.vertex[0].y = pt1.y; - triangle.vertex[0].l = t1; - triangle.vertex[1].x = pt2.x; - triangle.vertex[1].y = pt2.y; - triangle.vertex[1].l = t0; - triangle.vertex[2].x = pt4.x; - triangle.vertex[2].y = pt4.y; - triangle.vertex[2].l = t0; - fz_drawgouraudtriangle(triangle, dstp, destcol, 0, 0, dstp->w, dstp->h); - - triangle.vertex[0].x = pt1.x; - triangle.vertex[0].y = pt1.y; - triangle.vertex[0].l = t1; - triangle.vertex[1].x = pt3.x; - triangle.vertex[1].y = pt3.y; - triangle.vertex[1].l = t1; - triangle.vertex[2].x = pt4.x; - triangle.vertex[2].y = pt4.y; - triangle.vertex[2].l = t0; - - fz_drawgouraudtriangle(triangle, dstp, destcol, 0, 0, dstp->w, dstp->h); - } + return nil; } fz_error * -fz_rendershade3(fz_shade *shade, fz_matrix ctm, fz_colorspace *dsts, fz_pixmap *dstp, int over) +fz_rendershade(fz_shade *shade, fz_matrix ctm, fz_colorspace *dsts, fz_pixmap *dstp) { - fz_error *error; int x, y; - int dx, dy, dw, dh; - float x0, y0, r0, x1, y1, r1; - float t0, t1; - float xp; - float yp; - int e0, e1; - float t; + fz_triangle triangle; + fz_point point; int destcol[512][4]; - int cidx0, cidx1; - - ctm = fz_concat(shade->matrix, ctm); - - dx = dstp->x; dy = dstp->y; - dw = dstp->w; dh = dstp->h; - - x0 = fz_toreal(fz_arrayget(shade->coords, 0)); - y0 = fz_toreal(fz_arrayget(shade->coords, 1)); - r0 = fz_toreal(fz_arrayget(shade->coords, 2)); - x1 = fz_toreal(fz_arrayget(shade->coords, 3)); - y1 = fz_toreal(fz_arrayget(shade->coords, 4)); - r1 = fz_toreal(fz_arrayget(shade->coords, 5)); - - if (shade->domain) { - t0 = fz_toreal(fz_arrayget(shade->domain, 0)); - t1 = fz_toreal(fz_arrayget(shade->domain, 1)); - } else { - t0 = 0.; - t1 = 1.; - } - - if (shade->extend) { - e0 = fz_toint(fz_arrayget(shade->extend, 0)); - e1 = fz_toint(fz_arrayget(shade->extend, 1)); - } else { - e0 = 0; - e1 = 0; - } - - /* build color table */ + for (int i=0; i<512; ++i) { - float destc[4]; - float outcol[4]; - float t = (i / 511.) / (t1 - t0) - t0; - error = pdf_evalfunction(shade->function, &t, 1, outcol, 3); - shade->cs->convcolor(shade->cs, outcol, dsts, destc); - destcol[i][0] = destc[0]*255.; - destcol[i][1] = destc[1]*255.; - destcol[i][2] = destc[2]*255.; + float col[4]; + shade->colorspace->convcolor(shade->colorspace, + shade->function[i], dsts, col); + for (int j=0; j<3; ++j) { + destcol[i][j] = col[j] * 255; + } } - int steps = 10; - float step = 0.1; - steps = 10; - step = 0.1; - for (int i=0; i<steps ; ++i) { - float nt0, nt1; - float nx0, ny0, nr0; - float nx1, ny1, nr1; - - nt0 = t0 + ((t1 - t0) * step * (i)); - nt1 = t0 + ((t1 - t0) * step * (i+1)); - - nx0 = x0 + ((x1 - x0) * step * (i)); - nx1 = x0 + ((x1 - x0) * step * (i+1)); + if (!shade) return nil; - ny0 = y0 + ((y1 - y0) * step * (i)); - ny1 = y0 + ((y1 - y0) * step * (i+1)); - - nr0 = r0 + ((r1 - r0) * step * (i)); - nr1 = r0 + ((r1 - r0) * step * (i+1)); - - cidx0 = ((nt0 + t0) * (t1 - t0)) * 511; - cidx1 = ((nt1 + t0) * (t1 - t0)) * 511; + ctm = fz_concat(shade->matrix, ctm); + ctm = fz_concat(ctm, fz_translate(-dstp->x, -dstp->y)); - if (cidx0 < 0 || cidx0 > 511) { - int a; - a++; - } - if (cidx1 < 0 || cidx1 > 511) { - int a; - a++; + int ncomp = shade->meshcap; + for (int i=0; i<shade->meshlen; ++i) { + for (int j=0; j<3; ++j) { + point.x = shade->mesh[(i*3+j)*3+0]; + point.y = shade->mesh[(i*3+j)*3+1]; + point = fz_transformpoint(ctm, point); + triangle.vertex[j].x = point.x; + triangle.vertex[j].y = point.y; + triangle.vertex[j].l = shade->mesh[(i*3+j)*3+2]; } - - fz_renderannulus(nx0, ny0, nr0, nx1, ny1, nr1, cidx0, cidx1, ctm, dstp, destcol); - } -} + fz_drawgouraudtriangle(triangle, dstp, destcol, 0, 0, dstp->w, dstp->h); + } -fz_error * -fz_rendershade(fz_shade *shade, fz_matrix ctm, fz_colorspace *dsts, fz_pixmap *dstp, int over) -{ - int x, y, w, h; - - switch (shade->type) { - case 1: - fz_rendershade1(shade, ctm, dsts, dstp, over); - break; - case 2: - fz_rendershade2(shade, ctm, dsts, dstp, over); - break; - case 3: - fz_rendershade3(shade, ctm, dsts, dstp, over); - break; - default: - } - - //dstp->samples - // if (!over) - // fz_clearpixmap(dstp); return nil; } diff --git a/render/render.c b/render/render.c index 3d745165..41c0d3c1 100644 --- a/render/render.c +++ b/render/render.c @@ -492,7 +492,7 @@ rendershade(fz_renderer *gc, fz_shadenode *node, fz_matrix ctm) if (error) return error; - return fz_rendershade(node->shade, ctm, gc->model, gc->dest, 0); + return fz_rendershade(node->shade, ctm, gc->model, gc->dest); } /* diff --git a/tree/shade.c b/tree/shade.c index cb33072e..f092fa9d 100644 --- a/tree/shade.c +++ b/tree/shade.c @@ -12,8 +12,8 @@ fz_dropshade(fz_shade *shade) { if (--shade->refs == 0) { - if (shade->cs) - fz_dropcolorspace(shade->cs); + if (shade->colorspace) + fz_dropcolorspace(shade->colorspace); fz_free(shade); } } |