first commit

This commit is contained in:
2023-10-17 17:51:53 +02:00
commit 9c7f9cfea0
107 changed files with 22995 additions and 0 deletions

921
include/mupdf/pdf/annot.h Normal file
View File

@ -0,0 +1,921 @@
// Copyright (C) 2004-2023 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_PDF_ANNOT_H
#define MUPDF_PDF_ANNOT_H
#include "mupdf/fitz/display-list.h"
#include "mupdf/fitz/stream.h"
#include "mupdf/fitz/structured-text.h"
#include "mupdf/pdf/object.h"
#include "mupdf/pdf/page.h"
typedef struct pdf_annot pdf_annot;
enum pdf_annot_type
{
PDF_ANNOT_TEXT,
PDF_ANNOT_LINK,
PDF_ANNOT_FREE_TEXT,
PDF_ANNOT_LINE,
PDF_ANNOT_SQUARE,
PDF_ANNOT_CIRCLE,
PDF_ANNOT_POLYGON,
PDF_ANNOT_POLY_LINE,
PDF_ANNOT_HIGHLIGHT,
PDF_ANNOT_UNDERLINE,
PDF_ANNOT_SQUIGGLY,
PDF_ANNOT_STRIKE_OUT,
PDF_ANNOT_REDACT,
PDF_ANNOT_STAMP,
PDF_ANNOT_CARET,
PDF_ANNOT_INK,
PDF_ANNOT_POPUP,
PDF_ANNOT_FILE_ATTACHMENT,
PDF_ANNOT_SOUND,
PDF_ANNOT_MOVIE,
PDF_ANNOT_RICH_MEDIA,
PDF_ANNOT_WIDGET,
PDF_ANNOT_SCREEN,
PDF_ANNOT_PRINTER_MARK,
PDF_ANNOT_TRAP_NET,
PDF_ANNOT_WATERMARK,
PDF_ANNOT_3D,
PDF_ANNOT_PROJECTION,
PDF_ANNOT_UNKNOWN = -1
};
/*
Map an annotation type to a (static) string.
The returned string must not be freed by the caller.
*/
const char *pdf_string_from_annot_type(fz_context *ctx, enum pdf_annot_type type);
/*
Map from a (non-NULL, case sensitive) string to an annotation
type.
*/
enum pdf_annot_type pdf_annot_type_from_string(fz_context *ctx, const char *subtype);
enum
{
PDF_ANNOT_IS_INVISIBLE = 1 << (1-1),
PDF_ANNOT_IS_HIDDEN = 1 << (2-1),
PDF_ANNOT_IS_PRINT = 1 << (3-1),
PDF_ANNOT_IS_NO_ZOOM = 1 << (4-1),
PDF_ANNOT_IS_NO_ROTATE = 1 << (5-1),
PDF_ANNOT_IS_NO_VIEW = 1 << (6-1),
PDF_ANNOT_IS_READ_ONLY = 1 << (7-1),
PDF_ANNOT_IS_LOCKED = 1 << (8-1),
PDF_ANNOT_IS_TOGGLE_NO_VIEW = 1 << (9-1),
PDF_ANNOT_IS_LOCKED_CONTENTS = 1 << (10-1)
};
enum pdf_line_ending
{
PDF_ANNOT_LE_NONE = 0,
PDF_ANNOT_LE_SQUARE,
PDF_ANNOT_LE_CIRCLE,
PDF_ANNOT_LE_DIAMOND,
PDF_ANNOT_LE_OPEN_ARROW,
PDF_ANNOT_LE_CLOSED_ARROW,
PDF_ANNOT_LE_BUTT,
PDF_ANNOT_LE_R_OPEN_ARROW,
PDF_ANNOT_LE_R_CLOSED_ARROW,
PDF_ANNOT_LE_SLASH
};
enum
{
PDF_ANNOT_Q_LEFT = 0,
PDF_ANNOT_Q_CENTER = 1,
PDF_ANNOT_Q_RIGHT = 2
};
/*
Map from a PDF name specifying an annotation line ending
to an enumerated line ending value.
*/
enum pdf_line_ending pdf_line_ending_from_name(fz_context *ctx, pdf_obj *end);
/*
Map from a (non-NULL, case sensitive) C string specifying
an annotation line ending to an enumerated line ending value.
*/
enum pdf_line_ending pdf_line_ending_from_string(fz_context *ctx, const char *end);
/*
Map from an enumerated line ending to a pdf name object that
specifies it.
*/
pdf_obj *pdf_name_from_line_ending(fz_context *ctx, enum pdf_line_ending end);
/*
Map from an enumerated line ending to a C string that specifies
it.
The caller must not free the returned string.
*/
const char *pdf_string_from_line_ending(fz_context *ctx, enum pdf_line_ending end);
/*
Increment the reference count for an annotation.
Never throws exceptions. Returns the same pointer.
*/
pdf_annot *pdf_keep_annot(fz_context *ctx, pdf_annot *annot);
/*
Drop the reference count for an annotation.
When the reference count reaches zero, the annotation will
be destroyed. Never throws exceptions.
*/
void pdf_drop_annot(fz_context *ctx, pdf_annot *annot);
/*
Returns a borrowed reference to the first annotation on
a page, or NULL if none.
The caller should fz_keep this if it intends to hold the
pointer. Unless it fz_keeps it, it must not fz_drop it.
*/
pdf_annot *pdf_first_annot(fz_context *ctx, pdf_page *page);
/*
Returns a borrowed reference to the next annotation
on a page, or NULL if none.
The caller should fz_keep this if it intends to hold the
pointer. Unless it fz_keeps it, it must not fz_drop it.
*/
pdf_annot *pdf_next_annot(fz_context *ctx, pdf_annot *annot);
/*
Returns a borrowed reference to the object underlying
an annotation.
The caller should fz_keep this if it intends to hold the
pointer. Unless it fz_keeps it, it must not fz_drop it.
*/
pdf_obj *pdf_annot_obj(fz_context *ctx, pdf_annot *annot);
/*
Returns a borrowed reference to the page to which
an annotation belongs.
The caller should fz_keep this if it intends to hold the
pointer. Unless it fz_keeps it, it must not fz_drop it.
*/
pdf_page *pdf_annot_page(fz_context *ctx, pdf_annot *annot);
/*
Return the rectangle for an annotation on a page.
*/
fz_rect pdf_bound_annot(fz_context *ctx, pdf_annot *annot);
enum pdf_annot_type pdf_annot_type(fz_context *ctx, pdf_annot *annot);
/*
Interpret an annotation and render it on a device.
page: A page loaded by pdf_load_page.
annot: an annotation.
dev: Device used for rendering, obtained from fz_new_*_device.
ctm: A transformation matrix applied to the objects on the page,
e.g. to scale or rotate the page contents as desired.
*/
void pdf_run_annot(fz_context *ctx, pdf_annot *annot, fz_device *dev, fz_matrix ctm, fz_cookie *cookie);
/*
Lookup needle in the nametree of the document given by which.
The returned reference is borrowed, and should not be dropped,
unless it is kept first.
*/
pdf_obj *pdf_lookup_name(fz_context *ctx, pdf_document *doc, pdf_obj *which, pdf_obj *needle);
/*
Load a nametree, flattening it into a single dictionary.
The caller is responsible for pdf_dropping the returned
reference.
*/
pdf_obj *pdf_load_name_tree(fz_context *ctx, pdf_document *doc, pdf_obj *which);
/*
Lookup needle in the given number tree.
The returned reference is borrowed, and should not be dropped,
unless it is kept first.
*/
pdf_obj *pdf_lookup_number(fz_context *ctx, pdf_obj *root, int needle);
/*
Perform a depth first traversal of a tree.
Start at tree, looking for children in the array named
kid_name at each level.
The arrive callback is called when we arrive at a node (i.e.
before all the children are walked), and then the leave callback
is called as we leave it (after all the children have been
walked).
names and values are (matching) null terminated arrays of
names and values to be carried down the tree, to implement
inheritance. NULL is a permissible value.
*/
void pdf_walk_tree(fz_context *ctx, pdf_obj *tree, pdf_obj *kid_name,
void (*arrive)(fz_context *, pdf_obj *, void *, pdf_obj **),
void (*leave)(fz_context *, pdf_obj *, void *),
void *arg,
pdf_obj **names,
pdf_obj **values);
/*
Resolve a link within a document.
*/
int pdf_resolve_link(fz_context *ctx, pdf_document *doc, const char *uri, float *xp, float *yp);
fz_link_dest pdf_resolve_link_dest(fz_context *ctx, pdf_document *doc, const char *uri);
/*
Create an action object given a link URI. The action will
be a GoTo or URI action depending on whether the link URI
specifies a document internal or external destination.
*/
pdf_obj *pdf_new_action_from_link(fz_context *ctx, pdf_document *doc, const char *uri);
/*
Create a destination object given a link URI expected to adhere
to the Adobe specification "Parameters for Opening PDF files"
from the Adobe Acrobat SDK. The resulting destination object
will either be a PDF string, or a PDF array referring to a page
and suitable zoom level settings. In the latter case the page
can be referred to by PDF object number or by page number, this
is controlled by the is_remote argument. For remote destinations
it is not possible to refer to the page by object number, so
page numbers are used instead.
*/
pdf_obj *pdf_new_dest_from_link(fz_context *ctx, pdf_document *doc, const char *uri, int is_remote);
/*
Create a link URI string according to the Adobe specification
"Parameters for Opening PDF files" from the Adobe Acrobat SDK,
version 8.1, which can, at the time of writing, be found here:
https://web.archive.org/web/20170921000830/http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/pdf_open_parameters.pdf
The resulting string must be freed by the caller.
*/
char *pdf_new_uri_from_explicit_dest(fz_context *ctx, fz_link_dest dest);
/*
Create a remote link URI string according to the Adobe specification
"Parameters for Opening PDF files" from the Adobe Acrobat SDK,
version 8.1, which can, at the time of writing, be found here:
https://web.archive.org/web/20170921000830/http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/pdf_open_parameters.pdf
The file: URI scheme is used in the resulting URI if the remote document
is specified by a system independent path (already taking the recommendations
in table 3.40 of the PDF 1.7 specification into account), and either a
destination name or a page number and zoom level are appended:
file:///path/doc.pdf#page=42&view=FitV,100
file:///path/doc.pdf#nameddest=G42.123456
If a URL is used to specify the remote document, then its scheme takes
precedence and either a destination name or a page number and zoom level
are appended:
ftp://example.com/alpha.pdf#page=42&view=Fit
https://example.com/bravo.pdf?query=parameter#page=42&view=Fit
The resulting string must be freed by the caller.
*/
char *pdf_append_named_dest_to_uri(fz_context *ctx, const char *url, const char *name);
char *pdf_append_explicit_dest_to_uri(fz_context *ctx, const char *url, fz_link_dest dest);
char *pdf_new_uri_from_path_and_named_dest(fz_context *ctx, const char *path, const char *name);
char *pdf_new_uri_from_path_and_explicit_dest(fz_context *ctx, const char *path, fz_link_dest dest);
/*
Create transform to fit appearance stream to annotation Rect
*/
fz_matrix pdf_annot_transform(fz_context *ctx, pdf_annot *annot);
/*
Create a new link object.
*/
fz_link *pdf_new_link(fz_context *ctx, pdf_page *page, fz_rect rect, const char *uri, pdf_obj *obj);
/*
create a new annotation of the specified type on the
specified page. The returned pdf_annot structure is owned by the
page and does not need to be freed.
*/
pdf_annot *pdf_create_annot_raw(fz_context *ctx, pdf_page *page, enum pdf_annot_type type);
/*
create a new link on the specified page. The returned fz_link
structure is owned by the page and does not need to be freed.
*/
fz_link *pdf_create_link(fz_context *ctx, pdf_page *page, fz_rect bbox, const char *uri);
/*
delete an existing link from the specified page.
*/
void pdf_delete_link(fz_context *ctx, pdf_page *page, fz_link *link);
enum pdf_border_style
{
PDF_BORDER_STYLE_SOLID = 0,
PDF_BORDER_STYLE_DASHED,
PDF_BORDER_STYLE_BEVELED,
PDF_BORDER_STYLE_INSET,
PDF_BORDER_STYLE_UNDERLINE,
};
enum pdf_border_effect
{
PDF_BORDER_EFFECT_NONE = 0,
PDF_BORDER_EFFECT_CLOUDY,
};
/*
create a new annotation of the specified type on the
specified page. Populate it with sensible defaults per the type.
Currently this returns a reference that the caller owns, and
must drop when finished with it. Up until release 1.18, the
returned reference was owned by the page and did not need to
be freed.
*/
pdf_annot *pdf_create_annot(fz_context *ctx, pdf_page *page, enum pdf_annot_type type);
/*
Delete an annoation from the page.
This unlinks the annotation from the page structure and drops
the pages reference to it. Any reference held by the caller
will not be dropped automatically, so this can safely be used
on a borrowed reference.
*/
void pdf_delete_annot(fz_context *ctx, pdf_page *page, pdf_annot *annot);
/*
Edit the associated Popup annotation rectangle.
Popup annotations are used to store the size and position of the
popup box that is used to edit the contents of the markup annotation.
*/
void pdf_set_annot_popup(fz_context *ctx, pdf_annot *annot, fz_rect rect);
fz_rect pdf_annot_popup(fz_context *ctx, pdf_annot *annot);
/*
Check to see if an annotation has a rect.
*/
int pdf_annot_has_rect(fz_context *ctx, pdf_annot *annot);
/*
Check to see if an annotation has an ink list.
*/
int pdf_annot_has_ink_list(fz_context *ctx, pdf_annot *annot);
/*
Check to see if an annotation has quad points data.
*/
int pdf_annot_has_quad_points(fz_context *ctx, pdf_annot *annot);
/*
Check to see if an annotation has vertex data.
*/
int pdf_annot_has_vertices(fz_context *ctx, pdf_annot *annot);
/*
Check to see if an annotation has line data.
*/
int pdf_annot_has_line(fz_context *ctx, pdf_annot *annot);
/*
Check to see if an annotation has an interior color.
*/
int pdf_annot_has_interior_color(fz_context *ctx, pdf_annot *annot);
/*
Check to see if an annotation has line ending styles.
*/
int pdf_annot_has_line_ending_styles(fz_context *ctx, pdf_annot *annot);
/*
Check to see if an annotation has a border.
*/
int pdf_annot_has_border(fz_context *ctx, pdf_annot *annot);
/*
Check to see if an annotation has a border effect.
*/
int pdf_annot_has_border_effect(fz_context *ctx, pdf_annot *annot);
/*
Check to see if an annotation has an icon name.
*/
int pdf_annot_has_icon_name(fz_context *ctx, pdf_annot *annot);
/*
Check to see if an annotation has an open action.
*/
int pdf_annot_has_open(fz_context *ctx, pdf_annot *annot);
/*
Check to see if an annotation has author data.
*/
int pdf_annot_has_author(fz_context *ctx, pdf_annot *annot);
/*
Retrieve the annotation flags.
*/
int pdf_annot_flags(fz_context *ctx, pdf_annot *annot);
/*
Retrieve the annotation bounds in doc space.
*/
fz_rect pdf_annot_rect(fz_context *ctx, pdf_annot *annot);
/*
Retrieve the annotation border line width in points.
*/
float pdf_annot_border(fz_context *ctx, pdf_annot *annot);
/*
Retrieve the annotation border style.
*/
enum pdf_border_style pdf_annot_border_style(fz_context *ctx, pdf_annot *annot);
/*
Retrieve the annotation border width in points.
*/
float pdf_annot_border_width(fz_context *ctx, pdf_annot *annot);
/*
How many items does the annotation border dash pattern have?
*/
int pdf_annot_border_dash_count(fz_context *ctx, pdf_annot *annot);
/*
How long is dash item i in the annotation border dash pattern?
*/
float pdf_annot_border_dash_item(fz_context *ctx, pdf_annot *annot, int i);
/*
Retrieve the annotation border effect.
*/
enum pdf_border_effect pdf_annot_border_effect(fz_context *ctx, pdf_annot *annot);
/*
Retrieve the annotation border effect intensity.
*/
float pdf_annot_border_effect_intensity(fz_context *ctx, pdf_annot *annot);
/*
Retrieve the annotation opacity. (0 transparent, 1 solid).
*/
float pdf_annot_opacity(fz_context *ctx, pdf_annot *annot);
/*
Retrieve the annotation color.
n components, each between 0 and 1.
n = 1 (grey), 3 (rgb) or 4 (cmyk).
*/
void pdf_annot_color(fz_context *ctx, pdf_annot *annot, int *n, float color[4]);
/*
Retrieve the annotation interior color.
n components, each between 0 and 1.
n = 1 (grey), 3 (rgb) or 4 (cmyk).
*/
void pdf_annot_interior_color(fz_context *ctx, pdf_annot *annot, int *n, float color[4]);
/*
Retrieve the annotation quadding (justification) to use.
0 = Left-justified
1 = Centered
2 = Right-justified
*/
int pdf_annot_quadding(fz_context *ctx, pdf_annot *annot);
/*
Retrieve the annotations text language (either from the
annotation, or from the document).
*/
fz_text_language pdf_annot_language(fz_context *ctx, pdf_annot *annot);
/*
How many quad points does an annotation have?
*/
int pdf_annot_quad_point_count(fz_context *ctx, pdf_annot *annot);
/*
Get quadpoint i for an annotation.
*/
fz_quad pdf_annot_quad_point(fz_context *ctx, pdf_annot *annot, int i);
/*
How many strokes in the ink list for an annotation?
*/
int pdf_annot_ink_list_count(fz_context *ctx, pdf_annot *annot);
/*
How many vertexes in stroke i of the ink list for an annotation?
*/
int pdf_annot_ink_list_stroke_count(fz_context *ctx, pdf_annot *annot, int i);
/*
Get vertex k from stroke i of the ink list for an annoation, in
doc space.
*/
fz_point pdf_annot_ink_list_stroke_vertex(fz_context *ctx, pdf_annot *annot, int i, int k);
/*
Set the flags for an annotation.
*/
void pdf_set_annot_flags(fz_context *ctx, pdf_annot *annot, int flags);
/*
Set the stamp appearance stream to a custom image.
Fits the image to the current Rect, and shrinks the Rect
to fit the image aspect ratio.
*/
void pdf_set_annot_stamp_image(fz_context *ctx, pdf_annot *annot, fz_image *image);
/*
Set the bounding box for an annotation, in doc space.
*/
void pdf_set_annot_rect(fz_context *ctx, pdf_annot *annot, fz_rect rect);
/*
Set the border width for an annotation, in points and remove any border effect.
*/
void pdf_set_annot_border(fz_context *ctx, pdf_annot *annot, float width);
/*
Set the border style for an annotation.
*/
void pdf_set_annot_border_style(fz_context *ctx, pdf_annot *annot, enum pdf_border_style style);
/*
Set the border width for an annotation in points;
*/
void pdf_set_annot_border_width(fz_context *ctx, pdf_annot *annot, float width);
/*
Clear the entire border dash pattern for an annotation.
*/
void pdf_clear_annot_border_dash(fz_context *ctx, pdf_annot *annot);
/*
Add an item to the end of the border dash pattern for an annotation.
*/
void pdf_add_annot_border_dash_item(fz_context *ctx, pdf_annot *annot, float length);
/*
Set the border effect for an annotation.
*/
void pdf_set_annot_border_effect(fz_context *ctx, pdf_annot *annot, enum pdf_border_effect effect);
/*
Set the border effect intensity for an annotation.
*/
void pdf_set_annot_border_effect_intensity(fz_context *ctx, pdf_annot *annot, float intensity);
/*
Set the opacity for an annotation, between 0 (transparent) and 1
(solid).
*/
void pdf_set_annot_opacity(fz_context *ctx, pdf_annot *annot, float opacity);
/*
Set the annotation color.
n components, each between 0 and 1.
n = 1 (grey), 3 (rgb) or 4 (cmyk).
*/
void pdf_set_annot_color(fz_context *ctx, pdf_annot *annot, int n, const float *color);
/*
Set the annotation interior color.
n components, each between 0 and 1.
n = 1 (grey), 3 (rgb) or 4 (cmyk).
*/
void pdf_set_annot_interior_color(fz_context *ctx, pdf_annot *annot, int n, const float *color);
/*
Set the quadding (justification) to use for the annotation.
0 = Left-justified
1 = Centered
2 = Right-justified
*/
void pdf_set_annot_quadding(fz_context *ctx, pdf_annot *annot, int q);
/*
Set the language for the annotation.
*/
void pdf_set_annot_language(fz_context *ctx, pdf_annot *annot, fz_text_language lang);
/*
Set the quad points for an annotation to those in the qv array
of length n.
*/
void pdf_set_annot_quad_points(fz_context *ctx, pdf_annot *annot, int n, const fz_quad *qv);
/*
Clear the quadpoint data for an annotation.
*/
void pdf_clear_annot_quad_points(fz_context *ctx, pdf_annot *annot);
/*
Append a new quad point to the quad point data in an annotation.
*/
void pdf_add_annot_quad_point(fz_context *ctx, pdf_annot *annot, fz_quad quad);
/*
Set the ink list for an annotation.
n strokes. For 0 <= i < n, stroke i has count[i] points,
The vertexes for all the strokes are packed into a single
array, pointed to by v.
*/
void pdf_set_annot_ink_list(fz_context *ctx, pdf_annot *annot, int n, const int *count, const fz_point *v);
/*
Clear the ink list for an annotation.
*/
void pdf_clear_annot_ink_list(fz_context *ctx, pdf_annot *annot);
/*
Add a new stroke (initially empty) to the ink list for an
annotation.
*/
void pdf_add_annot_ink_list_stroke(fz_context *ctx, pdf_annot *annot);
/*
Add a new vertex to the last stroke in the ink list for an
annotation.
*/
void pdf_add_annot_ink_list_stroke_vertex(fz_context *ctx, pdf_annot *annot, fz_point p);
/*
Add a new stroke to the ink list for an annotation, and
populate it with the n points from stroke[].
*/
void pdf_add_annot_ink_list(fz_context *ctx, pdf_annot *annot, int n, fz_point stroke[]);
/*
*/
void pdf_set_annot_icon_name(fz_context *ctx, pdf_annot *annot, const char *name);
void pdf_set_annot_is_open(fz_context *ctx, pdf_annot *annot, int is_open);
enum pdf_line_ending pdf_annot_line_start_style(fz_context *ctx, pdf_annot *annot);
enum pdf_line_ending pdf_annot_line_end_style(fz_context *ctx, pdf_annot *annot);
void pdf_annot_line_ending_styles(fz_context *ctx, pdf_annot *annot, enum pdf_line_ending *start_style, enum pdf_line_ending *end_style);
void pdf_set_annot_line_start_style(fz_context *ctx, pdf_annot *annot, enum pdf_line_ending s);
void pdf_set_annot_line_end_style(fz_context *ctx, pdf_annot *annot, enum pdf_line_ending e);
void pdf_set_annot_line_ending_styles(fz_context *ctx, pdf_annot *annot, enum pdf_line_ending start_style, enum pdf_line_ending end_style);
const char *pdf_annot_icon_name(fz_context *ctx, pdf_annot *annot);
int pdf_annot_is_open(fz_context *ctx, pdf_annot *annot);
int pdf_annot_is_standard_stamp(fz_context *ctx, pdf_annot *annot);
void pdf_annot_line(fz_context *ctx, pdf_annot *annot, fz_point *a, fz_point *b);
void pdf_set_annot_line(fz_context *ctx, pdf_annot *annot, fz_point a, fz_point b);
int pdf_annot_vertex_count(fz_context *ctx, pdf_annot *annot);
fz_point pdf_annot_vertex(fz_context *ctx, pdf_annot *annot, int i);
void pdf_set_annot_vertices(fz_context *ctx, pdf_annot *annot, int n, const fz_point *v);
void pdf_clear_annot_vertices(fz_context *ctx, pdf_annot *annot);
void pdf_add_annot_vertex(fz_context *ctx, pdf_annot *annot, fz_point p);
void pdf_set_annot_vertex(fz_context *ctx, pdf_annot *annot, int i, fz_point p);
const char *pdf_annot_contents(fz_context *ctx, pdf_annot *annot);
void pdf_set_annot_contents(fz_context *ctx, pdf_annot *annot, const char *text);
const char *pdf_annot_author(fz_context *ctx, pdf_annot *annot);
void pdf_set_annot_author(fz_context *ctx, pdf_annot *annot, const char *author);
int64_t pdf_annot_modification_date(fz_context *ctx, pdf_annot *annot);
void pdf_set_annot_modification_date(fz_context *ctx, pdf_annot *annot, int64_t time);
int64_t pdf_annot_creation_date(fz_context *ctx, pdf_annot *annot);
void pdf_set_annot_creation_date(fz_context *ctx, pdf_annot *annot, int64_t time);
void pdf_parse_default_appearance(fz_context *ctx, const char *da, const char **font, float *size, int *n, float color[4]);
void pdf_print_default_appearance(fz_context *ctx, char *buf, int nbuf, const char *font, float size, int n, const float *color);
void pdf_annot_default_appearance(fz_context *ctx, pdf_annot *annot, const char **font, float *size, int *n, float color[4]);
void pdf_set_annot_default_appearance(fz_context *ctx, pdf_annot *annot, const char *font, float size, int n, const float *color);
void pdf_annot_request_resynthesis(fz_context *ctx, pdf_annot *annot);
int pdf_annot_needs_resynthesis(fz_context *ctx, pdf_annot *annot);
void pdf_set_annot_resynthesised(fz_context *ctx, pdf_annot *annot);
void pdf_dirty_annot(fz_context *ctx, pdf_annot *annot);
int pdf_annot_field_flags(fz_context *ctx, pdf_annot *annot);
const char *pdf_annot_field_value(fz_context *ctx, pdf_annot *annot);
const char *pdf_annot_field_label(fz_context *ctx, pdf_annot *widget);
int pdf_set_annot_field_value(fz_context *ctx, pdf_document *doc, pdf_annot *widget, const char *text, int ignore_trigger_events);
/*
Recreate the appearance stream for an annotation, if necessary.
*/
fz_text *pdf_layout_fit_text(fz_context *ctx, fz_font *font, fz_text_language lang, const char *str, fz_rect bounds);
/*
Start/Stop using the annotation-local xref. This allows us to
generate appearance streams that don't actually hit the underlying
document.
*/
void pdf_annot_push_local_xref(fz_context *ctx, pdf_annot *annot);
void pdf_annot_pop_local_xref(fz_context *ctx, pdf_annot *annot);
void pdf_annot_ensure_local_xref(fz_context *ctx, pdf_annot *annot);
void pdf_annot_pop_and_discard_local_xref(fz_context *ctx, pdf_annot *annot);
/*
Regenerate any appearance streams that are out of date and check for
cases where a different appearance stream should be selected because of
state changes.
Note that a call to pdf_pass_event for one page may lead to changes on
any other, so an app should call pdf_update_annot for every annotation
it currently displays. Also it is important that the pdf_annot object
is the one used to last render the annotation. If instead the app were
to drop the page or annotations and reload them then a call to
pdf_update_annot would not reliably be able to report all changed
annotations.
Returns true if the annotation appearance has changed since the last time
pdf_update_annot was called or the annotation was first loaded.
*/
int pdf_update_annot(fz_context *ctx, pdf_annot *annot);
/*
Recalculate form fields if necessary.
Loop through all annotations on the page and update them. Return true
if any of them were changed (by either event or javascript actions, or
by annotation editing) and need re-rendering.
If you need more granularity, loop through the annotations and call
pdf_update_annot for each one to detect changes on a per-annotation
basis.
*/
int pdf_update_page(fz_context *ctx, pdf_page *page);
/*
Update internal state appropriate for editing this field. When editing
is true, updating the text of the text widget will not have any
side-effects such as changing other widgets or running javascript.
This state is intended for the period when a text widget is having
characters typed into it. The state should be reverted at the end of
the edit sequence and the text newly updated.
*/
void pdf_set_widget_editing_state(fz_context *ctx, pdf_annot *widget, int editing);
int pdf_get_widget_editing_state(fz_context *ctx, pdf_annot *widget);
/*
Toggle the state of a specified annotation. Applies only to check-box
and radio-button widgets.
*/
int pdf_toggle_widget(fz_context *ctx, pdf_annot *widget);
fz_display_list *pdf_new_display_list_from_annot(fz_context *ctx, pdf_annot *annot);
/*
Render an annotation suitable for blending on top of the opaque
pixmap returned by fz_new_pixmap_from_page_contents.
*/
fz_pixmap *pdf_new_pixmap_from_annot(fz_context *ctx, pdf_annot *annot, fz_matrix ctm, fz_colorspace *cs, fz_separations *seps, int alpha);
fz_stext_page *pdf_new_stext_page_from_annot(fz_context *ctx, pdf_annot *annot, const fz_stext_options *options);
fz_layout_block *pdf_layout_text_widget(fz_context *ctx, pdf_annot *annot);
typedef struct pdf_embedded_file_params pdf_embedded_file_params;
/*
Parameters for and embedded file. Obtained through
pdf_get_embedded_file_params(). The creation and
modification date fields are < 0 if unknown.
*/
struct pdf_embedded_file_params {
const char *filename;
const char *mimetype;
int size;
int64_t created;
int64_t modified;
};
/*
Check if pdf object is a file specification.
*/
int pdf_is_embedded_file(fz_context *ctx, pdf_obj *fs);
/*
Add an embedded file to the document. This can later
be passed e.g. to pdf_annot_set_filespec(). If unknown,
supply NULL for MIME type and -1 for the date arguments.
If a checksum is added it can later be verified by calling
pdf_verify_embedded_file_checksum().
*/
pdf_obj *pdf_add_embedded_file(fz_context *ctx, pdf_document *doc, const char *filename, const char *mimetype, fz_buffer *contents, int64_t created, int64_t modifed, int add_checksum);
/*
Obtain parameters for embedded file: name, size,
creation and modification dates cnad MIME type.
*/
void pdf_get_embedded_file_params(fz_context *ctx, pdf_obj *fs, pdf_embedded_file_params *out);
/*
Load embedded file contents in a buffer which
needs to be dropped by the called after use.
*/
fz_buffer *pdf_load_embedded_file_contents(fz_context *ctx, pdf_obj *fs);
/*
Verifies the embedded file checksum. Returns 1
if the verifiction is successful or there is no
checksum to be verified, or 0 if verification fails.
*/
int pdf_verify_embedded_file_checksum(fz_context *ctx, pdf_obj *fs);
pdf_obj *pdf_lookup_dest(fz_context *ctx, pdf_document *doc, pdf_obj *needle);
fz_link *pdf_load_link_annots(fz_context *ctx, pdf_document *, pdf_page *, pdf_obj *annots, int pagenum, fz_matrix page_ctm);
void pdf_annot_MK_BG(fz_context *ctx, pdf_annot *annot, int *n, float color[4]);
void pdf_annot_MK_BC(fz_context *ctx, pdf_annot *annot, int *n, float color[4]);
int pdf_annot_MK_BG_rgb(fz_context *ctx, pdf_annot *annot, float rgb[3]);
int pdf_annot_MK_BC_rgb(fz_context *ctx, pdf_annot *annot, float rgb[3]);
pdf_obj *pdf_annot_ap(fz_context *ctx, pdf_annot *annot);
int pdf_annot_active(fz_context *ctx, pdf_annot *annot);
void pdf_set_annot_active(fz_context *ctx, pdf_annot *annot, int active);
int pdf_annot_hot(fz_context *ctx, pdf_annot *annot);
void pdf_set_annot_hot(fz_context *ctx, pdf_annot *annot, int hot);
void pdf_set_annot_appearance(fz_context *ctx, pdf_annot *annot, const char *appearance, const char *state, fz_matrix ctm, fz_rect bbox, pdf_obj *res, fz_buffer *contents);
void pdf_set_annot_appearance_from_display_list(fz_context *ctx, pdf_annot *annot, const char *appearance, const char *state, fz_matrix ctm, fz_display_list *list);
/*
Check to see if an annotation has a file specification.
*/
int pdf_annot_has_filespec(fz_context *ctx, pdf_annot *annot);
/*
Retrieve the file specification for the given annotation.
*/
pdf_obj *pdf_annot_filespec(fz_context *ctx, pdf_annot *annot);
/*
Set the annotation file specification.
*/
void pdf_set_annot_filespec(fz_context *ctx, pdf_annot *annot, pdf_obj *obj);
/*
Get/set a hidden flag preventing the annotation from being
rendered when it is being edited. This flag is independent
of the hidden flag in the PDF annotation object described in the PDF specification.
*/
int pdf_annot_hidden_for_editing(fz_context *ctx, pdf_annot *annot);
void pdf_set_annot_hidden_for_editing(fz_context *ctx, pdf_annot *annot, int hidden);
/*
* Apply Redaction annotation by redacting page underneath and removing the annotation.
*/
int pdf_apply_redaction(fz_context *ctx, pdf_annot *annot, pdf_redact_options *opts);
#endif

