summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--draw/draw_mesh.c200
-rw-r--r--fitz/res_shade.c179
2 files changed, 185 insertions, 194 deletions
diff --git a/draw/draw_mesh.c b/draw/draw_mesh.c
index 532f78f4..885a6944 100644
--- a/draw/draw_mesh.c
+++ b/draw/draw_mesh.c
@@ -448,184 +448,6 @@ fz_paint_triangle(fz_pixmap *pix, float *av, float *bv, float *cv, int n, fz_bbo
}
}
-static void
-fz_paint_quad(fz_pixmap *pix,
- fz_point p0, fz_point p1, fz_point p2, fz_point p3,
- float c0, float c1, float c2, float c3,
- int n, fz_bbox bbox)
-{
- float v[4][3];
-
- v[0][0] = p0.x;
- v[0][1] = p0.y;
- v[0][2] = c0;
-
- v[1][0] = p1.x;
- v[1][1] = p1.y;
- v[1][2] = c1;
-
- v[2][0] = p2.x;
- v[2][1] = p2.y;
- v[2][2] = c2;
-
- v[3][0] = p3.x;
- v[3][1] = p3.y;
- v[3][2] = c3;
-
- fz_paint_triangle(pix, v[0], v[2], v[3], n, bbox);
- fz_paint_triangle(pix, v[0], v[3], v[1], n, bbox);
-}
-
-/*
- * linear, radial and mesh painting
- */
-
-#define HUGENUM 32000 /* how far to extend axial/radial shadings */
-#define RADSEGS 32 /* how many segments to generate for radial meshes */
-
-static fz_point
-fz_point_on_circle(fz_point p, float r, float theta)
-{
- p.x = p.x + my_cosf(theta) * r;
- p.y = p.y + my_sinf(theta) * r;
-
- return p;
-}
-
-static void
-fz_paint_linear(fz_shade *shade, fz_matrix ctm, fz_pixmap *dest, fz_bbox bbox)
-{
- fz_point p0, p1;
- fz_point v0, v1, v2, v3;
- fz_point e0, e1;
- float theta;
-
- p0.x = shade->u.a_or_r.coords[0][0];
- p0.y = shade->u.a_or_r.coords[0][1];
- p0 = fz_transform_point(ctm, p0);
-
- p1.x = shade->u.a_or_r.coords[1][0];
- p1.y = shade->u.a_or_r.coords[1][1];
- p1 = fz_transform_point(ctm, p1);
-
- theta = my_atan2f(p1.y - p0.y, p1.x - p0.x);
- theta += (float)M_PI * 0.5f;
-
- v0 = fz_point_on_circle(p0, HUGENUM, theta);
- v1 = fz_point_on_circle(p1, HUGENUM, theta);
- v2 = fz_point_on_circle(p0, -HUGENUM, theta);
- v3 = fz_point_on_circle(p1, -HUGENUM, theta);
-
- fz_paint_quad(dest, v0, v1, v2, v3, 0, 255, 0, 255, 3, bbox);
-
- if (shade->u.a_or_r.extend[0])
- {
- e0.x = v0.x - (p1.x - p0.x) * HUGENUM;
- e0.y = v0.y - (p1.y - p0.y) * HUGENUM;
-
- e1.x = v2.x - (p1.x - p0.x) * HUGENUM;
- e1.y = v2.y - (p1.y - p0.y) * HUGENUM;
-
- fz_paint_quad(dest, e0, e1, v0, v2, 0, 0, 0, 0, 3, bbox);
- }
-
- if (shade->u.a_or_r.extend[1])
- {
- e0.x = v1.x + (p1.x - p0.x) * HUGENUM;
- e0.y = v1.y + (p1.y - p0.y) * HUGENUM;
-
- e1.x = v3.x + (p1.x - p0.x) * HUGENUM;
- e1.y = v3.y + (p1.y - p0.y) * HUGENUM;
-
- fz_paint_quad(dest, e0, e1, v1, v3, 255, 255, 255, 255, 3, bbox);
- }
-}
-
-static void
-fz_paint_annulus(fz_matrix ctm,
- fz_point p0, float r0, float c0,
- fz_point p1, float r1, float c1,
- fz_pixmap *dest, fz_bbox bbox)
-{
- fz_point t0, t1, t2, t3, b0, b1, b2, b3;
- float theta, step;
- int i;
-
- theta = my_atan2f(p1.y - p0.y, p1.x - p0.x);
- step = (float)M_PI * 2 / RADSEGS;
-
- for (i = 0; i < RADSEGS / 2; i++)
- {
- t0 = fz_point_on_circle(p0, r0, theta + i * step);
- t1 = fz_point_on_circle(p0, r0, theta + i * step + step);
- t2 = fz_point_on_circle(p1, r1, theta + i * step);
- t3 = fz_point_on_circle(p1, r1, theta + i * step + step);
- b0 = fz_point_on_circle(p0, r0, theta - i * step);
- b1 = fz_point_on_circle(p0, r0, theta - i * step - step);
- b2 = fz_point_on_circle(p1, r1, theta - i * step);
- b3 = fz_point_on_circle(p1, r1, theta - i * step - step);
-
- t0 = fz_transform_point(ctm, t0);
- t1 = fz_transform_point(ctm, t1);
- t2 = fz_transform_point(ctm, t2);
- t3 = fz_transform_point(ctm, t3);
- b0 = fz_transform_point(ctm, b0);
- b1 = fz_transform_point(ctm, b1);
- b2 = fz_transform_point(ctm, b2);
- b3 = fz_transform_point(ctm, b3);
-
- fz_paint_quad(dest, t0, t1, t2, t3, c0, c0, c1, c1, 3, bbox);
- fz_paint_quad(dest, b0, b1, b2, b3, c0, c0, c1, c1, 3, bbox);
- }
-}
-
-static void
-fz_paint_radial(fz_shade *shade, fz_matrix ctm, fz_pixmap *dest, fz_bbox bbox)
-{
- fz_point p0, p1;
- float r0, r1;
- fz_point e;
- float er, rs;
-
- p0.x = shade->u.a_or_r.coords[0][0];
- p0.y = shade->u.a_or_r.coords[0][1];
- r0 = shade->u.a_or_r.coords[0][2];
-
- p1.x = shade->u.a_or_r.coords[1][0];
- p1.y = shade->u.a_or_r.coords[1][1];
- r1 = shade->u.a_or_r.coords[1][2];
-
- if (shade->u.a_or_r.extend[0])
- {
- if (r0 < r1)
- rs = r0 / (r0 - r1);
- else
- rs = -HUGENUM;
-
- e.x = p0.x + (p1.x - p0.x) * rs;
- e.y = p0.y + (p1.y - p0.y) * rs;
- er = r0 + (r1 - r0) * rs;
-
- fz_paint_annulus(ctm, e, er, 0, p0, r0, 0, dest, bbox);
- }
-
- fz_paint_annulus(ctm, p0, r0, 0, p1, r1, 255, dest, bbox);
-
- if (shade->u.a_or_r.extend[1])
- {
- if (r0 > r1)
- rs = r1 / (r1 - r0);
- else
- rs = -HUGENUM;
-
- e.x = p1.x + (p0.x - p1.x) * rs;
- e.y = p1.y + (p0.y - p1.y) * rs;
- er = r1 + (r0 - r1) * rs;
-
- fz_paint_annulus(ctm, p1, r1, 255, e, er, 255, dest, bbox);
- }
-}
-
struct paint_tri_data
{
fz_context *ctx;
@@ -679,6 +501,7 @@ fz_paint_shade(fz_context *ctx, fz_shade *shade, fz_matrix ctm, fz_pixmap *dest,
fz_pixmap *temp = NULL;
fz_pixmap *conv = NULL;
float color[FZ_MAX_COLORS];
+ struct paint_tri_data ptd;
int i, k;
fz_var(temp);
@@ -706,21 +529,12 @@ fz_paint_shade(fz_context *ctx, fz_shade *shade, fz_matrix ctm, fz_pixmap *dest,
temp = dest;
}
- switch (shade->type)
- {
- case FZ_LINEAR: fz_paint_linear(shade, ctm, temp, bbox); break;
- case FZ_RADIAL: fz_paint_radial(shade, ctm, temp, bbox); break;
- default:
- {
- struct paint_tri_data ptd;
- ptd.ctx = ctx;
- ptd.dest = temp;
- ptd.shade = shade;
- ptd.bbox = bbox;
- fz_process_mesh(ctx, shade, ctm, &do_paint_tri, &ptd);
- break;
- }
- }
+ ptd.ctx = ctx;
+ ptd.dest = temp;
+ ptd.shade = shade;
+ ptd.bbox = bbox;
+
+ fz_process_mesh(ctx, shade, ctm, &do_paint_tri, &ptd);
if (shade->use_function)
{
diff --git a/fitz/res_shade.c b/fitz/res_shade.c
index 231a7ba0..4bd3ad39 100644
--- a/fitz/res_shade.c
+++ b/fitz/res_shade.c
@@ -12,7 +12,7 @@ static void
paint_quad(fz_mesh_processor *painter, fz_vertex *v0, fz_vertex *v1, fz_vertex *v2, fz_vertex *v3)
{
painter->process(painter->process_arg, v0, v1, v3);
- painter->process(painter->process_arg, v1, v3, v2);
+ painter->process(painter->process_arg, v2, v3, v1);
}
static void
@@ -66,6 +66,179 @@ fz_mesh_type1_process(fz_context *ctx, fz_shade *shade, fz_matrix ctm, fz_mesh_p
}
}
+/* FIXME: Nasty */
+#define HUGENUM 32000 /* how far to extend axial/radial shadings */
+
+static fz_point
+fz_point_on_circle(fz_point p, float r, float theta)
+{
+ p.x = p.x + cosf(theta) * r;
+ p.y = p.y + sinf(theta) * r;
+
+ return p;
+}
+
+static void
+fz_mesh_type2_process(fz_context *ctx, fz_shade *shade, fz_matrix ctm, fz_mesh_processor *painter)
+{
+ fz_point p0, p1;
+ fz_vertex v0, v1, v2, v3;
+ fz_vertex e0, e1;
+ float theta;
+
+ p0.x = shade->u.a_or_r.coords[0][0];
+ p0.y = shade->u.a_or_r.coords[0][1];
+ p0 = fz_transform_point(ctm, p0);
+
+ p1.x = shade->u.a_or_r.coords[1][0];
+ p1.y = shade->u.a_or_r.coords[1][1];
+ p1 = fz_transform_point(ctm, p1);
+
+ theta = atan2f(p1.y - p0.y, p1.x - p0.x);
+ theta += (float)M_PI * 0.5f;
+
+ v0.p = fz_point_on_circle(p0, HUGENUM, theta);
+ v1.p = fz_point_on_circle(p1, HUGENUM, theta);
+ v2.p = fz_point_on_circle(p0, -HUGENUM, theta);
+ v3.p = fz_point_on_circle(p1, -HUGENUM, theta);
+
+ v0.c[0] = 0;
+ v1.c[0] = 1;
+ v2.c[0] = 0;
+ v3.c[0] = 1;
+
+ paint_quad(painter, &v0, &v2, &v3, &v1);
+
+ if (shade->u.a_or_r.extend[0])
+ {
+ e0.p.x = v0.p.x - (p1.x - p0.x) * HUGENUM;
+ e0.p.y = v0.p.y - (p1.y - p0.y) * HUGENUM;
+
+ e1.p.x = v2.p.x - (p1.x - p0.x) * HUGENUM;
+ e1.p.y = v2.p.y - (p1.y - p0.y) * HUGENUM;
+
+ e0.c[0] = 0;
+ e1.c[0] = 0;
+ v0.c[0] = 0;
+ v2.c[0] = 0;
+
+ paint_quad(painter, &e0, &v0, &v2, &e1);
+ }
+
+ if (shade->u.a_or_r.extend[1])
+ {
+ e0.p.x = v1.p.x + (p1.x - p0.x) * HUGENUM;
+ e0.p.y = v1.p.y + (p1.y - p0.y) * HUGENUM;
+
+ e1.p.x = v3.p.x + (p1.x - p0.x) * HUGENUM;
+ e1.p.y = v3.p.y + (p1.y - p0.y) * HUGENUM;
+
+ e0.c[0] = 1;
+ e1.c[0] = 1;
+ v1.c[0] = 1;
+ v3.c[0] = 1;
+
+ paint_quad(painter, &e0, &v1, &v3, &e1);
+ }
+}
+
+/* FIXME: Nasty */
+#define RADSEGS 32 /* how many segments to generate for radial meshes */
+
+static void
+fz_paint_annulus(fz_matrix ctm,
+ fz_point p0, float r0, float c0,
+ fz_point p1, float r1, float c1,
+ fz_mesh_processor *painter)
+{
+ fz_vertex t0, t1, t2, t3, b0, b1, b2, b3;
+ float theta, step;
+ int i;
+
+ theta = atan2f(p1.y - p0.y, p1.x - p0.x);
+ step = (float)M_PI * 2 / RADSEGS;
+
+ for (i = 0; i < RADSEGS / 2; i++)
+ {
+ t0.p = fz_point_on_circle(p0, r0, theta + i * step);
+ t1.p = fz_point_on_circle(p0, r0, theta + i * step + step);
+ t2.p = fz_point_on_circle(p1, r1, theta + i * step);
+ t3.p = fz_point_on_circle(p1, r1, theta + i * step + step);
+ b0.p = fz_point_on_circle(p0, r0, theta - i * step);
+ b1.p = fz_point_on_circle(p0, r0, theta - i * step - step);
+ b2.p = fz_point_on_circle(p1, r1, theta - i * step);
+ b3.p = fz_point_on_circle(p1, r1, theta - i * step - step);
+
+ t0.p = fz_transform_point(ctm, t0.p);
+ t1.p = fz_transform_point(ctm, t1.p);
+ t2.p = fz_transform_point(ctm, t2.p);
+ t3.p = fz_transform_point(ctm, t3.p);
+ b0.p = fz_transform_point(ctm, b0.p);
+ b1.p = fz_transform_point(ctm, b1.p);
+ b2.p = fz_transform_point(ctm, b2.p);
+ b3.p = fz_transform_point(ctm, b3.p);
+
+ t0.c[0] = c0;
+ t1.c[0] = c0;
+ t2.c[0] = c1;
+ t3.c[0] = c1;
+ b0.c[0] = c0;
+ b1.c[0] = c0;
+ b2.c[0] = c1;
+ b3.c[0] = c1;
+
+ paint_quad(painter, &t0, &t2, &t3, &t1);
+ paint_quad(painter, &b0, &b2, &b3, &b1);
+ }
+}
+
+static void
+fz_mesh_type3_process(fz_context *ctx, fz_shade *shade, fz_matrix ctm, fz_mesh_processor *painter)
+{
+ fz_point p0, p1;
+ float r0, r1;
+ fz_point e;
+ float er, rs;
+
+ p0.x = shade->u.a_or_r.coords[0][0];
+ p0.y = shade->u.a_or_r.coords[0][1];
+ r0 = shade->u.a_or_r.coords[0][2];
+
+ p1.x = shade->u.a_or_r.coords[1][0];
+ p1.y = shade->u.a_or_r.coords[1][1];
+ r1 = shade->u.a_or_r.coords[1][2];
+
+ if (shade->u.a_or_r.extend[0])
+ {
+ if (r0 < r1)
+ rs = r0 / (r0 - r1);
+ else
+ rs = -HUGENUM;
+
+ e.x = p0.x + (p1.x - p0.x) * rs;
+ e.y = p0.y + (p1.y - p0.y) * rs;
+ er = r0 + (r1 - r0) * rs;
+
+ fz_paint_annulus(ctm, e, er, 0, p0, r0, 0, painter);
+ }
+
+ fz_paint_annulus(ctm, p0, r0, 0, p1, r1, 1, painter);
+
+ if (shade->u.a_or_r.extend[1])
+ {
+ if (r0 > r1)
+ rs = r1 / (r1 - r0);
+ else
+ rs = -HUGENUM;
+
+ e.x = p1.x + (p0.x - p1.x) * rs;
+ e.y = p1.y + (p0.y - p1.y) * rs;
+ er = r1 + (r0 - r1) * rs;
+
+ fz_paint_annulus(ctm, p1, r1, 1, e, er, 1, painter);
+ }
+}
+
static inline float read_sample(fz_stream *stream, int bits, float min, float max)
{
/* we use pow(2,x) because (1<<x) would overflow the math on 32-bit samples */
@@ -738,6 +911,10 @@ fz_process_mesh(fz_context *ctx, fz_shade *shade, fz_matrix ctm,
if (shade->type == FZ_FUNCTION_BASED)
fz_mesh_type1_process(ctx, shade, ctm, &painter);
+ else if (shade->type == FZ_LINEAR)
+ fz_mesh_type2_process(ctx, shade, ctm, &painter);
+ else if (shade->type == FZ_RADIAL)
+ fz_mesh_type3_process(ctx, shade, ctm, &painter);
else if (shade->type == FZ_MESH_TYPE4)
fz_mesh_type4_process(ctx, shade, ctm, &painter);
else if (shade->type == FZ_MESH_TYPE5)