typedef struct pdf_gstate pdf_gstate
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_resource_stack
{
pdf_resource_stack *next;
pdf_obj *resources;
}
Stack of resources used during interpretation (holding page and xobject/font/type3 glyph resource dictionaries).
pdf_obj *
pdf_lookup_resource (
fz_context *ctx,
pdf_resource_stack *stack,
pdf_obj *type,
const char *name
)
enum pdf_processor_requirements
{
PDF_PROCESSOR_REQUIRES_DECODED_IMAGES = 1
}
struct pdf_processor
{
int refs;
int closed;
/* 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);
void (*reset_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.
* NOTE: This must NOT throw as it may be called during cleanup!
*/
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, fz_colorspace *smask_cs, float *bc, int luminosity, pdf_obj *tr);
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);
/* EOD is used to signify end of data (before any finalise/close down/
* automatically added gstate pops). */
void (*op_EOD)(fz_context *ctx, pdf_processor *proc);
/* 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;
pdf_processor_requirements requirements;
/* resource dictionary stack */
pdf_resource_stack *rstack;
/* Unused, except when inited as chain processor */
pdf_processor *chain;
}
struct pdf_csi
{
/* input */
pdf_document *doc;
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];
}
void
pdf_count_q_balance (
fz_context *ctx,
pdf_document *doc,
pdf_obj *res,
pdf_obj *stm,
int *prepend,
int *append
)
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,
pdf_gstate *fill_gstate,
pdf_gstate *stroke_gstate
)
Functions to set up pdf_process structures
pdf_processor *
pdf_new_buffer_processor (
fz_context *ctx,
fz_buffer *buffer,
int ahxencode,
int newlines
)
Create a buffer processor.
This collects the incoming PDF operator stream into an fz_buffer.
void
pdf_reset_processor (
fz_context *ctx,
pdf_processor *proc
)
Reopen a closed processor to be used again.
This brings a processor back to life after a close. Not all processors may support this, so this may throw an exception.
pdf_processor *
pdf_new_output_processor (
fz_context *ctx,
fz_output *out,
int ahxencode,
int newlines
)
Create an output processor. This sends the incoming PDF operator stream to an fz_output stream.
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)
Create a filter processor. This filters the PDF operators it is fed, and passes them down (with some changes) to the child filter.
The options field contains a pointer to a structure with filter specific options in.
struct pdf_filter_factory
{
pdf_filter_factory_fn *filter;
void *options;
}
A pdf_filter_factory is a pdf_filter_factory_fn, plus the options needed to instantiate it.
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 *opaque);
pdf_filter_factory *filters;
int newlines;
}
enum fz_cull_type
{
FZ_CULL_PATH_DROP,
FZ_CULL_PATH_FILL,
FZ_CULL_PATH_STROKE,
FZ_CULL_PATH_FILL_STROKE,
FZ_CULL_CLIP_PATH_DROP,
FZ_CULL_CLIP_PATH_FILL,
FZ_CULL_CLIP_PATH_STROKE,
FZ_CULL_CLIP_PATH_FILL_STROKE,
FZ_CULL_GLYPH,
FZ_CULL_IMAGE,
FZ_CULL_SHADING
}
struct pdf_sanitize_filter_options
{
void *opaque;
fz_image *(*image_filter)(fz_context *ctx, void *opaque, fz_matrix ctm, const char *name, fz_image *image, fz_rect scissor);
int (*text_filter)(fz_context *ctx, void *opaque, int *ucsbuf, int ucslen, fz_matrix trm, fz_matrix ctm, fz_rect bbox, int tr, float ca, float CA);
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
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
)
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.
struct pdf_vectorize_filter_options
{
void *opaque;
/* To be expanded */
}
pdf_vectorize_filter_options
pdf_processor *
pdf_new_vectorize_filter (
fz_context *ctx,
pdf_document *doc,
pdf_processor *chain,
int structparents,
fz_matrix transform,
pdf_filter_options *options,
void *vopts
)
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
)
struct pdf_color_filter_options
{
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, fz_matrix ctm, pdf_obj *obj);
pdf_shade_recolorer *shade_rewrite;
int repeated_image_rewrite;
}
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
)
void
pdf_process_contents (
fz_context *ctx,
pdf_processor *proc,
pdf_document *doc,
pdf_obj *res,
pdf_obj *stm,
fz_cookie *cookie,
pdf_obj **out_res
)
Functions to actually process annotations, glyphs and general stream objects.
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
)
void
pdf_process_raw_contents (
fz_context *ctx,
pdf_processor *proc,
pdf_document *doc,
pdf_obj *stmobj,
fz_cookie *cookie
)
Function to process a contents stream without handling the resources. The caller is responsible for pushing/popping the resources.
struct pdf_text_state
{
float char_space;
float word_space;
float scale;
float leading;
pdf_font_desc *font;
fz_string *fontname;
float size;
int render;
float rise;
}
Text handling helper functions
struct pdf_text_object_state
{
fz_text *clip_text; /* accumulator for clip mode text */
fz_rect clip_text_bbox;
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;
}
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
)
fz_text *
pdf_tos_get_clip_text (
fz_context *ctx,
pdf_text_object_state *tos
)
void
pdf_tos_reset (
fz_context *ctx,
pdf_text_object_state *tos,
int render
)
void
pdf_tos_accumulate_clip (
fz_context *ctx,
pdf_text_object_state *tos
)
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,
float *adv
)
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
)