33
include/mupdf/pdf/clean.h Normal file
View File

@ -0,0 +1,33 @@
// Copyright (C) 2004-2021 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_PDF_CLEAN_H
#define MUPDF_PDF_CLEAN_H
#include "mupdf/pdf/document.h"
/*
Read infile, and write selected pages to outfile with the given options.
*/
void pdf_clean_file(fz_context *ctx, char *infile, char *outfile, char *password, pdf_write_options *opts, int retainlen, char *retainlist[]);
#endif

143
include/mupdf/pdf/cmap.h Normal file
View File

@ -0,0 +1,143 @@
// Copyright (C) 2004-2021 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_PDF_CMAP_H
#define MUPDF_PDF_CMAP_H
#include "mupdf/fitz/store.h"
#include "mupdf/pdf/document.h"
#define PDF_MRANGE_CAP 32
typedef struct
{
unsigned short low, high, out;
} pdf_range;
typedef struct
{
unsigned int low, high, out;
} pdf_xrange;
typedef struct
{
unsigned int low, out;
} pdf_mrange;
typedef struct cmap_splay cmap_splay;
typedef struct pdf_cmap
{
fz_storable storable;
char cmap_name[32];
char usecmap_name[32];
struct pdf_cmap *usecmap;
int wmode;
int codespace_len;
struct
{
int n;
unsigned int low;
unsigned int high;
} codespace[40];
int rlen, rcap;
pdf_range *ranges;
int xlen, xcap;
pdf_xrange *xranges;
int mlen, mcap;
pdf_mrange *mranges;
int dlen, dcap;
int *dict;
int tlen, tcap, ttop;
cmap_splay *tree;
} pdf_cmap;
pdf_cmap *pdf_new_cmap(fz_context *ctx);
pdf_cmap *pdf_keep_cmap(fz_context *ctx, pdf_cmap *cmap);
void pdf_drop_cmap(fz_context *ctx, pdf_cmap *cmap);
void pdf_drop_cmap_imp(fz_context *ctx, fz_storable *cmap);
size_t pdf_cmap_size(fz_context *ctx, pdf_cmap *cmap);
int pdf_cmap_wmode(fz_context *ctx, pdf_cmap *cmap);
void pdf_set_cmap_wmode(fz_context *ctx, pdf_cmap *cmap, int wmode);
void pdf_set_usecmap(fz_context *ctx, pdf_cmap *cmap, pdf_cmap *usecmap);
/*
Add a codespacerange section.
These ranges are used by pdf_decode_cmap to decode
multi-byte encoded strings.
*/
void pdf_add_codespace(fz_context *ctx, pdf_cmap *cmap, unsigned int low, unsigned int high, size_t n);
/*
Add a range of contiguous one-to-one mappings (ie 1..5 maps to 21..25)
*/
void pdf_map_range_to_range(fz_context *ctx, pdf_cmap *cmap, unsigned int srclo, unsigned int srchi, int dstlo);
/*
Add a single one-to-many mapping.
*/
void pdf_map_one_to_many(fz_context *ctx, pdf_cmap *cmap, unsigned int one, int *many, size_t len);
void pdf_sort_cmap(fz_context *ctx, pdf_cmap *cmap);
/*
Lookup the mapping of a codepoint.
*/
int pdf_lookup_cmap(pdf_cmap *cmap, unsigned int cpt);
int pdf_lookup_cmap_full(pdf_cmap *cmap, unsigned int cpt, int *out);
/*
Use the codespace ranges to extract a codepoint from a
multi-byte encoded string.
*/
int pdf_decode_cmap(pdf_cmap *cmap, unsigned char *s, unsigned char *e, unsigned int *cpt);
/*
Create an Identity-* CMap (for both 1 and 2-byte encodings)
*/
pdf_cmap *pdf_new_identity_cmap(fz_context *ctx, int wmode, int bytes);
pdf_cmap *pdf_load_cmap(fz_context *ctx, fz_stream *file);
/*
Load predefined CMap from system.
*/
pdf_cmap *pdf_load_system_cmap(fz_context *ctx, const char *name);
/*
Load built-in CMap resource.
*/
pdf_cmap *pdf_load_builtin_cmap(fz_context *ctx, const char *name);
/*
Load CMap stream in PDF file
*/
pdf_cmap *pdf_load_embedded_cmap(fz_context *ctx, pdf_document *doc, pdf_obj *ref);
#endif

107
include/mupdf/pdf/crypt.h Normal file
View File

@ -0,0 +1,107 @@
// Copyright (C) 2004-2021 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_PDF_CRYPT_H
#define MUPDF_PDF_CRYPT_H
#include "mupdf/pdf/document.h"
#include "mupdf/pdf/object.h"
enum
{
PDF_ENCRYPT_KEEP,
PDF_ENCRYPT_NONE,
PDF_ENCRYPT_RC4_40,
PDF_ENCRYPT_RC4_128,
PDF_ENCRYPT_AES_128,
PDF_ENCRYPT_AES_256,
PDF_ENCRYPT_UNKNOWN
};
/*
Create crypt object for decrypting strings and streams
given the Encryption and ID objects.
*/
pdf_crypt *pdf_new_crypt(fz_context *ctx, pdf_obj *enc, pdf_obj *id);
pdf_crypt *pdf_new_encrypt(fz_context *ctx, const char *opwd_utf8, const char *upwd_utf8, pdf_obj *id, int permissions, int algorithm);
void pdf_drop_crypt(fz_context *ctx, pdf_crypt *crypt);
void pdf_crypt_obj(fz_context *ctx, pdf_crypt *crypt, pdf_obj *obj, int num, int gen);
fz_stream *pdf_open_crypt(fz_context *ctx, fz_stream *chain, pdf_crypt *crypt, int num, int gen);
fz_stream *pdf_open_crypt_with_filter(fz_context *ctx, fz_stream *chain, pdf_crypt *crypt, pdf_obj *name, int num, int gen);
int pdf_crypt_version(fz_context *ctx, pdf_crypt *crypt);
int pdf_crypt_revision(fz_context *ctx, pdf_crypt *crypt);
const char *pdf_crypt_method(fz_context *ctx, pdf_crypt *crypt);
const char *pdf_crypt_string_method(fz_context *ctx, pdf_crypt *crypt);
const char *pdf_crypt_stream_method(fz_context *ctx, pdf_crypt *crypt);
int pdf_crypt_length(fz_context *ctx, pdf_crypt *crypt);
int pdf_crypt_permissions(fz_context *ctx, pdf_crypt *crypt);
int pdf_crypt_encrypt_metadata(fz_context *ctx, pdf_crypt *crypt);
unsigned char *pdf_crypt_owner_password(fz_context *ctx, pdf_crypt *crypt);
unsigned char *pdf_crypt_user_password(fz_context *ctx, pdf_crypt *crypt);
unsigned char *pdf_crypt_owner_encryption(fz_context *ctx, pdf_crypt *crypt);
unsigned char *pdf_crypt_user_encryption(fz_context *ctx, pdf_crypt *crypt);
unsigned char *pdf_crypt_permissions_encryption(fz_context *ctx, pdf_crypt *crypt);
unsigned char *pdf_crypt_key(fz_context *ctx, pdf_crypt *crypt);
void pdf_print_crypt(fz_context *ctx, fz_output *out, pdf_crypt *crypt);
void pdf_write_digest(fz_context *ctx, fz_output *out, pdf_obj *byte_range, pdf_obj *field, size_t digest_offset, size_t digest_length, pdf_pkcs7_signer *signer);
/*
User access permissions from PDF reference.
*/
enum
{
PDF_PERM_PRINT = 1 << 2,
PDF_PERM_MODIFY = 1 << 3,
PDF_PERM_COPY = 1 << 4,
PDF_PERM_ANNOTATE = 1 << 5,
PDF_PERM_FORM = 1 << 8,
PDF_PERM_ACCESSIBILITY = 1 << 9, /* deprecated in pdf 2.0 (this permission is always granted) */
PDF_PERM_ASSEMBLE = 1 << 10,
PDF_PERM_PRINT_HQ = 1 << 11,
};
int pdf_document_permissions(fz_context *ctx, pdf_document *doc);
int pdf_signature_byte_range(fz_context *ctx, pdf_document *doc, pdf_obj *signature, fz_range *byte_range);
/*
retrieve an fz_stream to read the bytes hashed for the signature
*/
fz_stream *pdf_signature_hash_bytes(fz_context *ctx, pdf_document *doc, pdf_obj *signature);
int pdf_signature_incremental_change_since_signing(fz_context *ctx, pdf_document *doc, pdf_obj *signature);
/*
Retrieve the contents of a signature as a counted allocated
block that must be freed by the caller.
*/
size_t pdf_signature_contents(fz_context *ctx, pdf_document *doc, pdf_obj *signature, char **contents);
void pdf_encrypt_data(fz_context *ctx, pdf_crypt *crypt, int num, int gen, void (*fmt_str_out)(fz_context *, void *, const unsigned char *, size_t), void *arg, const unsigned char *s, size_t n);
size_t pdf_encrypted_len(fz_context *ctx, pdf_crypt *crypt, int num, int gen, size_t len);
#endif

View File

