void divide_patch( vec4 p[4][4], int count ) { if ( count > 0 ) { vec4 q[4][4], r[4][4], s[4][4], t[4][4]; vec4 a[4][4], b[4][4]; // subdivide curves in u direction, transpose results, divide // in u direction again (equivalent to subdivision in v) for ( int k = 0; k < 4; ++k ) { divide_curve( p[k], a[k], b[k] ); } transpose( a ); transpose( b ); for ( int k = 0; k < 4; ++k ) { divide_curve( a[k], q[k], r[k] ); divide_curve( b[k], s[k], t[k] ); } // recursive division of 4 resulting patches divide_patch( q, count - 1 ); divide_patch( r, count - 1 ); divide_patch( s, count - 1 ); divide_patch( t, count - 1 ); } else { draw_patch( p ); } }
static void draw_patch(fz_context *ctx, fz_shade *shade, pdf_tensor_patch *p, int depth, int origdepth) { pdf_tensor_patch s0, s1; /* split patch into two half-width patches */ split_patch(p, &s0, &s1); depth--; if (depth == 0) { /* if no more subdividing, draw two new patches... */ draw_stripe(ctx, &s0, shade, origdepth); draw_stripe(ctx, &s1, shade, origdepth); } else { /* ...otherwise, continue subdividing. */ draw_patch(ctx, shade, &s0, depth, origdepth); draw_patch(ctx, shade, &s1, depth, origdepth); } }
static void draw_patch(fz_mesh_processor *painter, tensor_patch *p, int depth, int origdepth) { tensor_patch s0, s1; /* split patch into two half-width patches */ split_patch(p, &s0, &s1); depth--; if (depth == 0) { /* if no more subdividing, draw two new patches... */ draw_stripe(painter, &s0, origdepth); draw_stripe(painter, &s1, origdepth); } else { /* ...otherwise, continue subdividing. */ draw_patch(painter, &s0, depth, origdepth); draw_patch(painter, &s1, depth, origdepth); } }
static void pdf_load_type7_shade(fz_shade *shade, pdf_document *xref, pdf_obj *dict, int funcs, pdf_function **func) { fz_context *ctx = xref->ctx; struct mesh_params p; int haspatch, hasprevpatch; float prevc[4][FZ_MAX_COLORS]; fz_point prevp[16]; int ncomp; int i, k; fz_stream *stream; pdf_load_mesh_params(xref, dict, &p); if (funcs > 0) { ncomp = 1; pdf_sample_shade_function(ctx, shade, funcs, func, p.c0[0], p.c1[0]); } else ncomp = shade->colorspace->n; hasprevpatch = 0; stream = pdf_open_stream(xref, pdf_to_num(dict), pdf_to_gen(dict)); while (!fz_is_eof_bits(stream)) { float c[4][FZ_MAX_COLORS]; fz_point v[16]; int startcolor; int startpt; int flag; flag = fz_read_bits(stream, p.bpflag); if (flag == 0) { startpt = 0; startcolor = 0; } else { startpt = 4; startcolor = 2; } for (i = startpt; i < 16; i++) { v[i].x = read_sample(stream, p.bpcoord, p.x0, p.x1); v[i].y = read_sample(stream, p.bpcoord, p.y0, p.y1); } for (i = startcolor; i < 4; i++) { for (k = 0; k < ncomp; k++) c[i][k] = read_sample(stream, p.bpcomp, p.c0[k], p.c1[k]); } haspatch = 0; if (flag == 0) { haspatch = 1; } else if (flag == 1 && hasprevpatch) { v[0] = prevp[3]; v[1] = prevp[4]; v[2] = prevp[5]; v[3] = prevp[6]; memcpy(c[0], prevc[1], ncomp * sizeof(float)); memcpy(c[1], prevc[2], ncomp * sizeof(float)); haspatch = 1; } else if (flag == 2 && hasprevpatch) { v[0] = prevp[6]; v[1] = prevp[7]; v[2] = prevp[8]; v[3] = prevp[9]; memcpy(c[0], prevc[2], ncomp * sizeof(float)); memcpy(c[1], prevc[3], ncomp * sizeof(float)); haspatch = 1; } else if (flag == 3 && hasprevpatch) { v[0] = prevp[ 9]; v[1] = prevp[10]; v[2] = prevp[11]; v[3] = prevp[ 0]; memcpy(c[0], prevc[3], ncomp * sizeof(float)); memcpy(c[1], prevc[0], ncomp * sizeof(float)); haspatch = 1; } if (haspatch) { pdf_tensor_patch patch; pdf_make_tensor_patch(&patch, 7, v); for (i = 0; i < 4; i++) memcpy(patch.color[i], c[i], ncomp * sizeof(float)); draw_patch(ctx, shade, &patch, SUBDIV, SUBDIV); for (i = 0; i < 16; i++) prevp[i] = v[i]; for (i = 0; i < 4; i++) memcpy(prevc[i], c[i], FZ_MAX_COLORS * sizeof(float)); hasprevpatch = 1; } } fz_close(stream); }
static void fz_mesh_type7_process(fz_context *ctx, fz_shade *shade, const fz_matrix *ctm, fz_mesh_processor *painter) { fz_stream *stream = fz_open_compressed_buffer(ctx, shade->buffer); int bpflag = shade->u.m.bpflag; int bpcoord = shade->u.m.bpcoord; int bpcomp = shade->u.m.bpcomp; float x0 = shade->u.m.x0; float x1 = shade->u.m.x1; float y0 = shade->u.m.y0; float y1 = shade->u.m.y1; float *c0 = shade->u.m.c0; float *c1 = shade->u.m.c1; float prevc[4][FZ_MAX_COLORS]; fz_point prevp[16]; int ncomp; int i, k; int haspatch, hasprevpatch; fz_try(ctx) { hasprevpatch = 0; ncomp = (shade->use_function > 0 ? 1 : shade->colorspace->n); while (!fz_is_eof_bits(stream)) { float c[4][FZ_MAX_COLORS]; fz_point v[16]; int startcolor; int startpt; int flag; flag = fz_read_bits(stream, bpflag); if (flag == 0) { startpt = 0; startcolor = 0; } else { startpt = 4; startcolor = 2; } for (i = startpt; i < 16; i++) { v[i].x = read_sample(stream, bpcoord, x0, x1); v[i].y = read_sample(stream, bpcoord, y0, y1); fz_transform_point(&v[i], ctm); } for (i = startcolor; i < 4; i++) { for (k = 0; k < ncomp; k++) c[i][k] = read_sample(stream, bpcomp, c0[k], c1[k]); } haspatch = 0; if (flag == 0) { haspatch = 1; } else if (flag == 1 && hasprevpatch) { v[0] = prevp[3]; v[1] = prevp[4]; v[2] = prevp[5]; v[3] = prevp[6]; memcpy(c[0], prevc[1], ncomp * sizeof(float)); memcpy(c[1], prevc[2], ncomp * sizeof(float)); haspatch = 1; } else if (flag == 2 && hasprevpatch) { v[0] = prevp[6]; v[1] = prevp[7]; v[2] = prevp[8]; v[3] = prevp[9]; memcpy(c[0], prevc[2], ncomp * sizeof(float)); memcpy(c[1], prevc[3], ncomp * sizeof(float)); haspatch = 1; } else if (flag == 3 && hasprevpatch) { v[0] = prevp[ 9]; v[1] = prevp[10]; v[2] = prevp[11]; v[3] = prevp[ 0]; memcpy(c[0], prevc[3], ncomp * sizeof(float)); memcpy(c[1], prevc[0], ncomp * sizeof(float)); haspatch = 1; } if (haspatch) { tensor_patch patch; make_tensor_patch(&patch, 7, v); for (i = 0; i < 4; i++) memcpy(patch.color[i], c[i], ncomp * sizeof(float)); draw_patch(painter, &patch, SUBDIV, SUBDIV); for (i = 0; i < 16; i++) prevp[i] = v[i]; for (i = 0; i < 4; i++) memcpy(prevc[i], c[i], FZ_MAX_COLORS * sizeof(float)); hasprevpatch = 1; } } } fz_always(ctx) { fz_close(stream); } fz_catch(ctx) { fz_rethrow(ctx); } }
static void fz_process_mesh_type7(fz_context *ctx, fz_shade *shade, const fz_matrix *ctm, fz_mesh_processor *painter) { fz_stream *stream = fz_open_compressed_buffer(ctx, shade->buffer); int bpflag = shade->u.m.bpflag; int bpcoord = shade->u.m.bpcoord; int bpcomp = shade->u.m.bpcomp; float x0 = shade->u.m.x0; float x1 = shade->u.m.x1; float y0 = shade->u.m.y0; float y1 = shade->u.m.y1; float *c0 = shade->u.m.c0; float *c1 = shade->u.m.c1; float color_storage[2][4][FZ_MAX_COLORS]; fz_point point_storage[2][16]; int store = 0; int ncomp = painter->ncomp; int i, k; float (*prevc)[FZ_MAX_COLORS] = NULL; fz_point (*prevp) = NULL; fz_try(ctx) { while (!fz_is_eof_bits(ctx, stream)) { float (*c)[FZ_MAX_COLORS] = color_storage[store]; fz_point *v = point_storage[store]; int startcolor; int startpt; int flag; tensor_patch patch; flag = fz_read_bits(ctx, stream, bpflag); if (flag == 0) { startpt = 0; startcolor = 0; } else { startpt = 4; startcolor = 2; } for (i = startpt; i < 16; i++) { v[i].x = read_sample(ctx, stream, bpcoord, x0, x1); v[i].y = read_sample(ctx, stream, bpcoord, y0, y1); fz_transform_point(&v[i], ctm); } for (i = startcolor; i < 4; i++) { for (k = 0; k < ncomp; k++) c[i][k] = read_sample(ctx, stream, bpcomp, c0[k], c1[k]); } if (flag == 0) { } else if (flag == 1 && prevc) { v[0] = prevp[3]; v[1] = prevp[4]; v[2] = prevp[5]; v[3] = prevp[6]; memcpy(c[0], prevc[1], ncomp * sizeof(float)); memcpy(c[1], prevc[2], ncomp * sizeof(float)); } else if (flag == 2 && prevc) { v[0] = prevp[6]; v[1] = prevp[7]; v[2] = prevp[8]; v[3] = prevp[9]; memcpy(c[0], prevc[2], ncomp * sizeof(float)); memcpy(c[1], prevc[3], ncomp * sizeof(float)); } else if (flag == 3 && prevc) { v[0] = prevp[ 9]; v[1] = prevp[10]; v[2] = prevp[11]; v[3] = prevp[ 0]; memcpy(c[0], prevc[3], ncomp * sizeof(float)); memcpy(c[1], prevc[0], ncomp * sizeof(float)); } else continue; /* We have no patch! */ make_tensor_patch(&patch, 7, v); for (i = 0; i < 4; i++) memcpy(patch.color[i], c[i], ncomp * sizeof(float)); draw_patch(ctx, painter, &patch, SUBDIV, SUBDIV); prevp = v; prevc = c; store ^= 1; } } fz_always(ctx) { fz_drop_stream(ctx, stream); } fz_catch(ctx) { fz_rethrow(ctx); } }