pdf_obj * pdf_copy_dict(fz_context *ctx, pdf_obj *obj) { pdf_document *doc; pdf_obj *dict; int i, n; RESOLVE(obj); if (!OBJ_IS_DICT(obj)) fz_throw(ctx, FZ_ERROR_GENERIC, "not a dict (%s)", pdf_objkindstr(obj)); doc = DICT(obj)->doc; n = pdf_dict_len(ctx, obj); dict = pdf_new_dict(ctx, doc, n); fz_try(ctx) for (i = 0; i < n; i++) pdf_dict_put(ctx, dict, pdf_dict_get_key(ctx, obj, i), pdf_dict_get_val(ctx, obj, i)); fz_catch(ctx) { pdf_drop_obj(ctx, dict); fz_rethrow(ctx); } return dict; }
static void load_portfolio(fz_context *ctx, pdf_document *doc) { pdf_obj *obj; int i, n; pdf_portfolio **pp; obj = pdf_dict_getl(ctx, pdf_trailer(ctx, doc), PDF_NAME_Root, PDF_NAME_Collection, PDF_NAME_Schema, NULL); n = pdf_dict_len(ctx, obj); for (i = 0; i < n; i++) { pdf_obj *k = pdf_dict_get_key(ctx, obj, i); pdf_obj *v = pdf_dict_get_val(ctx, obj, i); int sort = pdf_to_int(ctx, pdf_dict_get(ctx, v, PDF_NAME_O)); pdf_obj *eo = pdf_dict_get(ctx, v, PDF_NAME_E); int editable = eo ? pdf_to_bool(ctx, eo) : 0; pdf_obj *vo = pdf_dict_get(ctx, v, PDF_NAME_V); int visible = vo ? pdf_to_bool(ctx, vo) : 1; char *subtype = pdf_to_name(ctx, pdf_dict_get(ctx, v, PDF_NAME_Subtype)); pdf_obj *name = pdf_dict_get(ctx, v, PDF_NAME_N); pdf_portfolio *p = fz_malloc_struct(ctx, pdf_portfolio); p->key = pdf_keep_obj(ctx, k); p->val = pdf_keep_obj(ctx, v); p->sort = sort; p->entry.visible = visible; p->entry.editable = editable; p->entry.name = pdf_keep_obj(ctx, name); if (!strcmp(subtype, "S")) p->entry.type = PDF_SCHEMA_TEXT; else if (!strcmp(subtype, "D")) p->entry.type = PDF_SCHEMA_DATE; else if (!strcmp(subtype, "N")) p->entry.type = PDF_SCHEMA_NUMBER; else if (!strcmp(subtype, "F")) p->entry.type = PDF_SCHEMA_FILENAME; else if (!strcmp(subtype, "Desc")) p->entry.type = PDF_SCHEMA_DESC; else if (!strcmp(subtype, "ModDate")) p->entry.type = PDF_SCHEMA_MODDATE; else if (!strcmp(subtype, "CreationDate")) p->entry.type = PDF_SCHEMA_CREATIONDATE; else if (!strcmp(subtype, "Size")) p->entry.type = PDF_SCHEMA_SIZE; else p->entry.type = PDF_SCHEMA_UNKNOWN; /* Now insert p */ pp = &doc->portfolio; while (*pp && (*pp)->sort <= p->sort) pp = &(*pp)->next; p->next = *pp; *pp = p; } }
/* ** Merge srcdict into dstdict. */ static void wmupdf_dict_merge(fz_context *ctx,char *dictname,pdf_obj *dstdict,pdf_obj *srcdict) { int i,len; /* printf(" Merging %s dictionaries (%d <-- %d)\n",dictname,pdf_to_num(dstdict),pdf_to_num(srcdict)); */ len=pdf_dict_len(srcdict); for (i=0;i<len;i++) { pdf_obj *key,*value; key=pdf_dict_get_key(srcdict,i); value=pdf_dict_get_val(srcdict,i); wmupdf_dict_merge_keyval(ctx,dstdict,key,value); } }
pdf_obj * pdf_copy_dict(fz_context *ctx, pdf_obj *obj) { pdf_obj *dict; int i, n; RESOLVE(obj); if (!obj) return NULL; /* Can't warn :( */ if (obj->kind != PDF_DICT) fz_warn(ctx, "assert: not a dict (%s)", pdf_objkindstr(obj)); n = pdf_dict_len(obj); dict = pdf_new_dict(ctx, n); for (i = 0; i < n; i++) fz_dict_put(dict, pdf_dict_get_key(obj, i), pdf_dict_get_val(obj, i)); return dict; }
pdf_obj * pdf_copy_dict(fz_context *ctx, pdf_obj *obj) { pdf_obj *dict; int i, n; RESOLVE(obj); if (obj >= PDF_OBJ__LIMIT) { pdf_document *doc = DICT(obj)->doc; if (obj->kind != PDF_DICT) fz_warn(ctx, "assert: not a dict (%s)", pdf_objkindstr(obj)); n = pdf_dict_len(ctx, obj); dict = pdf_new_dict(ctx, doc, n); for (i = 0; i < n; i++) pdf_dict_put(ctx, dict, pdf_dict_get_key(ctx, obj, i), pdf_dict_get_val(ctx, obj, i)); return dict; } return NULL; /* Can't warn :( */ }
/* ** From MuPDF pdfclean.c */ static void wmupdf_preserve_old_dests(pdf_obj *olddests,fz_context *ctx,pdf_document *xref, pdf_obj *pages) { int i; pdf_obj *names = pdf_new_dict(ctx,1); pdf_obj *dests = pdf_new_dict(ctx,1); pdf_obj *names_list = pdf_new_array(ctx,32); int len = pdf_dict_len(olddests); pdf_obj *root; for (i=0;i<len;i++) { pdf_obj *key = pdf_dict_get_key(olddests,i); pdf_obj *val = pdf_dict_get_val(olddests,i); pdf_obj *key_str = pdf_new_string(ctx,pdf_to_name(key),strlen(pdf_to_name(key))); pdf_obj *dest = pdf_dict_gets(val,"D"); dest = pdf_array_get(dest ? dest : val, 0); if (pdf_array_contains(pdf_dict_gets(pages,"Kids"),dest)) { pdf_array_push(names_list, key_str); pdf_array_push(names_list, val); } pdf_drop_obj(key_str); } root = pdf_dict_gets(xref->trailer,"Root"); pdf_dict_puts(dests,"Names",names_list); pdf_dict_puts(names,"Dests",dests); pdf_dict_puts(root,"Names",names); pdf_drop_obj(names); pdf_drop_obj(dests); pdf_drop_obj(names_list); pdf_drop_obj(olddests); }
static void retainpages(fz_context *ctx, globals *glo, int argc, char **argv) { pdf_obj *oldroot, *root, *pages, *kids, *countobj, *parent, *olddests; pdf_document *doc = glo->doc; int argidx = 0; pdf_obj *names_list = NULL; int pagecount; int i; /* Keep only pages/type and (reduced) dest entries to avoid * references to unretained pages */ oldroot = pdf_dict_get(ctx, pdf_trailer(ctx, doc), PDF_NAME_Root); pages = pdf_dict_get(ctx, oldroot, PDF_NAME_Pages); olddests = pdf_load_name_tree(ctx, doc, PDF_NAME_Dests); root = pdf_new_dict(ctx, doc, 2); pdf_dict_put(ctx, root, PDF_NAME_Type, pdf_dict_get(ctx, oldroot, PDF_NAME_Type)); pdf_dict_put(ctx, root, PDF_NAME_Pages, pdf_dict_get(ctx, oldroot, PDF_NAME_Pages)); pdf_update_object(ctx, doc, pdf_to_num(ctx, oldroot), root); pdf_drop_obj(ctx, root); /* Create a new kids array with only the pages we want to keep */ parent = pdf_new_indirect(ctx, doc, pdf_to_num(ctx, pages), pdf_to_gen(ctx, pages)); kids = pdf_new_array(ctx, doc, 1); /* Retain pages specified */ while (argc - argidx) { int page, spage, epage; char *spec, *dash; char *pagelist = argv[argidx]; pagecount = pdf_count_pages(ctx, doc); spec = fz_strsep(&pagelist, ","); while (spec) { dash = strchr(spec, '-'); if (dash == spec) spage = epage = pagecount; else spage = epage = atoi(spec); if (dash) { if (strlen(dash) > 1) epage = atoi(dash + 1); else epage = pagecount; } spage = fz_clampi(spage, 1, pagecount); epage = fz_clampi(epage, 1, pagecount); if (spage < epage) for (page = spage; page <= epage; ++page) retainpage(ctx, doc, parent, kids, page); else for (page = spage; page >= epage; --page) retainpage(ctx, doc, parent, kids, page); spec = fz_strsep(&pagelist, ","); } argidx++; } pdf_drop_obj(ctx, parent); /* Update page count and kids array */ countobj = pdf_new_int(ctx, doc, pdf_array_len(ctx, kids)); pdf_dict_put(ctx, pages, PDF_NAME_Count, countobj); pdf_drop_obj(ctx, countobj); pdf_dict_put(ctx, pages, PDF_NAME_Kids, kids); pdf_drop_obj(ctx, kids); /* Also preserve the (partial) Dests name tree */ if (olddests) { pdf_obj *names = pdf_new_dict(ctx, doc, 1); pdf_obj *dests = pdf_new_dict(ctx, doc, 1); int len = pdf_dict_len(ctx, olddests); names_list = pdf_new_array(ctx, doc, 32); for (i = 0; i < len; i++) { pdf_obj *key = pdf_dict_get_key(ctx, olddests, i); pdf_obj *val = pdf_dict_get_val(ctx, olddests, i); pdf_obj *dest = pdf_dict_get(ctx, val, PDF_NAME_D); dest = pdf_array_get(ctx, dest ? dest : val, 0); if (pdf_array_contains(ctx, pdf_dict_get(ctx, pages, PDF_NAME_Kids), dest)) { pdf_obj *key_str = pdf_new_string(ctx, doc, pdf_to_name(ctx, key), strlen(pdf_to_name(ctx, key))); pdf_array_push(ctx, names_list, key_str); pdf_array_push(ctx, names_list, val); pdf_drop_obj(ctx, key_str); } } root = pdf_dict_get(ctx, pdf_trailer(ctx, doc), PDF_NAME_Root); pdf_dict_put(ctx, dests, PDF_NAME_Names, names_list); pdf_dict_put(ctx, names, PDF_NAME_Dests, dests); pdf_dict_put(ctx, root, PDF_NAME_Names, names); pdf_drop_obj(ctx, names); pdf_drop_obj(ctx, dests); pdf_drop_obj(ctx, names_list); pdf_drop_obj(ctx, olddests); } /* Force the next call to pdf_count_pages to recount */ glo->doc->page_count = 0; /* Edit each pages /Annot list to remove any links that point to * nowhere. */ pagecount = pdf_count_pages(ctx, doc); for (i = 0; i < pagecount; i++) { pdf_obj *pageref = pdf_lookup_page_obj(ctx, doc, i); pdf_obj *pageobj = pdf_resolve_indirect(ctx, pageref); pdf_obj *annots = pdf_dict_get(ctx, pageobj, PDF_NAME_Annots); int len = pdf_array_len(ctx, annots); int j; for (j = 0; j < len; j++) { pdf_obj *o = pdf_array_get(ctx, annots, j); pdf_obj *p; if (!pdf_name_eq(ctx, pdf_dict_get(ctx, o, PDF_NAME_Subtype), PDF_NAME_Link)) continue; p = pdf_dict_get(ctx, o, PDF_NAME_A); if (!pdf_name_eq(ctx, pdf_dict_get(ctx, p, PDF_NAME_S), PDF_NAME_GoTo)) continue; if (string_in_names_list(ctx, pdf_dict_get(ctx, p, PDF_NAME_D), names_list)) continue; /* FIXME: Should probably look at Next too */ /* Remove this annotation */ pdf_array_delete(ctx, annots, j); j--; } } }
// just copy one of the resource sub-entries (e.g. /Font) static int copy_and_rename_resource(fz_context *dest_ctx, pdf_obj *dest, fz_context *src_ctx, pdf_obj *src, char *prefix, struct put_info *info) { char new_name[64]; /* this buffer is big enough up to hold all digits for two 16-bit numbers */ int i; for(i = 0; i < pdf_dict_len(src_ctx, src); i++) { pdf_obj *src_key = pdf_dict_get_key(src_ctx, src, i); pdf_obj *src_val = pdf_dict_get_val(src_ctx, src, i); if(!pdf_is_name(src_ctx, src_key)) { return(2); } /* if this is an inline resource, just copy this object into the new resource dict */ if(!pdf_is_indirect(src_ctx, src_val)) { if(snprintf(new_name, sizeof(new_name) / sizeof(new_name[0]), "%sinline_%d", prefix, info->next_inline_id++) >= sizeof(new_name) / sizeof(new_name[0])) return(1); // not enough space pdf_obj *new_res = copy_unassigned_object_continue(dest_ctx, info->dest_doc, src_ctx, info->src_doc, src_val, &info->new_ids); //pdf_obj *new_res = pdf_new_dict(dest_ctx, info->dest_doc, 10); printf("dump it...\n"); pdf_fprint_obj(dest_ctx, stdout, new_res, 0); /* now reference this new object in the resource object of this sheet */ pdf_obj *dest_key = pdf_new_name(dest_ctx, info->dest_doc, new_name); pdf_dict_put(dest_ctx, dest, dest_key, new_res); pdf_drop_obj(dest_ctx, dest_key); pdf_drop_obj(dest_ctx, new_res); } else { /* The new name of resource objects is always the num/gen of the referenced object in the src-file. Thus we can check by that name if the object was already referenced by another page of this sheet. */ if(snprintf(new_name, sizeof(new_name) / sizeof(new_name[0]), "%s%d_%d", prefix, pdf_to_num(dest_ctx, src_val), pdf_to_gen(dest_ctx, src_val)) >= sizeof(new_name) / sizeof(new_name[0])) return(1); // not enough space if(pdf_dict_gets(dest_ctx, dest, new_name) == NULL) { /* if this resource is not inlined and not already in the resource-dict of the current sheet... */ /* ...copy the referenced resource to the new document! If this object has copied already (for another sheet in dest_doc), copy_object_continue() will do nothing */ pdf_obj *new_res = copy_object_continue(dest_ctx, info->dest_doc, src_ctx, info->src_doc, src_val, &info->new_ids); /* now reference this new object in the resource object of this sheet */ pdf_obj *dest_key = pdf_new_name(dest_ctx, info->dest_doc, new_name); pdf_dict_put(dest_ctx, dest, dest_key, new_res); pdf_drop_obj(dest_ctx, dest_key); pdf_drop_obj(dest_ctx, new_res); } } /* even if it was used on another sheet or on this sheet, add it to the rename-dict for this sheet! Because it could have different names on different source-pages */ pdf_obj *rename_key = pdf_new_name(dest_ctx, info->dest_doc, pdf_to_name(dest_ctx, src_key)); pdf_obj *rename_val = pdf_new_name(dest_ctx, info->dest_doc, new_name); pdf_dict_put(dest_ctx, info->rename_dict, rename_key, rename_val); pdf_drop_obj(dest_ctx, rename_key); pdf_drop_obj(dest_ctx, rename_val); } return(0); }
static void retainpages(int argc, char **argv) { pdf_obj *oldroot, *root, *pages, *kids, *countobj, *parent, *olddests; /* Keep only pages/type and (reduced) dest entries to avoid * references to unretained pages */ oldroot = pdf_dict_gets(xref->trailer, "Root"); pages = pdf_dict_gets(oldroot, "Pages"); olddests = pdf_load_name_tree(xref, "Dests"); root = pdf_new_dict(ctx, 2); pdf_dict_puts(root, "Type", pdf_dict_gets(oldroot, "Type")); pdf_dict_puts(root, "Pages", pdf_dict_gets(oldroot, "Pages")); pdf_update_object(xref, pdf_to_num(oldroot), root); pdf_drop_obj(root); /* Create a new kids array with only the pages we want to keep */ parent = pdf_new_indirect(ctx, pdf_to_num(pages), pdf_to_gen(pages), xref); kids = pdf_new_array(ctx, 1); /* Retain pages specified */ while (argc - fz_optind) { int page, spage, epage, pagecount; char *spec, *dash; char *pagelist = argv[fz_optind]; pagecount = pdf_count_pages(xref); spec = fz_strsep(&pagelist, ","); while (spec) { dash = strchr(spec, '-'); if (dash == spec) spage = epage = pagecount; else spage = epage = atoi(spec); if (dash) { if (strlen(dash) > 1) epage = atoi(dash + 1); else epage = pagecount; } if (spage > epage) page = spage, spage = epage, epage = page; spage = fz_clampi(spage, 1, pagecount); epage = fz_clampi(epage, 1, pagecount); for (page = spage; page <= epage; page++) { pdf_obj *pageobj = xref->page_objs[page-1]; pdf_obj *pageref = xref->page_refs[page-1]; pdf_dict_puts(pageobj, "Parent", parent); /* Store page object in new kids array */ pdf_array_push(kids, pageref); } spec = fz_strsep(&pagelist, ","); } fz_optind++; } pdf_drop_obj(parent); /* Update page count and kids array */ countobj = pdf_new_int(ctx, pdf_array_len(kids)); pdf_dict_puts(pages, "Count", countobj); pdf_drop_obj(countobj); pdf_dict_puts(pages, "Kids", kids); pdf_drop_obj(kids); /* Also preserve the (partial) Dests name tree */ if (olddests) { int i; pdf_obj *names = pdf_new_dict(ctx, 1); pdf_obj *dests = pdf_new_dict(ctx, 1); pdf_obj *names_list = pdf_new_array(ctx, 32); int len = pdf_dict_len(olddests); for (i = 0; i < len; i++) { pdf_obj *key = pdf_dict_get_key(olddests, i); pdf_obj *val = pdf_dict_get_val(olddests, i); pdf_obj *key_str = pdf_new_string(ctx, pdf_to_name(key), strlen(pdf_to_name(key))); pdf_obj *dest = pdf_dict_gets(val, "D"); dest = pdf_array_get(dest ? dest : val, 0); if (pdf_array_contains(pdf_dict_gets(pages, "Kids"), dest)) { pdf_array_push(names_list, key_str); pdf_array_push(names_list, val); } pdf_drop_obj(key_str); } root = pdf_dict_gets(xref->trailer, "Root"); pdf_dict_puts(dests, "Names", names_list); pdf_dict_puts(names, "Dests", dests); pdf_dict_puts(root, "Names", names); pdf_drop_obj(names); pdf_drop_obj(dests); pdf_drop_obj(names_list); pdf_drop_obj(olddests); } }
static void retainpages(fz_context *ctx, globals *glo, int argc, char **argv) { pdf_obj *oldroot, *root, *pages, *kids, *countobj, *parent, *olddests; pdf_document *doc = glo->doc; int argidx = 0; pdf_obj *names_list = NULL; pdf_obj *outlines; int pagecount; int i; int *page_object_nums; /* Keep only pages/type and (reduced) dest entries to avoid * references to unretained pages */ oldroot = pdf_dict_get(ctx, pdf_trailer(ctx, doc), PDF_NAME_Root); pages = pdf_dict_get(ctx, oldroot, PDF_NAME_Pages); olddests = pdf_load_name_tree(ctx, doc, PDF_NAME_Dests); outlines = pdf_dict_get(ctx, oldroot, PDF_NAME_Outlines); root = pdf_new_dict(ctx, doc, 3); pdf_dict_put(ctx, root, PDF_NAME_Type, pdf_dict_get(ctx, oldroot, PDF_NAME_Type)); pdf_dict_put(ctx, root, PDF_NAME_Pages, pdf_dict_get(ctx, oldroot, PDF_NAME_Pages)); pdf_dict_put(ctx, root, PDF_NAME_Outlines, outlines); pdf_update_object(ctx, doc, pdf_to_num(ctx, oldroot), root); /* Create a new kids array with only the pages we want to keep */ parent = pdf_new_indirect(ctx, doc, pdf_to_num(ctx, pages), pdf_to_gen(ctx, pages)); kids = pdf_new_array(ctx, doc, 1); /* Retain pages specified */ while (argc - argidx) { int page, spage, epage; char *spec, *dash; char *pagelist = argv[argidx]; pagecount = pdf_count_pages(ctx, doc); spec = fz_strsep(&pagelist, ","); while (spec) { dash = strchr(spec, '-'); if (dash == spec) spage = epage = pagecount; else spage = epage = atoi(spec); if (dash) { if (strlen(dash) > 1) epage = atoi(dash + 1); else epage = pagecount; } spage = fz_clampi(spage, 1, pagecount); epage = fz_clampi(epage, 1, pagecount); if (spage < epage) for (page = spage; page <= epage; ++page) retainpage(ctx, doc, parent, kids, page); else for (page = spage; page >= epage; --page) retainpage(ctx, doc, parent, kids, page); spec = fz_strsep(&pagelist, ","); } argidx++; } pdf_drop_obj(ctx, parent); /* Update page count and kids array */ countobj = pdf_new_int(ctx, doc, pdf_array_len(ctx, kids)); pdf_dict_put(ctx, pages, PDF_NAME_Count, countobj); pdf_drop_obj(ctx, countobj); pdf_dict_put(ctx, pages, PDF_NAME_Kids, kids); pdf_drop_obj(ctx, kids); /* Force the next call to pdf_count_pages to recount */ glo->doc->page_count = 0; pagecount = pdf_count_pages(ctx, doc); page_object_nums = fz_calloc(ctx, pagecount, sizeof(*page_object_nums)); for (i = 0; i < pagecount; i++) { pdf_obj *pageref = pdf_lookup_page_obj(ctx, doc, i); page_object_nums[i] = pdf_to_num(ctx, pageref); } /* If we had an old Dests tree (now reformed as an olddests * dictionary), keep any entries in there that point to * valid pages. This may mean we keep more than we need, but * it's safe at least. */ if (olddests) { pdf_obj *names = pdf_new_dict(ctx, doc, 1); pdf_obj *dests = pdf_new_dict(ctx, doc, 1); int len = pdf_dict_len(ctx, olddests); names_list = pdf_new_array(ctx, doc, 32); for (i = 0; i < len; i++) { pdf_obj *key = pdf_dict_get_key(ctx, olddests, i); pdf_obj *val = pdf_dict_get_val(ctx, olddests, i); pdf_obj *dest = pdf_dict_get(ctx, val, PDF_NAME_D); dest = pdf_array_get(ctx, dest ? dest : val, 0); if (dest_is_valid_page(ctx, dest, page_object_nums, pagecount)) { pdf_obj *key_str = pdf_new_string(ctx, doc, pdf_to_name(ctx, key), strlen(pdf_to_name(ctx, key))); pdf_array_push(ctx, names_list, key_str); pdf_array_push(ctx, names_list, val); pdf_drop_obj(ctx, key_str); } } pdf_dict_put(ctx, dests, PDF_NAME_Names, names_list); pdf_dict_put(ctx, names, PDF_NAME_Dests, dests); pdf_dict_put(ctx, root, PDF_NAME_Names, names); pdf_drop_obj(ctx, names); pdf_drop_obj(ctx, dests); pdf_drop_obj(ctx, olddests); } /* Edit each pages /Annot list to remove any links that point to * nowhere. */ for (i = 0; i < pagecount; i++) { pdf_obj *pageref = pdf_lookup_page_obj(ctx, doc, i); pdf_obj *pageobj = pdf_resolve_indirect(ctx, pageref); pdf_obj *annots = pdf_dict_get(ctx, pageobj, PDF_NAME_Annots); int len = pdf_array_len(ctx, annots); int j; for (j = 0; j < len; j++) { pdf_obj *o = pdf_array_get(ctx, annots, j); if (!pdf_name_eq(ctx, pdf_dict_get(ctx, o, PDF_NAME_Subtype), PDF_NAME_Link)) continue; if (!dest_is_valid(ctx, o, pagecount, page_object_nums, names_list)) { /* Remove this annotation */ pdf_array_delete(ctx, annots, j); j--; } } } if (strip_outlines(ctx, doc, outlines, pagecount, page_object_nums, names_list) == 0) { pdf_dict_del(ctx, root, PDF_NAME_Outlines); } fz_free(ctx, page_object_nums); pdf_drop_obj(ctx, names_list); pdf_drop_obj(ctx, root); }
static void wmupdf_convert_single_page_to_form(pdf_document *xref,fz_context *ctx,int pageno) { pdf_obj *array,*srcpageobj,*srcpagecontents; int i,len,streamlen,pageref,pagegen,compressed; double bbox_array[4]; double matrix[6]; /* New source page, so get the source page objects */ srcpageobj = xref->page_objs[pageno-1]; pageref=pdf_to_num(xref->page_refs[pageno-1]); pagegen=pdf_to_gen(xref->page_refs[pageno-1]); wmupdf_page_bbox(srcpageobj,bbox_array); for (i=0;i<6;i++) matrix[i]=0.; matrix[0]=matrix[3]=1.; srcpagecontents=pdf_dict_gets(srcpageobj,"Contents"); /* Concatenate all indirect streams from source page directly into it. */ // printf("Adding streams to source page %d (pageref=%d, pagegen=%d)...\n",pageno,pageref,pagegen); streamlen=0; if (pdf_is_array(srcpagecontents)) { int k; for (k=0;k<pdf_array_len(srcpagecontents);k++) { pdf_obj *obj; obj=pdf_array_get(srcpagecontents,k); if (pdf_is_indirect(obj)) pdf_resolve_indirect(obj); streamlen=add_to_srcpage_stream(xref,ctx,pageref,pagegen,obj); } } else { if (pdf_is_indirect(srcpagecontents)) pdf_resolve_indirect(srcpagecontents); streamlen=add_to_srcpage_stream(xref,ctx,pageref,pagegen,srcpagecontents); } compressed=stream_deflate(xref,ctx,pageref,pagegen,&streamlen); srcpageobj = xref->page_objs[pageno-1]; pageref=pdf_to_num(xref->page_refs[pageno-1]); len=pdf_dict_len(srcpageobj); for (i=0;i<len;i++) { pdf_obj *key; /* *value */ key=pdf_dict_get_key(srcpageobj,i); /* if (pdf_is_name(key)) printf("key[%d] = name = %s\n",i,pdf_to_name(key)); else printf("key[%d] = ??\n",i); */ /* value=pdf_dict_get_val(srcpageobj,i); */ /* Keep same resources */ if (!pdf_is_name(key)) continue; if (pdf_is_name(key) && !stricmp("Resources",pdf_to_name(key))) continue; /* Drop dictionary entry otherwise */ // printf("Deleting key %s.\n",pdf_to_name(key)); pdf_dict_del(srcpageobj,key); i=-1; len=pdf_dict_len(srcpageobj); } pdf_dict_puts(srcpageobj,"Type",pdf_new_name(ctx,"XObject")); pdf_dict_puts(srcpageobj,"Subtype",pdf_new_name(ctx,"Form")); pdf_dict_puts(srcpageobj,"FormType",pdf_new_int(ctx,1)); if (compressed) pdf_dict_puts(srcpageobj,"Filter",pdf_new_name(ctx,"FlateDecode")); pdf_dict_puts(srcpageobj,"Length",pdf_new_int(ctx,streamlen)); array=pdf_new_array(ctx,4); for (i=0;i<4;i++) pdf_array_push(array,pdf_new_real(ctx,bbox_array[i])); pdf_dict_puts(srcpageobj,"BBox",array); array=pdf_new_array(ctx,6); for (i=0;i<6;i++) pdf_array_push(array,pdf_new_real(ctx,matrix[i])); pdf_dict_puts(srcpageobj,"Matrix",array); /* (It's no longer a "page"--it's a Form-type XObject) */ /* I don't think this call should be made since it will call fz_drop_object on srcpageobj */ /* pdf_update_object(xref,pageref,srcpageobj); */ }