@ -0,0 +1,808 @@
// Copyright (C) 2004-2023 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_PDF_DOCUMENT_H
#define MUPDF_PDF_DOCUMENT_H
#include "mupdf/fitz/export.h"
#include "mupdf/fitz/document.h"
#include "mupdf/fitz/hash.h"
#include "mupdf/fitz/stream.h"
#include "mupdf/fitz/xml.h"
#include "mupdf/pdf/object.h"
typedef struct pdf_xref pdf_xref;
typedef struct pdf_ocg_descriptor pdf_ocg_descriptor;
typedef struct pdf_page pdf_page;
typedef struct pdf_annot pdf_annot;
typedef struct pdf_js pdf_js;
typedef struct pdf_document pdf_document;
enum
{
PDF_LEXBUF_SMALL = 256,
PDF_LEXBUF_LARGE = 65536
};
typedef struct
{
size_t size;
size_t base_size;
size_t len;
int64_t i;
float f;
char *scratch;
char buffer[PDF_LEXBUF_SMALL];
} pdf_lexbuf;
typedef struct
{
pdf_lexbuf base;
char buffer[PDF_LEXBUF_LARGE - PDF_LEXBUF_SMALL];
} pdf_lexbuf_large;
/*
Document event structures are mostly opaque to the app. Only the type
is visible to the app.
*/
typedef struct pdf_doc_event pdf_doc_event;
/*
the type of function via which the app receives
document events.
*/
typedef void (pdf_doc_event_cb)(fz_context *ctx, pdf_document *doc, pdf_doc_event *evt, void *data);
/*
the type of function via which the app frees
the data provided to the event callback pdf_doc_event_cb.
*/
typedef void (pdf_free_doc_event_data_cb)(fz_context *ctx, void *data);
typedef struct pdf_js_console pdf_js_console;
/*
Callback called when the console is dropped because it
is being replaced or the javascript is being disabled
by a call to pdf_disable_js().
*/
typedef void (pdf_js_console_drop_cb)(pdf_js_console *console, void *user);
/*
Callback signalling that a piece of javascript is asking
the javascript console to be displayed.
*/
typedef void (pdf_js_console_show_cb)(void *user);
/*
Callback signalling that a piece of javascript is asking
the javascript console to be hidden.
*/
typedef void (pdf_js_console_hide_cb)(void *user);
/*
Callback signalling that a piece of javascript is asking
the javascript console to remove all its contents.
*/
typedef void (pdf_js_console_clear_cb)(void *user);
/*
Callback signalling that a piece of javascript is appending
the given message to the javascript console contents.
*/
typedef void (pdf_js_console_write_cb)(void *user, const char *msg);
/*
The callback functions relating to a javascript console.
*/
typedef struct pdf_js_console {
pdf_js_console_drop_cb *drop;
pdf_js_console_show_cb *show;
pdf_js_console_hide_cb *hide;
pdf_js_console_clear_cb *clear;
pdf_js_console_write_cb *write;
} pdf_js_console;
/*
Retrieve the currently set javascript console, or NULL
if none is set.
*/
pdf_js_console *pdf_js_get_console(fz_context *ctx, pdf_document *doc);
/*
Set a new javascript console.
console: A set of callback functions informing about
what pieces of executed js is trying to do
to the js console. The caller transfers ownership of
console when calling pdf_js_set_console(). Once it and
the corresponding user pointer are no longer needed
console->drop() will be called passing both the console
and the user pointer.
user: Opaque data that will be passed unchanged to all
js console callbacks when called. The caller ensures
that this is valid until either the js console is
replaced by calling pdf_js_set_console() again with a
new console, or pdf_disable_js() is called. In either
case the caller to ensures that the user data is freed.
*/
void pdf_js_set_console(fz_context *ctx, pdf_document *doc, pdf_js_console *console, void *user);
/*
Open a PDF document.
Open a PDF document by reading its cross reference table, so
MuPDF can locate PDF objects inside the file. Upon an broken
cross reference table or other parse errors MuPDF will restart
parsing the file from the beginning to try to rebuild a
(hopefully correct) cross reference table to allow further
processing of the file.
The returned pdf_document should be used when calling most
other PDF functions. Note that it wraps the context, so those
functions implicitly get access to the global state in
context.
filename: a path to a file as it would be given to open(2).
*/
pdf_document *pdf_open_document(fz_context *ctx, const char *filename);
/*
Opens a PDF document.
Same as pdf_open_document, but takes a stream instead of a
filename to locate the PDF document to open. Increments the
reference count of the stream. See fz_open_file,
fz_open_file_w or fz_open_fd for opening a stream, and
fz_drop_stream for closing an open stream.
*/
pdf_document *pdf_open_document_with_stream(fz_context *ctx, fz_stream *file);
/*
Closes and frees an opened PDF document.
The resource store in the context associated with pdf_document
is emptied.
*/
void pdf_drop_document(fz_context *ctx, pdf_document *doc);
pdf_document *pdf_keep_document(fz_context *ctx, pdf_document *doc);
/*
down-cast a fz_document to a pdf_document.
Returns NULL if underlying document is not PDF
*/
pdf_document *pdf_specifics(fz_context *ctx, fz_document *doc);
/*
Down-cast generic fitz objects into pdf specific variants.
Returns NULL if the objects are not from a PDF document.
*/
pdf_document *pdf_document_from_fz_document(fz_context *ctx, fz_document *ptr);
pdf_page *pdf_page_from_fz_page(fz_context *ctx, fz_page *ptr);
int pdf_needs_password(fz_context *ctx, pdf_document *doc);
/*
Attempt to authenticate a
password.
Returns 0 for failure, non-zero for success.
In the non-zero case:
bit 0 set => no password required
bit 1 set => user password authenticated
bit 2 set => owner password authenticated
*/
int pdf_authenticate_password(fz_context *ctx, pdf_document *doc, const char *pw);
int pdf_has_permission(fz_context *ctx, pdf_document *doc, fz_permission p);
int pdf_lookup_metadata(fz_context *ctx, pdf_document *doc, const char *key, char *ptr, int size);
fz_outline *pdf_load_outline(fz_context *ctx, pdf_document *doc);
fz_outline_iterator *pdf_new_outline_iterator(fz_context *ctx, pdf_document *doc);
void pdf_invalidate_xfa(fz_context *ctx, pdf_document *doc);
/*
Get the number of layer configurations defined in this document.
doc: The document in question.
*/
int pdf_count_layer_configs(fz_context *ctx, pdf_document *doc);
/*
Configure visibility of individual layers in this document.
*/
int pdf_count_layers(fz_context *ctx, pdf_document *doc);
const char *pdf_layer_name(fz_context *ctx, pdf_document *doc, int layer);
int pdf_layer_is_enabled(fz_context *ctx, pdf_document *doc, int layer);
void pdf_enable_layer(fz_context *ctx, pdf_document *doc, int layer, int enabled);
typedef struct
{
const char *name;
const char *creator;
} pdf_layer_config;
/*
Fetch the name (and optionally creator) of the given layer config.
doc: The document in question.
config_num: A value in the 0..n-1 range, where n is the
value returned from pdf_count_layer_configs.
info: Pointer to structure to fill in. Pointers within
this structure may be set to NULL if no information is
available.
*/
void pdf_layer_config_info(fz_context *ctx, pdf_document *doc, int config_num, pdf_layer_config *info);
/*
Set the current configuration.
This updates the visibility of the optional content groups
within the document.
doc: The document in question.
config_num: A value in the 0..n-1 range, where n is the
value returned from pdf_count_layer_configs.
*/
void pdf_select_layer_config(fz_context *ctx, pdf_document *doc, int config_num);
/*
Returns the number of entries in the 'UI' for this layer configuration.
doc: The document in question.
*/
int pdf_count_layer_config_ui(fz_context *ctx, pdf_document *doc);
/*
Select a checkbox/radiobox within the 'UI' for this layer
configuration.
Selecting a UI entry that is a radiobox may disable
other UI entries.
doc: The document in question.
ui: A value in the 0..m-1 range, where m is the value
returned by pdf_count_layer_config_ui.
*/
void pdf_select_layer_config_ui(fz_context *ctx, pdf_document *doc, int ui);
/*
Select a checkbox/radiobox within the 'UI' for this layer configuration.
doc: The document in question.
ui: A value in the 0..m-1 range, where m is the value
returned by pdf_count_layer_config_ui.
*/
void pdf_deselect_layer_config_ui(fz_context *ctx, pdf_document *doc, int ui);
/*
Toggle a checkbox/radiobox within the 'UI' for this layer configuration.
Toggling a UI entry that is a radiobox may disable
other UI entries.
doc: The document in question.
ui: A value in the 0..m-1 range, where m is the value
returned by pdf_count_layer_config_ui.
*/
void pdf_toggle_layer_config_ui(fz_context *ctx, pdf_document *doc, int ui);
typedef enum
{
PDF_LAYER_UI_LABEL = 0,
PDF_LAYER_UI_CHECKBOX = 1,
PDF_LAYER_UI_RADIOBOX = 2
} pdf_layer_config_ui_type;
typedef struct
{
const char *text;
int depth;
pdf_layer_config_ui_type type;
int selected;
int locked;
} pdf_layer_config_ui;
/*
Get the info for a given entry in the layer config ui.
doc: The document in question.
ui: A value in the 0..m-1 range, where m is the value
returned by pdf_count_layer_config_ui.
info: Pointer to a structure to fill in with information
about the requested ui entry.
*/
void pdf_layer_config_ui_info(fz_context *ctx, pdf_document *doc, int ui, pdf_layer_config_ui *info);
/*
Write the current layer config back into the document as the default state.
*/
void pdf_set_layer_config_as_default(fz_context *ctx, pdf_document *doc);
/*
Determine whether changes have been made since the
document was opened or last saved.
*/
int pdf_has_unsaved_changes(fz_context *ctx, pdf_document *doc);
/*
Determine if this PDF has been repaired since opening.
*/
int pdf_was_repaired(fz_context *ctx, pdf_document *doc);
/* Object that can perform the cryptographic operation necessary for document signing */
typedef struct pdf_pkcs7_signer pdf_pkcs7_signer;
/* Unsaved signature fields */
typedef struct pdf_unsaved_sig
{
pdf_obj *field;
size_t byte_range_start;
size_t byte_range_end;
size_t contents_start;
size_t contents_end;
pdf_pkcs7_signer *signer;
struct pdf_unsaved_sig *next;
} pdf_unsaved_sig;
typedef struct
{
int page;
int object;
} pdf_rev_page_map;
typedef struct
{
int number; /* Page object number */
int64_t offset; /* Offset of page object */
int64_t index; /* Index into shared hint_shared_ref */
} pdf_hint_page;
typedef struct
{
int number; /* Object number of first object */
int64_t offset; /* Offset of first object */
} pdf_hint_shared;
struct pdf_document
{
fz_document super;
fz_stream *file;
int version;
int64_t startxref;
int64_t file_size;
pdf_crypt *crypt;
pdf_ocg_descriptor *ocg;
fz_colorspace *oi;
int max_xref_len;
int num_xref_sections;
int saved_num_xref_sections;
int num_incremental_sections;
int xref_base;
int disallow_new_increments;
/* The local_xref is only active, if local_xref_nesting >= 0 */
pdf_xref *local_xref;
int local_xref_nesting;
pdf_xref *xref_sections;
pdf_xref *saved_xref_sections;
int *xref_index;
int save_in_progress;
int last_xref_was_old_style;
int has_linearization_object;
int map_page_count;
pdf_rev_page_map *rev_page_map;
pdf_obj **fwd_page_map;
int page_tree_broken;
int repair_attempted;
int repair_in_progress;
int non_structural_change; /* True if we are modifying the document in a way that does not change the (page) structure */
/* State indicating which file parsing method we are using */
int file_reading_linearly;
int64_t file_length;
int linear_page_count;
pdf_obj *linear_obj; /* Linearized object (if used) */
pdf_obj **linear_page_refs; /* Page objects for linear loading */
int linear_page1_obj_num;
/* The state for the pdf_progressive_advance parser */
int64_t linear_pos;
int linear_page_num;
int hint_object_offset;
int hint_object_length;
int hints_loaded; /* Set to 1 after the hints loading has completed,
* whether successful or not! */
/* Page n references shared object references:
* hint_shared_ref[i]
* where
* i = s to e-1
* s = hint_page[n]->index
* e = hint_page[n+1]->index
* Shared object reference r accesses objects:
* rs to re-1
* where
* rs = hint_shared[r]->number
* re = hint_shared[r]->count + rs
* These are guaranteed to lie within the region starting at
* hint_shared[r]->offset of length hint_shared[r]->length
*/
pdf_hint_page *hint_page;
int *hint_shared_ref;
pdf_hint_shared *hint_shared;
int hint_obj_offsets_max;
int64_t *hint_obj_offsets;
int resources_localised;
pdf_lexbuf_large lexbuf;
pdf_js *js;
int recalculate;
int redacted;
int resynth_required;
pdf_doc_event_cb *event_cb;
pdf_free_doc_event_data_cb *free_event_data_cb;
void *event_cb_data;
int num_type3_fonts;
int max_type3_fonts;
fz_font **type3_fonts;
struct {
fz_hash_table *fonts;
} resources;
int orphans_max;
int orphans_count;
pdf_obj **orphans;
fz_xml_doc *xfa;
pdf_journal *journal;
};
pdf_document *pdf_create_document(fz_context *ctx);
typedef struct pdf_graft_map pdf_graft_map;
/*
Return a deep copied object equivalent to the
supplied object, suitable for use within the given document.
dst: The document in which the returned object is to be used.
obj: The object deep copy.
Note: If grafting multiple objects, you should use a pdf_graft_map
to avoid potential duplication of target objects.
*/
pdf_obj *pdf_graft_object(fz_context *ctx, pdf_document *dst, pdf_obj *obj);
/*
Prepare a graft map object to allow objects
to be deep copied from one document to the given one, avoiding
problems with duplicated child objects.
dst: The document to copy objects to.
Note: all the source objects must come from the same document.
*/
pdf_graft_map *pdf_new_graft_map(fz_context *ctx, pdf_document *dst);
pdf_graft_map *pdf_keep_graft_map(fz_context *ctx, pdf_graft_map *map);
void pdf_drop_graft_map(fz_context *ctx, pdf_graft_map *map);
/*
Return a deep copied object equivalent
to the supplied object, suitable for use within the target
document of the map.
map: A map targeted at the document in which the returned
object is to be used.
obj: The object to be copied.
Note: Copying multiple objects via the same graft map ensures
that any shared children are not copied more than once.
*/
pdf_obj *pdf_graft_mapped_object(fz_context *ctx, pdf_graft_map *map, pdf_obj *obj);
/*
Graft a page (and its resources) from the src document to the
destination document of the graft. This involves a deep copy
of the objects in question.
map: A map targetted at the document into which the page should
be inserted.
page_to: The position within the destination document at which
the page should be inserted (pages numbered from 0, with -1
meaning "at the end").
src: The document from which the page should be copied.
page_from: The page number which should be copied from the src
document (pages numbered from 0, with -1 meaning "at the end").
*/
void pdf_graft_page(fz_context *ctx, pdf_document *dst, int page_to, pdf_document *src, int page_from);
void pdf_graft_mapped_page(fz_context *ctx, pdf_graft_map *map, int page_to, pdf_document *src, int page_from);
/*
Create a device that will record the
graphical operations given to it into a sequence of
pdf operations, together with a set of resources. This
sequence/set pair can then be used as the basis for
adding a page to the document (see pdf_add_page).
Returns a kept reference.
doc: The document for which these are intended.
mediabox: The bbox for the created page.
presources: Pointer to a place to put the created
resources dictionary.
pcontents: Pointer to a place to put the created
contents buffer.
*/
fz_device *pdf_page_write(fz_context *ctx, pdf_document *doc, fz_rect mediabox, pdf_obj **presources, fz_buffer **pcontents);
/*
Create a pdf device. Rendering to the device creates
new pdf content. WARNING: this device is work in progress. It doesn't
currently support all rendering cases.
Note that contents must be a stream (dictionary) to be updated (or
a reference to a stream). Callers should take care to ensure that it
is not an array, and that is it not shared with other objects/pages.
*/
fz_device *pdf_new_pdf_device(fz_context *ctx, pdf_document *doc, fz_matrix topctm, pdf_obj *resources, fz_buffer *contents);
/*
Create a pdf_obj within a document that
represents a page, from a previously created resources
dictionary and page content stream. This should then be
inserted into the document using pdf_insert_page.
After this call the page exists within the document
structure, but is not actually ever displayed as it is
not linked into the PDF page tree.
doc: The document to which to add the page.
mediabox: The mediabox for the page (should be identical
to that used when creating the resources/contents).
rotate: 0, 90, 180 or 270. The rotation to use for the
page.
resources: The resources dictionary for the new page
(typically created by pdf_page_write).
contents: The page contents for the new page (typically
create by pdf_page_write).
*/
pdf_obj *pdf_add_page(fz_context *ctx, pdf_document *doc, fz_rect mediabox, int rotate, pdf_obj *resources, fz_buffer *contents);
/*
Insert a page previously created by
pdf_add_page into the pages tree of the document.
doc: The document to insert into.
at: The page number to insert at (pages numbered from 0).
0 <= n <= page_count inserts before page n. Negative numbers
or INT_MAX are treated as page count, and insert at the end.
0 inserts at the start. All existing pages are after the
insertion point are shuffled up.
page: The page to insert.
*/
void pdf_insert_page(fz_context *ctx, pdf_document *doc, int at, pdf_obj *page);
/*
Delete a page from the page tree of
a document. This does not remove the page contents
or resources from the file.
doc: The document to operate on.
number: The page to remove (numbered from 0)
*/
void pdf_delete_page(fz_context *ctx, pdf_document *doc, int number);
/*
Delete a range of pages from the
page tree of a document. This does not remove the page
contents or resources from the file.
doc: The document to operate on.
start, end: The range of pages (numbered from 0)
(inclusive, exclusive) to remove. If end is negative or
greater than the number of pages in the document, it
will be taken to be the end of the document.
*/
void pdf_delete_page_range(fz_context *ctx, pdf_document *doc, int start, int end);
/*
Get page label (string) from a page number (index).
*/
void pdf_page_label(fz_context *ctx, pdf_document *doc, int page, char *buf, size_t size);
void pdf_page_label_imp(fz_context *ctx, fz_document *doc, int chapter, int page, char *buf, size_t size);
typedef enum {
PDF_PAGE_LABEL_NONE = 0,
PDF_PAGE_LABEL_DECIMAL = 'D',
PDF_PAGE_LABEL_ROMAN_UC = 'R',
PDF_PAGE_LABEL_ROMAN_LC = 'r',
PDF_PAGE_LABEL_ALPHA_UC = 'A',
PDF_PAGE_LABEL_ALPHA_LC = 'a',
} pdf_page_label_style;
void pdf_set_page_labels(fz_context *ctx, pdf_document *doc, int index, pdf_page_label_style style, const char *prefix, int start);
void pdf_delete_page_labels(fz_context *ctx, pdf_document *doc, int index);
fz_text_language pdf_document_language(fz_context *ctx, pdf_document *doc);
void pdf_set_document_language(fz_context *ctx, pdf_document *doc, fz_text_language lang);
/*
In calls to fz_save_document, the following options structure can be used
to control aspects of the writing process. This structure may grow
in the future, and should be zero-filled to allow forwards compatibility.
*/
typedef struct
{
int do_incremental; /* Write just the changed objects. */
int do_pretty; /* Pretty-print dictionaries and arrays. */
int do_ascii; /* ASCII hex encode binary streams. */
int do_compress; /* Compress streams. */
int do_compress_images; /* Compress (or leave compressed) image streams. */
int do_compress_fonts; /* Compress (or leave compressed) font streams. */
int do_decompress; /* Decompress streams (except when compressing images/fonts). */
int do_garbage; /* Garbage collect objects before saving; 1=gc, 2=re-number, 3=de-duplicate. */
int do_linear; /* Write linearised. */
int do_clean; /* Clean content streams. */
int do_sanitize; /* Sanitize content streams. */
int do_appearance; /* (Re)create appearance streams. */
int do_encrypt; /* Encryption method to use: keep, none, rc4-40, etc. */
int dont_regenerate_id; /* Don't regenerate ID if set (used for clean) */
int permissions; /* Document encryption permissions. */
char opwd_utf8[128]; /* Owner password. */
char upwd_utf8[128]; /* User password. */
int do_snapshot; /* Do not use directly. Use the snapshot functions. */
int do_preserve_metadata; /* When cleaning, preserve metadata unchanged. */
} pdf_write_options;
FZ_DATA extern const pdf_write_options pdf_default_write_options;
/*
Parse option string into a pdf_write_options struct.
Matches the command line options to 'mutool clean':
g: garbage collect
d, i, f: expand all, fonts, images
l: linearize
a: ascii hex encode
z: deflate
c: clean content streams
s: sanitize content streams
*/
pdf_write_options *pdf_parse_write_options(fz_context *ctx, pdf_write_options *opts, const char *args);
/*
Returns true if there are digital signatures waiting to
to updated on save.
*/
int pdf_has_unsaved_sigs(fz_context *ctx, pdf_document *doc);
/*
Write out the document to an output stream with all changes finalised.
*/
void pdf_write_document(fz_context *ctx, pdf_document *doc, fz_output *out, const pdf_write_options *opts);
/*
Write out the document to a file with all changes finalised.
*/
void pdf_save_document(fz_context *ctx, pdf_document *doc, const char *filename, const pdf_write_options *opts);
/*
Snapshot the document to a file. This does not cause the
incremental xref to be finalized, so the document in memory
remains (essentially) unchanged.
*/
void pdf_save_snapshot(fz_context *ctx, pdf_document *doc, const char *filename);
/*
Snapshot the document to an output stream. This does not cause
the incremental xref to be finalized, so the document in memory
remains (essentially) unchanged.
*/
void pdf_write_snapshot(fz_context *ctx, pdf_document *doc, fz_output *out);
char *pdf_format_write_options(fz_context *ctx, char *buffer, size_t buffer_len, const pdf_write_options *opts);
/*
Return true if the document can be saved incrementally. Applying
redactions or having a repaired document make incremental saving
impossible.
*/
int pdf_can_be_saved_incrementally(fz_context *ctx, pdf_document *doc);
/*
Write out the journal to an output stream.
*/
void pdf_write_journal(fz_context *ctx, pdf_document *doc, fz_output *out);
/*
Write out the journal to a file.
*/
void pdf_save_journal(fz_context *ctx, pdf_document *doc, const char *filename);
/*
Read a journal from a filename. Will do nothing if the journal
does not match. Will throw on a corrupted journal.
*/
void pdf_load_journal(fz_context *ctx, pdf_document *doc, const char *filename);
/*
Read a journal from a stream. Will do nothing if the journal
does not match. Will throw on a corrupted journal.
*/
void pdf_read_journal(fz_context *ctx, pdf_document *doc, fz_stream *stm);
/*
Minimize the memory used by a document.
We walk the in memory xref tables, evicting the PDF objects
therein that aren't in use.
This reduces the current memory use, but any subsequent use
of these objects will load them back into memory again.
*/
void pdf_minimize_document(fz_context *ctx, pdf_document *doc);
#endif

167
include/mupdf/pdf/event.h Normal file
View File

@ -0,0 +1,167 @@
// Copyright (C) 2004-2022 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_PDF_EVENT_H
#define MUPDF_PDF_EVENT_H
#include "mupdf/pdf/document.h"
/*
Document events: the objects via which MuPDF informs the calling app
of occurrences emanating from the document, possibly from user interaction
or javascript execution. MuPDF informs the app of document events via a
callback.
*/
struct pdf_doc_event
{
int type;
};
enum
{
PDF_DOCUMENT_EVENT_ALERT,
PDF_DOCUMENT_EVENT_PRINT,
PDF_DOCUMENT_EVENT_LAUNCH_URL,
PDF_DOCUMENT_EVENT_MAIL_DOC,
PDF_DOCUMENT_EVENT_SUBMIT,
PDF_DOCUMENT_EVENT_EXEC_MENU_ITEM,
};
/*
set the function via which to receive
document events.
*/
void pdf_set_doc_event_callback(fz_context *ctx, pdf_document *doc, pdf_doc_event_cb *event_cb, pdf_free_doc_event_data_cb *free_event_data_cb, void *data);
void *pdf_get_doc_event_callback_data(fz_context *ctx, pdf_document *doc);
/*
The various types of document events
*/
/*
details of an alert event. In response the app should
display an alert dialog with the buttons specified by "button_type_group".
If "check_box_message" is non-NULL, a checkbox should be displayed in
the lower-left corned along with the message.
"finally_checked" and "button_pressed" should be set by the app
before returning from the callback. "finally_checked" need be set
only if "check_box_message" is non-NULL.
*/
typedef struct
{
pdf_document *doc;
const char *message;
int icon_type;
int button_group_type;
const char *title;
int has_check_box;
const char *check_box_message;
int initially_checked;
int finally_checked;
int button_pressed;
} pdf_alert_event;
/* Possible values of icon_type */
enum
{
PDF_ALERT_ICON_ERROR,
PDF_ALERT_ICON_WARNING,
PDF_ALERT_ICON_QUESTION,
PDF_ALERT_ICON_STATUS
};
/* Possible values of button_group_type */
enum
{
PDF_ALERT_BUTTON_GROUP_OK,
PDF_ALERT_BUTTON_GROUP_OK_CANCEL,
PDF_ALERT_BUTTON_GROUP_YES_NO,
PDF_ALERT_BUTTON_GROUP_YES_NO_CANCEL
};
/* Possible values of button_pressed */
enum
{
PDF_ALERT_BUTTON_NONE,
PDF_ALERT_BUTTON_OK,
PDF_ALERT_BUTTON_CANCEL,
PDF_ALERT_BUTTON_NO,
PDF_ALERT_BUTTON_YES
};
/*
access the details of an alert event
The returned pointer and all the data referred to by the
structure are owned by mupdf and need not be freed by the
caller.
*/
pdf_alert_event *pdf_access_alert_event(fz_context *ctx, pdf_doc_event *evt);
/*
access the details of am execMenuItem
event, which consists of just the name of the menu item
*/
const char *pdf_access_exec_menu_item_event(fz_context *ctx, pdf_doc_event *evt);
/*
details of a launch-url event. The app should
open the url, either in a new frame or in the current window.
*/
typedef struct
{
const char *url;
int new_frame;
} pdf_launch_url_event;
/*
access the details of a launch-url
event. The returned pointer and all data referred to by the structure
are owned by mupdf and need not be freed by the caller.
*/
pdf_launch_url_event *pdf_access_launch_url_event(fz_context *ctx, pdf_doc_event *evt);
/*
details of a mail_doc event. The app should save
the current state of the document and email it using the specified
parameters.
*/
typedef struct
{
int ask_user;
const char *to;
const char *cc;
const char *bcc;
const char *subject;
const char *message;
} pdf_mail_doc_event;
pdf_mail_doc_event *pdf_access_mail_doc_event(fz_context *ctx, pdf_doc_event *evt);
void pdf_event_issue_alert(fz_context *ctx, pdf_document *doc, pdf_alert_event *evt);
void pdf_event_issue_print(fz_context *ctx, pdf_document *doc);
void pdf_event_issue_exec_menu_item(fz_context *ctx, pdf_document *doc, const char *item);
void pdf_event_issue_launch_url(fz_context *ctx, pdf_document *doc, const char *url, int new_frame);
void pdf_event_issue_mail_doc(fz_context *ctx, pdf_document *doc, pdf_mail_doc_event *evt);
#endif

160
include/mupdf/pdf/font.h Normal file
View File

@ -0,0 +1,160 @@
// Copyright (C) 2004-2021 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_PDF_FONT_H
#define MUPDF_PDF_FONT_H
#include "mupdf/pdf/cmap.h"
#include "mupdf/fitz/device.h"
#include "mupdf/fitz/font.h"
enum
{
PDF_FD_FIXED_PITCH = 1 << 0,
PDF_FD_SERIF = 1 << 1,
PDF_FD_SYMBOLIC = 1 << 2,
PDF_FD_SCRIPT = 1 << 3,
PDF_FD_NONSYMBOLIC = 1 << 5,
PDF_FD_ITALIC = 1 << 6,
PDF_FD_ALL_CAP = 1 << 16,
PDF_FD_SMALL_CAP = 1 << 17,
PDF_FD_FORCE_BOLD = 1 << 18
};
void pdf_load_encoding(const char **estrings, const char *encoding);
typedef struct
{
unsigned short lo;
unsigned short hi;
int w; /* type3 fonts can be big! */
} pdf_hmtx;
typedef struct
{
unsigned short lo;
unsigned short hi;
short x;
short y;
short w;
} pdf_vmtx;
typedef struct
{
fz_storable storable;
size_t size;
fz_font *font;
/* FontDescriptor */
int flags;
float italic_angle;
float ascent;
float descent;
float cap_height;
float x_height;
float missing_width;
/* Encoding (CMap) */
pdf_cmap *encoding;
pdf_cmap *to_ttf_cmap;
size_t cid_to_gid_len;
unsigned short *cid_to_gid;
/* ToUnicode */
pdf_cmap *to_unicode;
size_t cid_to_ucs_len;
unsigned short *cid_to_ucs;
/* Metrics (given in the PDF file) */
int wmode;
int hmtx_len, hmtx_cap;
pdf_hmtx dhmtx;
pdf_hmtx *hmtx;
int vmtx_len, vmtx_cap;
pdf_vmtx dvmtx;
pdf_vmtx *vmtx;
int is_embedded;
int t3loading;
} pdf_font_desc;
void pdf_set_font_wmode(fz_context *ctx, pdf_font_desc *font, int wmode);
void pdf_set_default_hmtx(fz_context *ctx, pdf_font_desc *font, int w);
void pdf_set_default_vmtx(fz_context *ctx, pdf_font_desc *font, int y, int w);
void pdf_add_hmtx(fz_context *ctx, pdf_font_desc *font, int lo, int hi, int w);
void pdf_add_vmtx(fz_context *ctx, pdf_font_desc *font, int lo, int hi, int x, int y, int w);
void pdf_end_hmtx(fz_context *ctx, pdf_font_desc *font);
void pdf_end_vmtx(fz_context *ctx, pdf_font_desc *font);
pdf_hmtx pdf_lookup_hmtx(fz_context *ctx, pdf_font_desc *font, int cid);
pdf_vmtx pdf_lookup_vmtx(fz_context *ctx, pdf_font_desc *font, int cid);
void pdf_load_to_unicode(fz_context *ctx, pdf_document *doc, pdf_font_desc *font, const char **strings, char *collection, pdf_obj *cmapstm);
int pdf_font_cid_to_gid(fz_context *ctx, pdf_font_desc *fontdesc, int cid);
const char *pdf_clean_font_name(const char *fontname);
const unsigned char *pdf_lookup_substitute_font(fz_context *ctx, int mono, int serif, int bold, int italic, int *len);
pdf_font_desc *pdf_load_type3_font(fz_context *ctx, pdf_document *doc, pdf_obj *rdb, pdf_obj *obj);
void pdf_load_type3_glyphs(fz_context *ctx, pdf_document *doc, pdf_font_desc *fontdesc);
pdf_font_desc *pdf_load_font(fz_context *ctx, pdf_document *doc, pdf_obj *rdb, pdf_obj *obj);
pdf_font_desc *pdf_load_hail_mary_font(fz_context *ctx, pdf_document *doc);
pdf_font_desc *pdf_new_font_desc(fz_context *ctx);
pdf_font_desc *pdf_keep_font(fz_context *ctx, pdf_font_desc *fontdesc);
void pdf_drop_font(fz_context *ctx, pdf_font_desc *font);
void pdf_print_font(fz_context *ctx, fz_output *out, pdf_font_desc *fontdesc);
void pdf_run_glyph(fz_context *ctx, pdf_document *doc, pdf_obj *resources, fz_buffer *contents, fz_device *dev, fz_matrix ctm, void *gstate, fz_default_colorspaces *default_cs);
pdf_obj *pdf_add_simple_font(fz_context *ctx, pdf_document *doc, fz_font *font, int encoding);
/*
Creates CID font with Identity-H CMap and a ToUnicode CMap that
is created by using the TTF cmap table "backwards" to go from
the GID to a Unicode value.
We can possibly get width information that may have been embedded
in the PDF /W array (or W2 if vertical text)
*/
pdf_obj *pdf_add_cid_font(fz_context *ctx, pdf_document *doc, fz_font *font);
/*
Add a non-embedded UTF16-encoded CID-font for the CJK scripts:
CNS1, GB1, Japan1, or Korea1
*/
pdf_obj *pdf_add_cjk_font(fz_context *ctx, pdf_document *doc, fz_font *font, int script, int wmode, int serif);
/*
Add a substitute font for any script.
*/
pdf_obj *pdf_add_substitute_font(fz_context *ctx, pdf_document *doc, fz_font *font);
int pdf_font_writing_supported(fz_font *font);
fz_buffer *fz_extract_ttf_from_ttc(fz_context *ctx, fz_font *font);
#endif

