예제 #1
0
파일: pdf-object.c 프로젝트: muennich/mupdf
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;
}
예제 #2
0
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;
	}
}
예제 #3
0
/*
** 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);
        }
    }
예제 #4
0
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;
}
예제 #5
0
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 :( */
}
예제 #6
0
/*
** 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--;
		}
	}
}
예제 #8
0
파일: put-content.c 프로젝트: s-k2/Juggler
// 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);
}
예제 #9
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);
	}
}
예제 #10
0
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);
}
예제 #11
0
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); */
    }