diff options
Diffstat (limited to 'pdf/pdf_gstate.c')
-rw-r--r-- | pdf/pdf_gstate.c | 624 |
1 files changed, 300 insertions, 324 deletions
diff --git a/pdf/pdf_gstate.c b/pdf/pdf_gstate.c index c1444b4b..5248bd40 100644 --- a/pdf/pdf_gstate.c +++ b/pdf/pdf_gstate.c @@ -44,6 +44,8 @@ #include "gscoord.h" /* For gs_concat() */ #include "gsutil.h" /* For gs_next_ids() */ #include "gscolor3.h" /* For gs_setsmoothness() */ +#include "gzpath.h" +#include "gspenum.h" static const char *blend_mode_names[] = { GS_BLEND_MODE_NAMES, 0 @@ -158,8 +160,7 @@ pdfi_gstate_set_client(pdf_context *ctx, gs_gstate *pgs) int pdfi_concat(pdf_context *ctx) { - int i, code; - pdf_num *num; + int code; double Values[6]; gs_matrix m; @@ -171,28 +172,18 @@ int pdfi_concat(pdf_context *ctx) if (ctx->text.BlockDepth != 0) pdfi_set_warning(ctx, 0, NULL, W_PDF_OPINVALIDINTEXT, "pdfi_concat", NULL); - for (i=0;i < 6;i++){ - num = (pdf_num *)ctx->stack_top[i - 6]; - if (num->type != PDF_INT) { - if(num->type != PDF_REAL) { - pdfi_pop(ctx, 6); - return_error(gs_error_typecheck); - } - else - Values[i] = num->value.d; - } else { - Values[i] = (double)num->value.i; - } - } + code = pdfi_destack_reals(ctx, Values, 6); + if (code < 0) + return code; + m.xx = (float)Values[0]; m.xy = (float)Values[1]; m.yx = (float)Values[2]; m.yy = (float)Values[3]; m.tx = (float)Values[4]; m.ty = (float)Values[5]; - code = gs_concat(ctx->pgs, (const gs_matrix *)&m); - pdfi_pop(ctx, 6); - return code; + + return gs_concat(ctx->pgs, (const gs_matrix *)&m); } int pdfi_op_q(pdf_context *ctx) @@ -216,7 +207,6 @@ int pdfi_op_q(pdf_context *ctx) int pdfi_op_Q(pdf_context *ctx) { int code = 0; - gx_path *ppath = NULL; #if DEBUG_GSAVE dbgmprintf(ctx->memory, "(doing Q)\n"); /* TODO: Spammy, delete me at some point */ @@ -232,30 +222,7 @@ int pdfi_op_Q(pdf_context *ctx) return code; } - /* Section 4.4.1 of the 3rd Edition PDF_Refrence Manual, p226 of the 1.7 version - * states that the current path is **NOT** part of the graphics state and is not - * saved and restored along with the other graphics state parameters. So here - * we need to indulge in some ugliness. We take a copy of the current path - * before we do a grestore, and below we assign the copy to the graphics state - * after the grestore, thus preserving it unchanged. This is still better than - * the 'PDF interpreter written in PostScript' method. - */ - ppath = gx_path_alloc_shared(ctx->pgs->path, ctx->memory, "temporary current path copy for Q"); - if (ppath == NULL) - return_error(gs_error_VMerror); - - code = pdfi_grestore(ctx); - - if (code >= 0) { - /* Put the path back, and make sure current point is properly set */ - code = gx_path_assign_preserve(ctx->pgs->path, ppath); - if (gx_path_position_valid(ctx->pgs->path)) - gx_setcurrentpoint_from_path(ctx->pgs, ctx->pgs->path); - } - - gx_path_free(ppath, "temporary current path copy for Q"); - - return code; + return pdfi_grestore(ctx); } /* We want pdfi_grestore() so we can track and warn of "too many Qs" @@ -296,86 +263,60 @@ int pdfi_gs_setgstate(gs_gstate * pgs, const gs_gstate * pfrom) int pdfi_setlinewidth(pdf_context *ctx) { int code; - pdf_num *n1; double d1; if (pdfi_count_stack(ctx) < 1) return_error(gs_error_stackunderflow); - n1 = (pdf_num *)ctx->stack_top[-1]; - if (n1->type == PDF_INT){ - d1 = (double)n1->value.i; - } else{ - if (n1->type == PDF_REAL) { - d1 = n1->value.d; - } else { - pdfi_pop(ctx, 1); - return_error(gs_error_typecheck); - } - } - code = gs_setlinewidth(ctx->pgs, d1); - pdfi_pop(ctx, 1); - return code; + code = pdfi_destack_real(ctx, &d1); + if (code < 0) + return code; + + return gs_setlinewidth(ctx->pgs, d1); } int pdfi_setlinejoin(pdf_context *ctx) { int code; - pdf_num *n1; + int64_t i; if (pdfi_count_stack(ctx) < 1) return_error(gs_error_stackunderflow); - n1 = (pdf_num *)ctx->stack_top[-1]; - if (n1->type == PDF_INT){ - code = gs_setlinejoin(ctx->pgs, n1->value.i); - } else { - pdfi_pop(ctx, 1); - return_error(gs_error_typecheck); - } - pdfi_pop(ctx, 1); - return code; + code = pdfi_destack_int(ctx, &i); + if (code < 0) + return code; + + return gs_setlinejoin(ctx->pgs, (int)i); } int pdfi_setlinecap(pdf_context *ctx) { int code; - pdf_num *n1; + int64_t i; if (pdfi_count_stack(ctx) < 1) return_error(gs_error_stackunderflow); - n1 = (pdf_num *)ctx->stack_top[-1]; - if (n1->type == PDF_INT){ - code = gs_setlinecap(ctx->pgs, n1->value.i); - } else { - pdfi_pop(ctx, 1); - return_error(gs_error_typecheck); - } - pdfi_pop(ctx, 1); - return code; + code = pdfi_destack_int(ctx, &i); + if (code < 0) + return code; + + return gs_setlinecap(ctx->pgs, i); } int pdfi_setflat(pdf_context *ctx) { int code; - pdf_num *n1; double d1; if (pdfi_count_stack(ctx) < 1) return_error(gs_error_stackunderflow); - n1 = (pdf_num *)ctx->stack_top[-1]; - if (n1->type == PDF_INT){ - d1 = (double)n1->value.i; - } else{ - if (n1->type == PDF_REAL) { - d1 = n1->value.d; - } else { - pdfi_pop(ctx, 1); - return_error(gs_error_typecheck); - } - } + code = pdfi_destack_real(ctx, &d1); + if (code < 0) + return code; + /* PDF spec says the value is 1-100, with 0 meaning "use the default" * But gs code (and now our code) forces the value to be <= 1 * This matches what Adobe and evince seem to do (see Bug 555657). @@ -384,9 +325,7 @@ int pdfi_setflat(pdf_context *ctx) */ if (d1 > 1.0) d1 = 1.0; - code = gs_setflat(ctx->pgs, d1); - pdfi_pop(ctx, 1); - return code; + return gs_setflat(ctx->pgs, d1); } int pdfi_setdash_impl(pdf_context *ctx, pdf_array *a, double phase_d) @@ -412,9 +351,9 @@ int pdfi_setdash_impl(pdf_context *ctx, pdf_array *a, double phase_d) gs_free_object(ctx->memory, dash_array, "error in setdash"); return code; } + int pdfi_setdash(pdf_context *ctx) { - pdf_num *phase; pdf_array *a; double phase_d; int code; @@ -424,52 +363,47 @@ int pdfi_setdash(pdf_context *ctx) return_error(gs_error_stackunderflow); } - phase = (pdf_num *)ctx->stack_top[-1]; - if (phase->type == PDF_INT){ - phase_d = (double)phase->value.i; - } else{ - if (phase->type == PDF_REAL) { - phase_d = phase->value.d; - } else { - pdfi_pop(ctx, 2); - return_error(gs_error_typecheck); - } + code = pdfi_destack_real(ctx, &phase_d); + if (code < 0) { + pdfi_pop(ctx, 1); + return code; } - a = (pdf_array *)ctx->stack_top[-2]; - if (a->type != PDF_ARRAY) { - pdfi_pop(ctx, 2); + a = (pdf_array *)ctx->stack_top[-1]; + pdfi_countup(a); + pdfi_pop(ctx, 1); + + if (pdfi_type_of(a) != PDF_ARRAY) { + pdfi_countdown(a); return_error(gs_error_typecheck); } code = pdfi_setdash_impl(ctx, a, phase_d); - pdfi_pop(ctx, 2); + pdfi_countdown(a); return code; } int pdfi_setmiterlimit(pdf_context *ctx) { int code; - pdf_num *n1; double d1; if (pdfi_count_stack(ctx) < 1) return_error(gs_error_stackunderflow); - n1 = (pdf_num *)ctx->stack_top[-1]; - if (n1->type == PDF_INT){ - d1 = (double)n1->value.i; - } else{ - if (n1->type == PDF_REAL) { - d1 = n1->value.d; - } else { - pdfi_pop(ctx, 1); - return_error(gs_error_typecheck); - } - } - code = gs_setmiterlimit(ctx->pgs, d1); - pdfi_pop(ctx, 1); - return code; + code = pdfi_destack_real(ctx, &d1); + if (code < 0) + return code; + + /* PostScript (and therefore the graphics library) impose a minimum + * value of 1.0 on miter limit. PDF does not specify a minimum, but less + * than 1 doesn't make a lot of sense. This code brought over from the old + * PDF interpreter which silently clamped the value to 1. + */ + if (d1 < 1.0) + d1 = 1.0; + + return gs_setmiterlimit(ctx->pgs, d1); } static int GS_LW(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict) @@ -569,38 +503,36 @@ static int GS_RI(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict static int GS_OP(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict) { - pdf_bool *b = NULL; + bool b; int code; bool known=false; - code = pdfi_dict_get_type(ctx, GS, "OP", PDF_BOOL, (pdf_obj **)&b); + code = pdfi_dict_get_bool(ctx, GS, "OP", &b); if (code < 0) return code; - gs_setstrokeoverprint(ctx->pgs, b->value); + gs_setstrokeoverprint(ctx->pgs, b); /* If op not in the dict, then also set it with OP * Because that's what gs does pdf_draw.ps/gsparamdict/OP */ code = pdfi_dict_known(ctx, GS, "op", &known); if (!known) - gs_setfilloverprint(ctx->pgs, b->value); + gs_setfilloverprint(ctx->pgs, b); - pdfi_countdown(b); return 0; } static int GS_op(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict) { - pdf_bool *b; + bool b; int code; - code = pdfi_dict_get_type(ctx, GS, "op", PDF_BOOL, (pdf_obj **)&b); + code = pdfi_dict_get_bool(ctx, GS, "op", &b); if (code < 0) return code; - gs_setfilloverprint(ctx->pgs, b->value); - pdfi_countdown(b); + gs_setfilloverprint(ctx->pgs, b); return 0; } @@ -652,46 +584,45 @@ static int pdfi_set_blackgeneration(pdf_context *ctx, pdf_obj *obj, pdf_dict *pa int code = 0, i; gs_function_t *pfn; - if (obj->type == PDF_NAME) { - if (pdfi_name_is((const pdf_name *)obj, "Identity")) { - code = gs_setblackgeneration_remap(ctx->pgs, gs_identity_transfer, false); - goto exit; - } else { - if (!is_BG && pdfi_name_is((const pdf_name *)obj, "Default")) { + switch (pdfi_type_of(obj)) { + case PDF_NAME: + if (pdfi_name_is((const pdf_name *)obj, "Identity")) + code = gs_setblackgeneration_remap(ctx->pgs, gs_identity_transfer, false); + else if (!is_BG && pdfi_name_is((const pdf_name *)obj, "Default")) { code = gs_setblackgeneration_remap(ctx->pgs, ctx->page.DefaultBG.proc, false); memcpy(ctx->pgs->black_generation->values, ctx->page.DefaultBG.values, transfer_map_size * sizeof(frac)); - goto exit; - } else { + } else code = gs_note_error(gs_error_rangecheck); - goto exit; - } - } - } else { - if (obj->type != PDF_DICT && obj->type != PDF_STREAM) - return_error(gs_error_typecheck); + goto exit; - code = pdfi_build_function(ctx, &pfn, NULL, 1, obj, page_dict); - if (code < 0) - return code; + case PDF_DICT: + case PDF_STREAM: + code = pdfi_build_function(ctx, &pfn, NULL, 1, obj, page_dict); + if (code < 0) + return code; - gs_setblackgeneration_remap(ctx->pgs, gs_mapped_transfer, false); - for (i = 0; i < transfer_map_size; i++) { - float v, f; + gs_setblackgeneration_remap(ctx->pgs, gs_mapped_transfer, false); + for (i = 0; i < transfer_map_size; i++) { + float v, f; - f = (1.0f / (transfer_map_size - 1)) * i; + f = (1.0f / (transfer_map_size - 1)) * i; - code = gs_function_evaluate(pfn, (const float *)&f, &v); - if (code < 0) { - pdfi_free_function(ctx, pfn); - return code; + code = gs_function_evaluate(pfn, (const float *)&f, &v); + if (code < 0) { + pdfi_free_function(ctx, pfn); + return code; + } + + ctx->pgs->black_generation->values[i] = + (v < 0.0 ? float2frac(0.0) : + v >= 1.0 ? frac_1 : + float2frac(v)); } + code = pdfi_free_function(ctx, pfn); + break; - ctx->pgs->black_generation->values[i] = - (v < 0.0 ? float2frac(0.0) : - v >= 1.0 ? frac_1 : - float2frac(v)); - } - code = pdfi_free_function(ctx, pfn); + default: + return_error(gs_error_typecheck); } exit: return code; @@ -741,46 +672,52 @@ static int pdfi_set_undercolorremoval(pdf_context *ctx, pdf_obj *obj, pdf_dict * int code = 0, i; gs_function_t *pfn; - if (obj->type == PDF_NAME) { - if (pdfi_name_is((const pdf_name *)obj, "Identity")) { - code = gs_setundercolorremoval_remap(ctx->pgs, gs_identity_transfer, false); - goto exit; - } else { - if (!is_BG && pdfi_name_is((const pdf_name *)obj, "Default")) { + switch (pdfi_type_of(obj)) { + case PDF_NAME: + if (pdfi_name_is((const pdf_name *)obj, "Identity")) { + code = gs_setundercolorremoval_remap(ctx->pgs, gs_identity_transfer, false); + } else if (!is_BG && pdfi_name_is((const pdf_name *)obj, "Default")) { code = gs_setundercolorremoval_remap(ctx->pgs, ctx->page.DefaultUCR.proc, false); memcpy(ctx->pgs->undercolor_removal->values, ctx->page.DefaultUCR.values, transfer_map_size * sizeof(frac)); - goto exit; } else { code = gs_note_error(gs_error_rangecheck); - goto exit; } - } - } else { - if (obj->type != PDF_DICT && obj->type != PDF_STREAM) - return_error(gs_error_typecheck); + goto exit; - code = pdfi_build_function(ctx, &pfn, NULL, 1, obj, page_dict); - if (code < 0) - return code; + case PDF_DICT: + case PDF_STREAM: + code = pdfi_build_function(ctx, &pfn, NULL, 1, obj, page_dict); + if (code < 0) + return code; - gs_setundercolorremoval_remap(ctx->pgs, gs_mapped_transfer, false); - for (i = 0; i < transfer_map_size; i++) { - float v, f; + if (pfn->params.n == 1) { + gs_setundercolorremoval_remap(ctx->pgs, gs_mapped_transfer, false); + for (i = 0; i < transfer_map_size; i++) { + float v, f; - f = (1.0f / (transfer_map_size - 1)) * i; + f = (1.0f / (transfer_map_size - 1)) * i; - code = gs_function_evaluate(pfn, (const float *)&f, &v); - if (code < 0) { - pdfi_free_function(ctx, pfn); - return code; + code = gs_function_evaluate(pfn, (const float *)&f, &v); + if (code < 0) { + pdfi_free_function(ctx, pfn); + return code; + } + + ctx->pgs->undercolor_removal->values[i] = + (v < 0.0 ? float2frac(0.0) : + v >= 1.0 ? frac_1 : + float2frac(v)); + } + code = pdfi_free_function(ctx, pfn); + } + else { + (void)pdfi_free_function(ctx, pfn); + code = gs_note_error(gs_error_rangecheck); } + break; - ctx->pgs->undercolor_removal->values[i] = - (v < 0.0 ? float2frac(0.0) : - v >= 1.0 ? frac_1 : - float2frac(v)); - } - code = pdfi_free_function(ctx, pfn); + default: + return_error(gs_error_typecheck); } exit: return code; @@ -852,12 +789,12 @@ static int pdfi_set_all_transfers(pdf_context *ctx, pdf_array *a, pdf_dict *page code = pdfi_array_get(ctx, a, (uint64_t)i, &o); if (code < 0) goto exit; - if (o->type == PDF_NAME) { - if (pdfi_name_is((const pdf_name *)o, "Identity")) { - proc_types[i] = E_IDENTITY; - map_procs[i] = gs_identity_transfer; - } else { - if (!is_TR && pdfi_name_is((const pdf_name *)o, "Default")) { + switch (pdfi_type_of(o)) { + case PDF_NAME: + if (pdfi_name_is((const pdf_name *)o, "Identity")) { + proc_types[i] = E_IDENTITY; + map_procs[i] = gs_identity_transfer; + } else if (!is_TR && pdfi_name_is((const pdf_name *)o, "Default")) { proc_types[i] = E_DEFAULT; map_procs[i] = ctx->page.DefaultTransfers[i].proc; } else { @@ -865,9 +802,9 @@ static int pdfi_set_all_transfers(pdf_context *ctx, pdf_array *a, pdf_dict *page code = gs_note_error(gs_error_typecheck); goto exit; } - } - } else { - if (o->type == PDF_STREAM || o->type == PDF_DICT) { + break; + case PDF_STREAM: + case PDF_DICT: proc_types[i] = E_FUNCTION; map_procs[i] = gs_mapped_transfer; code = pdfi_build_function(ctx, &pfn[i], NULL, 1, o, page_dict); @@ -880,11 +817,11 @@ static int pdfi_set_all_transfers(pdf_context *ctx, pdf_array *a, pdf_dict *page code = gs_note_error(gs_error_rangecheck); goto exit; } - } else { + break; + default: pdfi_countdown(o); code = gs_note_error(gs_error_typecheck); goto exit; - } } pdfi_countdown(o); } @@ -954,7 +891,7 @@ static int pdfi_set_gray_transfer(pdf_context *ctx, pdf_obj *tr_obj, pdf_dict *p int code = 0, i; gs_function_t *pfn; - if (tr_obj->type != PDF_DICT && tr_obj->type != PDF_STREAM) + if (pdfi_type_of(tr_obj) != PDF_DICT && pdfi_type_of(tr_obj) != PDF_STREAM) return_error(gs_error_typecheck); code = pdfi_build_function(ctx, &pfn, NULL, 1, tr_obj, page_dict); @@ -990,7 +927,7 @@ static int pdfi_set_transfer(pdf_context *ctx, pdf_obj *obj, pdf_dict *page_dict { int code = 0; - if (obj->type == PDF_NAME) { + if (pdfi_type_of(obj) == PDF_NAME) { if (pdfi_name_is((const pdf_name *)obj, "Identity")) { code = gs_settransfer_remap(ctx->pgs, gs_identity_transfer, false); goto exit; @@ -1006,7 +943,7 @@ static int pdfi_set_transfer(pdf_context *ctx, pdf_obj *obj, pdf_dict *page_dict } } - if (obj->type == PDF_ARRAY) { + if (pdfi_type_of(obj) == PDF_ARRAY) { if (pdfi_array_size((pdf_array *)obj) != 4) { code = gs_note_error(gs_error_rangecheck); goto exit; @@ -1157,7 +1094,7 @@ error: static int build_type1_halftone(pdf_context *ctx, pdf_dict *halftone_dict, pdf_dict *page_dict, gx_ht_order *porder, gs_halftone_component *phtc, char *name, int len, int comp_num) { - int code; + int code, i; pdf_obj *obj = NULL, *transfer = NULL; double f, a; float values[2] = {0, 0}, domain[4] = {-1, 1, -1, 1}, out; @@ -1193,46 +1130,48 @@ static int build_type1_halftone(pdf_context *ctx, pdf_dict *halftone_dict, pdf_d } memset(order, 0x00, sizeof(gx_ht_order)); - if (obj->type == PDF_NAME) { - int i; - - if (pdfi_name_is((pdf_name *)obj, "Default")) { - i = 0; - } else { - for (i = 0; i < (sizeof(spot_table) / sizeof (char *)); i++){ - if (pdfi_name_is((pdf_name *)obj, spot_table[i])) - break; + switch (pdfi_type_of(obj)) { + case PDF_NAME: + if (pdfi_name_is((pdf_name *)obj, "Default")) { + i = 0; + } else { + for (i = 0; i < (sizeof(spot_table) / sizeof (char *)); i++) { + if (pdfi_name_is((pdf_name *)obj, spot_table[i])) + break; + } + if (i >= (sizeof(spot_table) / sizeof (char *))) + return gs_note_error(gs_error_rangecheck); } - if (i >= (sizeof(spot_table) / sizeof (char *))) - return gs_note_error(gs_error_rangecheck); - } - code = pdfi_build_halftone_function(ctx, &pfn, (byte *)spot_functions[i], strlen(spot_functions[i])); - if (code < 0) - goto error; - } else { - if (obj->type == PDF_DICT || obj->type == PDF_STREAM) { + code = pdfi_build_halftone_function(ctx, &pfn, (byte *)spot_functions[i], strlen(spot_functions[i])); + if (code < 0) + goto error; + break; + case PDF_DICT: + case PDF_STREAM: code = pdfi_build_function(ctx, &pfn, (const float *)domain, 2, obj, page_dict); if (code < 0) goto error; - } else { + break; + default: code = gs_note_error(gs_error_typecheck); goto error; - } } if (pdfi_dict_knownget(ctx, halftone_dict, "TransferFunction", &transfer) > 0) { - if (transfer->type == PDF_NAME) { - /* As far as I can tell, only /Identity is valid as a name, so we can just ignore - * names, if it's not Identity it would be an error (which we would ignore) and if - * it is, it has no effect. So what's the point ? - */ - } else { - if (transfer->type == PDF_STREAM) { + switch (pdfi_type_of(transfer)) { + case PDF_NAME: + /* As far as I can tell, only /Identity is valid as a name, so we can just ignore + * names, if it's not Identity it would be an error (which we would ignore) and if + * it is, it has no effect. So what's the point ? + */ + break; + case PDF_STREAM: pdfi_evaluate_transfer(ctx, transfer, page_dict, &pmap); - } else { + break; + default: /* should be an error, but we can just ignore it */ pdfi_set_warning(ctx, 0, NULL, W_PDF_TYPECHECK, "build_type1_halftone", NULL); - } + break; } } @@ -1557,7 +1496,7 @@ static int build_type5_halftone(pdf_context *ctx, pdf_dict *halftone_dict, pdf_d * members. */ do { - if (Key->type != PDF_NAME) { + if (pdfi_type_of(Key) != PDF_NAME) { code = gs_note_error(gs_error_typecheck); goto error; } @@ -1630,7 +1569,7 @@ static int build_type5_halftone(pdf_context *ctx, pdf_dict *halftone_dict, pdf_d */ ix = 1; do { - if (Key->type != PDF_NAME) { + if (pdfi_type_of(Key) != PDF_NAME) { code = gs_note_error(gs_error_typecheck); goto error; } @@ -1673,7 +1612,7 @@ static int build_type5_halftone(pdf_context *ctx, pdf_dict *halftone_dict, pdf_d goto error; break; case 6: - if (Value->type != PDF_STREAM) { + if (pdfi_type_of(Value) != PDF_STREAM) { code = gs_note_error(gs_error_typecheck); goto error; } @@ -1682,7 +1621,7 @@ static int build_type5_halftone(pdf_context *ctx, pdf_dict *halftone_dict, pdf_d goto error; break; case 10: - if (Value->type != PDF_STREAM) { + if (pdfi_type_of(Value) != PDF_STREAM) { code = gs_note_error(gs_error_typecheck); goto error; } @@ -1691,7 +1630,7 @@ static int build_type5_halftone(pdf_context *ctx, pdf_dict *halftone_dict, pdf_d goto error; break; case 16: - if (Value->type != PDF_STREAM) { + if (pdfi_type_of(Value) != PDF_STREAM) { code = gs_note_error(gs_error_typecheck); goto error; } @@ -1849,7 +1788,7 @@ static int pdfi_do_halftone(pdf_context *ctx, pdf_obj *halftone_obj, pdf_dict *p break; case 6: - if (halftone_obj->type != PDF_STREAM) + if (pdfi_type_of(halftone_obj) != PDF_STREAM) return_error(gs_error_typecheck); phtc = (gs_halftone_component *)gs_alloc_bytes(ctx->memory, sizeof(gs_halftone_component), "pdfi_do_halftone"); if (phtc == 0) { @@ -1870,22 +1809,24 @@ static int pdfi_do_halftone(pdf_context *ctx, pdf_obj *halftone_obj, pdf_dict *p /* Transfer function pdht->order->transfer */ if (pdfi_dict_knownget(ctx, ((pdf_stream *)halftone_obj)->stream_dict, "TransferFunction", &transfer) > 0) { - if (transfer->type == PDF_NAME) { - /* As far as I can tell, only /Identity is valid as a name, so we can just ignore - * names, if it's not Identity it would be an error (which we would ignore) and if - * it is, it has no effect. So what's the point ? - */ - } else { - if (transfer->type == PDF_STREAM) { + switch (pdfi_type_of(transfer)) { + case PDF_NAME: + /* As far as I can tell, only /Identity is valid as a name, so we can just ignore + * names, if it's not Identity it would be an error (which we would ignore) and if + * it is, it has no effect. So what's the point ? + */ + break; + case PDF_STREAM: /* If we get an error here, we can just ignore it, and not apply the transfer */ code = pdfi_evaluate_transfer(ctx, transfer, page_dict, &pmap); if (code >= 0) { pdht->order.transfer = pmap; } - } else { + break; + default: /* should be an error, but we can just ignore it */ pdfi_set_warning(ctx, 0, NULL, W_PDF_TYPECHECK, "do_halftone", NULL); - } + break; } pdfi_countdown(transfer); } @@ -1901,7 +1842,7 @@ static int pdfi_do_halftone(pdf_context *ctx, pdf_obj *halftone_obj, pdf_dict *p gx_unset_both_dev_colors(ctx->pgs); break; case 10: - if (halftone_obj->type != PDF_STREAM) + if (pdfi_type_of(halftone_obj) != PDF_STREAM) return_error(gs_error_typecheck); phtc = (gs_halftone_component *)gs_alloc_bytes(ctx->memory, sizeof(gs_halftone_component), "pdfi_do_halftone"); if (phtc == 0) { @@ -1922,22 +1863,24 @@ static int pdfi_do_halftone(pdf_context *ctx, pdf_obj *halftone_obj, pdf_dict *p /* Transfer function pdht->order->transfer */ if (pdfi_dict_knownget(ctx, ((pdf_stream *)halftone_obj)->stream_dict, "TransferFunction", &transfer) > 0) { - if (transfer->type == PDF_NAME) { - /* As far as I can tell, only /Identity is valid as a name, so we can just ignore - * names, if it's not Identity it would be an error (which we would ignore) and if - * it is, it has no effect. So what's the point ? - */ - } else { - if (transfer->type == PDF_STREAM) { + switch (pdfi_type_of(transfer)) { + case PDF_NAME: + /* As far as I can tell, only /Identity is valid as a name, so we can just ignore + * names, if it's not Identity it would be an error (which we would ignore) and if + * it is, it has no effect. So what's the point ? + */ + break; + case PDF_STREAM: /* If we get an error here, we can just ignore it, and not apply the transfer */ code = pdfi_evaluate_transfer(ctx, transfer, page_dict, &pmap); if (code >= 0) { pdht->order.transfer = pmap; } - } else { + break; + default: /* should be an error, but we can just ignore it */ pdfi_set_warning(ctx, 0, NULL, W_PDF_TYPECHECK, "do_halftone", NULL); - } + break; } pdfi_countdown(transfer); } @@ -1953,7 +1896,7 @@ static int pdfi_do_halftone(pdf_context *ctx, pdf_obj *halftone_obj, pdf_dict *p gx_unset_both_dev_colors(ctx->pgs); break; case 16: - if (halftone_obj->type != PDF_STREAM) + if (pdfi_type_of(halftone_obj) != PDF_STREAM) return_error(gs_error_typecheck); phtc = (gs_halftone_component *)gs_alloc_bytes(ctx->memory, sizeof(gs_halftone_component), "pdfi_do_halftone"); if (phtc == 0) { @@ -1974,22 +1917,24 @@ static int pdfi_do_halftone(pdf_context *ctx, pdf_obj *halftone_obj, pdf_dict *p /* Transfer function pdht->order->transfer */ if (pdfi_dict_knownget(ctx, ((pdf_stream *)halftone_obj)->stream_dict, "TransferFunction", &transfer) > 0) { - if (transfer->type == PDF_NAME) { - /* As far as I can tell, only /Identity is valid as a name, so we can just ignore - * names, if it's not Identity it would be an error (which we would ignore) and if - * it is, it has no effect. So what's the point ? - */ - } else { - if (transfer->type == PDF_STREAM) { + switch (pdfi_type_of(transfer)) { + case PDF_NAME: + /* As far as I can tell, only /Identity is valid as a name, so we can just ignore + * names, if it's not Identity it would be an error (which we would ignore) and if + * it is, it has no effect. So what's the point ? + */ + break; + case PDF_STREAM: /* If we get an error here, we can just ignore it, and not apply the transfer */ code = pdfi_evaluate_transfer(ctx, transfer, page_dict, &pmap); if (code >= 0) { pdht->order.transfer = pmap; } - } else { + break; + default: /* should be an error, but we can just ignore it */ pdfi_set_warning(ctx, 0, NULL, W_PDF_TYPECHECK, "do_halftone", NULL); - } + break; } pdfi_countdown(transfer); } @@ -2034,7 +1979,7 @@ static int GS_HT(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict return code; - if (obj->type == PDF_NAME) { + if (pdfi_type_of(obj) == PDF_NAME) { if (pdfi_name_is((const pdf_name *)obj, "Default")) { goto exit; } else { @@ -2044,6 +1989,10 @@ static int GS_HT(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict } else { code = pdfi_do_halftone(ctx, obj, page_dict); } + if (code < 0 && !ctx->args.pdfstoponerror) { + pdfi_set_error(ctx, code, NULL, E_BAD_HALFTONE, "GS_HT", "Halftone will be ignored"); + code = 0; + } exit: pdfi_countdown(obj); @@ -2078,33 +2027,51 @@ static int GS_SM(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict static int GS_SA(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict) { - pdf_bool *b; + bool b; int code; - code = pdfi_dict_get_type(ctx, GS, "SA", PDF_BOOL, (pdf_obj **)&b); + code = pdfi_dict_get_bool(ctx, GS, "SA", &b); if (code < 0) return code; - code = gs_setstrokeadjust(ctx->pgs, b->value); - pdfi_countdown(b); - return 0; + return gs_setstrokeadjust(ctx->pgs, b); } static int GS_BM(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict) { pdf_name *n; int code; - gs_blend_mode_t mode; + gs_blend_mode_t mode = 0; /* Start with /Normal */ - code = pdfi_dict_get_type(ctx, GS, "BM", PDF_NAME, (pdf_obj **)&n); + code = pdfi_dict_get(ctx, GS, "BM", (pdf_obj **)&n); if (code < 0) return code; - code = pdfi_get_blend_mode(ctx, n, &mode); - pdfi_countdown(n); - if (code == 0) + if (pdfi_type_of(n) == PDF_ARRAY) { + int i; + pdf_array *a = (pdf_array *)n; + + for (i=0;i < pdfi_array_size(a);i++){ + code = pdfi_array_get_type(ctx, a, i, PDF_NAME, (pdf_obj **)&n); + if (code < 0) + continue; + code = pdfi_get_blend_mode(ctx, n, &mode); + pdfi_countdown(n); + if (code == 0) + break; + } + pdfi_countdown(a); return gs_setblendmode(ctx->pgs, mode); - return_error(gs_error_undefined); + } + + if (pdfi_type_of(n) == PDF_NAME) { + code = pdfi_get_blend_mode(ctx, n, &mode); + pdfi_countdown(n); + if (code == 0) + return gs_setblendmode(ctx->pgs, mode); + return_error(gs_error_undefined); + } + return_error(gs_error_typecheck); } static int GS_SMask(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict) @@ -2112,7 +2079,7 @@ static int GS_SMask(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_d pdf_obj *o = NULL; pdfi_int_gstate *igs = (pdfi_int_gstate *)ctx->pgs->client_data; int code; - pdf_bool *Processed = NULL; + bool Processed; if (ctx->page.has_transparency == false || ctx->args.notransparency == true) return 0; @@ -2121,40 +2088,51 @@ static int GS_SMask(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_d if (code < 0) return code; - if (o->type == PDF_NAME) { - pdf_name *n = (pdf_name *)o; + switch (pdfi_type_of(o)) { + case PDF_NAME: + { + pdf_name *n = (pdf_name *)o; - if (pdfi_name_is(n, "None")) { - if (igs->SMask) { - pdfi_gstate_smask_free(igs); - code = pdfi_trans_end_smask_notify(ctx); + if (pdfi_name_is(n, "None")) { + if (igs->SMask) { + pdfi_gstate_smask_free(igs); + code = pdfi_trans_end_smask_notify(ctx); + } + goto exit; } - goto exit; + code = pdfi_find_resource(ctx, (unsigned char *)"ExtGState", n, stream_dict, page_dict, &o); + pdfi_countdown(n); + if (code < 0) + return code; + break; } - code = pdfi_find_resource(ctx, (unsigned char *)"ExtGState", n, stream_dict, page_dict, &o); - pdfi_countdown(n); - if (code < 0) - return code; - } - if (o->type == PDF_DICT) { - code = pdfi_dict_knownget_type(ctx, (pdf_dict *)o, "Processed", PDF_BOOL, (pdf_obj **)&Processed); - /* Need to clear the Processed flag in the SMask if another value is set - * (even if it's the same SMask?) - * TODO: I think there is a better way to do this that doesn't require sticking this - * flag in the SMask dictionary. But for now, let's get correct behavior. - */ - if (code > 0 && Processed->value) - Processed->value = false; - if (igs->SMask) - pdfi_gstate_smask_free(igs); - /* We need to use the graphics state memory, in case we are running under Ghostscript. */ - pdfi_gstate_smask_install(igs, ctx->pgs->memory, (pdf_dict *)o, ctx->pgs); + case PDF_DICT: + { + code = pdfi_dict_knownget_bool(ctx, (pdf_dict *)o, "Processed", &Processed); + /* Need to clear the Processed flag in the SMask if another value is set + * (even if it's the same SMask?) + * TODO: I think there is a better way to do this that doesn't require sticking this + * flag in the SMask dictionary. But for now, let's get correct behavior. + */ + if (code > 0 && Processed) { + code = pdfi_dict_put_bool(ctx, (pdf_dict *)o, "Processed", false); + if (code < 0) + return code; + } + if (igs->SMask) + pdfi_gstate_smask_free(igs); + /* We need to use the graphics state memory, in case we are running under Ghostscript. */ + pdfi_gstate_smask_install(igs, ctx->pgs->memory, (pdf_dict *)o, ctx->pgs); + break; + } + + default: + break; } exit: pdfi_countdown(o); - pdfi_countdown(Processed); return 0; } @@ -2206,30 +2184,26 @@ static int GS_ca(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict static int GS_AIS(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict) { - pdf_bool *b; + bool b; int code; - code = pdfi_dict_get_type(ctx, GS, "AIS", PDF_BOOL, (pdf_obj **)&b); + code = pdfi_dict_get_bool(ctx, GS, "AIS", &b); if (code < 0) return code; - code = gs_setalphaisshape(ctx->pgs, b->value); - pdfi_countdown(b); - return 0; + return gs_setalphaisshape(ctx->pgs, b); } static int GS_TK(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict) { - pdf_bool *b; + bool b; int code; - code = pdfi_dict_get_type(ctx, GS, "TK", PDF_BOOL, (pdf_obj **)&b); + code = pdfi_dict_get_bool(ctx, GS, "TK", &b); if (code < 0) return code; - code = gs_settextknockout(ctx->pgs, b->value); - pdfi_countdown(b); - return 0; + return gs_settextknockout(ctx->pgs, b); } typedef int (*GS_proc)(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict); @@ -2293,7 +2267,7 @@ int pdfi_set_ExtGState(pdf_context *ctx, pdf_dict *stream_dict, int pdfi_setgstate(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict) { - pdf_name *n; + pdf_name *n = NULL; pdf_obj *o = NULL; int code=0, code1 = 0; @@ -2306,19 +2280,20 @@ int pdfi_setgstate(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict) goto setgstate_error; } n = (pdf_name *)ctx->stack_top[-1]; - if (n->type != PDF_NAME) { - pdfi_pop(ctx, 1); + pdfi_countup(n); + pdfi_pop(ctx, 1); + + if (pdfi_type_of(n) != PDF_NAME) { code = gs_note_error(gs_error_typecheck); goto setgstate_error; } code = pdfi_find_resource(ctx, (unsigned char *)"ExtGState", n, (pdf_dict *)stream_dict, page_dict, &o); - pdfi_pop(ctx, 1); if (code < 0) goto setgstate_error; - if (o->type != PDF_DICT) { + if (pdfi_type_of(o) != PDF_DICT) { code = gs_note_error(gs_error_typecheck); goto setgstate_error; } @@ -2329,6 +2304,7 @@ setgstate_error: code1 = pdfi_loop_detector_cleartomark(ctx); if (code == 0) code = code1; + pdfi_countdown(n); pdfi_countdown(o); return code; } |