382
include/mupdf/pdf/form.h Normal file
View File

@ -0,0 +1,382 @@
// Copyright (C) 2004-2021 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_PDF_FORM_H
#define MUPDF_PDF_FORM_H
#include "mupdf/fitz/display-list.h"
#include "mupdf/pdf/document.h"
/* Types of widget */
enum pdf_widget_type
{
PDF_WIDGET_TYPE_UNKNOWN,
PDF_WIDGET_TYPE_BUTTON,
PDF_WIDGET_TYPE_CHECKBOX,
PDF_WIDGET_TYPE_COMBOBOX,
PDF_WIDGET_TYPE_LISTBOX,
PDF_WIDGET_TYPE_RADIOBUTTON,
PDF_WIDGET_TYPE_SIGNATURE,
PDF_WIDGET_TYPE_TEXT,
};
/* Types of text widget content */
enum pdf_widget_tx_format
{
PDF_WIDGET_TX_FORMAT_NONE,
PDF_WIDGET_TX_FORMAT_NUMBER,
PDF_WIDGET_TX_FORMAT_SPECIAL,
PDF_WIDGET_TX_FORMAT_DATE,
PDF_WIDGET_TX_FORMAT_TIME
};
pdf_annot *pdf_keep_widget(fz_context *ctx, pdf_annot *widget);
void pdf_drop_widget(fz_context *ctx, pdf_annot *widget);
pdf_annot *pdf_first_widget(fz_context *ctx, pdf_page *page);
pdf_annot *pdf_next_widget(fz_context *ctx, pdf_annot *previous);
int pdf_update_widget(fz_context *ctx, pdf_annot *widget);
/*
create a new signature widget on the specified page, with the
specified name.
The returns pdf_annot reference must be dropped by the caller.
This is a change from releases up to an including 1.18, where
the returned reference was owned by the page and did not need
to be freed by the caller.
*/
pdf_annot *pdf_create_signature_widget(fz_context *ctx, pdf_page *page, char *name);
enum pdf_widget_type pdf_widget_type(fz_context *ctx, pdf_annot *widget);
fz_rect pdf_bound_widget(fz_context *ctx, pdf_annot *widget);
/*
get the maximum number of
characters permitted in a text widget
*/
int pdf_text_widget_max_len(fz_context *ctx, pdf_annot *tw);
/*
get the type of content
required by a text widget
*/
int pdf_text_widget_format(fz_context *ctx, pdf_annot *tw);
/*
get the list of options for a list box or combo box.
Returns the number of options and fills in their
names within the supplied array. Should first be called with a
NULL array to find out how big the array should be. If exportval
is true, then the export values will be returned and not the list
values if there are export values present.
*/
int pdf_choice_widget_options(fz_context *ctx, pdf_annot *tw, int exportval, const char *opts[]);
int pdf_choice_widget_is_multiselect(fz_context *ctx, pdf_annot *tw);
/*
get the value of a choice widget.
Returns the number of options currently selected and fills in
the supplied array with their strings. Should first be called
with NULL as the array to find out how big the array need to
be. The filled in elements should not be freed by the caller.
*/
int pdf_choice_widget_value(fz_context *ctx, pdf_annot *tw, const char *opts[]);
/*
set the value of a choice widget.
The caller should pass the number of options selected and an
array of their names
*/
void pdf_choice_widget_set_value(fz_context *ctx, pdf_annot *tw, int n, const char *opts[]);
int pdf_choice_field_option_count(fz_context *ctx, pdf_obj *field);
const char *pdf_choice_field_option(fz_context *ctx, pdf_obj *field, int exportval, int i);
int pdf_widget_is_signed(fz_context *ctx, pdf_annot *widget);
int pdf_widget_is_readonly(fz_context *ctx, pdf_annot *widget);
/* Field flags */
enum
{
/* All fields */
PDF_FIELD_IS_READ_ONLY = 1,
PDF_FIELD_IS_REQUIRED = 1 << 1,
PDF_FIELD_IS_NO_EXPORT = 1 << 2,
/* Text fields */
PDF_TX_FIELD_IS_MULTILINE = 1 << 12,
PDF_TX_FIELD_IS_PASSWORD = 1 << 13,
PDF_TX_FIELD_IS_FILE_SELECT = 1 << 20,
PDF_TX_FIELD_IS_DO_NOT_SPELL_CHECK = 1 << 22,
PDF_TX_FIELD_IS_DO_NOT_SCROLL = 1 << 23,
PDF_TX_FIELD_IS_COMB = 1 << 24,
PDF_TX_FIELD_IS_RICH_TEXT = 1 << 25,
/* Button fields */
PDF_BTN_FIELD_IS_NO_TOGGLE_TO_OFF = 1 << 14,
PDF_BTN_FIELD_IS_RADIO = 1 << 15,
PDF_BTN_FIELD_IS_PUSHBUTTON = 1 << 16,
PDF_BTN_FIELD_IS_RADIOS_IN_UNISON = 1 << 25,
/* Choice fields */
PDF_CH_FIELD_IS_COMBO = 1 << 17,
PDF_CH_FIELD_IS_EDIT = 1 << 18,
PDF_CH_FIELD_IS_SORT = 1 << 19,
PDF_CH_FIELD_IS_MULTI_SELECT = 1 << 21,
PDF_CH_FIELD_IS_DO_NOT_SPELL_CHECK = 1 << 22,
PDF_CH_FIELD_IS_COMMIT_ON_SEL_CHANGE = 1 << 25,
};
void pdf_calculate_form(fz_context *ctx, pdf_document *doc);
void pdf_reset_form(fz_context *ctx, pdf_document *doc, pdf_obj *fields, int exclude);
int pdf_field_type(fz_context *ctx, pdf_obj *field);
const char *pdf_field_type_string(fz_context *ctx, pdf_obj *field);
int pdf_field_flags(fz_context *ctx, pdf_obj *field);
/*
Retrieve the name for a field as a C string that
must be freed by the caller.
*/
char *pdf_load_field_name(fz_context *ctx, pdf_obj *field);
const char *pdf_field_value(fz_context *ctx, pdf_obj *field);
void pdf_create_field_name(fz_context *ctx, pdf_document *doc, const char *prefix, char *buf, size_t len);
char *pdf_field_border_style(fz_context *ctx, pdf_obj *field);
void pdf_field_set_border_style(fz_context *ctx, pdf_obj *field, const char *text);
void pdf_field_set_button_caption(fz_context *ctx, pdf_obj *field, const char *text);
void pdf_field_set_fill_color(fz_context *ctx, pdf_obj *field, pdf_obj *col);
void pdf_field_set_text_color(fz_context *ctx, pdf_obj *field, pdf_obj *col);
int pdf_field_display(fz_context *ctx, pdf_obj *field);
void pdf_field_set_display(fz_context *ctx, pdf_obj *field, int d);
const char *pdf_field_label(fz_context *ctx, pdf_obj *field);
pdf_obj *pdf_button_field_on_state(fz_context *ctx, pdf_obj *field);
int pdf_set_field_value(fz_context *ctx, pdf_document *doc, pdf_obj *field, const char *text, int ignore_trigger_events);
/*
Update the text of a text widget.
The text is first validated by the Field/Keystroke event processing and accepted only if it passes.
The function returns whether validation passed.
*/
int pdf_set_text_field_value(fz_context *ctx, pdf_annot *widget, const char *value);
int pdf_set_choice_field_value(fz_context *ctx, pdf_annot *widget, const char *value);
int pdf_edit_text_field_value(fz_context *ctx, pdf_annot *widget, const char *value, const char *change, int *selStart, int *selEnd, char **newvalue);
typedef struct
{
char *cn;
char *o;
char *ou;
char *email;
char *c;
}
pdf_pkcs7_distinguished_name;
typedef enum
{
PDF_SIGNATURE_ERROR_OKAY,
PDF_SIGNATURE_ERROR_NO_SIGNATURES,
PDF_SIGNATURE_ERROR_NO_CERTIFICATE,
PDF_SIGNATURE_ERROR_DIGEST_FAILURE,
PDF_SIGNATURE_ERROR_SELF_SIGNED,
PDF_SIGNATURE_ERROR_SELF_SIGNED_IN_CHAIN,
PDF_SIGNATURE_ERROR_NOT_TRUSTED,
PDF_SIGNATURE_ERROR_UNKNOWN
} pdf_signature_error;
/* Increment the reference count for a signer object */
typedef pdf_pkcs7_signer *(pdf_pkcs7_keep_signer_fn)(fz_context *ctx, pdf_pkcs7_signer *signer);
/* Drop a reference for a signer object */
typedef void (pdf_pkcs7_drop_signer_fn)(fz_context *ctx, pdf_pkcs7_signer *signer);
/* Obtain the distinguished name information from a signer object */
typedef pdf_pkcs7_distinguished_name *(pdf_pkcs7_get_signing_name_fn)(fz_context *ctx, pdf_pkcs7_signer *signer);
/* Predict the size of the digest. The actual digest returned by create_digest will be no greater in size */
typedef size_t (pdf_pkcs7_max_digest_size_fn)(fz_context *ctx, pdf_pkcs7_signer *signer);
/* Create a signature based on ranges of bytes drawn from a stream */
typedef int (pdf_pkcs7_create_digest_fn)(fz_context *ctx, pdf_pkcs7_signer *signer, fz_stream *in, unsigned char *digest, size_t digest_len);
struct pdf_pkcs7_signer
{
pdf_pkcs7_keep_signer_fn *keep;
pdf_pkcs7_drop_signer_fn *drop;
pdf_pkcs7_get_signing_name_fn *get_signing_name;
pdf_pkcs7_max_digest_size_fn *max_digest_size;
pdf_pkcs7_create_digest_fn *create_digest;
};
typedef struct pdf_pkcs7_verifier pdf_pkcs7_verifier;
typedef void (pdf_pkcs7_drop_verifier_fn)(fz_context *ctx, pdf_pkcs7_verifier *verifier);
typedef pdf_signature_error (pdf_pkcs7_check_certificate_fn)(fz_context *ctx, pdf_pkcs7_verifier *verifier, unsigned char *signature, size_t len);
typedef pdf_signature_error (pdf_pkcs7_check_digest_fn)(fz_context *ctx, pdf_pkcs7_verifier *verifier, fz_stream *in, unsigned char *signature, size_t len);
typedef pdf_pkcs7_distinguished_name *(pdf_pkcs7_get_signatory_fn)(fz_context *ctx, pdf_pkcs7_verifier *verifier, unsigned char *signature, size_t len);
struct pdf_pkcs7_verifier
{
pdf_pkcs7_drop_verifier_fn *drop;
pdf_pkcs7_check_certificate_fn *check_certificate;
pdf_pkcs7_check_digest_fn *check_digest;
pdf_pkcs7_get_signatory_fn *get_signatory;
};
int pdf_signature_is_signed(fz_context *ctx, pdf_document *doc, pdf_obj *field);
void pdf_signature_set_value(fz_context *ctx, pdf_document *doc, pdf_obj *field, pdf_pkcs7_signer *signer, int64_t stime);
int pdf_count_signatures(fz_context *ctx, pdf_document *doc);
char *pdf_signature_error_description(pdf_signature_error err);
pdf_pkcs7_distinguished_name *pdf_signature_get_signatory(fz_context *ctx, pdf_pkcs7_verifier *verifier, pdf_document *doc, pdf_obj *signature);
pdf_pkcs7_distinguished_name *pdf_signature_get_widget_signatory(fz_context *ctx, pdf_pkcs7_verifier *verifier, pdf_annot *widget);
void pdf_signature_drop_distinguished_name(fz_context *ctx, pdf_pkcs7_distinguished_name *name);
char *pdf_signature_format_distinguished_name(fz_context *ctx, pdf_pkcs7_distinguished_name *name);
char *pdf_signature_info(fz_context *ctx, const char *name, pdf_pkcs7_distinguished_name *dn, const char *reason, const char *location, int64_t date, int include_labels);
fz_display_list *pdf_signature_appearance_signed(fz_context *ctx, fz_rect rect, fz_text_language lang, fz_image *img, const char *left_text, const char *right_text, int include_logo);
fz_display_list *pdf_signature_appearance_unsigned(fz_context *ctx, fz_rect rect, fz_text_language lang);
pdf_signature_error pdf_check_digest(fz_context *ctx, pdf_pkcs7_verifier *verifier, pdf_document *doc, pdf_obj *signature);
pdf_signature_error pdf_check_certificate(fz_context *ctx, pdf_pkcs7_verifier *verifier, pdf_document *doc, pdf_obj *signature);
pdf_signature_error pdf_check_widget_digest(fz_context *ctx, pdf_pkcs7_verifier *verifier, pdf_annot *widget);
pdf_signature_error pdf_check_widget_certificate(fz_context *ctx, pdf_pkcs7_verifier *verifier, pdf_annot *widget);
void pdf_clear_signature(fz_context *ctx, pdf_annot *widget);
/*
Sign a signature field, while assigning it an arbitrary apparance determined by a display list.
The function pdf_signature_appearance can generate a variety of common signature appearances.
*/
void pdf_sign_signature_with_appearance(fz_context *ctx, pdf_annot *widget, pdf_pkcs7_signer *signer, int64_t date, fz_display_list *disp_list);
enum {
PDF_SIGNATURE_SHOW_LABELS = 1,
PDF_SIGNATURE_SHOW_DN = 2,
PDF_SIGNATURE_SHOW_DATE = 4,
PDF_SIGNATURE_SHOW_TEXT_NAME = 8,
PDF_SIGNATURE_SHOW_GRAPHIC_NAME = 16,
PDF_SIGNATURE_SHOW_LOGO = 32,
};
#define PDF_SIGNATURE_DEFAULT_APPEARANCE ( \
PDF_SIGNATURE_SHOW_LABELS | \
PDF_SIGNATURE_SHOW_DN | \
PDF_SIGNATURE_SHOW_DATE | \
PDF_SIGNATURE_SHOW_TEXT_NAME | \
PDF_SIGNATURE_SHOW_GRAPHIC_NAME | \
PDF_SIGNATURE_SHOW_LOGO )
/*
Sign a signature field, while assigning it a default appearance.
*/
void pdf_sign_signature(fz_context *ctx, pdf_annot *widget,
pdf_pkcs7_signer *signer,
int appearance_flags,
fz_image *graphic,
const char *reason,
const char *location);
/*
Create a preview of the default signature appearance.
*/
fz_display_list *pdf_preview_signature_as_display_list(fz_context *ctx,
float w, float h, fz_text_language lang,
pdf_pkcs7_signer *signer,
int appearance_flags,
fz_image *graphic,
const char *reason,
const char *location);
fz_pixmap *pdf_preview_signature_as_pixmap(fz_context *ctx,
int w, int h, fz_text_language lang,
pdf_pkcs7_signer *signer,
int appearance_flags,
fz_image *graphic,
const char *reason,
const char *location);
/*
check a signature's certificate chain and digest
This is a helper function defined to provide compatibility with older
versions of mupdf
*/
int pdf_check_signature(fz_context *ctx, pdf_pkcs7_verifier *verifier, pdf_document *doc, pdf_obj *signature, char *ebuf, size_t ebufsize);
void pdf_drop_signer(fz_context *ctx, pdf_pkcs7_signer *signer);
void pdf_drop_verifier(fz_context *ctx, pdf_pkcs7_verifier *verifier);
void pdf_field_reset(fz_context *ctx, pdf_document *doc, pdf_obj *field);
pdf_obj *pdf_lookup_field(fz_context *ctx, pdf_obj *form, const char *name);
/* Form text field editing events: */
typedef struct
{
const char *value;
const char *change;
int selStart, selEnd;
int willCommit;
char *newChange;
char *newValue;
} pdf_keystroke_event;
int pdf_field_event_keystroke(fz_context *ctx, pdf_document *doc, pdf_obj *field, pdf_keystroke_event *evt);
int pdf_field_event_validate(fz_context *ctx, pdf_document *doc, pdf_obj *field, const char *value, char **newvalue);
void pdf_field_event_calculate(fz_context *ctx, pdf_document *doc, pdf_obj *field);
char *pdf_field_event_format(fz_context *ctx, pdf_document *doc, pdf_obj *field);
int pdf_annot_field_event_keystroke(fz_context *ctx, pdf_document *doc, pdf_annot *annot, pdf_keystroke_event *evt);
/* Call these to trigger actions from various UI events: */
void pdf_document_event_will_close(fz_context *ctx, pdf_document *doc);
void pdf_document_event_will_save(fz_context *ctx, pdf_document *doc);
void pdf_document_event_did_save(fz_context *ctx, pdf_document *doc);
void pdf_document_event_will_print(fz_context *ctx, pdf_document *doc);
void pdf_document_event_did_print(fz_context *ctx, pdf_document *doc);
void pdf_page_event_open(fz_context *ctx, pdf_page *page);
void pdf_page_event_close(fz_context *ctx, pdf_page *page);
void pdf_annot_event_enter(fz_context *ctx, pdf_annot *annot);
void pdf_annot_event_exit(fz_context *ctx, pdf_annot *annot);
void pdf_annot_event_down(fz_context *ctx, pdf_annot *annot);
void pdf_annot_event_up(fz_context *ctx, pdf_annot *annot);
void pdf_annot_event_focus(fz_context *ctx, pdf_annot *annot);
void pdf_annot_event_blur(fz_context *ctx, pdf_annot *annot);
void pdf_annot_event_page_open(fz_context *ctx, pdf_annot *annot);
void pdf_annot_event_page_close(fz_context *ctx, pdf_annot *annot);
void pdf_annot_event_page_visible(fz_context *ctx, pdf_annot *annot);
void pdf_annot_event_page_invisible(fz_context *ctx, pdf_annot *annot);
#endif

View File

