summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Jamfile2
-rw-r--r--include/fitz/shade.h32
-rw-r--r--include/mupdf/rsrc.h5
-rw-r--r--mupdf/shade.c113
-rw-r--r--mupdf/shade1.c36
-rw-r--r--mupdf/shade2.c96
-rw-r--r--mupdf/shade3.c115
-rw-r--r--render/rastshade.c355
-rw-r--r--render/render.c2
-rw-r--r--tree/shade.c4
10 files changed, 393 insertions, 367 deletions
diff --git a/Jamfile b/Jamfile
index df98e735..81992755 100644
--- a/Jamfile
+++ b/Jamfile
@@ -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);
}
}