PDF-Make
view release on metacpan or search on metacpan
src/pdfmake_interpreter.c view on Meta::CPAN
pdfmake_err_t err;
pdfmake_obj_t *saved_resources;
int saved_in_text;
pdfmake_obj_t stream_dict;
uint32_t matrix_k;
pdfmake_obj_t *mat;
uint32_t res_k;
pdfmake_obj_t *form_res;
int i;
if (!form || form->kind != PDFMAKE_STREAM) return PDFMAKE_OK;
if (interp->form_depth >= 32) {
/* Cycle guard â spec doesn't allow cycles; silently stop. */
return PDFMAKE_OK;
}
/* Decode the form's content stream (decrypt + FlateDecode). */
if (pdfmake_buf_init(&content) != PDFMAKE_OK) return PDFMAKE_ENOMEM;
err = PDFMAKE_OK;
if (interp->reader && form_num > 0) {
err = pdfmake_reader_resolve_stream(
(pdfmake_reader_t *)interp->reader, form_num, form_gen, &content);
} else {
/* No reader attached: use parser-level decode without decryption.
* Will likely fail for encrypted PDFs but works for simple ones. */
err = PDFMAKE_EINVAL;
}
if (err != PDFMAKE_OK || pdfmake_buf_len(&content) == 0) {
pdfmake_buf_free(&content);
return PDFMAKE_OK;
}
/* Save state: push gstate, stash current resources. */
gstate_push(interp);
saved_resources = interp->resources;
saved_in_text = interp->in_text_object;
interp->in_text_object = 0;
/* Apply form's /Matrix to CTM (default = identity). */
stream_dict.kind = PDFMAKE_DICT;
stream_dict.as.dict = form->as.stream->dict;
matrix_k = pdfmake_arena_intern_name(interp->arena, "Matrix", 6);
mat = pdfmake_dict_get(&stream_dict, matrix_k);
if (mat && mat->kind == PDFMAKE_ARRAY && pdfmake_array_len(mat) == 6) {
double m[6];
for (i = 0; i < 6; i++) {
pdfmake_obj_t *v = pdfmake_array_get(mat, i);
if (!v) { m[i] = 0; continue; }
if (v->kind == PDFMAKE_INT) m[i] = (double)v->as.i;
else if (v->kind == PDFMAKE_REAL) m[i] = v->as.r;
else m[i] = 0;
}
/* CTM = form_matrix à CTM */
pdfmake_matrix_multiply(interp->gs->ctm, m, interp->gs->ctm);
}
/* Swap resources: form's /Resources (if any) overlays. If the form has
* no /Resources, keep the outer page's â matches §7.8.3 "If the form
* XObject does not have its own Resources dictionary, the form uses
* the page's". */
res_k = pdfmake_arena_intern_name(interp->arena, "Resources", 9);
form_res = pdfmake_dict_get(&stream_dict, res_k);
if (form_res && form_res->kind == PDFMAKE_REF && interp->reader) {
pdfmake_reader_t *rd = (pdfmake_reader_t *)interp->reader;
if (rd->parser)
form_res = pdfmake_parser_resolve(rd->parser, form_res->as.ref);
}
if (form_res && form_res->kind == PDFMAKE_DICT) {
interp->resources = form_res;
}
/* Recurse with the already-initialized interpreter */
interp->form_depth++;
(void)parse_content_stream(interp,
pdfmake_buf_data(&content),
pdfmake_buf_len(&content));
interp->form_depth--;
/* Restore */
interp->in_text_object = saved_in_text;
interp->resources = saved_resources;
gstate_pop(interp);
pdfmake_buf_free(&content);
return PDFMAKE_OK;
}
/* Do - Paint XObject */
static pdfmake_err_t op_Do(pdfmake_interp_t *interp) {
pdfmake_obj_t name = pop_operand(interp);
uint32_t xobj_num;
uint16_t xobj_gen;
pdfmake_obj_t *xobj;
if (name.kind != PDFMAKE_NAME) {
return PDFMAKE_OK;
}
xobj_num = 0;
xobj_gen = 0;
xobj = lookup_xobject_with_ref(interp, name.as.name.id,
&xobj_num, &xobj_gen);
if (!xobj) {
return PDFMAKE_OK;
}
/* Check subtype */
if (xobj->kind == PDFMAKE_STREAM) {
/* Get /Subtype from stream dict */
uint32_t subtype_id = pdfmake_arena_intern_name(interp->arena, "Subtype", 7);
pdfmake_obj_t stream_dict;
pdfmake_obj_t *subtype;
stream_dict.kind = PDFMAKE_DICT;
stream_dict.as.dict = xobj->as.stream->dict;
subtype = pdfmake_dict_get(&stream_dict, subtype_id);
if (subtype && subtype->kind == PDFMAKE_NAME) {
( run in 1.343 second using v1.01-cache-2.11-cpan-600a1bdf6e4 )