@ -0,0 +1,452 @@
// Copyright (C) 2004-2023 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef PDF_INTERPRET_H
#define PDF_INTERPRET_H
#include "mupdf/pdf/font.h"
#include "mupdf/pdf/resource.h"
#include "mupdf/pdf/document.h"
typedef struct pdf_gstate pdf_gstate;
typedef struct pdf_processor pdf_processor;
void *pdf_new_processor(fz_context *ctx, int size);
pdf_processor *pdf_keep_processor(fz_context *ctx, pdf_processor *proc);
void pdf_close_processor(fz_context *ctx, pdf_processor *proc);
void pdf_drop_processor(fz_context *ctx, pdf_processor *proc);
struct pdf_processor
{
int refs;
/* close the processor. Also closes any chained processors. */
void (*close_processor)(fz_context *ctx, pdf_processor *proc);
void (*drop_processor)(fz_context *ctx, pdf_processor *proc);
/* At any stage, we can have one set of resources in place.
* This function gives us a set of resources to use. We remember
* any previous set on a stack, so we can pop back to it later.
* Our responsibility (as well as remembering it for our own use)
* is to pass either it, or a filtered version of it onto any
* chained processor. */
void (*push_resources)(fz_context *ctx, pdf_processor *proc, pdf_obj *res);
/* Pop the resources stack. This must be passed on to any chained
* processors. This returns a pointer to the resource dict just
* popped by the deepest filter. The caller inherits this reference. */
pdf_obj *(*pop_resources)(fz_context *ctx, pdf_processor *proc);
/* general graphics state */
void (*op_w)(fz_context *ctx, pdf_processor *proc, float linewidth);
void (*op_j)(fz_context *ctx, pdf_processor *proc, int linejoin);
void (*op_J)(fz_context *ctx, pdf_processor *proc, int linecap);
void (*op_M)(fz_context *ctx, pdf_processor *proc, float miterlimit);
void (*op_d)(fz_context *ctx, pdf_processor *proc, pdf_obj *array, float phase);
void (*op_ri)(fz_context *ctx, pdf_processor *proc, const char *intent);
void (*op_i)(fz_context *ctx, pdf_processor *proc, float flatness);
void (*op_gs_begin)(fz_context *ctx, pdf_processor *proc, const char *name, pdf_obj *extgstate);
void (*op_gs_BM)(fz_context *ctx, pdf_processor *proc, const char *blendmode);
void (*op_gs_ca)(fz_context *ctx, pdf_processor *proc, float alpha);
void (*op_gs_CA)(fz_context *ctx, pdf_processor *proc, float alpha);
void (*op_gs_SMask)(fz_context *ctx, pdf_processor *proc, pdf_obj *smask, float *bc, int luminosity);
void (*op_gs_end)(fz_context *ctx, pdf_processor *proc);
/* special graphics state */
void (*op_q)(fz_context *ctx, pdf_processor *proc);
void (*op_Q)(fz_context *ctx, pdf_processor *proc);
void (*op_cm)(fz_context *ctx, pdf_processor *proc, float a, float b, float c, float d, float e, float f);
/* path construction */
void (*op_m)(fz_context *ctx, pdf_processor *proc, float x, float y);
void (*op_l)(fz_context *ctx, pdf_processor *proc, float x, float y);
void (*op_c)(fz_context *ctx, pdf_processor *proc, float x1, float y1, float x2, float y2, float x3, float y3);
void (*op_v)(fz_context *ctx, pdf_processor *proc, float x2, float y2, float x3, float y3);
void (*op_y)(fz_context *ctx, pdf_processor *proc, float x1, float y1, float x3, float y3);
void (*op_h)(fz_context *ctx, pdf_processor *proc);
void (*op_re)(fz_context *ctx, pdf_processor *proc, float x, float y, float w, float h);
/* path painting */
void (*op_S)(fz_context *ctx, pdf_processor *proc);
void (*op_s)(fz_context *ctx, pdf_processor *proc);
void (*op_F)(fz_context *ctx, pdf_processor *proc);
void (*op_f)(fz_context *ctx, pdf_processor *proc);
void (*op_fstar)(fz_context *ctx, pdf_processor *proc);
void (*op_B)(fz_context *ctx, pdf_processor *proc);
void (*op_Bstar)(fz_context *ctx, pdf_processor *proc);
void (*op_b)(fz_context *ctx, pdf_processor *proc);
void (*op_bstar)(fz_context *ctx, pdf_processor *proc);
void (*op_n)(fz_context *ctx, pdf_processor *proc);
/* clipping paths */
void (*op_W)(fz_context *ctx, pdf_processor *proc);
void (*op_Wstar)(fz_context *ctx, pdf_processor *proc);
/* text objects */
void (*op_BT)(fz_context *ctx, pdf_processor *proc);
void (*op_ET)(fz_context *ctx, pdf_processor *proc);
/* text state */
void (*op_Tc)(fz_context *ctx, pdf_processor *proc, float charspace);
void (*op_Tw)(fz_context *ctx, pdf_processor *proc, float wordspace);
void (*op_Tz)(fz_context *ctx, pdf_processor *proc, float scale);
void (*op_TL)(fz_context *ctx, pdf_processor *proc, float leading);
void (*op_Tf)(fz_context *ctx, pdf_processor *proc, const char *name, pdf_font_desc *font, float size);
void (*op_Tr)(fz_context *ctx, pdf_processor *proc, int render);
void (*op_Ts)(fz_context *ctx, pdf_processor *proc, float rise);
/* text positioning */
void (*op_Td)(fz_context *ctx, pdf_processor *proc, float tx, float ty);
void (*op_TD)(fz_context *ctx, pdf_processor *proc, float tx, float ty);
void (*op_Tm)(fz_context *ctx, pdf_processor *proc, float a, float b, float c, float d, float e, float f);
void (*op_Tstar)(fz_context *ctx, pdf_processor *proc);
/* text showing */
void (*op_TJ)(fz_context *ctx, pdf_processor *proc, pdf_obj *array);
void (*op_Tj)(fz_context *ctx, pdf_processor *proc, char *str, size_t len);
void (*op_squote)(fz_context *ctx, pdf_processor *proc, char *str, size_t len);
void (*op_dquote)(fz_context *ctx, pdf_processor *proc, float aw, float ac, char *str, size_t len);
/* type 3 fonts */
void (*op_d0)(fz_context *ctx, pdf_processor *proc, float wx, float wy);
void (*op_d1)(fz_context *ctx, pdf_processor *proc, float wx, float wy, float llx, float lly, float urx, float ury);
/* color */
void (*op_CS)(fz_context *ctx, pdf_processor *proc, const char *name, fz_colorspace *cs);
void (*op_cs)(fz_context *ctx, pdf_processor *proc, const char *name, fz_colorspace *cs);
void (*op_SC_pattern)(fz_context *ctx, pdf_processor *proc, const char *name, pdf_pattern *pat, int n, float *color);
void (*op_sc_pattern)(fz_context *ctx, pdf_processor *proc, const char *name, pdf_pattern *pat, int n, float *color);
void (*op_SC_shade)(fz_context *ctx, pdf_processor *proc, const char *name, fz_shade *shade);
void (*op_sc_shade)(fz_context *ctx, pdf_processor *proc, const char *name, fz_shade *shade);
void (*op_SC_color)(fz_context *ctx, pdf_processor *proc, int n, float *color);
void (*op_sc_color)(fz_context *ctx, pdf_processor *proc, int n, float *color);
void (*op_G)(fz_context *ctx, pdf_processor *proc, float g);
void (*op_g)(fz_context *ctx, pdf_processor *proc, float g);
void (*op_RG)(fz_context *ctx, pdf_processor *proc, float r, float g, float b);
void (*op_rg)(fz_context *ctx, pdf_processor *proc, float r, float g, float b);
void (*op_K)(fz_context *ctx, pdf_processor *proc, float c, float m, float y, float k);
void (*op_k)(fz_context *ctx, pdf_processor *proc, float c, float m, float y, float k);
/* shadings, images, xobjects */
void (*op_BI)(fz_context *ctx, pdf_processor *proc, fz_image *image, const char *colorspace_name);
void (*op_sh)(fz_context *ctx, pdf_processor *proc, const char *name, fz_shade *shade);
void (*op_Do_image)(fz_context *ctx, pdf_processor *proc, const char *name, fz_image *image);
void (*op_Do_form)(fz_context *ctx, pdf_processor *proc, const char *name, pdf_obj *form);
/* marked content */
void (*op_MP)(fz_context *ctx, pdf_processor *proc, const char *tag);
void (*op_DP)(fz_context *ctx, pdf_processor *proc, const char *tag, pdf_obj *raw, pdf_obj *cooked);
void (*op_BMC)(fz_context *ctx, pdf_processor *proc, const char *tag);
void (*op_BDC)(fz_context *ctx, pdf_processor *proc, const char *tag, pdf_obj *raw, pdf_obj *cooked);
void (*op_EMC)(fz_context *ctx, pdf_processor *proc);
/* compatibility */
void (*op_BX)(fz_context *ctx, pdf_processor *proc);
void (*op_EX)(fz_context *ctx, pdf_processor *proc);
/* Virtual ops for ExtGState entries */
void (*op_gs_OP)(fz_context *ctx, pdf_processor *proc, int b);
void (*op_gs_op)(fz_context *ctx, pdf_processor *proc, int b);
void (*op_gs_OPM)(fz_context *ctx, pdf_processor *proc, int i);
void (*op_gs_UseBlackPtComp)(fz_context *ctx, pdf_processor *proc, pdf_obj *name);
/* END is used to signify end of stream (finalise and close down) */
void (*op_END)(fz_context *ctx, pdf_processor *proc);
/* interpreter state that persists across content streams */
const char *usage;
int hidden;
};
typedef struct
{
/* input */
pdf_document *doc;
pdf_obj *rdb;
pdf_lexbuf *buf;
fz_cookie *cookie;
/* state */
int gstate;
int xbalance;
int in_text;
fz_rect d1_rect;
/* stack */
pdf_obj *obj;
char name[256];
char string[256];
size_t string_len;
int top;
float stack[32];
} pdf_csi;
/* Functions to set up pdf_process structures */
pdf_processor *pdf_new_run_processor(fz_context *ctx, pdf_document *doc, fz_device *dev, fz_matrix ctm, int struct_parent, const char *usage, pdf_gstate *gstate, fz_default_colorspaces *default_cs, fz_cookie *cookie);
/*
Create a buffer processor.
This collects the incoming PDF operator stream into an fz_buffer.
buffer: The (possibly empty) buffer to which operators will be
appended.
ahxencode: If 0, then image streams will be send as binary,
otherwise they will be asciihexencoded.
*/
pdf_processor *pdf_new_buffer_processor(fz_context *ctx, fz_buffer *buffer, int ahxencode);
/*
Create an output processor. This
sends the incoming PDF operator stream to an fz_output stream.
out: The output stream to which operators will be sent.
ahxencode: If 0, then image streams will be send as binary,
otherwise they will be asciihexencoded.
*/
pdf_processor *pdf_new_output_processor(fz_context *ctx, fz_output *out, int ahxencode);
typedef struct pdf_filter_options pdf_filter_options;
/*
Create a filter processor. This filters the PDF operators
it is fed, and passes them down (with some changes) to the
child filter.
chain: The child processor to which the filtered operators
will be fed.
The options field contains a pointer to a structure with
filter specific options in.
*/
typedef pdf_processor *(pdf_filter_factory_fn)(fz_context *ctx, pdf_document *doc, pdf_processor *chain, int struct_parents, fz_matrix transform, pdf_filter_options *options, void *factory_options);
/*
A pdf_filter_factory is a pdf_filter_factory_fn, plus the options
needed to instantiate it.
*/
typedef struct
{
pdf_filter_factory_fn *filter;
void *options;
} pdf_filter_factory;
/*
recurse: Filter resources recursively.
instance_forms: Always recurse on XObject Form resources, but will
create a new instance of each XObject Form that is used, filtered
individually.
ascii: If true, escape all binary data in the output.
no_update: If true, do not update the document at the end.
opaque: Opaque value that is passed to the complete function.
complete: A function called at the end of processing.
This allows the caller to insert some extra content after
all other content.
filters: Pointer to an array of filter factory/options.
The array is terminated by an entry with a NULL factory pointer.
Operators will be fed into the filter generated from the first
factory function in the list, and from there go to the filter
generated from the second factory in the list etc.
*/
struct pdf_filter_options
{
int recurse;
int instance_forms;
int ascii;
int no_update;
void *opaque;
void (*complete)(fz_context *ctx, fz_buffer *buffer, void *arg);
pdf_filter_factory *filters;
};
typedef enum
{
FZ_CULL_PATH_FILL,
FZ_CULL_PATH_STROKE,
FZ_CULL_PATH_FILL_STROKE,
FZ_CULL_CLIP_PATH,
FZ_CULL_GLYPH,
FZ_CULL_IMAGE,
FZ_CULL_SHADING
} fz_cull_type;
/*
image_filter: A function called to assess whether a given
image should be removed or not.
text_filter: A function called to assess whether a given
character should be removed or not.
after_text_object: A function called after each text object.
This allows the caller to insert some extra content if
desired.
culler: A function called to see whether each object should
be culled or not.
*/
typedef struct
{
void *opaque;
fz_image *(*image_filter)(fz_context *ctx, void *opaque, fz_matrix ctm, const char *name, fz_image *image);
int (*text_filter)(fz_context *ctx, void *opaque, int *ucsbuf, int ucslen, fz_matrix trm, fz_matrix ctm, fz_rect bbox);
void (*after_text_object)(fz_context *ctx, void *opaque, pdf_document *doc, pdf_processor *chain, fz_matrix ctm);
int (*culler)(fz_context *ctx, void *opaque, fz_rect bbox, fz_cull_type type);
}
pdf_sanitize_filter_options;
/*
A sanitize filter factory.
sopts = pointer to pdf_sanitize_filter_options.
The changes made by a filter generated from this are:
* No operations are allowed to change the top level gstate.
Additional q/Q operators are inserted to prevent this.
* Repeated/unnecessary colour operators are removed (so,
for example, "0 0 0 rg 0 1 rg 0.5 g" would be sanitised to
"0.5 g")
The intention of these changes is to provide a simpler,
but equivalent stream, repairing problems with mismatched
operators, maintaining structure (such as BMC, EMC calls)
and leaving the graphics state in an known (default) state
so that subsequent operations (such as synthesising new
operators to be appended to the stream) are easier.
The net graphical effect of the filtered operator stream
should be identical to the incoming operator stream.
*/
pdf_processor *pdf_new_sanitize_filter(fz_context *ctx, pdf_document *doc, pdf_processor *chain, int struct_parents, fz_matrix transform, pdf_filter_options *options, void *sopts);
pdf_obj *pdf_filter_xobject_instance(fz_context *ctx, pdf_obj *old_xobj, pdf_obj *page_res, fz_matrix ctm, pdf_filter_options *options, pdf_cycle_list *cycle_up);
void pdf_processor_push_resources(fz_context *ctx, pdf_processor *proc, pdf_obj *res);
pdf_obj *pdf_processor_pop_resources(fz_context *ctx, pdf_processor *proc);
/*
opaque: Opaque value that is passed to all the filter functions.
color_rewrite: function pointer called to rewrite a color
On entry:
*cs = reference to a pdf object representing the colorspace.
*n = number of color components
color = *n color values.
On exit:
*cs either the same (for no change in colorspace) or
updated to be a new one. Reference must be dropped, and
a new kept reference returned!
*n = number of color components (maybe updated)
color = *n color values (maybe updated)
image_rewrite: function pointer called to rewrite an image
On entry:
*image = reference to an fz_image.
On exit:
*image either the same (for no change) or updated
to be a new one. Reference must be dropped, and a
new kept reference returned.
*/
typedef struct
{
void *opaque;
void (*color_rewrite)(fz_context *ctx, void *opaque, pdf_obj **cs, int *n, float color[FZ_MAX_COLORS]);
void (*image_rewrite)(fz_context *ctx, void *opaque, fz_image **image);
pdf_shade_recolorer *shade_rewrite;
} pdf_color_filter_options;
pdf_processor *
pdf_new_color_filter(fz_context *ctx, pdf_document *doc, pdf_processor *chain, int struct_parents, fz_matrix transform, pdf_filter_options *options, void *copts);
/*
Functions to actually process annotations, glyphs and general stream objects.
*/
void pdf_process_contents(fz_context *ctx, pdf_processor *proc, pdf_document *doc, pdf_obj *obj, pdf_obj *res, fz_cookie *cookie, pdf_obj **out_res);
void pdf_process_annot(fz_context *ctx, pdf_processor *proc, pdf_annot *annot, fz_cookie *cookie);
void pdf_process_glyph(fz_context *ctx, pdf_processor *proc, pdf_document *doc, pdf_obj *resources, fz_buffer *contents);
/*
Function to process a contents stream without handling the resources.
The caller is responsible for pushing/popping the resources.
*/
void pdf_process_raw_contents(fz_context *ctx, pdf_processor *proc, pdf_document *doc, pdf_obj *rdb, pdf_obj *stmobj, fz_cookie *cookie);
/* Text handling helper functions */
typedef struct
{
float char_space;
float word_space;
float scale;
float leading;
pdf_font_desc *font;
float size;
int render;
float rise;
} pdf_text_state;
typedef struct
{
fz_text *text;
fz_rect text_bbox;
fz_matrix tlm;
fz_matrix tm;
int text_mode;
int cid;
int gid;
fz_rect char_bbox;
pdf_font_desc *fontdesc;
float char_tx;
float char_ty;
} pdf_text_object_state;
void pdf_tos_save(fz_context *ctx, pdf_text_object_state *tos, fz_matrix save[2]);
void pdf_tos_restore(fz_context *ctx, pdf_text_object_state *tos, fz_matrix save[2]);
fz_text *pdf_tos_get_text(fz_context *ctx, pdf_text_object_state *tos);
void pdf_tos_reset(fz_context *ctx, pdf_text_object_state *tos, int render);
int pdf_tos_make_trm(fz_context *ctx, pdf_text_object_state *tos, pdf_text_state *text, pdf_font_desc *fontdesc, int cid, fz_matrix *trm);
void pdf_tos_move_after_char(fz_context *ctx, pdf_text_object_state *tos);
void pdf_tos_translate(pdf_text_object_state *tos, float tx, float ty);
void pdf_tos_set_matrix(pdf_text_object_state *tos, float a, float b, float c, float d, float e, float f);
void pdf_tos_newline(pdf_text_object_state *tos, float leading);
#endif

View File

@ -0,0 +1,43 @@
// Copyright (C) 2004-2022 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_PDF_JAVASCRIPT_H
#define MUPDF_PDF_JAVASCRIPT_H
#include "mupdf/pdf/document.h"
#include "mupdf/pdf/form.h"
void pdf_enable_js(fz_context *ctx, pdf_document *doc);
void pdf_disable_js(fz_context *ctx, pdf_document *doc);
int pdf_js_supported(fz_context *ctx, pdf_document *doc);
void pdf_drop_js(fz_context *ctx, pdf_js *js);
void pdf_js_event_init(pdf_js *js, pdf_obj *target, const char *value, int willCommit);
int pdf_js_event_result(pdf_js *js);
int pdf_js_event_result_validate(pdf_js *js, char **newvalue);
char *pdf_js_event_value(pdf_js *js);
void pdf_js_event_init_keystroke(pdf_js *js, pdf_obj *target, pdf_keystroke_event *evt);
int pdf_js_event_result_keystroke(pdf_js *js, pdf_keystroke_event *evt);
void pdf_js_execute(pdf_js *js, const char *name, const char *code, char **result);
#endif

View File

