Exemple #1
2
fz_link_dest
pdf_parse_action(pdf_document *xref, pdf_obj *action)
{
	fz_link_dest ld;
	pdf_obj *obj, *dest;
	fz_context *ctx = xref->ctx;

	UNUSED(ctx);

	ld.kind = FZ_LINK_NONE;

	if (!action)
		return ld;

	obj = pdf_dict_gets(action, "S");
	if (!strcmp(pdf_to_name(obj), "GoTo"))
	{
		dest = pdf_dict_gets(action, "D");
		ld = pdf_parse_link_dest(xref, dest);
	}
	else if (!strcmp(pdf_to_name(obj), "URI"))
	{
		ld.kind = FZ_LINK_URI;
		ld.ld.uri.is_map = pdf_to_bool(pdf_dict_gets(action, "IsMap"));
		ld.ld.uri.uri = pdf_to_utf8(xref, pdf_dict_gets(action, "URI"));
	}
	else if (!strcmp(pdf_to_name(obj), "Launch"))
	{
		dest = pdf_dict_gets(action, "F");
		ld.kind = FZ_LINK_LAUNCH;
		if (pdf_is_dict(dest))
			dest = pdf_dict_gets(dest, "F");
		ld.ld.launch.file_spec = pdf_to_utf8(xref, dest);
		ld.ld.launch.new_window = pdf_to_int(pdf_dict_gets(action, "NewWindow"));
	}
	else if (!strcmp(pdf_to_name(obj), "Named"))
	{
		ld.kind = FZ_LINK_NAMED;
		ld.ld.named.named = pdf_to_utf8(xref, pdf_dict_gets(action, "N"));
	}
	else if (!strcmp(pdf_to_name(obj), "GoToR"))
	{
		dest = pdf_dict_gets(action, "D");
		ld = pdf_parse_link_dest(xref, dest);
		ld.kind = FZ_LINK_GOTOR;
		ld.ld.gotor.file_spec = pdf_to_utf8(xref, pdf_dict_gets(action, "F"));
		ld.ld.gotor.new_window = pdf_to_int(pdf_dict_gets(action, "NewWindow"));
	}
	return ld;
}
Exemple #2
1
static void execute_action(pdf_document *doc, pdf_obj *obj, pdf_obj *a)
{
	fz_context *ctx = doc->ctx;
	if (a)
	{
		char *type = pdf_to_name(pdf_dict_gets(a, "S"));

		if (!strcmp(type, "JavaScript"))
		{
			pdf_obj *js = pdf_dict_gets(a, "JS");
			if (js)
			{
				char *code = pdf_to_utf8(doc, js);
				fz_try(ctx)
				{
					pdf_js_execute(doc->js, code);
				}
				fz_always(ctx)
				{
					fz_free(ctx, code);
				}
				fz_catch(ctx)
				{
					fz_rethrow(ctx);
				}
			}
		}
		else if (!strcmp(type, "ResetForm"))
Exemple #3
1
pdf_obj *
pdf_to_utf8_name(fz_context *ctx, pdf_document *doc, pdf_obj *src)
{
	char *buf = pdf_to_utf8(ctx, doc, src);
	pdf_obj *dst = pdf_new_name(ctx, doc, buf);
	fz_free(ctx, buf);
	return dst;
}
Exemple #4
0
static fz_outline *
pdf_load_outline_imp(pdf_document *xref, pdf_obj *dict)
{
	fz_context *ctx = xref->ctx;
	fz_outline *node, **prev, *first;
	pdf_obj *obj;
	pdf_obj *odict = dict;

	fz_var(dict);

	fz_try(ctx)
	{
		first = NULL;
		prev = &first;
		while (dict && pdf_is_dict(dict))
		{
			if (pdf_obj_mark(dict))
				break;
			node = fz_malloc_struct(ctx, fz_outline);
			node->title = NULL;
			node->dest.kind = FZ_LINK_NONE;
			node->down = NULL;
			node->next = NULL;
			*prev = node;
			prev = &node->next;

			obj = pdf_dict_gets(dict, "Title");
			if (obj)
				node->title = pdf_to_utf8(xref, obj);

			/* SumatraPDF: support expansion states */
			node->is_open = pdf_to_int(pdf_dict_gets(dict, "Count")) >= 0;

			if ((obj = pdf_dict_gets(dict, "Dest")))
				node->dest = pdf_parse_link_dest(xref, obj);
			else if ((obj = pdf_dict_gets(dict, "A")))
				node->dest = pdf_parse_action(xref, obj);

			obj = pdf_dict_gets(dict, "First");
			if (obj)
				node->down = pdf_load_outline_imp(xref, obj);

			dict = pdf_dict_gets(dict, "Next");
		}
	}
	fz_always(ctx)
	{
		for (dict = odict; dict && pdf_obj_marked(dict); dict = pdf_dict_gets(dict, "Next"))
			pdf_obj_unmark(dict);
	}
	fz_catch(ctx)
	{
		/* SumatraPDF: fix memory leak */
		fz_free_outline(ctx, first);
		fz_rethrow(ctx);
	}

	return first;
}
pdf_obj *
pdf_to_utf8_name(pdf_document *doc, pdf_obj *src)
{
    char *buf = pdf_to_utf8(doc, src);
    pdf_obj *dst = pdf_new_name(doc, buf);
    fz_free(doc->ctx, buf);
    return dst;
}
Exemple #6
0
pdf_obj *
pdf_to_utf8_name(fz_context *ctx, pdf_obj *src)
{
    char *buf = pdf_to_utf8(ctx, src);
    pdf_obj *dst = fz_new_name(ctx, buf);
    fz_free(ctx, buf);
    return dst;
}
fz_obj *
pdf_to_utf8_name(fz_obj *src)
{
	char *buf = pdf_to_utf8(src);
	fz_obj *dst = fz_new_name(buf);
	fz_free(buf);
	return dst;
}
Exemple #8
0
static fz_outline *
pdf_load_outline_imp(pdf_document *xref, fz_obj *dict)
{
	fz_context *ctx = xref->ctx;
	fz_outline *node, **prev, *first;
	fz_obj *obj;
	fz_obj *odict = dict;

	fz_var(dict);

	fz_try(ctx)
	{
		first = NULL;
		prev = &first;
		while (dict && fz_is_dict(dict))
		{
			if (fz_dict_mark(dict))
				break;
			node = fz_malloc_struct(ctx, fz_outline);
			node->title = NULL;
			node->dest.kind = FZ_LINK_NONE;
			node->down = NULL;
			node->next = NULL;
			*prev = node;
			prev = &node->next;

			obj = fz_dict_gets(dict, "Title");
			if (obj)
				node->title = pdf_to_utf8(ctx, obj);

			if ((obj = fz_dict_gets(dict, "Dest")))
				node->dest = pdf_parse_link_dest(xref, obj);
			else if ((obj = fz_dict_gets(dict, "A")))
				node->dest = pdf_parse_action(xref, obj);

			obj = fz_dict_gets(dict, "First");
			if (obj)
				node->down = pdf_load_outline_imp(xref, obj);

			dict = fz_dict_gets(dict, "Next");
		}
	}
	fz_catch(ctx)
	{
		for (dict = odict; dict && fz_dict_marked(dict); dict = fz_dict_gets(dict, "Next"))
			fz_dict_unmark(dict);
		fz_rethrow(ctx);
	}

	for (dict = odict; dict && fz_dict_marked(dict); dict = fz_dict_gets(dict, "Next"))
		fz_dict_unmark(dict);

	return first;
}
Exemple #9
0
static const char* _pdf_doc_title(struct _pdf_doc *self)
{
    if (self->xref) {
        fz_obj *info, *obj;
        info = fz_dict_gets(self->xref->trailer, "Info");
        if (info) {
            obj = fz_dict_gets(info, "Title");
            if (obj)
                return pdf_to_utf8(obj);
        }
    }

    return NULL;
}
Exemple #10
0
static void execute_action(fz_context *ctx, pdf_document *doc, pdf_obj *obj, pdf_obj *a)
{
    if (a)
    {
        pdf_obj *type = pdf_dict_get(ctx, a, PDF_NAME_S);

        if (pdf_name_eq(ctx, type, PDF_NAME_JavaScript))
        {
            pdf_obj *js = pdf_dict_get(ctx, a, PDF_NAME_JS);
            if (js)
            {
                char *code = pdf_to_utf8(ctx, doc, js);
                fz_try(ctx)
                {
                    pdf_js_execute(doc->js, code);
                }
                fz_always(ctx)
                {
                    fz_free(ctx, code);
                }
                fz_catch(ctx)
                {
                    fz_rethrow(ctx);
                }
            }
        }
        else if (pdf_name_eq(ctx, type, PDF_NAME_ResetForm))
        {
            reset_form(ctx, doc, pdf_dict_get(ctx, a, PDF_NAME_Fields), pdf_to_int(ctx, pdf_dict_get(ctx, a, PDF_NAME_Flags)) & 1);
        }
        else if (pdf_name_eq(ctx, type, PDF_NAME_Named))
        {
            pdf_obj *name = pdf_dict_get(ctx, a, PDF_NAME_N);

            if (pdf_name_eq(ctx, name, PDF_NAME_Print))
                pdf_event_issue_print(ctx, doc);
        }
    }
Exemple #11
0
char *
pdf_copy_annot_contents(fz_context *ctx, pdf_annot *annot)
{
	return pdf_to_utf8(ctx, pdf_dict_get(ctx, annot->obj, PDF_NAME(Contents)));
}
Exemple #12
0
void pdfapp_open(pdfapp_t *app, char *filename)
{
#if 0
	fz_error error;
	fz_obj *obj;
	char *password = "";
#else
	fz_error error;
	fz_stream *file;
	char *password = "";
	fz_obj *obj;
	fz_obj *info;

	int fd;
	fd = open(filename, O_BINARY | O_RDONLY, 0666);
	if (fd < 0)
		fprintf(stderr, "error, file %s does not exist\n", filename);
#endif

	/*
	 * Open PDF and load xref table
	 */

	app->filename = filename;

#if 0
	app->xref = pdf_newxref();
	error = pdf_loadxref(app->xref, filename);
	if (error)
	{
		fz_catch(error, "trying to air");
		error = pdf_repairxref(app->xref, filename);
		if (error)
			pdfapp_error(app, error);
	}

	error = pdf_decryptxref(app->xref);
	if (error)
		pdfapp_error(app, error);
#else
	file = fz_open_fd(fd);
	error = pdf_open_xref_with_stream(&app->xref, file, NULL);
	if (error)
		pdfapp_error(app, fz_rethrow(error, "cannot open document '%s'", filename));
	fz_close(file);
#endif

	/*
	 * Handle encrypted PDF files
	 */

	if (pdf_needs_password(app->xref))
	{
		int okay = pdf_authenticate_password(app->xref, password);
		while (!okay)
		{	
		        //password = winpassword(app, filename);
			if (!password)
				exit(1);
			okay = pdf_authenticate_password(app->xref, password);
			if (!okay)
				pdfapp_warn(app, "Invalid password.");
		}
	}

	/*
	 * Load meta information
	 * TODO: move this into mupdf library
	 */

#if 0
	obj = fz_dictgets(app->xref->trailer, "Root");
	app->xref->root = fz_resolveindirect(obj);
	if (!app->xref->root)
		pdfapp_error(app, fz_throw("syntaxerror: missing Root object"));
	fz_keepobj(app->xref->root);

	obj = fz_dictgets(app->xref->trailer, "Info");
	app->xref->info = fz_resolveindirect(obj);
	if (!app->xref->info)
		pdfapp_warn(app, "Could not load PDF meta information.");
	if (app->xref->info)
		fz_keepobj(app->xref->info);

	/*app->outline = pdf_loadoutline(app->xref);*/

	app->doctitle = filename;
	if (strrchr(app->doctitle, '\\'))
		app->doctitle = strrchr(app->doctitle, '\\') + 1;
	if (strrchr(app->doctitle, '/'))
		app->doctitle = strrchr(app->doctitle, '/') + 1;
	if (app->xref->info)
	{
		obj = fz_dictgets(app->xref->info, "Title");
		if (obj)
		{
			app->doctitle = pdf_toutf8(obj);
		}
	}
#else
	app->outline = pdf_load_outline(app->xref);

	app->doctitle = filename;
	if (strrchr(app->doctitle, '\\'))
		app->doctitle = strrchr(app->doctitle, '\\') + 1;
	if (strrchr(app->doctitle, '/'))
		app->doctitle = strrchr(app->doctitle, '/') + 1;
	info = fz_dict_gets(app->xref->trailer, "Info");
	if (info)
	{
		obj = fz_dict_gets(info, "Title");
		if (obj)
			app->doctitle = pdf_to_utf8(obj);
	}
#endif

	/*
	 * Start at first page
	 */

#if 0
	app->pagecount = pdf_getpagecount(app->xref);
#else
	error = pdf_load_page_tree(app->xref);
	if (error)
		pdfapp_error(app, fz_rethrow(error, "cannot load page tree"));

	app->pagecount = pdf_count_pages(app->xref);
#endif
	
	app->rotate = 0;
	
}
Exemple #13
0
static fz_outline *
pdf_load_outline_imp(fz_context *ctx, pdf_document *doc, pdf_obj *dict)
{
    fz_outline *node, **prev, *first;
    pdf_obj *obj;
    pdf_obj *odict = dict;

    fz_var(dict);
    fz_var(first);

    fz_try(ctx)
    {
        first = NULL;
        prev = &first;
        while (dict && pdf_is_dict(ctx, dict))
        {
            if (pdf_mark_obj(ctx, dict))
                break;
            node = fz_new_outline(ctx);
            *prev = node;
            prev = &node->next;

            obj = pdf_dict_get(ctx, dict, PDF_NAME_Title);
            if (obj)
                node->title = pdf_to_utf8(ctx, obj);

            if ((obj = pdf_dict_get(ctx, dict, PDF_NAME_Dest)) != NULL)
                node->uri = pdf_parse_link_dest(ctx, doc, obj);
            else if ((obj = pdf_dict_get(ctx, dict, PDF_NAME_A)) != NULL)
                node->uri = pdf_parse_link_action(ctx, doc, obj);
            else
                node->uri = NULL;

            if (node->uri)
                node->page = pdf_resolve_link(ctx, doc, node->uri, NULL, NULL);
            else
                node->page = -1;

            obj = pdf_dict_get(ctx, dict, PDF_NAME_First);
            if (obj)
            {
                node->down = pdf_load_outline_imp(ctx, doc, obj);

                obj = pdf_dict_get(ctx, dict, PDF_NAME_Count);
                if (pdf_to_int(ctx, obj) > 0)
                    node->is_open = 1;
            }

            dict = pdf_dict_get(ctx, dict, PDF_NAME_Next);
        }
    }
    fz_always(ctx)
    {
        for (dict = odict; dict && pdf_obj_marked(ctx, dict); dict = pdf_dict_get(ctx, dict, PDF_NAME_Next))
            pdf_unmark_obj(ctx, dict);
    }
    fz_catch(ctx)
    {
        fz_drop_outline(ctx, first);
        fz_rethrow(ctx);
    }

    return first;
}
Exemple #14
0
static fz_outline *
pdf_load_outline_imp(pdf_xref *xref, fz_obj *dict)
{
    pdf_link *link;
    fz_outline *node;
    fz_obj *obj;
    /* SumatraPDF: prevent potential stack overflow */
    fz_outline *prev, *root = NULL;
    fz_obj *origDict = dict;
    fz_context *ctx = xref->ctx;

    if (fz_is_null(ctx, dict))
        return NULL;

    /* SumatraPDF: prevent cyclic outlines */
    do
    {
        if (fz_dict_gets(ctx, dict, ".seen"))
            break;
        obj = fz_new_null(ctx);
        fz_dict_puts(ctx, dict, ".seen", obj);
        fz_drop_obj(ctx, obj);

        node = fz_malloc(ctx, sizeof(fz_outline));
        node->title = NULL;
        node->page = -1;
        node->down = NULL;
        node->next = NULL;

        obj = fz_dict_gets(ctx, dict, "Title");
        if (obj)
            node->title = pdf_to_utf8(ctx, obj);

        /* SumatraPDF: support expansion states */
        node->is_open = fz_to_int(ctx, fz_dict_gets(ctx, dict, "Count")) >= 0;
        /* SumatraPDF: extended outline actions */
        node->data = node->free_data = NULL;

        if (fz_dict_gets(ctx, dict, "Dest") || fz_dict_gets(ctx, dict, "A"))
        {
            link = pdf_load_link(xref, dict);
            if (link) /* SumatraPDF: don't crash if it's no link after all */
            {
                if (link->kind == PDF_LINK_GOTO)
                    node->page = pdf_find_page_number(xref, fz_array_get(ctx, link->dest, 0));
                /* SumatraPDF: extended outline actions */
                node->data = link;
                node->free_data = pdf_free_link;
            }
        }

        obj = fz_dict_gets(ctx, dict, "First");
        if (obj)
            node->down = pdf_load_outline_imp(xref, obj);

        /* SumatraPDF: prevent potential stack overflow */
        if (!root)
            prev = root = node;
        else
            prev = prev->next = node;

        dict = fz_dict_gets(ctx, dict, "Next");
    } while (dict && !fz_is_null(ctx, dict));
    node = root;
    /* SumatraPDF: prevent cyclic outlines */
    for (dict = origDict; dict && fz_dict_gets(ctx, dict, ".seen"); dict = fz_dict_gets(ctx, dict, "Next"))
        fz_dict_dels(ctx, dict, ".seen");

    return node;
}
Exemple #15
0
char *
pdf_parse_file_spec(fz_context *ctx, pdf_document *doc, pdf_obj *file_spec, pdf_obj *dest)
{
	pdf_obj *filename=NULL;
	char *path = NULL;
	char *uri = NULL;
	char buf[256];
	size_t n;

	if (pdf_is_string(ctx, file_spec))
		filename = file_spec;

	if (pdf_is_dict(ctx, file_spec)) {
#if defined(_WIN32) || defined(_WIN64)
		filename = pdf_dict_get(ctx, file_spec, PDF_NAME_DOS);
#else
		filename = pdf_dict_get(ctx, file_spec, PDF_NAME_Unix);
#endif
		if (!filename)
			filename = pdf_dict_geta(ctx, file_spec, PDF_NAME_UF, PDF_NAME_F);
	}

	if (!pdf_is_string(ctx, filename))
	{
		fz_warn(ctx, "cannot parse file specification");
		return NULL;
	}

	path = pdf_to_utf8(ctx, filename);
#if defined(_WIN32) || defined(_WIN64)
	if (strcmp(pdf_to_name(ctx, pdf_dict_gets(ctx, file_spec, "FS")), "URL") != 0)
	{
		/* move the file name into the expected place and use the expected path separator */
		char *c;
		if (path[0] == '/' && (('A' <= path[1] && path[1] <= 'Z') || ('a' <= path[1] && path[1] <= 'z')) && path[2] == '/')
		{
			path[0] = path[1];
			path[1] = ':';
		}
		for (c = path; *c; c++)
		{
			if (*c == '/')
				*c = '\\';
		}
	}
#endif

	if (pdf_is_array(ctx, dest))
		fz_snprintf(buf, sizeof buf, "#page=%d", pdf_to_int(ctx, pdf_array_get(ctx, dest, 0)) + 1);
	else if (pdf_is_name(ctx, dest))
		fz_snprintf(buf, sizeof buf, "#%s", pdf_to_name(ctx, dest));
	else if (pdf_is_string(ctx, dest))
		fz_snprintf(buf, sizeof buf, "#%s", pdf_to_str_buf(ctx, dest));
	else
		buf[0] = 0;

	n = 7 + strlen(path) + strlen(buf) + 1;
	uri = fz_malloc(ctx, n);
	fz_strlcpy(uri, "file://", n);
	fz_strlcat(uri, path, n);
	fz_strlcat(uri, buf, n);
	fz_free(ctx, path);
	return uri;
}
Exemple #16
0
char *
pdf_copy_annot_author(fz_context *ctx, pdf_annot *annot)
{
	check_allowed_subtypes(ctx, annot, PDF_NAME(T), markup_subtypes);
	return pdf_to_utf8(ctx, pdf_dict_get(ctx, annot->obj, PDF_NAME(T)));
}
Exemple #17
0
static void pdfapp_open_pdf(pdfapp_t *app, char *filename, int fd)
{
	fz_error error;
	fz_stream *file;
	char *password = "";
	fz_obj *obj;
	fz_obj *info;

	/*
	 * Open PDF and load xref table
	 */

	file = fz_open_fd(fd);
	error = pdf_open_xref_with_stream(&app->xref, file, NULL);
	if (error)
		pdfapp_error(app, fz_rethrow(error, "cannot open document '%s'", filename));
	fz_close(file);

	/*
	 * Handle encrypted PDF files
	 */

	if (pdf_needs_password(app->xref))
	{
		int okay = pdf_authenticate_password(app->xref, password);
		while (!okay)
		{
			password = winpassword(app, filename);
			if (!password)
				exit(1);
			okay = pdf_authenticate_password(app->xref, password);
			if (!okay)
				pdfapp_warn(app, "Invalid password.");
		}
	}

	/*
	 * Load meta information
	 */

	app->outline = pdf_load_outline(app->xref);

	app->doctitle = filename;
	if (strrchr(app->doctitle, '\\'))
		app->doctitle = strrchr(app->doctitle, '\\') + 1;
	if (strrchr(app->doctitle, '/'))
		app->doctitle = strrchr(app->doctitle, '/') + 1;
	info = fz_dict_gets(app->xref->trailer, "Info");
	if (info)
	{
		obj = fz_dict_gets(info, "Title");
		if (obj)
			app->doctitle = pdf_to_utf8(obj);
	}

	/*
	 * Start at first page
	 */

	error = pdf_load_page_tree(app->xref);
	if (error)
		pdfapp_error(app, fz_rethrow(error, "cannot load page tree"));

	app->pagecount = pdf_count_pages(app->xref);
}