static void xps_draw_one_radial_gradient(xps_document *doc, fz_matrix ctm, struct stop *stops, int count, int extend, float x0, float y0, float r0, float x1, float y1, float r1) { fz_shade *shade; /* TODO: this (and the stuff in pdf_shade) should move to res_shade.c */ shade = fz_malloc_struct(doc->ctx, fz_shade); FZ_INIT_STORABLE(shade, 1, fz_free_shade_imp); shade->colorspace = fz_device_rgb; shade->bbox = fz_infinite_rect; shade->matrix = fz_identity; shade->use_background = 0; shade->use_function = 1; shade->type = FZ_RADIAL; shade->u.l_or_r.extend[0] = extend; shade->u.l_or_r.extend[1] = extend; xps_sample_gradient_stops(shade, stops, count); shade->u.l_or_r.coords[0][0] = x0; shade->u.l_or_r.coords[0][1] = y0; shade->u.l_or_r.coords[0][2] = r0; shade->u.l_or_r.coords[1][0] = x1; shade->u.l_or_r.coords[1][1] = y1; shade->u.l_or_r.coords[1][2] = r1; fz_fill_shade(doc->dev, shade, ctm, 1); fz_drop_shade(doc->ctx, shade); }
static void xps_draw_one_linear_gradient(fz_context *ctx, xps_document *doc, const fz_matrix *ctm, struct stop *stops, int count, int extend, float x0, float y0, float x1, float y1) { fz_device *dev = doc->dev; fz_shade *shade; /* TODO: this (and the stuff in pdf_shade) should move to res_shade.c */ shade = fz_malloc_struct(ctx, fz_shade); FZ_INIT_STORABLE(shade, 1, fz_drop_shade_imp); shade->colorspace = fz_device_rgb(ctx); shade->bbox = fz_infinite_rect; shade->matrix = fz_identity; shade->use_background = 0; shade->use_function = 1; shade->type = FZ_LINEAR; shade->u.l_or_r.extend[0] = extend; shade->u.l_or_r.extend[1] = extend; xps_sample_gradient_stops(ctx, doc, shade, stops, count); shade->u.l_or_r.coords[0][0] = x0; shade->u.l_or_r.coords[0][1] = y0; shade->u.l_or_r.coords[0][2] = 0; shade->u.l_or_r.coords[1][0] = x1; shade->u.l_or_r.coords[1][1] = y1; shade->u.l_or_r.coords[1][2] = 0; fz_fill_shade(ctx, dev, shade, ctm, doc->opacity[doc->opacity_top]); fz_drop_shade(ctx, shade); }
static void fz_free_display_node(fz_context *ctx, fz_display_node *node) { switch (node->cmd) { case FZ_CMD_FILL_PATH: case FZ_CMD_STROKE_PATH: case FZ_CMD_CLIP_PATH: case FZ_CMD_CLIP_STROKE_PATH: fz_free_path(ctx, node->item.path); break; case FZ_CMD_FILL_TEXT: case FZ_CMD_STROKE_TEXT: case FZ_CMD_CLIP_TEXT: case FZ_CMD_CLIP_STROKE_TEXT: case FZ_CMD_IGNORE_TEXT: fz_free_text(ctx, node->item.text); break; case FZ_CMD_FILL_SHADE: fz_drop_shade(ctx, node->item.shade); break; case FZ_CMD_FILL_IMAGE: case FZ_CMD_FILL_IMAGE_MASK: case FZ_CMD_CLIP_IMAGE_MASK: fz_drop_image(ctx, node->item.image); break; case FZ_CMD_POP_CLIP: case FZ_CMD_BEGIN_MASK: case FZ_CMD_END_MASK: case FZ_CMD_BEGIN_GROUP: case FZ_CMD_END_GROUP: case FZ_CMD_BEGIN_TILE: case FZ_CMD_END_TILE: case FZ_CMD_BEGIN_PAGE: case FZ_CMD_END_PAGE: break; /* SumatraPDF: support transfer functions */ case FZ_CMD_APPLY_TRANSFER_FUNCTION: fz_drop_transfer_function(ctx, node->item.tr); break; } if (node->stroke) fz_drop_stroke_state(ctx, node->stroke); if (node->colorspace) fz_drop_colorspace(ctx, node->colorspace); fz_free(ctx, node); }
static void fz_free_display_node(fz_display_node *node) { switch (node->cmd) { case FZ_CMD_FILL_PATH: case FZ_CMD_STROKE_PATH: case FZ_CMD_CLIP_PATH: case FZ_CMD_CLIP_STROKE_PATH: fz_free_path(node->item.path); break; case FZ_CMD_FILL_TEXT: case FZ_CMD_STROKE_TEXT: case FZ_CMD_CLIP_TEXT: case FZ_CMD_CLIP_STROKE_TEXT: case FZ_CMD_IGNORE_TEXT: fz_free_text(node->item.text); break; case FZ_CMD_FILL_SHADE: fz_drop_shade(node->item.shade); break; case FZ_CMD_FILL_IMAGE: case FZ_CMD_FILL_IMAGE_MASK: case FZ_CMD_CLIP_IMAGE_MASK: fz_drop_pixmap(node->item.image); break; case FZ_CMD_POP_CLIP: case FZ_CMD_BEGIN_MASK: case FZ_CMD_END_MASK: case FZ_CMD_BEGIN_GROUP: case FZ_CMD_END_GROUP: case FZ_CMD_BEGIN_TILE: case FZ_CMD_END_TILE: break; } if (node->stroke) fz_free(node->stroke); if (node->colorspace) fz_drop_colorspace(node->colorspace); fz_free(node); }
static fz_shade * pdf_load_shading_dict(pdf_document *xref, pdf_obj *dict, fz_matrix transform) { fz_shade *shade = NULL; pdf_function *func[FZ_MAX_COLORS] = { NULL }; pdf_obj *obj; int funcs = 0; int type = 0; int i, in, out; fz_context *ctx = xref->ctx; fz_var(shade); fz_var(func); fz_var(funcs); fz_var(type); fz_try(ctx) { shade = fz_malloc_struct(ctx, fz_shade); FZ_INIT_STORABLE(shade, 1, fz_free_shade_imp); shade->type = FZ_MESH_TYPE4; shade->use_background = 0; shade->use_function = 0; shade->matrix = transform; shade->bbox = fz_infinite_rect; shade->colorspace = NULL; funcs = 0; obj = pdf_dict_gets(dict, "ShadingType"); type = pdf_to_int(obj); obj = pdf_dict_gets(dict, "ColorSpace"); if (!obj) fz_throw(ctx, "shading colorspace is missing"); shade->colorspace = pdf_load_colorspace(xref, obj); obj = pdf_dict_gets(dict, "Background"); if (obj) { shade->use_background = 1; for (i = 0; i < shade->colorspace->n; i++) shade->background[i] = pdf_to_real(pdf_array_get(obj, i)); } obj = pdf_dict_gets(dict, "BBox"); if (pdf_is_array(obj)) { shade->bbox = pdf_to_rect(ctx, obj); } obj = pdf_dict_gets(dict, "Function"); if (pdf_is_dict(obj)) { funcs = 1; if (type == 1) in = 2; else in = 1; out = shade->colorspace->n; func[0] = pdf_load_function(xref, obj, in, out); if (!func[0]) fz_throw(ctx, "cannot load shading function (%d %d R)", pdf_to_num(obj), pdf_to_gen(obj)); } else if (pdf_is_array(obj)) { funcs = pdf_array_len(obj); if (funcs != 1 && funcs != shade->colorspace->n) { funcs = 0; fz_throw(ctx, "incorrect number of shading functions"); } if (funcs > FZ_MAX_COLORS) { funcs = 0; fz_throw(ctx, "too many shading functions"); } if (type == 1) in = 2; else in = 1; out = 1; for (i = 0; i < funcs; i++) { func[i] = pdf_load_function(xref, pdf_array_get(obj, i), in, out); if (!func[i]) fz_throw(ctx, "cannot load shading function (%d %d R)", pdf_to_num(obj), pdf_to_gen(obj)); } } else if (type < 4) { /* Functions are compulsory for types 1,2,3 */ fz_throw(ctx, "cannot load shading function (%d %d R)", pdf_to_num(obj), pdf_to_gen(obj)); } shade->type = type; switch (type) { case 1: pdf_load_function_based_shading(shade, xref, dict, func[0]); break; case 2: pdf_load_linear_shading(shade, xref, dict, funcs, func); break; case 3: pdf_load_radial_shading(shade, xref, dict, funcs, func); break; case 4: pdf_load_type4_shade(shade, xref, dict, funcs, func); break; case 5: pdf_load_type5_shade(shade, xref, dict, funcs, func); break; case 6: pdf_load_type6_shade(shade, xref, dict, funcs, func); break; case 7: pdf_load_type7_shade(shade, xref, dict, funcs, func); break; default: fz_throw(ctx, "unknown shading type: %d", type); } for (i = 0; i < funcs; i++) if (func[i]) pdf_drop_function(ctx, func[i]); } fz_catch(ctx) { for (i = 0; i < funcs; i++) if (func[i]) pdf_drop_function(ctx, func[i]); fz_drop_shade(ctx, shade); fz_throw(ctx, "cannot load shading type %d (%d %d R)", type, pdf_to_num(dict), pdf_to_gen(dict)); } return shade; }
static fz_shade * pdf_load_shading_dict(fz_context *ctx, pdf_document *doc, pdf_obj *dict, const fz_matrix *transform) { fz_shade *shade = NULL; pdf_function *func[FZ_MAX_COLORS] = { NULL }; pdf_obj *obj; int funcs = 0; int type = 0; int i, in, out, n; fz_var(shade); fz_var(func); fz_var(funcs); fz_var(type); fz_try(ctx) { shade = fz_malloc_struct(ctx, fz_shade); FZ_INIT_STORABLE(shade, 1, fz_drop_shade_imp); shade->type = FZ_MESH_TYPE4; shade->use_background = 0; shade->use_function = 0; shade->matrix = *transform; shade->bbox = fz_infinite_rect; shade->colorspace = NULL; funcs = 0; obj = pdf_dict_get(ctx, dict, PDF_NAME(ShadingType)); type = pdf_to_int(ctx, obj); obj = pdf_dict_get(ctx, dict, PDF_NAME(ColorSpace)); if (!obj) fz_throw(ctx, FZ_ERROR_SYNTAX, "shading colorspace is missing"); shade->colorspace = pdf_load_colorspace(ctx, obj); n = fz_colorspace_n(ctx, shade->colorspace); obj = pdf_dict_get(ctx, dict, PDF_NAME(Background)); if (obj) { shade->use_background = 1; for (i = 0; i < n; i++) shade->background[i] = pdf_array_get_real(ctx, obj, i); } obj = pdf_dict_get(ctx, dict, PDF_NAME(BBox)); if (pdf_is_array(ctx, obj)) pdf_to_rect(ctx, obj, &shade->bbox); obj = pdf_dict_get(ctx, dict, PDF_NAME(Function)); if (pdf_is_dict(ctx, obj)) { funcs = 1; if (type == 1) in = 2; else in = 1; out = n; func[0] = pdf_load_function(ctx, obj, in, out); if (!func[0]) fz_throw(ctx, FZ_ERROR_SYNTAX, "cannot load shading function (%d 0 R)", pdf_to_num(ctx, obj)); } else if (pdf_is_array(ctx, obj)) { funcs = pdf_array_len(ctx, obj); if (funcs != 1 && funcs != n) { funcs = 0; fz_throw(ctx, FZ_ERROR_SYNTAX, "incorrect number of shading functions"); } if (funcs > FZ_MAX_COLORS) { funcs = 0; fz_throw(ctx, FZ_ERROR_SYNTAX, "too many shading functions"); } if (type == 1) in = 2; else in = 1; out = 1; for (i = 0; i < funcs; i++) { func[i] = pdf_load_function(ctx, pdf_array_get(ctx, obj, i), in, out); if (!func[i]) fz_throw(ctx, FZ_ERROR_SYNTAX, "cannot load shading function (%d 0 R)", pdf_to_num(ctx, obj)); } } else if (type < 4) { /* Functions are compulsory for types 1,2,3 */ fz_throw(ctx, FZ_ERROR_SYNTAX, "cannot load shading function (%d 0 R)", pdf_to_num(ctx, obj)); } shade->type = type; switch (type) { case 1: pdf_load_function_based_shading(ctx, doc, shade, dict, func[0]); break; case 2: pdf_load_linear_shading(ctx, doc, shade, dict, funcs, func); break; case 3: pdf_load_radial_shading(ctx, doc, shade, dict, funcs, func); break; case 4: pdf_load_type4_shade(ctx, doc, shade, dict, funcs, func); break; case 5: pdf_load_type5_shade(ctx, doc, shade, dict, funcs, func); break; case 6: pdf_load_type6_shade(ctx, doc, shade, dict, funcs, func); break; case 7: pdf_load_type7_shade(ctx, doc, shade, dict, funcs, func); break; default: fz_throw(ctx, FZ_ERROR_SYNTAX, "unknown shading type: %d", type); } } fz_always(ctx) { for (i = 0; i < funcs; i++) pdf_drop_function(ctx, func[i]); } fz_catch(ctx) { fz_drop_shade(ctx, shade); fz_rethrow(ctx); } return shade; }
static fz_error pdf_load_shading_dict(fz_shade **shadep, pdf_xref *xref, fz_obj *dict, fz_matrix transform) { fz_error error; fz_shade *shade; pdf_function *func[FZ_MAX_COLORS] = { NULL }; fz_stream *stream = NULL; fz_obj *obj; int funcs; int type; int i; shade = fz_malloc(sizeof(fz_shade)); shade->refs = 1; shade->type = FZ_MESH; shade->use_background = 0; shade->use_function = 0; shade->matrix = transform; shade->bbox = fz_infinite_rect; shade->extend[0] = 0; shade->extend[1] = 0; shade->mesh_len = 0; shade->mesh_cap = 0; shade->mesh = NULL; shade->colorspace = NULL; funcs = 0; obj = fz_dict_gets(dict, "ShadingType"); type = fz_to_int(obj); obj = fz_dict_gets(dict, "ColorSpace"); if (!obj) { fz_drop_shade(shade); return fz_throw("shading colorspace is missing"); } error = pdf_load_colorspace(&shade->colorspace, xref, obj); if (error) { fz_drop_shade(shade); return fz_rethrow(error, "cannot load colorspace (%d %d R)", fz_to_num(obj), fz_to_gen(obj)); } obj = fz_dict_gets(dict, "Background"); if (obj) { shade->use_background = 1; for (i = 0; i < shade->colorspace->n; i++) shade->background[i] = fz_to_real(fz_array_get(obj, i)); } obj = fz_dict_gets(dict, "BBox"); if (fz_is_array(obj)) { shade->bbox = pdf_to_rect(obj); } obj = fz_dict_gets(dict, "Function"); if (fz_is_dict(obj)) { funcs = 1; error = pdf_load_function(&func[0], xref, obj); if (error) { error = fz_rethrow(error, "cannot load shading function (%d %d R)", fz_to_num(obj), fz_to_gen(obj)); goto cleanup; } } else if (fz_is_array(obj)) { funcs = fz_array_len(obj); if (funcs != 1 && funcs != shade->colorspace->n) { error = fz_throw("incorrect number of shading functions"); goto cleanup; } for (i = 0; i < funcs; i++) { error = pdf_load_function(&func[i], xref, fz_array_get(obj, i)); if (error) { error = fz_rethrow(error, "cannot load shading function (%d %d R)", fz_to_num(obj), fz_to_gen(obj)); goto cleanup; } } } if (type >= 4 && type <= 7) { error = pdf_open_stream(&stream, xref, fz_to_num(dict), fz_to_gen(dict)); if (error) { error = fz_rethrow(error, "cannot open shading stream (%d %d R)", fz_to_num(dict), fz_to_gen(dict)); goto cleanup; } } switch (type) { case 1: pdf_load_function_based_shading(shade, xref, dict, func[0]); break; case 2: pdf_load_axial_shading(shade, xref, dict, funcs, func); break; case 3: pdf_load_radial_shading(shade, xref, dict, funcs, func); break; case 4: pdf_load_type4_shade(shade, xref, dict, funcs, func, stream); break; case 5: pdf_load_type5_shade(shade, xref, dict, funcs, func, stream); break; case 6: pdf_load_type6_shade(shade, xref, dict, funcs, func, stream); break; case 7: pdf_load_type7_shade(shade, xref, dict, funcs, func, stream); break; default: error = fz_throw("unknown shading type: %d", type); goto cleanup; } if (stream) fz_close(stream); for (i = 0; i < funcs; i++) if (func[i]) pdf_drop_function(func[i]); *shadep = shade; return fz_okay; cleanup: if (stream) fz_close(stream); for (i = 0; i < funcs; i++) if (func[i]) pdf_drop_function(func[i]); fz_drop_shade(shade); return fz_rethrow(error, "cannot load shading type %d (%d %d R)", type, fz_to_num(dict), fz_to_gen(dict)); }