@ -0,0 +1,585 @@
// Copyright (C) 2004-2023 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
/* Alphabetically sorted list of all PDF names to be available as constants */
PDF_MAKE_NAME("1.2", 1_2)
PDF_MAKE_NAME("3D", 3D)
PDF_MAKE_NAME("A", A)
PDF_MAKE_NAME("A85", A85)
PDF_MAKE_NAME("AA", AA)
PDF_MAKE_NAME("AC", AC)
PDF_MAKE_NAME("AESV2", AESV2)
PDF_MAKE_NAME("AESV3", AESV3)
PDF_MAKE_NAME("AHx", AHx)
PDF_MAKE_NAME("AP", AP)
PDF_MAKE_NAME("AS", AS)
PDF_MAKE_NAME("ASCII85Decode", ASCII85Decode)
PDF_MAKE_NAME("ASCIIHexDecode", ASCIIHexDecode)
PDF_MAKE_NAME("AcroForm", AcroForm)
PDF_MAKE_NAME("Action", Action)
PDF_MAKE_NAME("ActualText", ActualText)
PDF_MAKE_NAME("Adobe.PPKLite", Adobe_PPKLite)
PDF_MAKE_NAME("All", All)
PDF_MAKE_NAME("AllOff", AllOff)
PDF_MAKE_NAME("AllOn", AllOn)
PDF_MAKE_NAME("Alpha", Alpha)
PDF_MAKE_NAME("Alt", Alt)
PDF_MAKE_NAME("Alternate", Alternate)
PDF_MAKE_NAME("Annot", Annot)
PDF_MAKE_NAME("Annots", Annots)
PDF_MAKE_NAME("AnyOff", AnyOff)
PDF_MAKE_NAME("App", App)
PDF_MAKE_NAME("Approved", Approved)
PDF_MAKE_NAME("Art", Art)
PDF_MAKE_NAME("ArtBox", ArtBox)
PDF_MAKE_NAME("Artifact", Artifact)
PDF_MAKE_NAME("AsIs", AsIs)
PDF_MAKE_NAME("Ascent", Ascent)
PDF_MAKE_NAME("Aside", Aside)
PDF_MAKE_NAME("AuthEvent", AuthEvent)
PDF_MAKE_NAME("Author", Author)
PDF_MAKE_NAME("B", B)
PDF_MAKE_NAME("BBox", BBox)
PDF_MAKE_NAME("BC", BC)
PDF_MAKE_NAME("BE", BE)
PDF_MAKE_NAME("BG", BG)
PDF_MAKE_NAME("BM", BM)
PDF_MAKE_NAME("BPC", BPC)
PDF_MAKE_NAME("BS", BS)
PDF_MAKE_NAME("Background", Background)
PDF_MAKE_NAME("BaseEncoding", BaseEncoding)
PDF_MAKE_NAME("BaseFont", BaseFont)
PDF_MAKE_NAME("BaseState", BaseState)
PDF_MAKE_NAME("BibEntry", BibEntry)
PDF_MAKE_NAME("BitsPerComponent", BitsPerComponent)
PDF_MAKE_NAME("BitsPerCoordinate", BitsPerCoordinate)
PDF_MAKE_NAME("BitsPerFlag", BitsPerFlag)
PDF_MAKE_NAME("BitsPerSample", BitsPerSample)
PDF_MAKE_NAME("BlackIs1", BlackIs1)
PDF_MAKE_NAME("BlackPoint", BlackPoint)
PDF_MAKE_NAME("BleedBox", BleedBox)
PDF_MAKE_NAME("Blinds", Blinds)
PDF_MAKE_NAME("BlockQuote", BlockQuote)
PDF_MAKE_NAME("Border", Border)
PDF_MAKE_NAME("Bounds", Bounds)
PDF_MAKE_NAME("Box", Box)
PDF_MAKE_NAME("Bt", Bt)
PDF_MAKE_NAME("Btn", Btn)
PDF_MAKE_NAME("Butt", Butt)
PDF_MAKE_NAME("ByteRange", ByteRange)
PDF_MAKE_NAME("C", C)
PDF_MAKE_NAME("C0", C0)
PDF_MAKE_NAME("C1", C1)
PDF_MAKE_NAME("CA", CA)
PDF_MAKE_NAME("CCF", CCF)
PDF_MAKE_NAME("CCITTFaxDecode", CCITTFaxDecode)
PDF_MAKE_NAME("CF", CF)
PDF_MAKE_NAME("CFM", CFM)
PDF_MAKE_NAME("CI", CI)
PDF_MAKE_NAME("CIDFontType0", CIDFontType0)
PDF_MAKE_NAME("CIDFontType0C", CIDFontType0C)
PDF_MAKE_NAME("CIDFontType2", CIDFontType2)
PDF_MAKE_NAME("CIDSystemInfo", CIDSystemInfo)
PDF_MAKE_NAME("CIDToGIDMap", CIDToGIDMap)
PDF_MAKE_NAME("CMYK", CMYK)
PDF_MAKE_NAME("CS", CS)
PDF_MAKE_NAME("CalCMYK", CalCMYK)
PDF_MAKE_NAME("CalGray", CalGray)
PDF_MAKE_NAME("CalRGB", CalRGB)
PDF_MAKE_NAME("CapHeight", CapHeight)
PDF_MAKE_NAME("Caption", Caption)
PDF_MAKE_NAME("Caret", Caret)
PDF_MAKE_NAME("Catalog", Catalog)
PDF_MAKE_NAME("Cert", Cert)
PDF_MAKE_NAME("Ch", Ch)
PDF_MAKE_NAME("Changes", Changes)
PDF_MAKE_NAME("CharProcs", CharProcs)
PDF_MAKE_NAME("CheckSum", CheckSum)
PDF_MAKE_NAME("Circle", Circle)
PDF_MAKE_NAME("ClosedArrow", ClosedArrow)
PDF_MAKE_NAME("Code", Code)
PDF_MAKE_NAME("Collection", Collection)
PDF_MAKE_NAME("ColorSpace", ColorSpace)
PDF_MAKE_NAME("ColorTransform", ColorTransform)
PDF_MAKE_NAME("Colorants", Colorants)
PDF_MAKE_NAME("Colors", Colors)
PDF_MAKE_NAME("Columns", Columns)
PDF_MAKE_NAME("Confidential", Confidential)
PDF_MAKE_NAME("Configs", Configs)
PDF_MAKE_NAME("ContactInfo", ContactInfo)
PDF_MAKE_NAME("Contents", Contents)
PDF_MAKE_NAME("Coords", Coords)
PDF_MAKE_NAME("Count", Count)
PDF_MAKE_NAME("Cover", Cover)
PDF_MAKE_NAME("CreationDate", CreationDate)
PDF_MAKE_NAME("Creator", Creator)
PDF_MAKE_NAME("CropBox", CropBox)
PDF_MAKE_NAME("Crypt", Crypt)
PDF_MAKE_NAME("D", D)
PDF_MAKE_NAME("DA", DA)
PDF_MAKE_NAME("DC", DC)
PDF_MAKE_NAME("DCT", DCT)
PDF_MAKE_NAME("DCTDecode", DCTDecode)
PDF_MAKE_NAME("DL", DL)
PDF_MAKE_NAME("DOS", DOS)
PDF_MAKE_NAME("DP", DP)
PDF_MAKE_NAME("DR", DR)
PDF_MAKE_NAME("DS", DS)
PDF_MAKE_NAME("DV", DV)
PDF_MAKE_NAME("DW", DW)
PDF_MAKE_NAME("DW2", DW2)
PDF_MAKE_NAME("DamagedRowsBeforeError", DamagedRowsBeforeError)
PDF_MAKE_NAME("Data", Data)
PDF_MAKE_NAME("Date", Date)
PDF_MAKE_NAME("Decode", Decode)
PDF_MAKE_NAME("DecodeParms", DecodeParms)
PDF_MAKE_NAME("Default", Default)
PDF_MAKE_NAME("DefaultCMYK", DefaultCMYK)
PDF_MAKE_NAME("DefaultGray", DefaultGray)
PDF_MAKE_NAME("DefaultRGB", DefaultRGB)
PDF_MAKE_NAME("Departmental", Departmental)
PDF_MAKE_NAME("Desc", Desc)
PDF_MAKE_NAME("DescendantFonts", DescendantFonts)
PDF_MAKE_NAME("Descent", Descent)
PDF_MAKE_NAME("Design", Design)
PDF_MAKE_NAME("Dest", Dest)
PDF_MAKE_NAME("DestOutputProfile", DestOutputProfile)
PDF_MAKE_NAME("Dests", Dests)
PDF_MAKE_NAME("DeviceCMYK", DeviceCMYK)
PDF_MAKE_NAME("DeviceGray", DeviceGray)
PDF_MAKE_NAME("DeviceN", DeviceN)
PDF_MAKE_NAME("DeviceRGB", DeviceRGB)
PDF_MAKE_NAME("Di", Di)
PDF_MAKE_NAME("Diamond", Diamond)
PDF_MAKE_NAME("Differences", Differences)
PDF_MAKE_NAME("DigestLocation", DigestLocation)
PDF_MAKE_NAME("DigestMethod", DigestMethod)
PDF_MAKE_NAME("DigestValue", DigestValue)
PDF_MAKE_NAME("Dissolve", Dissolve)
PDF_MAKE_NAME("Div", Div)
PDF_MAKE_NAME("Dm", Dm)
PDF_MAKE_NAME("DocMDP", DocMDP)
PDF_MAKE_NAME("Document", Document)
PDF_MAKE_NAME("DocumentFragment", DocumentFragment)
PDF_MAKE_NAME("Domain", Domain)
PDF_MAKE_NAME("Draft", Draft)
PDF_MAKE_NAME("Dur", Dur)
PDF_MAKE_NAME("E", E)
PDF_MAKE_NAME("EF", EF)
PDF_MAKE_NAME("EarlyChange", EarlyChange)
PDF_MAKE_NAME("Em", Em)
PDF_MAKE_NAME("EmbeddedFile", EmbeddedFile)
PDF_MAKE_NAME("EmbeddedFiles", EmbeddedFiles)
PDF_MAKE_NAME("Encode", Encode)
PDF_MAKE_NAME("EncodedByteAlign", EncodedByteAlign)
PDF_MAKE_NAME("Encoding", Encoding)
PDF_MAKE_NAME("Encrypt", Encrypt)
PDF_MAKE_NAME("EncryptMetadata", EncryptMetadata)
PDF_MAKE_NAME("EndOfBlock", EndOfBlock)
PDF_MAKE_NAME("EndOfLine", EndOfLine)
PDF_MAKE_NAME("Exclude", Exclude)
PDF_MAKE_NAME("Experimental", Experimental)
PDF_MAKE_NAME("Expired", Expired)
PDF_MAKE_NAME("ExtGState", ExtGState)
PDF_MAKE_NAME("Extend", Extend)
PDF_MAKE_NAME("F", F)
PDF_MAKE_NAME("FENote", FENote)
PDF_MAKE_NAME("FL", FL)
PDF_MAKE_NAME("FRM", FRM)
PDF_MAKE_NAME("FS", FS)
PDF_MAKE_NAME("FT", FT)
PDF_MAKE_NAME("Fade", Fade)
PDF_MAKE_NAME("Ff", Ff)
PDF_MAKE_NAME("FieldMDP", FieldMDP)
PDF_MAKE_NAME("Fields", Fields)
PDF_MAKE_NAME("Figure", Figure)
PDF_MAKE_NAME("FileAttachment", FileAttachment)
PDF_MAKE_NAME("FileSize", FileSize)
PDF_MAKE_NAME("Filespec", Filespec)
PDF_MAKE_NAME("Filter", Filter)
PDF_MAKE_NAME("Final", Final)
PDF_MAKE_NAME("Fingerprint", Fingerprint)
PDF_MAKE_NAME("First", First)
PDF_MAKE_NAME("FirstChar", FirstChar)
PDF_MAKE_NAME("FirstPage", FirstPage)
PDF_MAKE_NAME("Fit", Fit)
PDF_MAKE_NAME("FitB", FitB)
PDF_MAKE_NAME("FitBH", FitBH)
PDF_MAKE_NAME("FitBV", FitBV)
PDF_MAKE_NAME("FitH", FitH)
PDF_MAKE_NAME("FitR", FitR)
PDF_MAKE_NAME("FitV", FitV)
PDF_MAKE_NAME("Fl", Fl)
PDF_MAKE_NAME("Flags", Flags)
PDF_MAKE_NAME("FlateDecode", FlateDecode)
PDF_MAKE_NAME("Fly", Fly)
PDF_MAKE_NAME("Font", Font)
PDF_MAKE_NAME("FontBBox", FontBBox)
PDF_MAKE_NAME("FontDescriptor", FontDescriptor)
PDF_MAKE_NAME("FontFile", FontFile)
PDF_MAKE_NAME("FontFile2", FontFile2)
PDF_MAKE_NAME("FontFile3", FontFile3)
PDF_MAKE_NAME("FontMatrix", FontMatrix)
PDF_MAKE_NAME("FontName", FontName)
PDF_MAKE_NAME("ForComment", ForComment)
PDF_MAKE_NAME("ForPublicRelease", ForPublicRelease)
PDF_MAKE_NAME("Form", Form)
PDF_MAKE_NAME("FormEx", FormEx)
PDF_MAKE_NAME("FormType", FormType)
PDF_MAKE_NAME("Formula", Formula)
PDF_MAKE_NAME("FreeText", FreeText)
PDF_MAKE_NAME("Function", Function)
PDF_MAKE_NAME("FunctionType", FunctionType)
PDF_MAKE_NAME("Functions", Functions)
PDF_MAKE_NAME("G", G)
PDF_MAKE_NAME("GTS_PDFX", GTS_PDFX)
PDF_MAKE_NAME("Gamma", Gamma)
PDF_MAKE_NAME("Glitter", Glitter)
PDF_MAKE_NAME("GoTo", GoTo)
PDF_MAKE_NAME("GoToR", GoToR)
PDF_MAKE_NAME("Group", Group)
PDF_MAKE_NAME("H", H)
PDF_MAKE_NAME("H1", H1)
PDF_MAKE_NAME("H2", H2)
PDF_MAKE_NAME("H3", H3)
PDF_MAKE_NAME("H4", H4)
PDF_MAKE_NAME("H5", H5)
PDF_MAKE_NAME("H6", H6)
PDF_MAKE_NAME("Height", Height)
PDF_MAKE_NAME("Helv", Helv)
PDF_MAKE_NAME("Highlight", Highlight)
PDF_MAKE_NAME("HistoryPos", HistoryPos)
PDF_MAKE_NAME("I", I)
PDF_MAKE_NAME("IC", IC)
PDF_MAKE_NAME("ICCBased", ICCBased)
PDF_MAKE_NAME("ID", ID)
PDF_MAKE_NAME("IM", IM)
PDF_MAKE_NAME("IRT", IRT)
PDF_MAKE_NAME("Identity", Identity)
PDF_MAKE_NAME("Identity-H", Identity_H)
PDF_MAKE_NAME("Identity-V", Identity_V)
PDF_MAKE_NAME("Image", Image)
PDF_MAKE_NAME("ImageB", ImageB)
PDF_MAKE_NAME("ImageC", ImageC)
PDF_MAKE_NAME("ImageI", ImageI)
PDF_MAKE_NAME("ImageMask", ImageMask)
PDF_MAKE_NAME("Include", Include)
PDF_MAKE_NAME("Index", Index)
PDF_MAKE_NAME("Indexed", Indexed)
PDF_MAKE_NAME("Info", Info)
PDF_MAKE_NAME("Ink", Ink)
PDF_MAKE_NAME("InkList", InkList)
PDF_MAKE_NAME("Intent", Intent)
PDF_MAKE_NAME("Interpolate", Interpolate)
PDF_MAKE_NAME("IsMap", IsMap)
PDF_MAKE_NAME("ItalicAngle", ItalicAngle)
PDF_MAKE_NAME("JBIG2Decode", JBIG2Decode)
PDF_MAKE_NAME("JBIG2Globals", JBIG2Globals)
PDF_MAKE_NAME("JPXDecode", JPXDecode)
PDF_MAKE_NAME("JS", JS)
PDF_MAKE_NAME("JavaScript", JavaScript)
PDF_MAKE_NAME("K", K)
PDF_MAKE_NAME("Keywords", Keywords)
PDF_MAKE_NAME("Kids", Kids)
PDF_MAKE_NAME("L", L)
PDF_MAKE_NAME("LBody", LBody)
PDF_MAKE_NAME("LC", LC)
PDF_MAKE_NAME("LE", LE)
PDF_MAKE_NAME("LI", LI)
PDF_MAKE_NAME("LJ", LJ)
PDF_MAKE_NAME("LW", LW)
PDF_MAKE_NAME("LZ", LZ)
PDF_MAKE_NAME("LZW", LZW)
PDF_MAKE_NAME("LZWDecode", LZWDecode)
PDF_MAKE_NAME("Lab", Lab)
PDF_MAKE_NAME("Label", Label)
PDF_MAKE_NAME("Lang", Lang)
PDF_MAKE_NAME("Last", Last)
PDF_MAKE_NAME("LastChar", LastChar)
PDF_MAKE_NAME("LastPage", LastPage)
PDF_MAKE_NAME("Launch", Launch)
PDF_MAKE_NAME("Layer", Layer)
PDF_MAKE_NAME("Lbl", Lbl)
PDF_MAKE_NAME("Length", Length)
PDF_MAKE_NAME("Length1", Length1)
PDF_MAKE_NAME("Length2", Length2)
PDF_MAKE_NAME("Length3", Length3)
PDF_MAKE_NAME("Limits", Limits)
PDF_MAKE_NAME("Line", Line)
PDF_MAKE_NAME("Linearized", Linearized)
PDF_MAKE_NAME("Link", Link)
PDF_MAKE_NAME("List", List)
PDF_MAKE_NAME("Location", Location)
PDF_MAKE_NAME("Lock", Lock)
PDF_MAKE_NAME("Locked", Locked)
PDF_MAKE_NAME("Luminosity", Luminosity)
PDF_MAKE_NAME("M", M)
PDF_MAKE_NAME("MCID", MCID)
PDF_MAKE_NAME("MK", MK)
PDF_MAKE_NAME("ML", ML)
PDF_MAKE_NAME("MMType1", MMType1)
PDF_MAKE_NAME("Mac", Mac)
PDF_MAKE_NAME("Mask", Mask)
PDF_MAKE_NAME("Matrix", Matrix)
PDF_MAKE_NAME("Matte", Matte)
PDF_MAKE_NAME("MaxLen", MaxLen)
PDF_MAKE_NAME("MediaBox", MediaBox)
PDF_MAKE_NAME("Metadata", Metadata)
PDF_MAKE_NAME("MissingWidth", MissingWidth)
PDF_MAKE_NAME("ModDate", ModDate)
PDF_MAKE_NAME("Movie", Movie)
PDF_MAKE_NAME("Msg", Msg)
PDF_MAKE_NAME("Multiply", Multiply)
PDF_MAKE_NAME("N", N)
PDF_MAKE_NAME("Name", Name)
PDF_MAKE_NAME("Named", Named)
PDF_MAKE_NAME("Names", Names)
PDF_MAKE_NAME("NewWindow", NewWindow)
PDF_MAKE_NAME("Next", Next)
PDF_MAKE_NAME("NextPage", NextPage)
PDF_MAKE_NAME("NonEFontNoWarn", NonEFontNoWarn)
PDF_MAKE_NAME("NonStruct", NonStruct)
PDF_MAKE_NAME("None", None)
PDF_MAKE_NAME("Normal", Normal)
PDF_MAKE_NAME("NotApproved", NotApproved)
PDF_MAKE_NAME("NotForPublicRelease", NotForPublicRelease)
PDF_MAKE_NAME("Note", Note)
PDF_MAKE_NAME("NumSections", NumSections)
PDF_MAKE_NAME("Nums", Nums)
PDF_MAKE_NAME("O", O)
PDF_MAKE_NAME("OC", OC)
PDF_MAKE_NAME("OCG", OCG)
PDF_MAKE_NAME("OCGs", OCGs)
PDF_MAKE_NAME("OCMD", OCMD)
PDF_MAKE_NAME("OCProperties", OCProperties)
PDF_MAKE_NAME("OE", OE)
PDF_MAKE_NAME("OFF", OFF)
PDF_MAKE_NAME("ON", ON)
PDF_MAKE_NAME("OP", OP)
PDF_MAKE_NAME("OPM", OPM)
PDF_MAKE_NAME("OS", OS)
PDF_MAKE_NAME("ObjStm", ObjStm)
PDF_MAKE_NAME("Of", Of)
PDF_MAKE_NAME("Off", Off)
PDF_MAKE_NAME("Open", Open)
PDF_MAKE_NAME("OpenArrow", OpenArrow)
PDF_MAKE_NAME("OpenType", OpenType)
PDF_MAKE_NAME("Opt", Opt)
PDF_MAKE_NAME("Order", Order)
PDF_MAKE_NAME("Ordering", Ordering)
PDF_MAKE_NAME("Outlines", Outlines)
PDF_MAKE_NAME("OutputCondition", OutputCondition)
PDF_MAKE_NAME("OutputConditionIdentifier", OutputConditionIdentifier)
PDF_MAKE_NAME("OutputIntent", OutputIntent)
PDF_MAKE_NAME("OutputIntents", OutputIntents)
PDF_MAKE_NAME("P", P)
PDF_MAKE_NAME("PDF", PDF)
PDF_MAKE_NAME("PS", PS)
PDF_MAKE_NAME("Page", Page)
PDF_MAKE_NAME("PageLabels", PageLabels)
PDF_MAKE_NAME("PageMode", PageMode)
PDF_MAKE_NAME("Pages", Pages)
PDF_MAKE_NAME("PaintType", PaintType)
PDF_MAKE_NAME("Params", Params)
PDF_MAKE_NAME("Parent", Parent)
PDF_MAKE_NAME("ParentTree", ParentTree)
PDF_MAKE_NAME("Part", Part)
PDF_MAKE_NAME("Pattern", Pattern)
PDF_MAKE_NAME("PatternType", PatternType)
PDF_MAKE_NAME("Perms", Perms)
PDF_MAKE_NAME("PolyLine", PolyLine)
PDF_MAKE_NAME("Polygon", Polygon)
PDF_MAKE_NAME("Popup", Popup)
PDF_MAKE_NAME("PreRelease", PreRelease)
PDF_MAKE_NAME("Predictor", Predictor)
PDF_MAKE_NAME("Prev", Prev)
PDF_MAKE_NAME("PrevPage", PrevPage)
PDF_MAKE_NAME("Preview", Preview)
PDF_MAKE_NAME("Print", Print)
PDF_MAKE_NAME("PrinterMark", PrinterMark)
PDF_MAKE_NAME("Private", Private)
PDF_MAKE_NAME("ProcSet", ProcSet)
PDF_MAKE_NAME("Producer", Producer)
PDF_MAKE_NAME("Prop_AuthTime", Prop_AuthTime)
PDF_MAKE_NAME("Prop_AuthType", Prop_AuthType)
PDF_MAKE_NAME("Prop_Build", Prop_Build)
PDF_MAKE_NAME("Properties", Properties)
PDF_MAKE_NAME("PubSec", PubSec)
PDF_MAKE_NAME("Push", Push)
PDF_MAKE_NAME("Q", Q)
PDF_MAKE_NAME("QuadPoints", QuadPoints)
PDF_MAKE_NAME("Quote", Quote)
PDF_MAKE_NAME("R", R)
PDF_MAKE_NAME("RB", RB)
PDF_MAKE_NAME("RBGroups", RBGroups)
PDF_MAKE_NAME("RC", RC)
PDF_MAKE_NAME("RClosedArrow", RClosedArrow)
PDF_MAKE_NAME("RD", RD)
PDF_MAKE_NAME("REx", REx)
PDF_MAKE_NAME("RGB", RGB)
PDF_MAKE_NAME("RI", RI)
PDF_MAKE_NAME("RL", RL)
PDF_MAKE_NAME("ROpenArrow", ROpenArrow)
PDF_MAKE_NAME("RP", RP)
PDF_MAKE_NAME("RT", RT)
PDF_MAKE_NAME("Range", Range)
PDF_MAKE_NAME("Reason", Reason)
PDF_MAKE_NAME("Rect", Rect)
PDF_MAKE_NAME("Redact", Redact)
PDF_MAKE_NAME("Ref", Ref)
PDF_MAKE_NAME("Reference", Reference)
PDF_MAKE_NAME("Registry", Registry)
PDF_MAKE_NAME("ResetForm", ResetForm)
PDF_MAKE_NAME("Resources", Resources)
PDF_MAKE_NAME("RoleMap", RoleMap)
PDF_MAKE_NAME("Root", Root)
PDF_MAKE_NAME("Rotate", Rotate)
PDF_MAKE_NAME("Rows", Rows)
PDF_MAKE_NAME("Ruby", Ruby)
PDF_MAKE_NAME("RunLengthDecode", RunLengthDecode)
PDF_MAKE_NAME("S", S)
PDF_MAKE_NAME("SMask", SMask)
PDF_MAKE_NAME("SMaskInData", SMaskInData)
PDF_MAKE_NAME("Schema", Schema)
PDF_MAKE_NAME("Screen", Screen)
PDF_MAKE_NAME("Sect", Sect)
PDF_MAKE_NAME("Separation", Separation)
PDF_MAKE_NAME("Shading", Shading)
PDF_MAKE_NAME("ShadingType", ShadingType)
PDF_MAKE_NAME("Si", Si)
PDF_MAKE_NAME("Sig", Sig)
PDF_MAKE_NAME("SigFlags", SigFlags)
PDF_MAKE_NAME("SigQ", SigQ)
PDF_MAKE_NAME("SigRef", SigRef)
PDF_MAKE_NAME("Size", Size)
PDF_MAKE_NAME("Slash", Slash)
PDF_MAKE_NAME("Sold", Sold)
PDF_MAKE_NAME("Sound", Sound)
PDF_MAKE_NAME("Span", Span)
PDF_MAKE_NAME("Split", Split)
PDF_MAKE_NAME("Square", Square)
PDF_MAKE_NAME("Squiggly", Squiggly)
PDF_MAKE_NAME("St", St)
PDF_MAKE_NAME("Stamp", Stamp)
PDF_MAKE_NAME("Standard", Standard)
PDF_MAKE_NAME("StdCF", StdCF)
PDF_MAKE_NAME("StemV", StemV)
PDF_MAKE_NAME("StmF", StmF)
PDF_MAKE_NAME("StrF", StrF)
PDF_MAKE_NAME("StrikeOut", StrikeOut)
PDF_MAKE_NAME("Strong", Strong)
PDF_MAKE_NAME("StructParent", StructParent)
PDF_MAKE_NAME("StructParents", StructParents)
PDF_MAKE_NAME("StructTreeRoot", StructTreeRoot)
PDF_MAKE_NAME("Sub", Sub)
PDF_MAKE_NAME("SubFilter", SubFilter)
PDF_MAKE_NAME("Subject", Subject)
PDF_MAKE_NAME("Subtype", Subtype)
PDF_MAKE_NAME("Subtype2", Subtype2)
PDF_MAKE_NAME("Supplement", Supplement)
PDF_MAKE_NAME("Symb", Symb)
PDF_MAKE_NAME("T", T)
PDF_MAKE_NAME("TBody", TBody)
PDF_MAKE_NAME("TD", TD)
PDF_MAKE_NAME("TFoot", TFoot)
PDF_MAKE_NAME("TH", TH)
PDF_MAKE_NAME("THead", THead)
PDF_MAKE_NAME("TI", TI)
PDF_MAKE_NAME("TOC", TOC)
PDF_MAKE_NAME("TOCI", TOCI)
PDF_MAKE_NAME("TR", TR)
PDF_MAKE_NAME("TR2", TR2)
PDF_MAKE_NAME("TU", TU)
PDF_MAKE_NAME("Table", Table)
PDF_MAKE_NAME("Text", Text)
PDF_MAKE_NAME("TilingType", TilingType)
PDF_MAKE_NAME("Times", Times)
PDF_MAKE_NAME("Title", Title)
PDF_MAKE_NAME("ToUnicode", ToUnicode)
PDF_MAKE_NAME("TopSecret", TopSecret)
PDF_MAKE_NAME("Trans", Trans)
PDF_MAKE_NAME("TransformMethod", TransformMethod)
PDF_MAKE_NAME("TransformParams", TransformParams)
PDF_MAKE_NAME("Transparency", Transparency)
PDF_MAKE_NAME("TrapNet", TrapNet)
PDF_MAKE_NAME("TrimBox", TrimBox)
PDF_MAKE_NAME("TrueType", TrueType)
PDF_MAKE_NAME("TrustedMode", TrustedMode)
PDF_MAKE_NAME("Tx", Tx)
PDF_MAKE_NAME("Type", Type)
PDF_MAKE_NAME("Type0", Type0)
PDF_MAKE_NAME("Type1", Type1)
PDF_MAKE_NAME("Type1C", Type1C)
PDF_MAKE_NAME("Type3", Type3)
PDF_MAKE_NAME("U", U)
PDF_MAKE_NAME("UE", UE)
PDF_MAKE_NAME("UF", UF)
PDF_MAKE_NAME("URI", URI)
PDF_MAKE_NAME("URL", URL)
PDF_MAKE_NAME("Unchanged", Unchanged)
PDF_MAKE_NAME("Uncover", Uncover)
PDF_MAKE_NAME("Underline", Underline)
PDF_MAKE_NAME("Unix", Unix)
PDF_MAKE_NAME("Usage", Usage)
PDF_MAKE_NAME("UseBlackPtComp", UseBlackPtComp)
PDF_MAKE_NAME("UseCMap", UseCMap)
PDF_MAKE_NAME("UseOutlines", UseOutlines)
PDF_MAKE_NAME("UserUnit", UserUnit)
PDF_MAKE_NAME("V", V)
PDF_MAKE_NAME("V2", V2)
PDF_MAKE_NAME("VE", VE)
PDF_MAKE_NAME("Version", Version)
PDF_MAKE_NAME("Vertices", Vertices)
PDF_MAKE_NAME("VerticesPerRow", VerticesPerRow)
PDF_MAKE_NAME("View", View)
PDF_MAKE_NAME("W", W)
PDF_MAKE_NAME("W2", W2)
PDF_MAKE_NAME("WMode", WMode)
PDF_MAKE_NAME("WP", WP)
PDF_MAKE_NAME("WT", WT)
PDF_MAKE_NAME("Warichu", Warichu)
PDF_MAKE_NAME("Watermark", Watermark)
PDF_MAKE_NAME("WhitePoint", WhitePoint)
PDF_MAKE_NAME("Widget", Widget)
PDF_MAKE_NAME("Width", Width)
PDF_MAKE_NAME("Widths", Widths)
PDF_MAKE_NAME("WinAnsiEncoding", WinAnsiEncoding)
PDF_MAKE_NAME("Wipe", Wipe)
PDF_MAKE_NAME("XFA", XFA)
PDF_MAKE_NAME("XHeight", XHeight)
PDF_MAKE_NAME("XML", XML)
PDF_MAKE_NAME("XObject", XObject)
PDF_MAKE_NAME("XRef", XRef)
PDF_MAKE_NAME("XRefStm", XRefStm)
PDF_MAKE_NAME("XStep", XStep)
PDF_MAKE_NAME("XYZ", XYZ)
PDF_MAKE_NAME("YStep", YStep)
PDF_MAKE_NAME("Yes", Yes)
PDF_MAKE_NAME("ZaDb", ZaDb)
PDF_MAKE_NAME("a", a)
PDF_MAKE_NAME("adbe.pkcs7.detached", adbe_pkcs7_detached)
PDF_MAKE_NAME("ca", ca)
PDF_MAKE_NAME("n0", n0)
PDF_MAKE_NAME("n1", n1)
PDF_MAKE_NAME("n2", n2)
PDF_MAKE_NAME("op", op)
PDF_MAKE_NAME("r", r)

406
include/mupdf/pdf/object.h Normal file
View File

@ -0,0 +1,406 @@
// Copyright (C) 2004-2021 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_PDF_OBJECT_H
#define MUPDF_PDF_OBJECT_H
#include "mupdf/fitz/stream.h"
typedef struct pdf_document pdf_document;
typedef struct pdf_crypt pdf_crypt;
typedef struct pdf_journal pdf_journal;
/* Defined in PDF 1.7 according to Acrobat limit. */
#define PDF_MAX_OBJECT_NUMBER 8388607
#define PDF_MAX_GEN_NUMBER 65535
/*
* Dynamic objects.
* The same type of objects as found in PDF and PostScript.
* Used by the filters and the mupdf parser.
*/
typedef struct pdf_obj pdf_obj;
pdf_obj *pdf_new_int(fz_context *ctx, int64_t i);
pdf_obj *pdf_new_real(fz_context *ctx, float f);
pdf_obj *pdf_new_name(fz_context *ctx, const char *str);
pdf_obj *pdf_new_string(fz_context *ctx, const char *str, size_t len);
/*
Create a PDF 'text string' by encoding input string as either ASCII or UTF-16BE.
In theory, we could also use PDFDocEncoding.
*/
pdf_obj *pdf_new_text_string(fz_context *ctx, const char *s);
pdf_obj *pdf_new_indirect(fz_context *ctx, pdf_document *doc, int num, int gen);
pdf_obj *pdf_new_array(fz_context *ctx, pdf_document *doc, int initialcap);
pdf_obj *pdf_new_dict(fz_context *ctx, pdf_document *doc, int initialcap);
pdf_obj *pdf_new_rect(fz_context *ctx, pdf_document *doc, fz_rect rect);
pdf_obj *pdf_new_matrix(fz_context *ctx, pdf_document *doc, fz_matrix mtx);
pdf_obj *pdf_new_date(fz_context *ctx, pdf_document *doc, int64_t time);
pdf_obj *pdf_copy_array(fz_context *ctx, pdf_obj *array);
pdf_obj *pdf_copy_dict(fz_context *ctx, pdf_obj *dict);
pdf_obj *pdf_deep_copy_obj(fz_context *ctx, pdf_obj *obj);
pdf_obj *pdf_keep_obj(fz_context *ctx, pdf_obj *obj);
void pdf_drop_obj(fz_context *ctx, pdf_obj *obj);
pdf_obj *pdf_drop_singleton_obj(fz_context *ctx, pdf_obj *obj);
int pdf_is_null(fz_context *ctx, pdf_obj *obj);
int pdf_is_bool(fz_context *ctx, pdf_obj *obj);
int pdf_is_int(fz_context *ctx, pdf_obj *obj);
int pdf_is_real(fz_context *ctx, pdf_obj *obj);
int pdf_is_number(fz_context *ctx, pdf_obj *obj);
int pdf_is_name(fz_context *ctx, pdf_obj *obj);
int pdf_is_string(fz_context *ctx, pdf_obj *obj);
int pdf_is_array(fz_context *ctx, pdf_obj *obj);
int pdf_is_dict(fz_context *ctx, pdf_obj *obj);
int pdf_is_indirect(fz_context *ctx, pdf_obj *obj);
/*
Check if an object is a stream or not.
*/
int pdf_obj_num_is_stream(fz_context *ctx, pdf_document *doc, int num);
int pdf_is_stream(fz_context *ctx, pdf_obj *obj);
/* Compare 2 objects. Returns 0 on match, non-zero on mismatch.
* Streams always mismatch.
*/
int pdf_objcmp(fz_context *ctx, pdf_obj *a, pdf_obj *b);
int pdf_objcmp_resolve(fz_context *ctx, pdf_obj *a, pdf_obj *b);
/* Compare 2 objects. Returns 0 on match, non-zero on mismatch.
* Stream contents are explicitly checked.
*/
int pdf_objcmp_deep(fz_context *ctx, pdf_obj *a, pdf_obj *b);
int pdf_name_eq(fz_context *ctx, pdf_obj *a, pdf_obj *b);
int pdf_obj_marked(fz_context *ctx, pdf_obj *obj);
int pdf_mark_obj(fz_context *ctx, pdf_obj *obj);
void pdf_unmark_obj(fz_context *ctx, pdf_obj *obj);
typedef struct pdf_cycle_list pdf_cycle_list;
struct pdf_cycle_list {
pdf_cycle_list *up;
int num;
};
int pdf_cycle(fz_context *ctx, pdf_cycle_list *here, pdf_cycle_list *prev, pdf_obj *obj);
typedef struct
{
int len;
unsigned char bits[1];
} pdf_mark_bits;
pdf_mark_bits *pdf_new_mark_bits(fz_context *ctx, pdf_document *doc);
void pdf_drop_mark_bits(fz_context *ctx, pdf_mark_bits *marks);
void pdf_mark_bits_reset(fz_context *ctx, pdf_mark_bits *marks);
int pdf_mark_bits_set(fz_context *ctx, pdf_mark_bits *marks, pdf_obj *obj);
typedef struct
{
int len;
int max;
int *list;
int local_list[8];
} pdf_mark_list;
int pdf_mark_list_push(fz_context *ctx, pdf_mark_list *list, pdf_obj *obj);
void pdf_mark_list_pop(fz_context *ctx, pdf_mark_list *list);
void pdf_mark_list_init(fz_context *ctx, pdf_mark_list *list);
void pdf_mark_list_free(fz_context *ctx, pdf_mark_list *list);
void pdf_set_obj_memo(fz_context *ctx, pdf_obj *obj, int bit, int memo);
int pdf_obj_memo(fz_context *ctx, pdf_obj *obj, int bit, int *memo);
int pdf_obj_is_dirty(fz_context *ctx, pdf_obj *obj);
void pdf_dirty_obj(fz_context *ctx, pdf_obj *obj);
void pdf_clean_obj(fz_context *ctx, pdf_obj *obj);
int pdf_to_bool(fz_context *ctx, pdf_obj *obj);
int pdf_to_int(fz_context *ctx, pdf_obj *obj);
int64_t pdf_to_int64(fz_context *ctx, pdf_obj *obj);
float pdf_to_real(fz_context *ctx, pdf_obj *obj);
const char *pdf_to_name(fz_context *ctx, pdf_obj *obj);
const char *pdf_to_text_string(fz_context *ctx, pdf_obj *obj);
const char *pdf_to_string(fz_context *ctx, pdf_obj *obj, size_t *sizep);
char *pdf_to_str_buf(fz_context *ctx, pdf_obj *obj);
size_t pdf_to_str_len(fz_context *ctx, pdf_obj *obj);
int pdf_to_num(fz_context *ctx, pdf_obj *obj);
int pdf_to_gen(fz_context *ctx, pdf_obj *obj);
int pdf_array_len(fz_context *ctx, pdf_obj *array);
pdf_obj *pdf_array_get(fz_context *ctx, pdf_obj *array, int i);
void pdf_array_put(fz_context *ctx, pdf_obj *array, int i, pdf_obj *obj);
void pdf_array_put_drop(fz_context *ctx, pdf_obj *array, int i, pdf_obj *obj);
void pdf_array_push(fz_context *ctx, pdf_obj *array, pdf_obj *obj);
void pdf_array_push_drop(fz_context *ctx, pdf_obj *array, pdf_obj *obj);
void pdf_array_insert(fz_context *ctx, pdf_obj *array, pdf_obj *obj, int index);
void pdf_array_insert_drop(fz_context *ctx, pdf_obj *array, pdf_obj *obj, int index);
void pdf_array_delete(fz_context *ctx, pdf_obj *array, int index);
int pdf_array_find(fz_context *ctx, pdf_obj *array, pdf_obj *obj);
int pdf_array_contains(fz_context *ctx, pdf_obj *array, pdf_obj *obj);
int pdf_dict_len(fz_context *ctx, pdf_obj *dict);
pdf_obj *pdf_dict_get_key(fz_context *ctx, pdf_obj *dict, int idx);
pdf_obj *pdf_dict_get_val(fz_context *ctx, pdf_obj *dict, int idx);
void pdf_dict_put_val_null(fz_context *ctx, pdf_obj *obj, int idx);
pdf_obj *pdf_dict_get(fz_context *ctx, pdf_obj *dict, pdf_obj *key);
pdf_obj *pdf_dict_getp(fz_context *ctx, pdf_obj *dict, const char *path);
pdf_obj *pdf_dict_getl(fz_context *ctx, pdf_obj *dict, ...);
pdf_obj *pdf_dict_geta(fz_context *ctx, pdf_obj *dict, pdf_obj *key, pdf_obj *abbrev);
pdf_obj *pdf_dict_gets(fz_context *ctx, pdf_obj *dict, const char *key);
pdf_obj *pdf_dict_getsa(fz_context *ctx, pdf_obj *dict, const char *key, const char *abbrev);
pdf_obj *pdf_dict_get_inheritable(fz_context *ctx, pdf_obj *dict, pdf_obj *key);
pdf_obj *pdf_dict_getp_inheritable(fz_context *ctx, pdf_obj *dict, const char *path);
pdf_obj *pdf_dict_gets_inheritable(fz_context *ctx, pdf_obj *dict, const char *key);
void pdf_dict_put(fz_context *ctx, pdf_obj *dict, pdf_obj *key, pdf_obj *val);
void pdf_dict_put_drop(fz_context *ctx, pdf_obj *dict, pdf_obj *key, pdf_obj *val);
void pdf_dict_get_put_drop(fz_context *ctx, pdf_obj *dict, pdf_obj *key, pdf_obj *val, pdf_obj **old_val);
void pdf_dict_puts(fz_context *ctx, pdf_obj *dict, const char *key, pdf_obj *val);
void pdf_dict_puts_drop(fz_context *ctx, pdf_obj *dict, const char *key, pdf_obj *val);
void pdf_dict_putp(fz_context *ctx, pdf_obj *dict, const char *path, pdf_obj *val);
void pdf_dict_putp_drop(fz_context *ctx, pdf_obj *dict, const char *path, pdf_obj *val);
void pdf_dict_putl(fz_context *ctx, pdf_obj *dict, pdf_obj *val, ...);
void pdf_dict_putl_drop(fz_context *ctx, pdf_obj *dict, pdf_obj *val, ...);
void pdf_dict_del(fz_context *ctx, pdf_obj *dict, pdf_obj *key);
void pdf_dict_dels(fz_context *ctx, pdf_obj *dict, const char *key);
void pdf_sort_dict(fz_context *ctx, pdf_obj *dict);
void pdf_dict_put_bool(fz_context *ctx, pdf_obj *dict, pdf_obj *key, int x);
void pdf_dict_put_int(fz_context *ctx, pdf_obj *dict, pdf_obj *key, int64_t x);
void pdf_dict_put_real(fz_context *ctx, pdf_obj *dict, pdf_obj *key, double x);
void pdf_dict_put_name(fz_context *ctx, pdf_obj *dict, pdf_obj *key, const char *x);
void pdf_dict_put_string(fz_context *ctx, pdf_obj *dict, pdf_obj *key, const char *x, size_t n);
void pdf_dict_put_text_string(fz_context *ctx, pdf_obj *dict, pdf_obj *key, const char *x);
void pdf_dict_put_rect(fz_context *ctx, pdf_obj *dict, pdf_obj *key, fz_rect x);
void pdf_dict_put_matrix(fz_context *ctx, pdf_obj *dict, pdf_obj *key, fz_matrix x);
void pdf_dict_put_date(fz_context *ctx, pdf_obj *dict, pdf_obj *key, int64_t time);
pdf_obj *pdf_dict_put_array(fz_context *ctx, pdf_obj *dict, pdf_obj *key, int initial);
pdf_obj *pdf_dict_put_dict(fz_context *ctx, pdf_obj *dict, pdf_obj *key, int initial);
pdf_obj *pdf_dict_puts_dict(fz_context *ctx, pdf_obj *dict, const char *key, int initial);
int pdf_dict_get_bool(fz_context *ctx, pdf_obj *dict, pdf_obj *key);
int pdf_dict_get_int(fz_context *ctx, pdf_obj *dict, pdf_obj *key);
int64_t pdf_dict_get_int64(fz_context *ctx, pdf_obj *dict, pdf_obj *key);
float pdf_dict_get_real(fz_context *ctx, pdf_obj *dict, pdf_obj *key);
const char *pdf_dict_get_name(fz_context *ctx, pdf_obj *dict, pdf_obj *key);
const char *pdf_dict_get_string(fz_context *ctx, pdf_obj *dict, pdf_obj *key, size_t *sizep);
const char *pdf_dict_get_text_string(fz_context *ctx, pdf_obj *dict, pdf_obj *key);
fz_rect pdf_dict_get_rect(fz_context *ctx, pdf_obj *dict, pdf_obj *key);
fz_matrix pdf_dict_get_matrix(fz_context *ctx, pdf_obj *dict, pdf_obj *key);
int64_t pdf_dict_get_date(fz_context *ctx, pdf_obj *dict, pdf_obj *key);
void pdf_array_push_bool(fz_context *ctx, pdf_obj *array, int x);
void pdf_array_push_int(fz_context *ctx, pdf_obj *array, int64_t x);
void pdf_array_push_real(fz_context *ctx, pdf_obj *array, double x);
void pdf_array_push_name(fz_context *ctx, pdf_obj *array, const char *x);
void pdf_array_push_string(fz_context *ctx, pdf_obj *array, const char *x, size_t n);
void pdf_array_push_text_string(fz_context *ctx, pdf_obj *array, const char *x);
pdf_obj *pdf_array_push_array(fz_context *ctx, pdf_obj *array, int initial);
pdf_obj *pdf_array_push_dict(fz_context *ctx, pdf_obj *array, int initial);
int pdf_array_get_bool(fz_context *ctx, pdf_obj *array, int index);
int pdf_array_get_int(fz_context *ctx, pdf_obj *array, int index);
float pdf_array_get_real(fz_context *ctx, pdf_obj *array, int index);
const char *pdf_array_get_name(fz_context *ctx, pdf_obj *array, int index);
const char *pdf_array_get_string(fz_context *ctx, pdf_obj *array, int index, size_t *sizep);
const char *pdf_array_get_text_string(fz_context *ctx, pdf_obj *array, int index);
fz_rect pdf_array_get_rect(fz_context *ctx, pdf_obj *array, int index);
fz_matrix pdf_array_get_matrix(fz_context *ctx, pdf_obj *array, int index);
void pdf_set_obj_parent(fz_context *ctx, pdf_obj *obj, int num);
int pdf_obj_refs(fz_context *ctx, pdf_obj *ref);
int pdf_obj_parent_num(fz_context *ctx, pdf_obj *obj);
char *pdf_sprint_obj(fz_context *ctx, char *buf, size_t cap, size_t *len, pdf_obj *obj, int tight, int ascii);
void pdf_print_obj(fz_context *ctx, fz_output *out, pdf_obj *obj, int tight, int ascii);
void pdf_print_encrypted_obj(fz_context *ctx, fz_output *out, pdf_obj *obj, int tight, int ascii, pdf_crypt *crypt, int num, int gen);
void pdf_debug_obj(fz_context *ctx, pdf_obj *obj);
void pdf_debug_ref(fz_context *ctx, pdf_obj *obj);
/*
Convert Unicode/PdfDocEncoding string into utf-8.
The returned string must be freed by the caller.
*/
char *pdf_new_utf8_from_pdf_string(fz_context *ctx, const char *srcptr, size_t srclen);
/*
Convert text string object to UTF-8.
The returned string must be freed by the caller.
*/
char *pdf_new_utf8_from_pdf_string_obj(fz_context *ctx, pdf_obj *src);
/*
Load text stream and convert to UTF-8.
The returned string must be freed by the caller.
*/
char *pdf_new_utf8_from_pdf_stream_obj(fz_context *ctx, pdf_obj *src);
/*
Load text stream or text string and convert to UTF-8.
The returned string must be freed by the caller.
*/
char *pdf_load_stream_or_string_as_utf8(fz_context *ctx, pdf_obj *src);
fz_quad pdf_to_quad(fz_context *ctx, pdf_obj *array, int offset);
fz_rect pdf_to_rect(fz_context *ctx, pdf_obj *array);
fz_matrix pdf_to_matrix(fz_context *ctx, pdf_obj *array);
int64_t pdf_to_date(fz_context *ctx, pdf_obj *time);
/*
pdf_get_indirect_document and pdf_get_bound_document are
now deprecated. Please do not use them in future. They will
be removed.
Please use pdf_pin_document instead.
*/
pdf_document *pdf_get_indirect_document(fz_context *ctx, pdf_obj *obj);
pdf_document *pdf_get_bound_document(fz_context *ctx, pdf_obj *obj);
/*
pdf_pin_document returns a new reference to the document
to which obj is bound. The caller is responsible for
dropping this reference once they have finished with it.
This is a replacement for pdf_get_indirect_document
and pdf_get_bound_document that are now deprecated. Those
returned a borrowed reference that did not need to be
dropped.
Note that this can validly return NULL in various cases:
1) When the object is of a simple type (such as a number
or a string), it contains no reference to the enclosing
document. 2) When the object has yet to be inserted into
a PDF document (such as during parsing). 3) And (in
future versions) when the document has been destroyed
but the object reference remains.
It is the caller's responsibility to deal with a NULL
return here.
*/
pdf_document *pdf_pin_document(fz_context *ctx, pdf_obj *obj);
void pdf_set_int(fz_context *ctx, pdf_obj *obj, int64_t i);
/* Voodoo to create PDF_NAME(Foo) macros from name-table.h */
#define PDF_NAME(X) ((pdf_obj*)(intptr_t)PDF_ENUM_NAME_##X)
#define PDF_MAKE_NAME(STRING,NAME) PDF_ENUM_NAME_##NAME,
enum {
PDF_ENUM_NULL,
PDF_ENUM_TRUE,
PDF_ENUM_FALSE,
#include "mupdf/pdf/name-table.h"
PDF_ENUM_LIMIT,
};
#undef PDF_MAKE_NAME
#define PDF_NULL ((pdf_obj*)(intptr_t)PDF_ENUM_NULL)
#define PDF_TRUE ((pdf_obj*)(intptr_t)PDF_ENUM_TRUE)
#define PDF_FALSE ((pdf_obj*)(intptr_t)PDF_ENUM_FALSE)
#define PDF_LIMIT ((pdf_obj*)(intptr_t)PDF_ENUM_LIMIT)
/* Implementation details: subject to change. */
/*
for use by pdf_crypt_obj_imp to decrypt AES string in place
*/
void pdf_set_str_len(fz_context *ctx, pdf_obj *obj, size_t newlen);
/* Journalling */
/* Call this to enable journalling on a given document. */
void pdf_enable_journal(fz_context *ctx, pdf_document *doc);
/* Call this to start an operation. Undo/redo works at 'operation'
* granularity. Nested operations are all counted within the outermost
* operation. Any modification performed on a journalled PDF without an
* operation having been started will throw an error. */
void pdf_begin_operation(fz_context *ctx, pdf_document *doc, const char *operation);
/* Call this to start an implicit operation. Implicit operations are
* operations that happen as a consequence of things like updating
* an annotation. They get rolled into the previous operation, because
* they generally happen as a result of them. */
void pdf_begin_implicit_operation(fz_context *ctx, pdf_document *doc);
/* Call this to end an operation. */
void pdf_end_operation(fz_context *ctx, pdf_document *doc);
/* Call this to abandon an operation. Revert to the state
* when you began. */
void pdf_abandon_operation(fz_context *ctx, pdf_document *doc);
/* Call this to find out how many undo/redo steps there are, and the
* current position we are within those. 0 = original document,
* *steps = final edited version. */
int pdf_undoredo_state(fz_context *ctx, pdf_document *doc, int *steps);
/* Call this to find the title of the operation within the undo state. */
const char *pdf_undoredo_step(fz_context *ctx, pdf_document *doc, int step);
/* Helper functions to identify if we are in a state to be able to undo
* or redo. */
int pdf_can_undo(fz_context *ctx, pdf_document *doc);
int pdf_can_redo(fz_context *ctx, pdf_document *doc);
/* Move backwards in the undo history. Throws an error if we are at the
* start. Any edits to the document at this point will discard all
* subsequent history. */
void pdf_undo(fz_context *ctx, pdf_document *doc);
/* Move forwards in the undo history. Throws an error if we are at the
* end. */
void pdf_redo(fz_context *ctx, pdf_document *doc);
/* Called to reset the entire history. This is called implicitly when
* a non-undoable change occurs (such as a pdf repair). */
void pdf_discard_journal(fz_context *ctx, pdf_journal *journal);
/* Internal destructor. */
void pdf_drop_journal(fz_context *ctx, pdf_journal *journal);
/* Internal call as part of saving a snapshot of a PDF document. */
void pdf_serialise_journal(fz_context *ctx, pdf_document *doc, fz_output *out);
/* Internal call as part of loading a snapshot of a PDF document. */
void pdf_deserialise_journal(fz_context *ctx, pdf_document *doc, fz_stream *stm);
/* Internal call as part of creating objects. */
void pdf_add_journal_fragment(fz_context *ctx, pdf_document *doc, int parent, pdf_obj *copy, fz_buffer *copy_stream, int newobj);
char *pdf_format_date(fz_context *ctx, int64_t time, char *s, size_t n);
int64_t pdf_parse_date(fz_context *ctx, const char *s);
#endif

200
include/mupdf/pdf/page.h Normal file
View File

@ -0,0 +1,200 @@
// Copyright (C) 2004-2021 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_PDF_PAGE_H
#define MUPDF_PDF_PAGE_H
#include "mupdf/pdf/interpret.h"
int pdf_lookup_page_number(fz_context *ctx, pdf_document *doc, pdf_obj *pageobj);
int pdf_count_pages(fz_context *ctx, pdf_document *doc);
int pdf_count_pages_imp(fz_context *ctx, fz_document *doc, int chapter);
pdf_obj *pdf_lookup_page_obj(fz_context *ctx, pdf_document *doc, int needle);
/*
Cache the page tree for fast forward/reverse page lookups.
No longer required. This is a No Op, now as page tree
maps are loaded automatically 'just in time'.
*/
void pdf_load_page_tree(fz_context *ctx, pdf_document *doc);
/*
Discard the page tree maps.
No longer required. This is a No Op, now as page tree
maps are discarded automatically 'just in time'.
*/
void pdf_drop_page_tree(fz_context *ctx, pdf_document *doc);
void pdf_drop_page_tree_internal(fz_context *ctx, pdf_document *doc);
/*
Make page self sufficient.
Copy any inheritable page keys into the actual page object, removing
any dependencies on the page tree parents.
*/
void pdf_flatten_inheritable_page_items(fz_context *ctx, pdf_obj *page);
/*
Load a page and its resources.
Locates the page in the PDF document and loads the page and its
resources. After pdf_load_page is it possible to retrieve the size
of the page using pdf_bound_page, or to render the page using
pdf_run_page_*.
number: page number, where 0 is the first page of the document.
*/
pdf_page *pdf_load_page(fz_context *ctx, pdf_document *doc, int number);
fz_page *pdf_load_page_imp(fz_context *ctx, fz_document *doc, int chapter, int number);
int pdf_page_has_transparency(fz_context *ctx, pdf_page *page);
void pdf_page_obj_transform(fz_context *ctx, pdf_obj *pageobj, fz_rect *page_mediabox, fz_matrix *page_ctm);
void pdf_page_transform(fz_context *ctx, pdf_page *page, fz_rect *mediabox, fz_matrix *ctm);
void pdf_page_obj_transform_box(fz_context *ctx, pdf_obj *pageobj, fz_rect *page_mediabox, fz_matrix *page_ctm, fz_box_type box);
void pdf_page_transform_box(fz_context *ctx, pdf_page *page, fz_rect *mediabox, fz_matrix *ctm, fz_box_type box);
pdf_obj *pdf_page_resources(fz_context *ctx, pdf_page *page);
pdf_obj *pdf_page_contents(fz_context *ctx, pdf_page *page);
pdf_obj *pdf_page_group(fz_context *ctx, pdf_page *page);
/*
Get the separation details for a page.
*/
fz_separations *pdf_page_separations(fz_context *ctx, pdf_page *page);
pdf_ocg_descriptor *pdf_read_ocg(fz_context *ctx, pdf_document *doc);
void pdf_drop_ocg(fz_context *ctx, pdf_document *doc);
int pdf_is_ocg_hidden(fz_context *ctx, pdf_document *doc, pdf_obj *rdb, const char *usage, pdf_obj *ocg);
fz_link *pdf_load_links(fz_context *ctx, pdf_page *page);
/*
Determine the size of a page.
Determine the page size in points, taking page rotation
into account. The page size is taken to be the crop box if it
exists (visible area after cropping), otherwise the media box will
be used (possibly including printing marks).
*/
fz_rect pdf_bound_page(fz_context *ctx, pdf_page *page, fz_box_type box);
/*
Interpret a loaded page and render it on a device.
page: A page loaded by pdf_load_page.
dev: Device used for rendering, obtained from fz_new_*_device.
ctm: A transformation matrix applied to the objects on the page,
e.g. to scale or rotate the page contents as desired.
*/
void pdf_run_page(fz_context *ctx, pdf_page *page, fz_device *dev, fz_matrix ctm, fz_cookie *cookie);
/*
Interpret a loaded page and render it on a device.
page: A page loaded by pdf_load_page.
dev: Device used for rendering, obtained from fz_new_*_device.
ctm: A transformation matrix applied to the objects on the page,
e.g. to scale or rotate the page contents as desired.
usage: The 'usage' for displaying the file (typically
'View', 'Print' or 'Export'). NULL means 'View'.
cookie: A pointer to an optional fz_cookie structure that can be used
to track progress, collect errors etc.
*/
void pdf_run_page_with_usage(fz_context *ctx, pdf_page *page, fz_device *dev, fz_matrix ctm, const char *usage, fz_cookie *cookie);
/*
Interpret a loaded page and render it on a device.
Just the main page contents without the annotations
page: A page loaded by pdf_load_page.
dev: Device used for rendering, obtained from fz_new_*_device.
ctm: A transformation matrix applied to the objects on the page,
e.g. to scale or rotate the page contents as desired.
*/
void pdf_run_page_contents(fz_context *ctx, pdf_page *page, fz_device *dev, fz_matrix ctm, fz_cookie *cookie);
void pdf_run_page_annots(fz_context *ctx, pdf_page *page, fz_device *dev, fz_matrix ctm, fz_cookie *cookie);
void pdf_run_page_widgets(fz_context *ctx, pdf_page *page, fz_device *dev, fz_matrix ctm, fz_cookie *cookie);
void pdf_run_page_contents_with_usage(fz_context *ctx, pdf_page *page, fz_device *dev, fz_matrix ctm, const char *usage, fz_cookie *cookie);
void pdf_run_page_annots_with_usage(fz_context *ctx, pdf_page *page, fz_device *dev, fz_matrix ctm, const char *usage, fz_cookie *cookie);
void pdf_run_page_widgets_with_usage(fz_context *ctx, pdf_page *page, fz_device *dev, fz_matrix ctm, const char *usage, fz_cookie *cookie);
void pdf_filter_page_contents(fz_context *ctx, pdf_document *doc, pdf_page *page, pdf_filter_options *options);
void pdf_filter_annot_contents(fz_context *ctx, pdf_document *doc, pdf_annot *annot, pdf_filter_options *options);
fz_pixmap *pdf_new_pixmap_from_page_contents_with_usage(fz_context *ctx, pdf_page *page, fz_matrix ctm, fz_colorspace *cs, int alpha, const char *usage, fz_box_type box);
fz_pixmap *pdf_new_pixmap_from_page_with_usage(fz_context *ctx, pdf_page *page, fz_matrix ctm, fz_colorspace *cs, int alpha, const char *usage, fz_box_type box);
fz_pixmap *pdf_new_pixmap_from_page_contents_with_separations_and_usage(fz_context *ctx, pdf_page *page, fz_matrix ctm, fz_colorspace *cs, fz_separations *seps, int alpha, const char *usage, fz_box_type box);
fz_pixmap *pdf_new_pixmap_from_page_with_separations_and_usage(fz_context *ctx, pdf_page *page, fz_matrix ctm, fz_colorspace *cs, fz_separations *seps, int alpha, const char *usage, fz_box_type box);
enum {
PDF_REDACT_IMAGE_NONE,
PDF_REDACT_IMAGE_REMOVE,
PDF_REDACT_IMAGE_PIXELS,
};
typedef struct
{
int black_boxes;
int image_method;
} pdf_redact_options;
int pdf_redact_page(fz_context *ctx, pdf_document *doc, pdf_page *page, pdf_redact_options *opts);
fz_transition *pdf_page_presentation(fz_context *ctx, pdf_page *page, fz_transition *transition, float *duration);
fz_default_colorspaces *pdf_load_default_colorspaces(fz_context *ctx, pdf_document *doc, pdf_page *page);
/*
Update default colorspaces for an xobject.
*/
fz_default_colorspaces *pdf_update_default_colorspaces(fz_context *ctx, fz_default_colorspaces *old_cs, pdf_obj *res);
/*
* Page tree, pages and related objects
*/
struct pdf_page
{
fz_page super;
pdf_document *doc; /* type alias for super.doc */
pdf_obj *obj;
int transparency;
int overprint;
fz_link *links;
pdf_annot *annots, **annot_tailp;
pdf_annot *widgets, **widget_tailp;
};
#endif

61
include/mupdf/pdf/parse.h Normal file
View File

@ -0,0 +1,61 @@
// Copyright (C) 2004-2021 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_PDF_PARSE_H
#define MUPDF_PDF_PARSE_H
#include "mupdf/pdf/document.h"
typedef enum
{
PDF_TOK_ERROR, PDF_TOK_EOF,
PDF_TOK_OPEN_ARRAY, PDF_TOK_CLOSE_ARRAY,
PDF_TOK_OPEN_DICT, PDF_TOK_CLOSE_DICT,
PDF_TOK_OPEN_BRACE, PDF_TOK_CLOSE_BRACE,
PDF_TOK_NAME, PDF_TOK_INT, PDF_TOK_REAL, PDF_TOK_STRING, PDF_TOK_KEYWORD,
PDF_TOK_R, PDF_TOK_TRUE, PDF_TOK_FALSE, PDF_TOK_NULL,
PDF_TOK_OBJ, PDF_TOK_ENDOBJ,
PDF_TOK_STREAM, PDF_TOK_ENDSTREAM,
PDF_TOK_XREF, PDF_TOK_TRAILER, PDF_TOK_STARTXREF,
PDF_TOK_NEWOBJ,
PDF_NUM_TOKENS
} pdf_token;
void pdf_lexbuf_init(fz_context *ctx, pdf_lexbuf *lexbuf, int size);
void pdf_lexbuf_fin(fz_context *ctx, pdf_lexbuf *lexbuf);
ptrdiff_t pdf_lexbuf_grow(fz_context *ctx, pdf_lexbuf *lexbuf);
pdf_token pdf_lex(fz_context *ctx, fz_stream *f, pdf_lexbuf *lexbuf);
pdf_token pdf_lex_no_string(fz_context *ctx, fz_stream *f, pdf_lexbuf *lexbuf);
pdf_obj *pdf_parse_array(fz_context *ctx, pdf_document *doc, fz_stream *f, pdf_lexbuf *buf);
pdf_obj *pdf_parse_dict(fz_context *ctx, pdf_document *doc, fz_stream *f, pdf_lexbuf *buf);
pdf_obj *pdf_parse_stm_obj(fz_context *ctx, pdf_document *doc, fz_stream *f, pdf_lexbuf *buf);
pdf_obj *pdf_parse_ind_obj(fz_context *ctx, pdf_document *doc, fz_stream *f, int *num, int *gen, int64_t *stm_ofs, int *try_repair);
pdf_obj *pdf_parse_journal_obj(fz_context *ctx, pdf_document *doc, fz_stream *stm, int *onum, fz_buffer **ostm, int *newobj);
/*
print a lexed token to a buffer, growing if necessary
*/
void pdf_append_token(fz_context *ctx, fz_buffer *buf, int tok, pdf_lexbuf *lex);
#endif

View File

@ -0,0 +1,133 @@
// Copyright (C) 2004-2021 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_PDF_RESOURCE_H
#define MUPDF_PDF_RESOURCE_H
#include "mupdf/fitz/font.h"
#include "mupdf/fitz/image.h"
#include "mupdf/fitz/shade.h"
#include "mupdf/fitz/store.h"
#include "mupdf/pdf/object.h"
void pdf_store_item(fz_context *ctx, pdf_obj *key, void *val, size_t itemsize);
void *pdf_find_item(fz_context *ctx, fz_store_drop_fn *drop, pdf_obj *key);
void pdf_remove_item(fz_context *ctx, fz_store_drop_fn *drop, pdf_obj *key);
void pdf_empty_store(fz_context *ctx, pdf_document *doc);
void pdf_purge_locals_from_store(fz_context *ctx, pdf_document *doc);
/*
* Structures used for managing resource locations and avoiding multiple
* occurrences when resources are added to the document. The search for existing
* resources will be performed when we are first trying to add an item. Object
* refs are stored in a fz_hash_table structure using a hash of the md5 sum of
* the data, enabling rapid lookup.
*/
enum { PDF_SIMPLE_FONT_RESOURCE=1, PDF_CID_FONT_RESOURCE=2, PDF_CJK_FONT_RESOURCE=3 };
enum { PDF_SIMPLE_ENCODING_LATIN, PDF_SIMPLE_ENCODING_GREEK, PDF_SIMPLE_ENCODING_CYRILLIC };
/* The contents of this structure are defined publically just so we can
* define this on the stack. */
typedef struct
{
unsigned char digest[16];
int type;
int encoding;
int local_xref;
} pdf_font_resource_key;
pdf_obj *pdf_find_font_resource(fz_context *ctx, pdf_document *doc, int type, int encoding, fz_font *item, pdf_font_resource_key *key);
pdf_obj *pdf_insert_font_resource(fz_context *ctx, pdf_document *doc, pdf_font_resource_key *key, pdf_obj *obj);
void pdf_drop_resource_tables(fz_context *ctx, pdf_document *doc);
void pdf_purge_local_font_resources(fz_context *ctx, pdf_document *doc);
typedef struct pdf_function pdf_function;
void pdf_eval_function(fz_context *ctx, pdf_function *func, const float *in, int inlen, float *out, int outlen);
pdf_function *pdf_keep_function(fz_context *ctx, pdf_function *func);
void pdf_drop_function(fz_context *ctx, pdf_function *func);
size_t pdf_function_size(fz_context *ctx, pdf_function *func);
pdf_function *pdf_load_function(fz_context *ctx, pdf_obj *ref, int in, int out);
fz_colorspace *pdf_document_output_intent(fz_context *ctx, pdf_document *doc);
fz_colorspace *pdf_load_colorspace(fz_context *ctx, pdf_obj *obj);
int pdf_is_tint_colorspace(fz_context *ctx, fz_colorspace *cs);
fz_shade *pdf_load_shading(fz_context *ctx, pdf_document *doc, pdf_obj *obj);
void pdf_sample_shade_function(fz_context *ctx, float shade[256][FZ_MAX_COLORS+1], int n, int funcs, pdf_function **func, float t0, float t1);
/**
Function to recolor a single color from a shade.
*/
typedef void (pdf_recolor_vertex)(fz_context *ctx, void *opaque, fz_colorspace *dst_cs, float *d, fz_colorspace *src_cs, const float *src);
/**
Function to handle recoloring a shade.
Called with src_cs from the shade. If no recoloring is required, return NULL. Otherwise
fill in *dst_cs, and return a vertex recolorer.
*/
typedef pdf_recolor_vertex *(pdf_shade_recolorer)(fz_context *ctx, void *opaque, fz_colorspace *src_cs, fz_colorspace **dst_cs);
/**
Recolor a shade.
*/
pdf_obj *pdf_recolor_shade(fz_context *ctx, pdf_obj *shade, pdf_shade_recolorer *reshade, void *opaque);
fz_image *pdf_load_inline_image(fz_context *ctx, pdf_document *doc, pdf_obj *rdb, pdf_obj *dict, fz_stream *file);
int pdf_is_jpx_image(fz_context *ctx, pdf_obj *dict);
fz_image *pdf_load_image(fz_context *ctx, pdf_document *doc, pdf_obj *obj);
pdf_obj *pdf_add_image(fz_context *ctx, pdf_document *doc, fz_image *image);
typedef struct
{
fz_storable storable;
int ismask;
float xstep;
float ystep;
fz_matrix matrix;
fz_rect bbox;
pdf_document *document;
pdf_obj *resources;
pdf_obj *contents;
int id; /* unique ID for caching rendered tiles */
} pdf_pattern;
pdf_pattern *pdf_load_pattern(fz_context *ctx, pdf_document *doc, pdf_obj *obj);
pdf_pattern *pdf_keep_pattern(fz_context *ctx, pdf_pattern *pat);
void pdf_drop_pattern(fz_context *ctx, pdf_pattern *pat);
pdf_obj *pdf_new_xobject(fz_context *ctx, pdf_document *doc, fz_rect bbox, fz_matrix matrix, pdf_obj *res, fz_buffer *buffer);
void pdf_update_xobject(fz_context *ctx, pdf_document *doc, pdf_obj *xobj, fz_rect bbox, fz_matrix mat, pdf_obj *res, fz_buffer *buffer);
pdf_obj *pdf_xobject_resources(fz_context *ctx, pdf_obj *xobj);
fz_rect pdf_xobject_bbox(fz_context *ctx, pdf_obj *xobj);
fz_matrix pdf_xobject_matrix(fz_context *ctx, pdf_obj *xobj);
int pdf_xobject_isolated(fz_context *ctx, pdf_obj *xobj);
int pdf_xobject_knockout(fz_context *ctx, pdf_obj *xobj);
int pdf_xobject_transparency(fz_context *ctx, pdf_obj *xobj);
fz_colorspace *pdf_xobject_colorspace(fz_context *ctx, pdf_obj *xobj);
#endif

300
include/mupdf/pdf/xref.h Normal file
View File

@ -0,0 +1,300 @@
// Copyright (C) 2004-2022 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_PDF_XREF_H
#define MUPDF_PDF_XREF_H
#include "mupdf/pdf/document.h"
/*
Allocate a slot in the xref table and return a fresh unused object number.
*/
int pdf_create_object(fz_context *ctx, pdf_document *doc);
/*
Remove object from xref table, marking the slot as free.
*/
void pdf_delete_object(fz_context *ctx, pdf_document *doc, int num);
/*
Replace object in xref table with the passed in object.
*/
void pdf_update_object(fz_context *ctx, pdf_document *doc, int num, pdf_obj *obj);
/*
Replace stream contents for object in xref table with the passed in buffer.
The buffer contents must match the /Filter setting if 'compressed' is true.
If 'compressed' is false, the /Filter and /DecodeParms entries are deleted.
The /Length entry is updated.
*/
void pdf_update_stream(fz_context *ctx, pdf_document *doc, pdf_obj *ref, fz_buffer *buf, int compressed);
/*
Return true if 'obj' is an indirect reference to an object that is held
by the "local" xref section.
*/
int pdf_is_local_object(fz_context *ctx, pdf_document *doc, pdf_obj *obj);
pdf_obj *pdf_add_object(fz_context *ctx, pdf_document *doc, pdf_obj *obj);
pdf_obj *pdf_add_object_drop(fz_context *ctx, pdf_document *doc, pdf_obj *obj);
pdf_obj *pdf_add_stream(fz_context *ctx, pdf_document *doc, fz_buffer *buf, pdf_obj *obj, int compressed);
pdf_obj *pdf_add_new_dict(fz_context *ctx, pdf_document *doc, int initial);
pdf_obj *pdf_add_new_array(fz_context *ctx, pdf_document *doc, int initial);
typedef struct
{
char type; /* 0=unset (f)ree i(n)use (o)bjstm */
unsigned char marked; /* marked to keep alive with pdf_mark_xref */
unsigned short gen; /* generation / objstm index */
int num; /* original object number (for decryption after renumbering) */
int64_t ofs; /* file offset / objstm object number */
int64_t stm_ofs; /* on-disk stream */
fz_buffer *stm_buf; /* in-memory stream (for updated objects) */
pdf_obj *obj; /* stored/cached object */
} pdf_xref_entry;
typedef struct pdf_xref_subsec
{
struct pdf_xref_subsec *next;
int len;
int start;
pdf_xref_entry *table;
} pdf_xref_subsec;
struct pdf_xref
{
int num_objects;
pdf_xref_subsec *subsec;
pdf_obj *trailer;
pdf_obj *pre_repair_trailer;
pdf_unsaved_sig *unsaved_sigs;
pdf_unsaved_sig **unsaved_sigs_end;
int64_t end_ofs; /* file offset to end of xref */
};
/**
Retrieve the pdf_xref_entry for a given object.
This can cause xref reorganisations (solidifications etc) due to
repairs, so all held pdf_xref_entries should be considered
invalid after this call (other than the returned one).
*/
pdf_xref_entry *pdf_cache_object(fz_context *ctx, pdf_document *doc, int num);
int pdf_count_objects(fz_context *ctx, pdf_document *doc);
/**
Resolve an indirect object (or chain of objects).
This can cause xref reorganisations (solidifications etc) due to
repairs, so all held pdf_xref_entries should be considered
invalid after this call (other than the returned one).
*/
pdf_obj *pdf_resolve_indirect(fz_context *ctx, pdf_obj *ref);
pdf_obj *pdf_resolve_indirect_chain(fz_context *ctx, pdf_obj *ref);
/**
Load a given object.
This can cause xref reorganisations (solidifications etc) due to
repairs, so all held pdf_xref_entries should be considered
invalid after this call (other than the returned one).
*/
pdf_obj *pdf_load_object(fz_context *ctx, pdf_document *doc, int num);
pdf_obj *pdf_load_unencrypted_object(fz_context *ctx, pdf_document *doc, int num);
/*
Load raw (compressed but decrypted) contents of a stream into buf.
*/
fz_buffer *pdf_load_raw_stream_number(fz_context *ctx, pdf_document *doc, int num);
fz_buffer *pdf_load_raw_stream(fz_context *ctx, pdf_obj *ref);
/*
Load uncompressed contents of a stream into buf.
*/
fz_buffer *pdf_load_stream_number(fz_context *ctx, pdf_document *doc, int num);
fz_buffer *pdf_load_stream(fz_context *ctx, pdf_obj *ref);
/*
Open a stream for reading the raw (compressed but decrypted) data.
*/
fz_stream *pdf_open_raw_stream_number(fz_context *ctx, pdf_document *doc, int num);
fz_stream *pdf_open_raw_stream(fz_context *ctx, pdf_obj *ref);
/*
Open a stream for reading uncompressed data.
Put the opened file in doc->stream.
Using doc->file while a stream is open is a Bad idea.
*/
fz_stream *pdf_open_stream_number(fz_context *ctx, pdf_document *doc, int num);
fz_stream *pdf_open_stream(fz_context *ctx, pdf_obj *ref);
/*
Construct a filter to decode a stream, without
constraining to stream length, and without decryption.
*/
fz_stream *pdf_open_inline_stream(fz_context *ctx, pdf_document *doc, pdf_obj *stmobj, int length, fz_stream *chain, fz_compression_params *params);
fz_compressed_buffer *pdf_load_compressed_stream(fz_context *ctx, pdf_document *doc, int num, size_t worst_case);
void pdf_load_compressed_inline_image(fz_context *ctx, pdf_document *doc, pdf_obj *dict, int length, fz_stream *cstm, int indexed, fz_compressed_image *image);
fz_stream *pdf_open_stream_with_offset(fz_context *ctx, pdf_document *doc, int num, pdf_obj *dict, int64_t stm_ofs);
fz_stream *pdf_open_contents_stream(fz_context *ctx, pdf_document *doc, pdf_obj *obj);
int pdf_version(fz_context *ctx, pdf_document *doc);
pdf_obj *pdf_trailer(fz_context *ctx, pdf_document *doc);
void pdf_set_populating_xref_trailer(fz_context *ctx, pdf_document *doc, pdf_obj *trailer);
int pdf_xref_len(fz_context *ctx, pdf_document *doc);
pdf_obj *pdf_metadata(fz_context *ctx, pdf_document *doc);
/*
Used while reading the individual xref sections from a file.
*/
pdf_xref_entry *pdf_get_populating_xref_entry(fz_context *ctx, pdf_document *doc, int i);
/*
Used after loading a document to access entries.
This will never throw anything, or return NULL if it is
only asked to return objects in range within a 'solid'
xref.
This may "solidify" the xref (so can cause allocations).
*/
pdf_xref_entry *pdf_get_xref_entry(fz_context *ctx, pdf_document *doc, int i);
/*
Map a function across all xref entries in a document.
*/
void pdf_xref_entry_map(fz_context *ctx, pdf_document *doc, void (*fn)(fz_context *, pdf_xref_entry *, int i, pdf_document *doc, void *), void *arg);
/*
Used after loading a document to access entries.
This will never throw anything, or return NULL if it is
only asked to return objects in range within a 'solid'
xref.
This will never "solidify" the xref, so no entry may be found
(NULL will be returned) for free entries.
Called with a valid i, this will never try/catch or throw.
*/
pdf_xref_entry *pdf_get_xref_entry_no_change(fz_context *ctx, pdf_document *doc, int i);
pdf_xref_entry *pdf_get_xref_entry_no_null(fz_context *ctx, pdf_document *doc, int i);
void pdf_replace_xref(fz_context *ctx, pdf_document *doc, pdf_xref_entry *entries, int n);
void pdf_forget_xref(fz_context *ctx, pdf_document *doc);
pdf_xref_entry *pdf_get_incremental_xref_entry(fz_context *ctx, pdf_document *doc, int i);
/*
Ensure that an object has been cloned into the incremental xref section.
*/
int pdf_xref_ensure_incremental_object(fz_context *ctx, pdf_document *doc, int num);
int pdf_xref_is_incremental(fz_context *ctx, pdf_document *doc, int num);
void pdf_xref_store_unsaved_signature(fz_context *ctx, pdf_document *doc, pdf_obj *field, pdf_pkcs7_signer *signer);
void pdf_xref_remove_unsaved_signature(fz_context *ctx, pdf_document *doc, pdf_obj *field);
int pdf_xref_obj_is_unsaved_signature(pdf_document *doc, pdf_obj *obj);
void pdf_xref_ensure_local_object(fz_context *ctx, pdf_document *doc, int num);
int pdf_obj_is_incremental(fz_context *ctx, pdf_obj *obj);
void pdf_repair_xref(fz_context *ctx, pdf_document *doc);
void pdf_repair_obj_stms(fz_context *ctx, pdf_document *doc);
void pdf_repair_trailer(fz_context *ctx, pdf_document *doc);
/*
Ensure that the current populating xref has a single subsection
that covers the entire range.
*/
void pdf_ensure_solid_xref(fz_context *ctx, pdf_document *doc, int num);
void pdf_mark_xref(fz_context *ctx, pdf_document *doc);
void pdf_clear_xref(fz_context *ctx, pdf_document *doc);
void pdf_clear_xref_to_mark(fz_context *ctx, pdf_document *doc);
int pdf_repair_obj(fz_context *ctx, pdf_document *doc, pdf_lexbuf *buf, int64_t *stmofsp, int64_t *stmlenp, pdf_obj **encrypt, pdf_obj **id, pdf_obj **page, int64_t *tmpofs, pdf_obj **root);
pdf_obj *pdf_progressive_advance(fz_context *ctx, pdf_document *doc, int pagenum);
/*
Return the number of versions that there
are in a file. i.e. 1 + the number of updates that
the file on disc has been through. i.e. internal
unsaved changes to the file (such as appearance streams)
are ignored. Also, the initial write of a linearized
file (which appears as a base file write + an incremental
update) is treated as a single version.
*/
int pdf_count_versions(fz_context *ctx, pdf_document *doc);
int pdf_count_unsaved_versions(fz_context *ctx, pdf_document *doc);
int pdf_validate_changes(fz_context *ctx, pdf_document *doc, int version);
int pdf_doc_was_linearized(fz_context *ctx, pdf_document *doc);
typedef struct pdf_locked_fields pdf_locked_fields;
int pdf_is_field_locked(fz_context *ctx, pdf_locked_fields *locked, const char *name);
void pdf_drop_locked_fields(fz_context *ctx, pdf_locked_fields *locked);
pdf_locked_fields *pdf_find_locked_fields(fz_context *ctx, pdf_document *doc, int version);
pdf_locked_fields *pdf_find_locked_fields_for_sig(fz_context *ctx, pdf_document *doc, pdf_obj *sig);
/*
Check the entire history of the document, and return the number of
the last version that checked out OK.
i.e. 0 = "the entire history checks out OK".
n = "none of the history checked out OK".
*/
int pdf_validate_change_history(fz_context *ctx, pdf_document *doc);
/*
Find which version of a document the current version of obj
was defined in.
version = 0 = latest, 1 = previous update etc, allowing for
the first incremental update in a linearized file being ignored.
*/
int pdf_find_version_for_obj(fz_context *ctx, pdf_document *doc, pdf_obj *obj);
/*
Return the number of updates ago when a signature became invalid,
not counting any unsaved changes.
Thus:
-1 => Has changed in the current unsaved changes.
0 => still valid.
1 => became invalid on the last save
n => became invalid n saves ago
*/
int pdf_validate_signature(fz_context *ctx, pdf_annot *widget);
int pdf_was_pure_xfa(fz_context *ctx, pdf_document *doc);
/* Local xrefs - designed for holding stuff that shouldn't be written
* back into the actual document, such as synthesized appearance
* streams. */
pdf_xref *pdf_new_local_xref(fz_context *ctx, pdf_document *doc);
void pdf_drop_local_xref(fz_context *ctx, pdf_xref *xref);
void pdf_drop_local_xref_and_resources(fz_context *ctx, pdf_document *doc);
/* Debug call to dump the incremental/local xrefs to the
* debug channel. */
void pdf_debug_doc_changes(fz_context *ctx, pdf_document *doc);
#endif