summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mupdf/fitz/device.h2
-rw-r--r--include/mupdf/pdf.h1
-rw-r--r--include/mupdf/pdf/interpret.h165
-rw-r--r--include/mupdf/pdf/resource.h2
-rw-r--r--source/fitz/draw-blend.c2
-rw-r--r--source/fitz/list-device.c2
-rw-r--r--source/html/css-parse.c2
-rw-r--r--source/pdf/pdf-clean.c74
-rw-r--r--source/pdf/pdf-interpret-imp.h158
-rw-r--r--source/pdf/pdf-interpret.c1314
-rw-r--r--source/pdf/pdf-object.c4
-rw-r--r--source/pdf/pdf-op-buffer.c1166
-rw-r--r--source/pdf/pdf-op-filter.c1625
-rw-r--r--source/pdf/pdf-op-run.c2006
-rw-r--r--source/pdf/pdf-pattern.c38
-rw-r--r--source/pdf/pdf-run.c37
-rw-r--r--source/pdf/pdf-stream.c3
-rw-r--r--source/pdf/pdf-write.c2
-rw-r--r--source/pdf/pdf-xobject.c2
19 files changed, 3258 insertions, 3347 deletions
diff --git a/include/mupdf/fitz/device.h b/include/mupdf/fitz/device.h
index 55674abd..ac1c15a5 100644
--- a/include/mupdf/fitz/device.h
+++ b/include/mupdf/fitz/device.h
@@ -71,7 +71,7 @@ enum
FZ_BLEND_KNOCKOUT = 32
};
-int fz_lookup_blendmode(char *name);
+int fz_lookup_blendmode(const char *name);
char *fz_blendmode_name(int blendmode);
typedef struct fz_device_container_stack_s fz_device_container_stack;
diff --git a/include/mupdf/pdf.h b/include/mupdf/pdf.h
index 976aaa07..b2b54c10 100644
--- a/include/mupdf/pdf.h
+++ b/include/mupdf/pdf.h
@@ -13,6 +13,7 @@
#include "mupdf/pdf/resource.h"
#include "mupdf/pdf/cmap.h"
#include "mupdf/pdf/font.h"
+#include "mupdf/pdf/interpret.h"
#include "mupdf/pdf/annot.h"
#include "mupdf/pdf/field.h"
diff --git a/include/mupdf/pdf/interpret.h b/include/mupdf/pdf/interpret.h
new file mode 100644
index 00000000..72d042e5
--- /dev/null
+++ b/include/mupdf/pdf/interpret.h
@@ -0,0 +1,165 @@
+#ifndef PDF_INTERPRET_H
+#define PDF_INTERPRET_H
+
+typedef struct pdf_csi_s pdf_csi;
+typedef struct pdf_gstate_s pdf_gstate;
+typedef struct pdf_processor_s pdf_processor;
+
+void *pdf_new_processor(fz_context *ctx, int size);
+void pdf_drop_processor(fz_context *ctx, pdf_processor *proc);
+
+struct pdf_processor_s
+{
+ void (*drop_imp)(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_xobject *smask, pdf_obj *page_resources, 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, int len);
+ void (*op_squote)(fz_context *ctx, pdf_processor *proc, char *str, int len);
+ void (*op_dquote)(fz_context *ctx, pdf_processor *proc, float aw, float ac, char *str, int 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);
+ 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_xobject *form, pdf_obj *page_resources);
+
+ /* 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 *properties);
+ 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 *properties);
+ 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);
+
+ /* 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 *event;
+ int hidden;
+};
+
+struct pdf_csi_s
+{
+ /* 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];
+ int string_len;
+ int top;
+ float stack[32];
+};
+
+/* Functions to set up pdf_process structures */
+pdf_processor *pdf_new_run_processor(fz_context *ctx, fz_device *dev, const fz_matrix *ctm, const char *event, pdf_gstate *gstate, int nested);
+pdf_processor *pdf_new_buffer_processor(fz_context *ctx, fz_buffer *buffer);
+pdf_processor *pdf_new_filter_processor(fz_context *ctx, pdf_processor *chain, pdf_document *doc, pdf_obj *old_res, pdf_obj *new_res);
+
+/* 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);
+void pdf_process_annot(fz_context *ctx, pdf_processor *proc, pdf_document *doc, pdf_page *page, 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);
+
+#endif
diff --git a/include/mupdf/pdf/resource.h b/include/mupdf/pdf/resource.h
index fb542f59..868bd168 100644
--- a/include/mupdf/pdf/resource.h
+++ b/include/mupdf/pdf/resource.h
@@ -38,6 +38,7 @@ struct pdf_pattern_s
float ystep;
fz_matrix matrix;
fz_rect bbox;
+ pdf_document *document;
pdf_obj *resources;
pdf_obj *contents;
};
@@ -61,6 +62,7 @@ struct pdf_xobject_s
int knockout;
int transparency;
fz_colorspace *colorspace;
+ pdf_document *document;
pdf_obj *resources;
pdf_obj *contents;
pdf_obj *me;
diff --git a/source/fitz/draw-blend.c b/source/fitz/draw-blend.c
index 62666fc5..ea5d30bc 100644
--- a/source/fitz/draw-blend.c
+++ b/source/fitz/draw-blend.c
@@ -25,7 +25,7 @@ static const char *fz_blendmode_names[] =
"Luminosity",
};
-int fz_lookup_blendmode(char *name)
+int fz_lookup_blendmode(const char *name)
{
int i;
for (i = 0; i < nelem(fz_blendmode_names); i++)
diff --git a/source/fitz/list-device.c b/source/fitz/list-device.c
index fc2bb3f8..738499b1 100644
--- a/source/fitz/list-device.c
+++ b/source/fitz/list-device.c
@@ -954,7 +954,7 @@ fz_list_fill_shade(fz_context *ctx, fz_device *dev, fz_shade *shade, const fz_ma
&rect,
NULL, /* path */
NULL, /* color */
- NULL, /* colorspace */
+ NULL, /* colorspace */
&alpha, /* alpha */
ctm,
NULL, /* stroke */
diff --git a/source/html/css-parse.c b/source/html/css-parse.c
index e3ddd48f..91958a98 100644
--- a/source/html/css-parse.c
+++ b/source/html/css-parse.c
@@ -414,7 +414,7 @@ restart:
{
buf->color = (a << 20) | (b << 12) | (c << 4);
}
- sprintf(buf->string, "%06x", buf->color); // XXX
+ sprintf(buf->string, "%06x", buf->color);
return CSS_COLOR;
colorerror:
fz_css_error(buf, "invalid color");
diff --git a/source/pdf/pdf-clean.c b/source/pdf/pdf-clean.c
index 4bdaae7b..399d9339 100644
--- a/source/pdf/pdf-clean.c
+++ b/source/pdf/pdf-clean.c
@@ -1,18 +1,21 @@
-#include "pdf-interpret-imp.h"
+#include "mupdf/pdf.h"
static void
pdf_clean_stream_object(fz_context *ctx, pdf_document *doc, pdf_obj *obj, pdf_obj *orig_res, fz_cookie *cookie, int own_res)
{
- pdf_process process, process2;
- fz_buffer *buffer;
+ pdf_processor *proc_buffer = NULL;
+ pdf_processor *proc_filter = NULL;
pdf_obj *res = NULL;
pdf_obj *ref = NULL;
+ fz_buffer *buffer;
if (!obj)
return;
fz_var(res);
fz_var(ref);
+ fz_var(proc_buffer);
+ fz_var(proc_filter);
buffer = fz_new_buffer(ctx, 1024);
@@ -27,10 +30,10 @@ pdf_clean_stream_object(fz_context *ctx, pdf_document *doc, pdf_obj *obj, pdf_ob
res = pdf_new_dict(ctx, doc, 1);
- pdf_init_process_buffer(ctx, &process2, buffer);
- pdf_init_process_filter(ctx, &process, &process2, res);
+ proc_buffer = pdf_new_buffer_processor(ctx, buffer);
+ proc_filter = pdf_new_filter_processor(ctx, proc_buffer, doc, orig_res, res);
- pdf_process_stream_object(ctx, doc, obj, &process, orig_res, cookie);
+ pdf_process_contents(ctx, proc_filter, doc, orig_res, obj, cookie);
pdf_update_stream(ctx, doc, obj, buffer, 0);
@@ -42,6 +45,8 @@ pdf_clean_stream_object(fz_context *ctx, pdf_document *doc, pdf_obj *obj, pdf_ob
}
fz_always(ctx)
{
+ pdf_drop_processor(ctx, proc_filter);
+ pdf_drop_processor(ctx, proc_buffer);
fz_drop_buffer(ctx, buffer);
pdf_drop_obj(ctx, res);
pdf_drop_obj(ctx, ref);
@@ -55,15 +60,17 @@ pdf_clean_stream_object(fz_context *ctx, pdf_document *doc, pdf_obj *obj, pdf_ob
static void
pdf_clean_type3(fz_context *ctx, pdf_document *doc, pdf_obj *obj, pdf_obj *orig_res, fz_cookie *cookie)
{
- pdf_process process, process2;
- fz_buffer *buffer;
- int i, l;
+ pdf_processor *proc_buffer = NULL;
+ pdf_processor *proc_filter = NULL;
pdf_obj *res = NULL;
pdf_obj *ref = NULL;
pdf_obj *charprocs;
+ int i, l;
fz_var(res);
fz_var(ref);
+ fz_var(proc_buffer);
+ fz_var(proc_filter);
fz_try(ctx)
{
@@ -79,19 +86,27 @@ pdf_clean_type3(fz_context *ctx, pdf_document *doc, pdf_obj *obj, pdf_obj *orig_
for (i = 0; i < l; i++)
{
- pdf_obj *key = pdf_dict_get_key(ctx, charprocs, i);
pdf_obj *val = pdf_dict_get_val(ctx, charprocs, i);
+ fz_buffer *buffer = fz_new_buffer(ctx, 1024);
+ fz_try(ctx)
+ {
+ proc_buffer = pdf_new_buffer_processor(ctx, buffer);
+ proc_filter = pdf_new_filter_processor(ctx, proc_buffer, doc, orig_res, res);
- buffer = fz_new_buffer(ctx, 1024);
- pdf_init_process_buffer(ctx, &process2, buffer);
- pdf_init_process_filter(ctx, &process, &process2, res);
-
- pdf_process_stream_object(ctx, doc, val, &process, orig_res, cookie);
+ pdf_process_contents(ctx, proc_filter, doc, orig_res, val, cookie);
- pdf_update_stream(ctx, doc, val, buffer, 0);
- pdf_dict_put(ctx, charprocs, key, val);
- fz_drop_buffer(ctx, buffer);
- buffer = NULL;
+ pdf_update_stream(ctx, doc, val, buffer, 0);
+ }
+ fz_always(ctx)
+ {
+ pdf_drop_processor(ctx, proc_filter);
+ pdf_drop_processor(ctx, proc_buffer);
+ fz_drop_buffer(ctx, buffer);
+ }
+ fz_catch(ctx)
+ {
+ fz_rethrow(ctx);
+ }
}
/* ProcSet - no cleaning possible. Inherit this from the old dict. */
@@ -102,7 +117,6 @@ pdf_clean_type3(fz_context *ctx, pdf_document *doc, pdf_obj *obj, pdf_obj *orig_
}
fz_always(ctx)
{
- fz_drop_buffer(ctx, buffer);
pdf_drop_obj(ctx, res);
pdf_drop_obj(ctx, ref);
}
@@ -114,28 +128,33 @@ pdf_clean_type3(fz_context *ctx, pdf_document *doc, pdf_obj *obj, pdf_obj *orig_
void pdf_clean_page_contents(fz_context *ctx, pdf_document *doc, pdf_page *page, fz_cookie *cookie, pdf_page_contents_process_fn *proc_fn, void *proc_arg)
{
- pdf_process process, process2;
- fz_buffer *buffer = fz_new_buffer(ctx, 1024);
- pdf_obj *contents;
+ pdf_processor *proc_buffer = NULL;
+ pdf_processor *proc_filter = NULL;
pdf_obj *new_obj = NULL;
pdf_obj *new_ref = NULL;
pdf_obj *res = NULL;
pdf_obj *ref = NULL;
pdf_obj *obj;
+ pdf_obj *contents;
+ fz_buffer *buffer;
fz_var(new_obj);
fz_var(new_ref);
fz_var(res);
fz_var(ref);
+ fz_var(proc_buffer);
+ fz_var(proc_filter);
+
+ buffer = fz_new_buffer(ctx, 1024);
fz_try(ctx)
{
res = pdf_new_dict(ctx, doc, 1);
- pdf_init_process_buffer(ctx, &process2, buffer);
- pdf_init_process_filter(ctx, &process, &process2, res);
+ proc_buffer = pdf_new_buffer_processor(ctx, buffer);
+ proc_filter = pdf_new_filter_processor(ctx, proc_buffer, doc, page->resources, res);
- pdf_process_stream_object(ctx, doc, page->contents, &process, page->resources, cookie);
+ pdf_process_contents(ctx, proc_filter, doc, page->resources, page->contents, cookie);
contents = page->contents;
if (pdf_is_array(ctx, contents))
@@ -247,7 +266,6 @@ void pdf_clean_page_contents(fz_context *ctx, pdf_document *doc, pdf_page *page,
(*proc_fn)(ctx, buffer, res, proc_arg);
pdf_update_stream(ctx, doc, contents, buffer, 0);
-
pdf_drop_obj(ctx, page->resources);
ref = pdf_new_ref(ctx, doc, res);
page->resources = pdf_keep_obj(ctx, ref);
@@ -255,6 +273,8 @@ void pdf_clean_page_contents(fz_context *ctx, pdf_document *doc, pdf_page *page,
}
fz_always(ctx)
{
+ pdf_drop_processor(ctx, proc_filter);
+ pdf_drop_processor(ctx, proc_buffer);
fz_drop_buffer(ctx, buffer);
pdf_drop_obj(ctx, new_obj);
pdf_drop_obj(ctx, new_ref);
diff --git a/source/pdf/pdf-interpret-imp.h b/source/pdf/pdf-interpret-imp.h
deleted file mode 100644
index 9c72bfe2..00000000
--- a/source/pdf/pdf-interpret-imp.h
+++ /dev/null
@@ -1,158 +0,0 @@
-#ifndef PDF_INTERPRET_IMP_H
-#define PDF_INTERPRET_IMP_H
-
-#include "mupdf/pdf.h"
-
-typedef struct pdf_csi_s pdf_csi;
-typedef struct pdf_gstate_s pdf_gstate;
-
-typedef void (*pdf_operator_fn)(pdf_csi *, void *user);
-typedef void (*pdf_process_annot_fn)(pdf_csi *csi, void *user, pdf_obj *resources, pdf_annot *annot);
-typedef void (*pdf_process_stream_fn)(pdf_csi *csi, void *user, pdf_lexbuf *buf);
-typedef void (*pdf_process_contents_fn)(pdf_csi *csi, void *user, pdf_obj *resources, pdf_obj *contents);
-
-typedef enum {
- /* The first section of op's all run without a try/catch */
- PDF_OP_dquote,
- PDF_OP_squote,
- PDF_OP_B,
- PDF_OP_Bstar,
- PDF_OP_BDC,
- PDF_OP_BI,
- PDF_OP_BMC,
- PDF_OP_BT,
- PDF_OP_BX,
- PDF_OP_CS,
- PDF_OP_DP,
- PDF_OP_EMC,
- PDF_OP_ET,
- PDF_OP_EX,
- PDF_OP_F,
- PDF_OP_G,
- PDF_OP_J,
- PDF_OP_K,
- PDF_OP_M,
- PDF_OP_MP,
- PDF_OP_Q,
- PDF_OP_RG,
- PDF_OP_S,
- PDF_OP_SC,
- PDF_OP_SCN,
- PDF_OP_Tstar,
- PDF_OP_TD,
- PDF_OP_TJ,
- PDF_OP_TL,
- PDF_OP_Tc,
- PDF_OP_Td,
- PDF_OP_Tj,
- PDF_OP_Tm,
- PDF_OP_Tr,
- PDF_OP_Ts,
- PDF_OP_Tw,
- PDF_OP_Tz,
- PDF_OP_W,
- PDF_OP_Wstar,
- PDF_OP_b,
- PDF_OP_bstar,
- PDF_OP_c,
- PDF_OP_cm,
- PDF_OP_cs,
- PDF_OP_d,
- PDF_OP_d0,
- PDF_OP_d1,
- PDF_OP_f,
- PDF_OP_fstar,
- PDF_OP_g,
- PDF_OP_h,
- PDF_OP_i,
- PDF_OP_j,
- PDF_OP_k,
- PDF_OP_l,
- PDF_OP_m,
- PDF_OP_n,
- PDF_OP_q,
- PDF_OP_re,
- PDF_OP_rg,
- PDF_OP_ri,
- PDF_OP_s,
- PDF_OP_sc,
- PDF_OP_scn,
- PDF_OP_v,
- PDF_OP_w,
- PDF_OP_y,
- /* ops in this second section require additional try/catch handling */
- PDF_OP_Do,
- PDF_OP_Tf,
- PDF_OP_gs,
- PDF_OP_sh,
- /* END is used to signify end of stream (finalise and close down) */
- PDF_OP_END,
- /* And finally we have a max */
- PDF_OP_MAX
-} PDF_OP;
-
-typedef struct pdf_processor_s {
- pdf_operator_fn op_table[PDF_OP_MAX];
- pdf_process_annot_fn process_annot;
- pdf_process_stream_fn process_stream;
- pdf_process_contents_fn process_contents;
-} pdf_processor;
-
-typedef struct pdf_process_s
-{
- const pdf_processor *processor;
- void *state;
-} pdf_process;
-
-struct pdf_csi_s
-{
- fz_context *ctx;
- pdf_document *doc;
-
- /* Current resource dict and file. These are in here to reduce param
- * passing. */
- pdf_obj *rdb;
- fz_stream *file;
-
- /* Operator table */
- pdf_process process;
-
- /* interpreter stack */
- pdf_obj *obj;
- char name[256];
- unsigned char string[256];
- int string_len;
- float stack[32];
- int top;
- fz_image *img;
-
- int xbalance;
- int in_text;
-
- fz_rect d1_rect;
-
- /* cookie support */
- fz_cookie *cookie;
-};
-
-static inline void pdf_process_op(pdf_csi *csi, int op, const pdf_process *process)
-{
- process->processor->op_table[op](csi, process->state);
-}
-
-/* Helper functions for the filter implementations to call */
-void pdf_process_contents_object(pdf_csi *csi, pdf_obj *rdb, pdf_obj *contents);
-void pdf_process_stream(pdf_csi *csi, pdf_lexbuf *buf);
-
-/* Functions to set up pdf_process structures */
-pdf_process *pdf_init_process_run(fz_context *ctx, pdf_process *process, fz_device *dev, const fz_matrix *ctm, const char *event, pdf_gstate *gstate, int nested);
-pdf_process *pdf_init_process_buffer(fz_context *ctx, pdf_process *process, fz_buffer *buffer);
-pdf_process *pdf_init_process_filter(fz_context *ctx, pdf_process *process, pdf_process *underlying, pdf_obj *resources);
-
-/* Functions to actually use the pdf_process structures to process
- * annotations, glyphs and general stream objects */
-void pdf_process_annot(fz_context *ctx, pdf_document *doc, pdf_page *page, pdf_annot *annot, const pdf_process *process, fz_cookie *cookie);
-void pdf_process_glyph(fz_context *ctx, pdf_document *doc, pdf_obj *resources, fz_buffer *contents, pdf_process *process);
-void pdf_process_stream_object(fz_context *ctx, pdf_document *doc, pdf_obj *obj, const pdf_process *process, pdf_obj *res, fz_cookie *cookie);
-
-#endif
diff --git a/source/pdf/pdf-interpret.c b/source/pdf/pdf-interpret.c
index a3df4c77..0961b742 100644
--- a/source/pdf/pdf-interpret.c
+++ b/source/pdf/pdf-interpret.c
@@ -1,307 +1,997 @@
-#include "pdf-interpret-imp.h"
+#include "mupdf/pdf.h"
-static pdf_csi *
-pdf_new_csi(fz_context *ctx, pdf_document *doc, fz_cookie *cookie, const pdf_process *process)
+void *
+pdf_new_processor(fz_context *ctx, int size)
{
- pdf_csi *csi = NULL;
+ return Memento_label(fz_calloc(ctx, 1, size), "pdf_processor");
+}
+
+void
+pdf_drop_processor(fz_context *ctx, pdf_processor *proc)
+{
+ if (proc && proc->drop_imp)
+ proc->drop_imp(ctx, proc);
+ fz_free(ctx, proc);
+}
+
+static void
+pdf_init_csi(fz_context *ctx, pdf_csi *csi, pdf_document *doc, pdf_obj *rdb, pdf_lexbuf *buf, fz_cookie *cookie)
+{
+ memset(csi, 0, sizeof *csi);
+ csi->doc = doc;
+ csi->rdb = rdb;
+ csi->buf = buf;
+ csi->cookie = cookie;
+}
+
+static void
+pdf_clear_stack(fz_context *ctx, pdf_csi *csi)
+{
+ int i;
+
+ pdf_drop_obj(ctx, csi->obj);
+ csi->obj = NULL;
- fz_var(csi);
+ csi->name[0] = 0;
+ csi->string_len = 0;
+ for (i = 0; i < csi->top; i++)
+ csi->stack[i] = 0;
+
+ csi->top = 0;
+}
+
+static pdf_font_desc *
+load_font_or_hail_mary(fz_context *ctx, pdf_document *doc, pdf_obj *rdb, pdf_obj *font, int depth, fz_cookie *cookie)
+{
+ pdf_font_desc *desc;
fz_try(ctx)
{
- csi = fz_malloc_struct(ctx, pdf_csi);
- csi->ctx = ctx; /* FIXME */
- csi->doc = doc; /* FIXME */
+ desc = pdf_load_font(ctx, doc, rdb, font, depth);
+ }
+ fz_catch(ctx)
+ {
+ if (fz_caught(ctx) == FZ_ERROR_TRYLATER && cookie && cookie->incomplete_ok)
+ {
+ desc = NULL;
+ cookie->incomplete++;
+ }
+ else
+ {
+ fz_rethrow(ctx);
+ }
+ }
+ if (desc == NULL)
+ desc = pdf_load_hail_mary_font(ctx, doc);
+ return desc;
+}
- csi->in_text = 0;
+static int
+ocg_intents_include(fz_context *ctx, pdf_ocg_descriptor *desc, char *name)
+{
+ int i, len;
- csi->top = 0;
- csi->obj = NULL;
- csi->name[0] = 0;
- csi->string_len = 0;
- memset(csi->stack, 0, sizeof csi->stack);
+ if (strcmp(name, "All") == 0)
+ return 1;
- csi->process = *process;
+ /* In the absence of a specified intent, it's 'View' */
+ if (!desc->intent)
+ return (strcmp(name, "View") == 0);
- csi->xbalance = 0;
- csi->cookie = cookie;
+ if (pdf_is_name(ctx, desc->intent))
+ {
+ char *intent = pdf_to_name(ctx, desc->intent);
+ if (strcmp(intent, "All") == 0)
+ return 1;
+ return (strcmp(intent, name) == 0);
}
- fz_catch(ctx)
+ if (!pdf_is_array(ctx, desc->intent))
+ return 0;
+
+ len = pdf_array_len(ctx, desc->intent);
+ for (i=0; i < len; i++)
{
- pdf_process_op(csi, PDF_OP_END, process);
- fz_free(ctx, csi);
- fz_rethrow(ctx);
+ char *intent = pdf_to_name(ctx, pdf_array_get(ctx, desc->intent, i));
+ if (strcmp(intent, "All") == 0)
+ return 1;
+ if (strcmp(intent, name) == 0)
+ return 1;
+ }
+ return 0;
+}
+
+static int
+pdf_is_hidden_ocg(fz_context *ctx, pdf_ocg_descriptor *desc, pdf_obj *rdb, const char *event, pdf_obj *ocg)
+{
+ char event_state[16];
+ pdf_obj *obj, *obj2;
+ char *type;
+
+ /* Avoid infinite recursions */
+ if (pdf_obj_marked(ctx, ocg))
+ return 0;
+
+ /* If no event, everything is visible */
+ if (!event)
+ return 0;
+
+ /* If no ocg descriptor, everything is visible */
+ if (!desc)
+ return 0;
+
+ /* If we've been handed a name, look it up in the properties. */
+ if (pdf_is_name(ctx, ocg))
+ {
+ ocg = pdf_dict_gets(ctx, pdf_dict_gets(ctx, rdb, "Properties"), pdf_to_name(ctx, ocg));
+ }
+ /* If we haven't been given an ocg at all, then we're visible */
+ if (!ocg)
+ return 0;
+
+ fz_strlcpy(event_state, event, sizeof event_state);
+ fz_strlcat(event_state, "State", sizeof event_state);
+
+ type = pdf_to_name(ctx, pdf_dict_gets(ctx, ocg, "Type"));
+
+ if (strcmp(type, "OCG") == 0)
+ {
+ /* An Optional Content Group */
+ int default_value = 0;
+ int num = pdf_to_num(ctx, ocg);
+ int gen = pdf_to_gen(ctx, ocg);
+ int len = desc->len;
+ int i;
+
+ /* by default an OCG is visible, unless it's explicitly hidden */
+ for (i = 0; i < len; i++)
+ {
+ if (desc->ocgs[i].num == num && desc->ocgs[i].gen == gen)
+ {
+ default_value = desc->ocgs[i].state == 0;
+ break;
+ }
+ }
+
+ /* Check Intents; if our intent is not part of the set given
+ * by the current config, we should ignore it. */
+ obj = pdf_dict_gets(ctx, ocg, "Intent");
+ if (pdf_is_name(ctx, obj))
+ {
+ /* If it doesn't match, it's hidden */
+ if (ocg_intents_include(ctx, desc, pdf_to_name(ctx, obj)) == 0)
+ return 1;
+ }
+ else if (pdf_is_array(ctx, obj))
+ {
+ int match = 0;
+ len = pdf_array_len(ctx, obj);
+ for (i=0; i<len; i++) {
+ match |= ocg_intents_include(ctx, desc, pdf_to_name(ctx, pdf_array_get(ctx, obj, i)));
+ if (match)
+ break;
+ }
+ /* If we don't match any, it's hidden */
+ if (match == 0)
+ return 1;
+ }
+ else
+ {
+ /* If it doesn't match, it's hidden */
+ if (ocg_intents_include(ctx, desc, "View") == 0)
+ return 1;
+ }
+
+ /* FIXME: Currently we do a very simple check whereby we look
+ * at the Usage object (an Optional Content Usage Dictionary)
+ * and check to see if the corresponding 'event' key is on
+ * or off.
+ *
+ * Really we should only look at Usage dictionaries that
+ * correspond to entries in the AS list in the OCG config.
+ * Given that we don't handle Zoom or User, or Language
+ * dicts, this is not really a problem. */
+ obj = pdf_dict_gets(ctx, ocg, "Usage");
+ if (!pdf_is_dict(ctx, obj))
+ return default_value;
+ /* FIXME: Should look at Zoom (and return hidden if out of
+ * max/min range) */
+ /* FIXME: Could provide hooks to the caller to check if
+ * User is appropriate - if not return hidden. */
+ obj2 = pdf_dict_gets(ctx, obj, event);
+ if (strcmp(pdf_to_name(ctx, pdf_dict_gets(ctx, obj2, event_state)), "OFF") == 0)
+ {
+ return 1;
+ }
+ if (strcmp(pdf_to_name(ctx, pdf_dict_gets(ctx, obj2, event_state)), "ON") == 0)
+ {
+ return 0;
+ }
+ return default_value;
}
+ else if (strcmp(type, "OCMD") == 0)
+ {
+ /* An Optional Content Membership Dictionary */
+ char *name;
+ int combine, on;
+
+ obj = pdf_dict_gets(ctx, ocg, "VE");
+ if (pdf_is_array(ctx, obj)) {
+ /* FIXME: Calculate visibility from array */
+ return 0;
+ }
+ name = pdf_to_name(ctx, pdf_dict_gets(ctx, ocg, "P"));
+ /* Set combine; Bit 0 set => AND, Bit 1 set => true means
+ * Off, otherwise true means On */
+ if (strcmp(name, "AllOn") == 0)
+ {
+ combine = 1;
+ }
+ else if (strcmp(name, "AnyOff") == 0)
+ {
+ combine = 2;
+ }
+ else if (strcmp(name, "AllOff") == 0)
+ {
+ combine = 3;
+ }
+ else /* Assume it's the default (AnyOn) */
+ {
+ combine = 0;
+ }
- return csi;
+ if (pdf_mark_obj(ctx, ocg))
+ return 0; /* Should never happen */
+ fz_try(ctx)
+ {
+ obj = pdf_dict_gets(ctx, ocg, "OCGs");
+ on = combine & 1;
+ if (pdf_is_array(ctx, obj)) {
+ int i, len;
+ len = pdf_array_len(ctx, obj);
+ for (i = 0; i < len; i++)
+ {
+ int hidden = pdf_is_hidden_ocg(ctx, desc, rdb, event, pdf_array_get(ctx, obj, i));
+ if ((combine & 1) == 0)
+ hidden = !hidden;
+ if (combine & 2)
+ on &= hidden;
+ else
+ on |= hidden;
+ }
+ }
+ else
+ {
+ on = pdf_is_hidden_ocg(ctx, desc, rdb, event, obj);
+ if ((combine & 1) == 0)
+ on = !on;
+ }
+ }
+ fz_always(ctx)
+ {
+ pdf_unmark_obj(ctx, ocg);
+ }
+ fz_catch(ctx)
+ {
+ fz_rethrow(ctx);
+ }
+ return !on;
+ }
+ /* No idea what sort of object this is - be visible */
+ return 0;
}
-static void
-pdf_clear_stack(pdf_csi *csi)
+static fz_image *
+parse_inline_image(fz_context *ctx, pdf_csi *csi, fz_stream *stm)
{
- fz_context *ctx = csi->ctx;
+ pdf_document *doc = csi->doc;
+ pdf_obj *rdb = csi->rdb;
+ pdf_obj *obj = NULL;
+ fz_image *img = NULL;
+ int ch, found;
- int i;
+ fz_var(obj);
+ fz_var(img);
- fz_drop_image(ctx, csi->img);
- csi->img = NULL;
+ fz_try(ctx)
+ {
+ obj = pdf_parse_dict(ctx, doc, stm, &doc->lexbuf.base);
- pdf_drop_obj(ctx, csi->obj);
- csi->obj = NULL;
+ /* read whitespace after ID keyword */
+ ch = fz_read_byte(ctx, stm);
+ if (ch == '\r')
+ if (fz_peek_byte(ctx, stm) == '\n')
+ fz_read_byte(ctx, stm);
- csi->name[0] = 0;
- csi->string_len = 0;
- for (i = 0; i < csi->top; i++)
- csi->stack[i] = 0;
+ img = pdf_load_inline_image(ctx, doc, rdb, obj, stm);
- csi->top = 0;
+ /* find EI */
+ found = 0;
+ ch = fz_read_byte(ctx, stm);
+ do
+ {
+ while (ch != 'E' && ch != EOF)
+ ch = fz_read_byte(ctx, stm);
+ if (ch == 'E')
+ {
+ ch = fz_read_byte(ctx, stm);
+ if (ch == 'I')
+ {
+ ch = fz_peek_byte(ctx, stm);
+ if (ch == ' ' || ch <= 32 || ch == EOF || ch == '<' || ch == '/')
+ {
+ found = 1;
+ break;
+ }
+ }
+ }
+ } while (ch != EOF);
+ if (!found)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "syntax error after inline image");
+ }
+ fz_catch(ctx)
+ {
+ pdf_drop_obj(ctx, obj);
+ fz_drop_image(ctx, img);
+ fz_rethrow(ctx);
+ }
+
+ return img;
}
static void
-pdf_drop_csi(pdf_csi *csi)
+pdf_process_extgstate(fz_context *ctx, pdf_processor *proc, pdf_csi *csi, pdf_obj *dict)
{
- fz_context *ctx = csi->ctx;
+ pdf_obj *obj;
- pdf_process_op(csi, PDF_OP_END, &csi->process);
- fz_free(ctx, csi);
-}
+ obj = pdf_dict_gets(ctx, dict, "LW");
+ if (pdf_is_number(ctx, obj) && proc->op_w)
+ proc->op_w(ctx, proc, pdf_to_real(ctx, obj));
-#define A(a) (a)
-#define B(a,b) (a | b << 8)
-#define C(a,b,c) (a | b << 8 | c << 16)
+ obj = pdf_dict_gets(ctx, dict, "LC");
+ if (pdf_is_int(ctx, obj) && proc->op_J)
+ proc->op_J(ctx, proc, pdf_to_int(ctx, obj));
+
+ obj = pdf_dict_gets(ctx, dict, "LJ");
+ if (pdf_is_int(ctx, obj) && proc->op_j)
+ proc->op_j(ctx, proc, pdf_to_int(ctx, obj));
+
+ obj = pdf_dict_gets(ctx, dict, "ML");
+ if (pdf_is_number(ctx, obj) && proc->op_M)
+ proc->op_M(ctx, proc, pdf_to_real(ctx, obj));
+
+ obj = pdf_dict_gets(ctx, dict, "D");
+ if (pdf_is_array(ctx, obj) && proc->op_d)
+ {
+ pdf_obj *dash_array = pdf_array_get(ctx, obj, 0);
+ pdf_obj *dash_phase = pdf_array_get(ctx, obj, 1);
+ proc->op_d(ctx, proc, dash_array, pdf_to_real(ctx, dash_phase));
+ }
+
+ obj = pdf_dict_gets(ctx, dict, "RI");
+ if (pdf_is_name(ctx, obj) && proc->op_ri)
+ proc->op_ri(ctx, proc, pdf_to_name(ctx, obj));
+
+ obj = pdf_dict_gets(ctx, dict, "FL");
+ if (pdf_is_number(ctx, obj) && proc->op_i)
+ proc->op_i(ctx, proc, pdf_to_real(ctx, obj));
+
+ obj = pdf_dict_gets(ctx, dict, "Font");
+ if (pdf_is_array(ctx, obj) && proc->op_Tf)
+ {
+ pdf_obj *font_ref = pdf_array_get(ctx, obj, 0);
+ pdf_obj *font_size = pdf_array_get(ctx, obj, 1);
+ pdf_font_desc *font = load_font_or_hail_mary(ctx, csi->doc, csi->rdb, font_ref, 0, csi->cookie);
+ fz_try(ctx)
+ proc->op_Tf(ctx, proc, "ExtGState", font, pdf_to_real(ctx, font_size));
+ fz_always(ctx)
+ pdf_drop_font(ctx, font);
+ fz_catch(ctx)
+ fz_rethrow(ctx);
+ }
+
+ /* transfer functions */
+
+ obj = pdf_dict_gets(ctx, dict, "TR2");
+ if (pdf_is_name(ctx, obj))
+ if (strcmp(pdf_to_name(ctx, obj), "Identity") && strcmp(pdf_to_name(ctx, obj), "Default"))
+ fz_warn(ctx, "ignoring transfer function");
+ if (!obj) /* TR is ignored in the presence of TR2 */
+ {
+ pdf_obj *tr = pdf_dict_gets(ctx, dict, "TR");
+ if (pdf_is_name(ctx, tr))
+ if (strcmp(pdf_to_name(ctx, tr), "Identity"))
+ fz_warn(ctx, "ignoring transfer function");
+ }
+
+ /* transparency state */
+
+ obj = pdf_dict_gets(ctx, dict, "CA");
+ if (pdf_is_number(ctx, obj) && proc->op_gs_CA)
+ proc->op_gs_CA(ctx, proc, pdf_to_real(ctx, obj));
+
+ obj = pdf_dict_gets(ctx, dict, "ca");
+ if (pdf_is_number(ctx, obj) && proc->op_gs_ca)
+ proc->op_gs_ca(ctx, proc, pdf_to_real(ctx, obj));
+
+ obj = pdf_dict_gets(ctx, dict, "BM");
+ if (pdf_is_array(ctx, obj))
+ obj = pdf_array_get(ctx, obj, 0);
+ if (pdf_is_name(ctx, obj) && proc->op_gs_BM)
+ proc->op_gs_BM(ctx, proc, pdf_to_name(ctx, obj));
+
+ obj = pdf_dict_gets(ctx, dict, "SMask");
+ if (proc->op_gs_SMask)
+ {
+ if (pdf_is_dict(ctx, obj))
+ {
+ pdf_xobject *xobj;
+ pdf_obj *group, *s, *bc, *tr;
+ float softmask_bc[FZ_MAX_COLORS];
+ fz_colorspace *colorspace;
+ int k, luminosity;
+
+ fz_var(xobj);
+
+ group = pdf_dict_gets(ctx, obj, "G");
+ if (!group)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "cannot load softmask xobject (%d %d R)", pdf_to_num(ctx, obj), pdf_to_gen(ctx, obj));
+ xobj = pdf_load_xobject(ctx, csi->doc, group);
+
+ fz_try(ctx)
+ {
+ colorspace = xobj->colorspace;
+ if (!colorspace)
+ colorspace = fz_device_gray(ctx);
+
+ for (k = 0; k < colorspace->n; k++)
+ softmask_bc[k] = 0;
+
+ bc = pdf_dict_gets(ctx, obj, "BC");
+ if (pdf_is_array(ctx, bc))
+ {
+ for (k = 0; k < colorspace->n; k++)
+ softmask_bc[k] = pdf_to_real(ctx, pdf_array_get(ctx, bc, k));
+ }
+
+ s = pdf_dict_gets(ctx, obj, "S");
+ if (pdf_is_name(ctx, s) && !strcmp(pdf_to_name(ctx, s), "Luminosity"))
+ luminosity = 1;
+ else
+ luminosity = 0;
+
+ tr = pdf_dict_gets(ctx, obj, "TR");
+ if (tr && strcmp(pdf_to_name(ctx, tr), "Identity"))
+ fz_warn(ctx, "ignoring transfer function");
+
+ proc->op_gs_SMask(ctx, proc, xobj, csi->rdb, softmask_bc, luminosity);
+ }
+ fz_always(ctx)
+ {
+ pdf_drop_xobject(ctx, xobj);
+ }
+ fz_catch(ctx)
+ {
+ fz_rethrow(ctx);
+ }
+ }
+ else if (pdf_is_name(ctx, obj) && !strcmp(pdf_to_name(ctx, obj), "None"))
+ {
+ proc->op_gs_SMask(ctx, proc, NULL, NULL, NULL, 0);
+ }
+ }
+}
static void
-parse_inline_image(pdf_csi *csi)
+pdf_process_Do(fz_context *ctx, pdf_processor *proc, pdf_csi *csi)
{
- fz_context *ctx = csi->ctx;
- pdf_document *doc = csi->doc;
+ pdf_obj *xres, *xobj, *subtype;
+
+ xres = pdf_dict_gets(ctx, csi->rdb, "XObject");
+ if (!xres)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find XObject dictionary");
+ xobj = pdf_dict_gets(ctx, xres, csi->name);
+ if (!xobj)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find XObject resource '%s'", csi->name);
+ subtype = pdf_dict_gets(ctx, xobj, "Subtype");
+ if (!strcmp(pdf_to_name(ctx, subtype), "Form") && pdf_dict_gets(ctx, xobj, "Subtype2"))
+ subtype = pdf_dict_gets(ctx, xobj, "Subtype2");
+ if (!pdf_is_name(ctx, subtype))
+ fz_throw(ctx, FZ_ERROR_GENERIC, "no XObject subtype specified");
+
+ if (pdf_is_hidden_ocg(ctx, csi->doc->ocg, csi->rdb, proc->event, pdf_dict_gets(ctx, xobj, "OC")))
+ return;
- pdf_obj *rdb = csi->rdb;
- fz_stream *file = csi->file;
- int ch, found;
+ if (!strcmp(pdf_to_name(ctx, subtype), "Form"))
+ {
+ if (proc->op_Do_form)
+ {
+ pdf_xobject *form = pdf_load_xobject(ctx, csi->doc, xobj);
- fz_drop_image(ctx, csi->img);
- csi->img = NULL;
- pdf_drop_obj(ctx, csi->obj);
- csi->obj = NULL;
+ fz_try(ctx)
+ proc->op_Do_form(ctx, proc, csi->name, form, csi->rdb);
+ fz_always(ctx)
+ pdf_drop_xobject(ctx, form);
+ fz_catch(ctx)
+ fz_rethrow(ctx);
+ }
+ }
- csi->obj = pdf_parse_dict(ctx, doc, file, &doc->lexbuf.base);
+ else if (!strcmp(pdf_to_name(ctx, subtype), "Image"))
+ {
+ if (proc->op_Do_image)
+ {
+ fz_image *image = pdf_load_image(ctx, csi->doc, xobj);
+ fz_try(ctx)
+ proc->op_Do_image(ctx, proc, csi->name, image);
+ fz_always(ctx)
+ fz_drop_image(ctx, image);
+ fz_catch(ctx)
+ fz_rethrow(ctx);
+ }
+ }
- /* read whitespace after ID keyword */
- ch = fz_read_byte(ctx, file);
- if (ch == '\r')
- if (fz_peek_byte(ctx, file) == '\n')
- fz_read_byte(ctx, file);
+ else if (!strcmp(pdf_to_name(ctx, subtype), "PS"))
+ fz_warn(ctx, "ignoring XObject with subtype PS");
+ else
+ fz_warn(ctx, "ignoring XObject with unknown subtype: '%s'", pdf_to_name(ctx, subtype));
+}
- fz_try(ctx)
+static void
+pdf_process_CS(fz_context *ctx, pdf_processor *proc, pdf_csi *csi, int stroke)
+{
+ if (!proc->op_CS || !proc->op_cs)
+ return;
+
+ if (!strcmp(csi->name, "Pattern"))
{
- csi->img = pdf_load_inline_image(ctx, doc, rdb, csi->obj, file);
+ if (stroke)
+ proc->op_CS(ctx, proc, "Pattern", NULL);
+ else
+ proc->op_cs(ctx, proc, "Pattern", NULL);
}
- fz_catch(ctx)
+ else
{
- fz_rethrow(ctx);
+ fz_colorspace *cs;
+
+ if (!strcmp(csi->name, "DeviceGray"))
+ cs = fz_keep_colorspace(ctx, fz_device_gray(ctx));
+ else if (!strcmp(csi->name, "DeviceRGB"))
+ cs = fz_keep_colorspace(ctx, fz_device_rgb(ctx));
+ else if (!strcmp(csi->name, "DeviceCMYK"))
+ cs = fz_keep_colorspace(ctx, fz_device_cmyk(ctx));
+ else
+ {
+ pdf_obj *csres, *csobj;
+ csres = pdf_dict_gets(ctx, csi->rdb, "ColorSpace");
+ if (!csres)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find ColorSpace dictionary");
+ csobj = pdf_dict_gets(ctx, csres, csi->name);
+ if (!csobj)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find ColorSpace resource '%s'", csi->name);
+ cs = pdf_load_colorspace(ctx, csi->doc, csobj);
+ }
+
+ fz_try(ctx)
+ {
+ if (stroke)
+ proc->op_CS(ctx, proc, csi->name, cs);
+ else
+ proc->op_cs(ctx, proc, csi->name, cs);
+ }
+ fz_always(ctx)
+ fz_drop_colorspace(ctx, cs);
+ fz_catch(ctx)
+ fz_rethrow(ctx);
}
+}
- /* find EI */
- found = 0;
- ch = fz_read_byte(ctx, file);
- do
+static void
+pdf_process_SC(fz_context *ctx, pdf_processor *proc, pdf_csi *csi, int stroke)
+{
+ if (csi->name[0])
{
- while (ch != 'E' && ch != EOF)
- ch = fz_read_byte(ctx, file);
- if (ch == 'E')
+ pdf_obj *patres, *patobj, *type;
+
+ patres = pdf_dict_gets(ctx, csi->rdb, "Pattern");
+ if (!patres)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find Pattern dictionary");
+ patobj = pdf_dict_gets(ctx, patres, csi->name);
+ if (!patobj)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find Pattern resource '%s'", csi->name);
+
+ type = pdf_dict_gets(ctx, patobj, "PatternType");
+
+ if (pdf_to_int(ctx, type) == 1)
{
- ch = fz_read_byte(ctx, file);
- if (ch == 'I')
+ if (proc->op_SC_pattern && proc->op_sc_pattern)
{
- ch = fz_peek_byte(ctx, file);
- if (ch == ' ' || ch <= 32 || ch == EOF || ch == '<' || ch == '/')
+ pdf_pattern *pat = pdf_load_pattern(ctx, csi->doc, patobj);
+ fz_try(ctx)
{
- found = 1;
- break;
+ if (stroke)
+ proc->op_SC_pattern(ctx, proc, csi->name, pat, csi->top, csi->stack);
+ else
+ proc->op_sc_pattern(ctx, proc, csi->name, pat, csi->top, csi->stack);
}
+ fz_always(ctx)
+ pdf_drop_pattern(ctx, pat);
+ fz_catch(ctx)
+ fz_rethrow(ctx);
}
}
- } while (ch != EOF);
- if (!found)
- fz_throw(ctx, FZ_ERROR_GENERIC, "syntax error after inline image");
+
+ else if (pdf_to_int(ctx, type) == 2)
+ {
+ if (proc->op_SC_shade && proc->op_sc_shade)
+ {
+ fz_shade *shade = pdf_load_shading(ctx, csi->doc, patobj);
+ fz_try(ctx)
+ {
+ if (stroke)
+ proc->op_SC_shade(ctx, proc, csi->name, shade);
+ else
+ proc->op_sc_shade(ctx, proc, csi->name, shade);
+ }
+ fz_always(ctx)
+ fz_drop_shade(ctx, shade);
+ fz_catch(ctx)
+ fz_rethrow(ctx);
+ }
+ }
+
+ else
+ {
+ fz_throw(ctx, FZ_ERROR_GENERIC, "unknown pattern type: %d", pdf_to_int(ctx, type));
+ }
+ }
+
+ else
+ {
+ if (proc->op_SC_color && proc->op_sc_color)
+ {
+ if (stroke)
+ proc->op_SC_color(ctx, proc, csi->top, csi->stack);
+ else
+ proc->op_sc_color(ctx, proc, csi->top, csi->stack);
+ }
+ }
}
-static int
-pdf_run_keyword(pdf_csi *csi, char *buf)
+static pdf_obj *
+resolve_properties(fz_context *ctx, pdf_csi *csi, pdf_obj *obj)
+{
+ if (pdf_is_name(ctx, obj))
+ return pdf_dict_gets(ctx, pdf_dict_gets(ctx, csi->rdb, "Properties"), pdf_to_name(ctx, obj));
+ else
+ return obj;
+}
+
+static void
+pdf_process_BDC(fz_context *ctx, pdf_processor *proc, pdf_csi *csi, const char *name, pdf_obj *properties)
{
- fz_context *ctx = csi->ctx;
+ if (proc->op_BDC)
+ proc->op_BDC(ctx, proc, name, properties);
+ /* Already hidden, no need to look further */
+ if (proc->hidden > 0)
+ {
+ ++proc->hidden;
+ return;
+ }
+
+ /* We only look at OC groups here */
+ if (strcmp(name, "OC"))
+ return;
+
+ /* No Properties array, or name not found, means visible. */
+ if (!properties)
+ return;
+
+ /* Wrong type of property */
+ if (strcmp(pdf_to_name(ctx, pdf_dict_gets(ctx, properties, "Type")), "OCG"))
+ return;
+
+ if (pdf_is_hidden_ocg(ctx, csi->doc->ocg, csi->rdb, proc->event, properties))
+ ++proc->hidden;
+}
+
+static void
+pdf_process_BMC(fz_context *ctx, pdf_processor *proc, pdf_csi *csi, const char *name)
+{
+ if (proc->op_BMC)
+ proc->op_BMC(ctx, proc, name);
+ if (proc->hidden > 0)
+ ++proc->hidden;
+}
+
+static void
+pdf_process_EMC(fz_context *ctx, pdf_processor *proc, pdf_csi *csi)
+{
+ if (proc->op_EMC)
+ proc->op_EMC(ctx, proc);
+ if (proc->hidden > 0)
+ --proc->hidden;
+}
+
+static void
+pdf_process_gsave(fz_context *ctx, pdf_processor *proc, pdf_csi *csi)
+{
+ if (proc->op_q)
+ proc->op_q(ctx, proc);
+ ++csi->gstate;
+}
+
+static void
+pdf_process_grestore(fz_context *ctx, pdf_processor *proc, pdf_csi *csi)
+{
+ if (csi->gstate > 0)
+ {
+ if (proc->op_Q)
+ proc->op_Q(ctx, proc);
+ --csi->gstate;
+ }
+}
+
+static void
+pdf_process_end(fz_context *ctx, pdf_processor *proc, pdf_csi *csi)
+{
+ while (csi->gstate > 0)
+ pdf_process_grestore(ctx, proc, csi);
+ if (proc->op_END)
+ proc->op_END(ctx, proc);
+}
+
+#define A(a) (a)
+#define B(a,b) (a | b << 8)
+#define C(a,b,c) (a | b << 8 | c << 16)
+
+static int
+pdf_process_keyword(fz_context *ctx, pdf_processor *proc, pdf_csi *csi, fz_stream *stm, char *word)
+{
+ float *s = csi->stack;
int key;
- PDF_OP op;
- key = buf[0];
- if (buf[1])
+ key = word[0];
+ if (word[1])
{
- key |= buf[1] << 8;
- if (buf[2])
+ key |= word[1] << 8;
+ if (word[2])
{
- key |= buf[2] << 16;
- if (buf[3])
+ key |= word[2] << 16;
+ if (word[3])
key = 0;
}
}
switch (key)
{
- case A('"'): op = PDF_OP_dquote; break;
- case A('\''): op = PDF_OP_squote; break;
- case A('B'): op = PDF_OP_B; break;
- case B('B','*'): op = PDF_OP_Bstar; break;
- case C('B','D','C'): op = PDF_OP_BDC; break;
- case B('B','I'): op = PDF_OP_BI; break;
- case C('B','M','C'): op = PDF_OP_BMC; break;
- case B('B','T'):
- op = PDF_OP_BT;
- csi->in_text = 1;
- break;
- case B('B','X'):
- op = PDF_OP_BX;
- csi->xbalance++;
- break;
- case B('C','S'): op = PDF_OP_CS; break;
- case B('D','P'): op = PDF_OP_DP; break;
- case B('D','o'): op = PDF_OP_Do; break;
- case C('E','M','C'): op = PDF_OP_EMC; break;
- case B('E','T'):
- op = PDF_OP_ET;
- csi->in_text = 0;
- break;
- case B('E','X'):
- op = PDF_OP_EX;
- csi->xbalance--;
- break;
- case A('F'): op = PDF_OP_F; break;
- case A('G'): op = PDF_OP_G; break;
- case A('J'): op = PDF_OP_J; break;
- case A('K'): op = PDF_OP_K; break;
- case A('M'): op = PDF_OP_M; break;
- case B('M','P'): op = PDF_OP_MP; break;
- case A('Q'): op = PDF_OP_Q; break;
- case B('R','G'): op = PDF_OP_RG; break;
- case A('S'): op = PDF_OP_S; break;
- case B('S','C'): op = PDF_OP_SC; break;
- case C('S','C','N'): op = PDF_OP_SCN; break;
- case B('T','*'): op = PDF_OP_Tstar; break;
- case B('T','D'): op = PDF_OP_TD; break;
- case B('T','J'): op = PDF_OP_TJ; break;
- case B('T','L'): op = PDF_OP_TL; break;
- case B('T','c'): op = PDF_OP_Tc; break;
- case B('T','d'): op = PDF_OP_Td; break;
- case B('T','f'): op = PDF_OP_Tf; break;
- case B('T','j'): op = PDF_OP_Tj; break;
- case B('T','m'): op = PDF_OP_Tm; break;
- case B('T','r'): op = PDF_OP_Tr; break;
- case B('T','s'): op = PDF_OP_Ts; break;
- case B('T','w'): op = PDF_OP_Tw; break;
- case B('T','z'): op = PDF_OP_Tz; break;
- case A('W'): op = PDF_OP_W; break;
- case B('W','*'): op = PDF_OP_Wstar; break;
- case A('b'): op = PDF_OP_b; break;
- case B('b','*'): op = PDF_OP_bstar; break;
- case A('c'): op = PDF_OP_c; break;
- case B('c','m'): op = PDF_OP_cm; break;
- case B('c','s'): op = PDF_OP_cs; break;
- case A('d'): op = PDF_OP_d; break;
- case B('d','0'): op = PDF_OP_d0; break;
- case B('d','1'): op = PDF_OP_d1; break;
- case A('f'): op = PDF_OP_f; break;
- case B('f','*'): op = PDF_OP_fstar; break;
- case A('g'): op = PDF_OP_g; break;
- case B('g','s'): op = PDF_OP_gs; break;
- case A('h'): op = PDF_OP_h; break;
- case A('i'): op = PDF_OP_i; break;
- case A('j'): op = PDF_OP_j; break;
- case A('k'): op = PDF_OP_k; break;
- case A('l'): op = PDF_OP_l; break;
- case A('m'): op = PDF_OP_m; break;
- case A('n'): op = PDF_OP_n; break;
- case A('q'): op = PDF_OP_q; break;
- case B('r','e'): op = PDF_OP_re; break;
- case B('r','g'): op = PDF_OP_rg; break;
- case B('r','i'): op = PDF_OP_ri; break;
- case A('s'): op = PDF_OP_s; break;
- case B('s','c'): op = PDF_OP_sc; break;
- case C('s','c','n'): op = PDF_OP_scn; break;
- case B('s','h'): op = PDF_OP_sh; break;
- case A('v'): op = PDF_OP_v; break;
- case A('w'): op = PDF_OP_w; break;
- case A('y'): op = PDF_OP_y; break;
default:
if (!csi->xbalance)
{
- fz_warn(ctx, "unknown keyword: '%s'", buf);
+ fz_warn(ctx, "unknown keyword: '%s'", word);
return 1;
}
- return 0;
- }
+ break;
- if (op == PDF_OP_BI)
- {
- parse_inline_image(csi);
- }
+ /* general graphics state */
+ case A('w'): if (proc->op_w) proc->op_w(ctx, proc, s[0]); break;
+ case A('j'): if (proc->op_j) proc->op_j(ctx, proc, s[0]); break;
+ case A('J'): if (proc->op_J) proc->op_J(ctx, proc, s[0]); break;
+ case A('M'): if (proc->op_M) proc->op_M(ctx, proc, s[0]); break;
+ case A('d'): if (proc->op_d) proc->op_d(ctx, proc, csi->obj, s[0]); break;
+ case B('r','i'): if (proc->op_ri) proc->op_ri(ctx, proc, csi->name); break;
+ case A('i'): if (proc->op_i) proc->op_i(ctx, proc, s[0]); break;
- if (op < PDF_OP_Do)
- {
- pdf_process_op(csi, op, &csi->process);
- }
- else if (op < PDF_OP_END)
- {
- fz_try(ctx)
+ case B('g','s'):
{
- pdf_process_op(csi, op, &csi->process);
+ pdf_obj *gsres, *gsobj;
+ gsres = pdf_dict_gets(ctx, csi->rdb, "ExtGState");
+ if (!gsres)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find ExtGState dictionary");
+ gsobj = pdf_dict_gets(ctx, gsres, csi->name);
+ if (!gsobj)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find ExtGState resource '%s'", csi->name);
+ if (proc->op_gs_begin)
+ proc->op_gs_begin(ctx, proc, csi->name, gsobj);
+ pdf_process_extgstate(ctx, proc, csi, gsobj);
+ if (proc->op_gs_end)
+ proc->op_gs_end(ctx, proc);
}
- fz_catch(ctx)
+ break;
+
+ /* special graphics state */
+ case A('q'): pdf_process_gsave(ctx, proc, csi); break;
+ case A('Q'): pdf_process_grestore(ctx, proc, csi); break;
+ case B('c','m'): if (proc->op_cm) proc->op_cm(ctx, proc, s[0], s[1], s[2], s[3], s[4], s[5]); break;
+
+ /* path construction */
+ case A('m'): if (proc->op_m) proc->op_m(ctx, proc, s[0], s[1]); break;
+ case A('l'): if (proc->op_l) proc->op_l(ctx, proc, s[0], s[1]); break;
+ case A('c'): if (proc->op_c) proc->op_c(ctx, proc, s[0], s[1], s[2], s[3], s[4], s[5]); break;
+ case A('v'): if (proc->op_v) proc->op_v(ctx, proc, s[0], s[1], s[2], s[3]); break;
+ case A('y'): if (proc->op_y) proc->op_y(ctx, proc, s[0], s[1], s[2], s[3]); break;
+ case A('h'): if (proc->op_h) proc->op_h(ctx, proc); break;
+ case B('r','e'): if (proc->op_re) proc->op_re(ctx, proc, s[0], s[1], s[2], s[3]); break;
+
+ /* path painting */
+ case A('S'): if (proc->op_S) proc->op_S(ctx, proc); break;
+ case A('s'): if (proc->op_s) proc->op_s(ctx, proc); break;
+ case A('F'): if (proc->op_F) proc->op_F(ctx, proc); break;
+ case A('f'): if (proc->op_f) proc->op_f(ctx, proc); break;
+ case B('f','*'): if (proc->op_fstar) proc->op_fstar(ctx, proc); break;
+ case A('B'): if (proc->op_B) proc->op_B(ctx, proc); break;
+ case B('B','*'): if (proc->op_Bstar) proc->op_Bstar(ctx, proc); break;
+ case A('b'): if (proc->op_b) proc->op_b(ctx, proc); break;
+ case B('b','*'): if (proc->op_bstar) proc->op_bstar(ctx, proc); break;
+ case A('n'): if (proc->op_n) proc->op_n(ctx, proc); break;
+
+ /* path clipping */
+ case A('W'): if (proc->op_W) proc->op_W(ctx, proc); break;
+ case B('W','*'): if (proc->op_Wstar) proc->op_Wstar(ctx, proc); break;
+
+ /* text objects */
+ case B('B','T'): csi->in_text = 1; if (proc->op_BT) proc->op_BT(ctx, proc); break;
+ case B('E','T'): csi->in_text = 0; if (proc->op_ET) proc->op_ET(ctx, proc); break;
+
+ /* text state */
+ case B('T','c'): if (proc->op_Tc) proc->op_Tc(ctx, proc, s[0]); break;
+ case B('T','w'): if (proc->op_Tw) proc->op_Tw(ctx, proc, s[0]); break;
+ case B('T','z'): if (proc->op_Tz) proc->op_Tz(ctx, proc, s[0]); break;
+ case B('T','L'): if (proc->op_TL) proc->op_TL(ctx, proc, s[0]); break;
+ case B('T','r'): if (proc->op_Tr) proc->op_Tr(ctx, proc, s[0]); break;
+ case B('T','s'): if (proc->op_Ts) proc->op_Ts(ctx, proc, s[0]); break;
+
+ case B('T','f'):
+ if (proc->op_Tf)
+ {
+ pdf_obj *fontres, *fontobj;
+ pdf_font_desc *font;
+ fontres = pdf_dict_gets(ctx, csi->rdb, "Font");
+ if (!fontres)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find Font dictionary");
+ fontobj = pdf_dict_gets(ctx, fontres, csi->name);
+ if (!fontobj)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find Font resource '%s'", csi->name);
+ font = load_font_or_hail_mary(ctx, csi->doc, csi->rdb, fontobj, 0, csi->cookie);
+ fz_try(ctx)
+ proc->op_Tf(ctx, proc, csi->name, font, s[0]); break;
+ fz_always(ctx)
+ pdf_drop_font(ctx, font);
+ fz_catch(ctx)
+ fz_rethrow(ctx);
+ }
+ break;
+
+ /* text positioning */
+ case B('T','d'): if (proc->op_Td) proc->op_Td(ctx, proc, s[0], s[1]); break;
+ case B('T','D'): if (proc->op_TD) proc->op_TD(ctx, proc, s[0], s[1]); break;
+ case B('T','m'): if (proc->op_Tm) proc->op_Tm(ctx, proc, s[0], s[1], s[2], s[3], s[4], s[5]); break;
+ case B('T','*'): if (proc->op_Tstar) proc->op_Tstar(ctx, proc); break;
+
+ /* text showing */
+ case B('T','J'): if (proc->op_TJ) proc->op_TJ(ctx, proc, csi->obj); break;
+ case B('T','j'):
+ if (proc->op_Tj)
+ {
+ if (csi->string_len > 0)
+ proc->op_Tj(ctx, proc, csi->string, csi->string_len);
+ else
+ proc->op_Tj(ctx, proc, pdf_to_str_buf(ctx, csi->obj), pdf_to_str_len(ctx, csi->obj));
+ }
+ break;
+ case A('\''):
+ if (proc->op_squote)
{
- fz_rethrow_if(ctx, FZ_ERROR_ABORT);
- switch (op)
+ if (csi->string_len > 0)
+ proc->op_squote(ctx, proc, csi->string, csi->string_len);
+ else
+ proc->op_squote(ctx, proc, pdf_to_str_buf(ctx, csi->obj), pdf_to_str_len(ctx, csi->obj));
+ }
+ break;
+ case A('"'):
+ if (proc->op_dquote)
+ {
+ if (csi->string_len > 0)
+ proc->op_dquote(ctx, proc, s[0], s[1], csi->string, csi->string_len);
+ else
+ proc->op_dquote(ctx, proc, s[0], s[1], pdf_to_str_buf(ctx, csi->obj), pdf_to_str_len(ctx, csi->obj));
+ }
+ break;
+
+ /* type 3 fonts */
+ case B('d','0'): if (proc->op_d0) proc->op_d0(ctx, proc, s[0], s[1]); break;
+ case B('d','1'): if (proc->op_d1) proc->op_d1(ctx, proc, s[0], s[1], s[2], s[3], s[4], s[5]); break;
+
+ /* color */
+ case B('C','S'): pdf_process_CS(ctx, proc, csi, 1); break;
+ case B('c','s'): pdf_process_CS(ctx, proc, csi, 0); break;
+ case B('S','C'): pdf_process_SC(ctx, proc, csi, 1); break;
+ case B('s','c'): pdf_process_SC(ctx, proc, csi, 0); break;
+ case C('S','C','N'): pdf_process_SC(ctx, proc, csi, 1); break;
+ case C('s','c','n'): pdf_process_SC(ctx, proc, csi, 0); break;
+
+ case A('G'): if (proc->op_G) proc->op_G(ctx, proc, s[0]); break;
+ case A('g'): if (proc->op_g) proc->op_g(ctx, proc, s[0]); break;
+ case B('R','G'): if (proc->op_RG) proc->op_RG(ctx, proc, s[0], s[1], s[2]); break;
+ case B('r','g'): if (proc->op_rg) proc->op_rg(ctx, proc, s[0], s[1], s[2]); break;
+ case A('K'): if (proc->op_K) proc->op_K(ctx, proc, s[0], s[1], s[2], s[3]); break;
+ case A('k'): if (proc->op_k) proc->op_k(ctx, proc, s[0], s[1], s[2], s[3]); break;
+
+ /* shadings, images, xobjects */
+ case B('B','I'):
+ {
+ fz_image *img = parse_inline_image(ctx, csi, stm);
+ fz_try(ctx)
{
- case PDF_OP_Do:
- fz_rethrow_message(ctx, "cannot draw xobject/image");
- break;
- case PDF_OP_Tf:
- fz_rethrow_message(ctx, "cannot set font");
- break;
- case PDF_OP_gs:
- fz_rethrow_message(ctx, "cannot set graphics state");
- break;
- case PDF_OP_sh:
- fz_rethrow_message(ctx, "cannot draw shading");
- break;
- default:
- fz_rethrow(ctx); /* Should never happen */
+ if (proc->op_BI)
+ proc->op_BI(ctx, proc, img);
}
+ fz_always(ctx)
+ fz_drop_image(ctx, img);
+ fz_catch(ctx)
+ fz_rethrow(ctx);
}
+ break;
+
+ case B('s','h'):
+ if (proc->op_sh)
+ {
+ pdf_obj *shaderes, *shadeobj;
+ fz_shade *shade;
+ shaderes = pdf_dict_gets(ctx, csi->rdb, "Shading");
+ if (!shaderes)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find Shading dictionary");
+ shadeobj = pdf_dict_gets(ctx, shaderes, csi->name);
+ if (!shadeobj)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find Shading resource '%s'", csi->name);
+ shade = pdf_load_shading(ctx, csi->doc, shadeobj);
+ fz_try(ctx)
+ proc->op_sh(ctx, proc, csi->name, shade);
+ fz_always(ctx)
+ fz_drop_shade(ctx, shade);
+ fz_catch(ctx)
+ fz_rethrow(ctx);
+ }
+ break;
+
+ case B('D','o'): pdf_process_Do(ctx, proc, csi); break;
+
+ /* marked content */
+ case B('M','P'): if (proc->op_MP) proc->op_MP(ctx, proc, csi->name); break;
+ case B('D','P'): if (proc->op_DP) proc->op_DP(ctx, proc, csi->name, resolve_properties(ctx, csi, csi->obj)); break;
+ case C('B','M','C'): pdf_process_BMC(ctx, proc, csi, csi->name); break;
+ case C('B','D','C'): pdf_process_BDC(ctx, proc, csi, csi->name, resolve_properties(ctx, csi, csi->obj)); break;
+ case C('E','M','C'): pdf_process_EMC(ctx, proc, csi); break;
+
+ /* compatibility */
+ case B('B','X'): ++csi->xbalance; if (proc->op_BX) proc->op_BX(ctx, proc); break;
+ case B('E','X'): --csi->xbalance; if (proc->op_EX) proc->op_EX(ctx, proc); break;
}
+
return 0;
}
-void
-pdf_process_stream(pdf_csi *csi, pdf_lexbuf *buf)
+static void
+pdf_process_stream(fz_context *ctx, pdf_processor *proc, pdf_csi *csi, fz_stream *stm)
{
- fz_context *ctx = csi->ctx;
pdf_document *doc = csi->doc;
+ pdf_lexbuf *buf = csi->buf;
+ fz_cookie *cookie = csi->cookie;
- fz_stream *file = csi->file;
pdf_token tok = PDF_TOK_ERROR;
int in_text_array = 0;
int ignoring_errors = 0;
/* make sure we have a clean slate if we come here from flush_text */
- pdf_clear_stack(csi);
+ pdf_clear_stack(ctx, csi);
fz_var(in_text_array);
fz_var(tok);
- if (csi->cookie)
+ if (cookie)
{
- csi->cookie->progress_max = -1;
- csi->cookie->progress = 0;
+ cookie->progress_max = -1;
+ cookie->progress = 0;
}
do
@@ -311,17 +1001,17 @@ pdf_process_stream(pdf_csi *csi, pdf_lexbuf *buf)
do
{
/* Check the cookie */
- if (csi->cookie)
+ if (cookie)
{
- if (csi->cookie->abort)
+ if (cookie->abort)
{
tok = PDF_TOK_EOF;
break;
}
- csi->cookie->progress++;
+ cookie->progress++;
}
- tok = pdf_lex(ctx, file, buf);
+ tok = pdf_lex(ctx, stm, buf);
if (in_text_array)
{
@@ -352,7 +1042,7 @@ pdf_process_stream(pdf_csi *csi, pdf_lexbuf *buf)
{
csi->stack[0] = pdf_to_real(ctx, o);
pdf_array_delete(ctx, csi->obj, l-1);
- if (pdf_run_keyword(csi, buf->scratch) == 0)
+ if (pdf_process_keyword(ctx, proc, csi, stm, buf->scratch) == 0)
break;
}
}
@@ -382,7 +1072,7 @@ pdf_process_stream(pdf_csi *csi, pdf_lexbuf *buf)
}
else
{
- csi->obj = pdf_parse_array(ctx, doc, file, buf);
+ csi->obj = pdf_parse_array(ctx, doc, stm, buf);
}
break;
@@ -392,7 +1082,7 @@ pdf_process_stream(pdf_csi *csi, pdf_lexbuf *buf)
pdf_drop_obj(ctx, csi->obj);
csi->obj = NULL;
}
- csi->obj = pdf_parse_dict(ctx, doc, file, buf);
+ csi->obj = pdf_parse_dict(ctx, doc, stm, buf);
break;
case PDF_TOK_NAME:
@@ -442,11 +1132,11 @@ pdf_process_stream(pdf_csi *csi, pdf_lexbuf *buf)
break;
case PDF_TOK_KEYWORD:
- if (pdf_run_keyword(csi, buf->scratch))
+ if (pdf_process_keyword(ctx, proc, csi, stm, buf->scratch))
{
tok = PDF_TOK_EOF;
}
- pdf_clear_stack(csi);
+ pdf_clear_stack(ctx, csi);
break;
default:
@@ -457,20 +1147,20 @@ pdf_process_stream(pdf_csi *csi, pdf_lexbuf *buf)
}
fz_always(ctx)
{
- pdf_clear_stack(csi);
+ pdf_clear_stack(ctx, csi);
}
fz_catch(ctx)
{
int caught;
- if (!csi->cookie)
+ if (!cookie)
{
fz_rethrow_if(ctx, FZ_ERROR_TRYLATER);
}
else if ((caught = fz_caught(ctx)) == FZ_ERROR_TRYLATER)
{
- if (csi->cookie->incomplete_ok)
- csi->cookie->incomplete++;
+ if (cookie->incomplete_ok)
+ cookie->incomplete++;
else
fz_rethrow(ctx);
}
@@ -480,7 +1170,7 @@ pdf_process_stream(pdf_csi *csi, pdf_lexbuf *buf)
}
else
{
- csi->cookie->errors++;
+ cookie->errors++;
}
if (!ignoring_errors)
{
@@ -495,169 +1185,99 @@ pdf_process_stream(pdf_csi *csi, pdf_lexbuf *buf)
while (tok != PDF_TOK_EOF);
}
-/*
- * Entry points
- */
-
-static void
-pdf_process_contents_stream(pdf_csi *csi, pdf_obj *rdb, fz_stream *file)
+void
+pdf_process_contents(fz_context *ctx, pdf_processor *proc, pdf_document *doc, pdf_obj *rdb, pdf_obj *stmobj, fz_cookie *cookie)
{
- fz_context *ctx = csi->ctx;
-
- pdf_lexbuf *buf;
- int save_in_text;
- pdf_obj *save_obj;
- pdf_obj *save_rdb = csi->rdb;
- fz_stream *save_file = csi->file;
-
- fz_var(buf);
+ pdf_csi csi;
+ pdf_lexbuf buf;
+ fz_stream *stm = NULL;
- if (file == NULL)
+ if (!stmobj)
return;
- buf = fz_malloc(ctx, sizeof(*buf)); /* we must be re-entrant for type3 fonts */
- pdf_lexbuf_init(ctx, buf, PDF_LEXBUF_SMALL);
- save_in_text = csi->in_text;
- csi->in_text = 0;
- save_obj = csi->obj;
- csi->obj = NULL;
- csi->rdb = rdb;
- csi->file = file;
- fz_try(ctx)
- {
- csi->process.processor->process_stream(csi, csi->process.state, buf);
- }
- fz_always(ctx)
- {
- csi->in_text = save_in_text;
- pdf_drop_obj(ctx, csi->obj);
- csi->obj = save_obj;
- csi->rdb = save_rdb;
- csi->file = save_file;
- pdf_lexbuf_fin(ctx, buf);
- fz_free(ctx, buf);
- }
- fz_catch(ctx)
- {
- fz_rethrow_if(ctx, FZ_ERROR_TRYLATER);
- fz_rethrow_if(ctx, FZ_ERROR_ABORT);
- fz_warn(ctx, "Content stream parsing error - rendering truncated");
- }
-}
+ fz_var(stm);
-void
-pdf_process_annot(fz_context *ctx, pdf_document *doc, pdf_page *page, pdf_annot *annot, const pdf_process *process, fz_cookie *cookie)
-{
- pdf_csi *csi;
- int flags;
+ pdf_lexbuf_init(ctx, &buf, PDF_LEXBUF_SMALL);
+ pdf_init_csi(ctx, &csi, doc, rdb, &buf, cookie);
- csi = pdf_new_csi(ctx, doc, cookie, process);
fz_try(ctx)
{
- flags = pdf_to_int(ctx, pdf_dict_gets(ctx, annot->obj, "F"));
-
- /* Check not invisible (bit 0) and hidden (bit 1) */
- /* TODO: NoZoom and NoRotate */
- if (flags & ((1 << 0) | (1 << 1)))
- break;
-
- csi->process.processor->process_annot(csi, csi->process.state, page->resources, annot);
+ stm = pdf_open_contents_stream(ctx, doc, stmobj);
+ pdf_process_stream(ctx, proc, &csi, stm);
+ pdf_process_end(ctx, proc, &csi);
}
fz_always(ctx)
{
- pdf_drop_csi(csi);
+ fz_drop_stream(ctx, stm);
+ pdf_clear_stack(ctx, &csi);
+ pdf_lexbuf_fin(ctx, &buf);
}
fz_catch(ctx)
{
- fz_rethrow_message(ctx, "cannot parse annotation appearance stream");
+ fz_rethrow_if(ctx, FZ_ERROR_ABORT);
+ fz_rethrow_message(ctx, "cannot parse content stream");
}
}
void
-pdf_process_contents_object(pdf_csi *csi, pdf_obj *rdb, pdf_obj *contents)
+pdf_process_annot(fz_context *ctx, pdf_processor *proc, pdf_document *doc, pdf_page *page, pdf_annot *annot, fz_cookie *cookie)
{
- fz_context *ctx = csi->ctx;
- pdf_document *doc = csi->doc;
-
- fz_stream *file = NULL;
+ int flags = pdf_to_int(ctx, pdf_dict_gets(ctx, annot->obj, "F"));
- if (contents == NULL)
+ if (flags & (F_Invisible | F_Hidden))
return;
- file = pdf_open_contents_stream(ctx, doc, contents);
- fz_try(ctx)
+ if (proc->event)
{
- pdf_process_contents_stream(csi, rdb, file);
+ if (!strcmp(proc->event, "Print") && !(flags & F_Print))
+ return;
+ if (!strcmp(proc->event, "View") && (flags & F_NoView))
+ return;
}
- fz_always(ctx)
- {
- fz_drop_stream(ctx, file);
- }
- fz_catch(ctx)
- {
- fz_rethrow(ctx);
- }
-}
-static void
-pdf_process_contents_buffer(pdf_csi *csi, pdf_obj *rdb, fz_buffer *contents)
-{
- fz_context *ctx = csi->ctx;
+ /* TODO: NoZoom and NoRotate */
- fz_stream *file = NULL;
-
- if (contents == NULL)
+ /* XXX what resources, if any, to use for this check? */
+ if (pdf_is_hidden_ocg(ctx, doc->ocg, NULL, proc->event, pdf_dict_gets(ctx, annot->obj, "OC")))
return;
- file = fz_open_buffer(ctx, contents);
- fz_try(ctx)
+ if (proc->op_q && proc->op_cm && proc->op_Do_form && proc->op_Q)
{
- pdf_process_contents_stream(csi, rdb, file);
- }
- fz_always(ctx)
- {
- fz_drop_stream(ctx, file);
- }
- fz_catch(ctx)
- {
- fz_rethrow(ctx);
+ proc->op_q(ctx, proc);
+ proc->op_cm(ctx, proc,
+ annot->matrix.a, annot->matrix.b, annot->matrix.c,
+ annot->matrix.d, annot->matrix.e, annot->matrix.f);
+ proc->op_Do_form(ctx, proc, "Annot", annot->ap, page->resources);
+ proc->op_Q(ctx, proc);
}
}
void
-pdf_process_stream_object(fz_context *ctx, pdf_document *doc, pdf_obj *obj, const pdf_process *process, pdf_obj *res, fz_cookie *cookie)
+pdf_process_glyph(fz_context *ctx, pdf_processor *proc, pdf_document *doc, pdf_obj *rdb, fz_buffer *contents)
{
- pdf_csi *csi;
+ pdf_csi csi;
+ pdf_lexbuf buf;
+ fz_stream *stm = NULL;
- csi = pdf_new_csi(ctx, doc, cookie, process);
- fz_try(ctx)
- {
- csi->process.processor->process_contents(csi, csi->process.state, res, obj);
- }
- fz_always(ctx)
- {
- pdf_drop_csi(csi);
- }
- fz_catch(ctx)
- {
- fz_rethrow_if(ctx, FZ_ERROR_ABORT);
- fz_rethrow_message(ctx, "cannot parse content stream");
- }
-}
+ fz_var(stm);
-void
-pdf_process_glyph(fz_context *ctx, pdf_document *doc, pdf_obj *resources, fz_buffer *contents, pdf_process *process)
-{
- pdf_csi *csi;
+ if (!contents)
+ return;
+
+ pdf_lexbuf_init(ctx, &buf, PDF_LEXBUF_SMALL);
+ pdf_init_csi(ctx, &csi, doc, rdb, &buf, NULL);
- csi = pdf_new_csi(ctx, doc, NULL, process);
fz_try(ctx)
{
- pdf_process_contents_buffer(csi, resources, contents);
+ fz_stream *stm = fz_open_buffer(ctx, contents);
+ pdf_process_stream(ctx, proc, &csi, stm);
+ pdf_process_end(ctx, proc, &csi);
}
fz_always(ctx)
{
- pdf_drop_csi(csi);
+ fz_drop_stream(ctx, stm);
+ pdf_clear_stack(ctx, &csi);
+ pdf_lexbuf_fin(ctx, &buf);
}
fz_catch(ctx)
{
diff --git a/source/pdf/pdf-object.c b/source/pdf/pdf-object.c
index 1a0b9abf..0ed9667d 100644
--- a/source/pdf/pdf-object.c
+++ b/source/pdf/pdf-object.c
@@ -1745,13 +1745,13 @@ int pdf_output_obj(fz_context *ctx, fz_output *out, pdf_obj *obj, int tight)
if ((n + 1) < sizeof buf)
{
pdf_sprint_obj(ctx, buf, sizeof buf, obj, tight);
- fz_printf(ctx, out, "%s\n", buf);
+ fz_puts(ctx, out, buf);
}
else
{
ptr = fz_malloc(ctx, n + 1);
pdf_sprint_obj(ctx, ptr, n + 1, obj, tight);
- fz_printf(ctx, out, "%s\n", ptr);
+ fz_puts(ctx, out, buf);
fz_free(ctx, ptr);
}
return n;
diff --git a/source/pdf/pdf-op-buffer.c b/source/pdf/pdf-op-buffer.c
index e2bbd343..cdea4c78 100644
--- a/source/pdf/pdf-op-buffer.c
+++ b/source/pdf/pdf-op-buffer.c
@@ -1,939 +1,889 @@
-#include "pdf-interpret-imp.h"
+#include "mupdf/pdf.h"
-typedef struct pdf_buffer_state_s
+typedef struct pdf_output_processor_s pdf_output_processor;
+
+struct pdf_output_processor_s
{
- fz_context *ctx;
- fz_buffer *buffer;
+ pdf_processor super;
fz_output *out;
-}
-pdf_buffer_state;
+ int extgstate;
+};
+
+/* general graphics state */
static void
-put_hexstring(fz_context *ctx, fz_output *out, pdf_csi *csi)
+pdf_out_w(fz_context *ctx, pdf_processor *proc, float linewidth)
{
- int i;
-
- fz_printf(ctx, out, "<");
- for (i = 0; i < csi->string_len; i++)
- fz_printf(ctx, out, "%02x", csi->string[i]);
- fz_printf(ctx, out, ">");
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ if (!((pdf_output_processor*)proc)->extgstate)
+ fz_printf(ctx, out, "%f w\n", linewidth);
}
static void
-put_string(fz_context *ctx, fz_output *out, pdf_csi *csi)
+pdf_out_j(fz_context *ctx, pdf_processor *proc, int linejoin)
{
- int i;
-
- for (i=0; i < csi->string_len; i++)
- if (csi->string[i] < 32 || csi->string[i] >= 127)
- break;
- if (i < csi->string_len)
- put_hexstring(ctx, out, csi);
- else
- {
- fz_printf(ctx, out, "(");
- for (i = 0; i < csi->string_len; i++)
- {
- char c = csi->string[i];
- switch (c)
- {
- case '(':
- fz_printf(ctx, out, "\\(");
- break;
- case ')':
- fz_printf(ctx, out, "\\)");
- break;
- case '\\':
- fz_printf(ctx, out, "\\\\");
- break;
- default:
- fz_printf(ctx, out, "%c", csi->string[i]);
- break;
- }
- }
- fz_printf(ctx, out, ")");
- }
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ if (!((pdf_output_processor*)proc)->extgstate)
+ fz_printf(ctx, out, "%d j\n", linejoin);
}
static void
-put_string_or_obj(fz_context *ctx, fz_output *out, pdf_csi *csi)
+pdf_out_J(fz_context *ctx, pdf_processor *proc, int linecap)
{
- if (csi->string_len)
- put_string(ctx, out, csi);
- else
- pdf_output_obj(ctx, out, csi->obj, 1);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ if (!((pdf_output_processor*)proc)->extgstate)
+ fz_printf(ctx, out, "%d J\n", linecap);
}
static void
-pdf_buffer_dquote(pdf_csi *csi, void *state_)
+pdf_out_M(fz_context *ctx, pdf_processor *proc, float a)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "%f %f ", csi->stack[0], csi->stack[1]);
- put_string_or_obj(state->ctx, state->out, csi);
- fz_printf(state->ctx, state->out, " \"\n");
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ if (!((pdf_output_processor*)proc)->extgstate)
+ fz_printf(ctx, out, "%f M\n", a);
}
static void
-pdf_buffer_squote(pdf_csi *csi, void *state_)
+pdf_out_d(fz_context *ctx, pdf_processor *proc, pdf_obj *array, float phase)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- put_string_or_obj(state->ctx, state->out, csi);
- fz_printf(state->ctx, state->out, " \'\n");
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ if (!((pdf_output_processor*)proc)->extgstate)
+ {
+ pdf_output_obj(ctx, out, array, 1);
+ fz_printf(ctx, out, " %f d\n", phase);
+ }
}
static void
-pdf_buffer_B(pdf_csi *csi, void *state_)
+pdf_out_ri(fz_context *ctx, pdf_processor *proc, const char *intent)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "B\n");
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ if (!((pdf_output_processor*)proc)->extgstate)
+ fz_printf(ctx, out, "/%s ri\n", intent);
}
static void
-pdf_buffer_Bstar(pdf_csi *csi, void *state_)
+pdf_out_i(fz_context *ctx, pdf_processor *proc, float flatness)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "B*\n");
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ if (!((pdf_output_processor*)proc)->extgstate)
+ fz_printf(ctx, out, "%f i\n", flatness);
}
static void
-pdf_buffer_BDC(pdf_csi *csi, void *state_)
+pdf_out_gs_begin(fz_context *ctx, pdf_processor *proc, const char *name, pdf_obj *extgstate)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "/%s ", csi->name);
- pdf_output_obj(state->ctx, state->out, csi->obj, 1);
- fz_printf(state->ctx, state->out, " BDC\n");
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ ((pdf_output_processor*)proc)->extgstate = 1;
+ fz_printf(ctx, out, "/%s gs\n", name);
}
static void
-pdf_buffer_BI(pdf_csi *csi, void *state_)
+pdf_out_gs_end(fz_context *ctx, pdf_processor *proc)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
- int len, i;
- unsigned char *data;
- fz_compressed_buffer *cbuf;
- fz_buffer *buffer;
- const char *match;
- const char *match2;
- pdf_obj *filter;
- fz_context *ctx = csi->ctx;
-
- if (csi->img == NULL)
- return;
- cbuf = csi->img->buffer;
- if (cbuf == NULL)
- return;
- buffer = cbuf->buffer;
- if (buffer == NULL)
- return;
-
- /* Tweak the /Filter entry in csi->obj to match the buffer params */
- switch (cbuf->params.type)
- {
- case FZ_IMAGE_JPEG:
- match = "DCTDecode";
- match2 = "DCT";
- break;
- case FZ_IMAGE_FAX:
- match = "CCITTFaxDecode";
- match2 = "CCF";
- break;
- case FZ_IMAGE_RAW:
- match = NULL;
- match2 = NULL;
- break;
- case FZ_IMAGE_RLD:
- match = "RunLengthDecode";
- match2 = "RL";
- break;
- case FZ_IMAGE_FLATE:
- match = "FlateDecode";
- match2 = "Fl";
- break;
- case FZ_IMAGE_LZW:
- match = "LZWDecode";
- match2 = "LZW";
- break;
- default:
- fz_warn(ctx, "Unsupported type (%d) of inline image", cbuf->params.type);
- return;
- }
-
- filter = pdf_dict_gets(ctx, csi->obj, "Filter");
- if (filter == NULL)
- filter = pdf_dict_gets(ctx, csi->obj, "F");
- if (match == NULL)
- {
- /* Remove any filter entry (e.g. Ascii85Decode) */
- if (filter)
- {
- pdf_dict_dels(ctx, csi->obj, "Filter");
- pdf_dict_dels(ctx, csi->obj, "F");
- }
- pdf_dict_dels(ctx, csi->obj, "DecodeParms");
- pdf_dict_dels(ctx, csi->obj, "DP");
- }
- else if (pdf_is_array(ctx, filter))
- {
- int l = pdf_array_len(ctx, filter);
- pdf_obj *o = (l == 0 ? NULL : pdf_array_get(ctx, filter, l-1));
- const char *fil = pdf_to_name(ctx, o);
-
- if (l == 0 || (strcmp(fil, match) && strcmp(fil, match2)))
- {
- fz_warn(ctx, "Unexpected Filter configuration in inline image");
- return;
- }
- pdf_dict_puts(ctx, csi->obj, "F", o);
-
- o = pdf_dict_gets(ctx, csi->obj, "DecodeParms");
- if (o == NULL)
- o = pdf_dict_gets(ctx, csi->obj, "DP");
- if (o)
- {
- o = pdf_array_get(ctx, o, l-1);
- if (o)
- pdf_dict_puts(ctx, csi->obj, "DP", o);
- else
- pdf_dict_dels(ctx, csi->obj, "DP");
- pdf_dict_dels(ctx, csi->obj, "DecodeParms");
- }
- }
- else
- {
- /* It's a singleton. It must be correct */
- }
-
- fz_printf(state->ctx, state->out, "BI\n");
-
- len = pdf_dict_len(ctx, csi->obj);
- for (i = 0; i < len; i++)
- {
- pdf_output_obj(state->ctx, state->out, pdf_dict_get_key(ctx, csi->obj, i), 1);
- pdf_output_obj(state->ctx, state->out, pdf_dict_get_val(ctx, csi->obj, i), 1);
- }
- fz_printf(state->ctx, state->out, "ID\n");
-
- buffer = csi->img->buffer->buffer;
- len = buffer->len;
- data = buffer->data;
- for (i = 0; i < len; i++)
- {
- fz_printf(state->ctx, state->out, "%c", data[i]);
- }
-
- fz_printf(state->ctx, state->out, "\nEI\n");
+ ((pdf_output_processor*)proc)->extgstate = 0;
}
+/* special graphics state */
+
static void
-pdf_buffer_BMC(pdf_csi *csi, void *state_)
+pdf_out_q(fz_context *ctx, pdf_processor *proc)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "/%s BMC\n", csi->name);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "q\n");
}
static void
-pdf_buffer_BT(pdf_csi *csi, void *state_)
+pdf_out_Q(fz_context *ctx, pdf_processor *proc)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "BT\n");
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "Q\n");
}
static void
-pdf_buffer_BX(pdf_csi *csi, void *state_)
+pdf_out_cm(fz_context *ctx, pdf_processor *proc, float a, float b, float c, float d, float e, float f)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "BX\n");
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "%f %f %f %f %f %f cm\n", a, b, c, d, e, f);
}
+/* path construction */
+
static void
-pdf_buffer_CS(pdf_csi *csi, void *state_)
+pdf_out_m(fz_context *ctx, pdf_processor *proc, float x, float y)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "/%s CS\n", csi->name);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "%f %f m\n", x, y);
}
static void
-pdf_buffer_DP(pdf_csi *csi, void *state_)
+pdf_out_l(fz_context *ctx, pdf_processor *proc, float x, float y)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "/%s ", csi->name);
- pdf_output_obj(state->ctx, state->out, csi->obj, 1);
- fz_printf(state->ctx, state->out, " DP\n");
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "%f %f l\n", x, y);
}
static void
-pdf_buffer_EMC(pdf_csi *csi, void *state_)
+pdf_out_c(fz_context *ctx, pdf_processor *proc, float x1, float y1, float x2, float y2, float x3, float y3)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "EMC\n");
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "%f %f %f %f %f %f c\n", x1, y1, x2, y2, x3, y3);
}
static void
-pdf_buffer_ET(pdf_csi *csi, void *state_)
+pdf_out_v(fz_context *ctx, pdf_processor *proc, float x2, float y2, float x3, float y3)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "ET\n");
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "%f %f %f %f v\n", x2, y2, x3, y3);
}
static void
-pdf_buffer_EX(pdf_csi *csi, void *state_)
+pdf_out_y(fz_context *ctx, pdf_processor *proc, float x1, float y1, float x3, float y3)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "EX\n");
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "%f %f %f %f y\n", x1, y1, x3, y3);
}
static void
-pdf_buffer_F(pdf_csi *csi, void *state_)
+pdf_out_h(fz_context *ctx, pdf_processor *proc)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "F\n");
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "h\n");
}
static void
-pdf_buffer_G(pdf_csi *csi, void *state_)
+pdf_out_re(fz_context *ctx, pdf_processor *proc, float x, float y, float w, float h)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "%f G\n", csi->stack[0]);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "%f %f %f %f re\n", x, y, w, h);
}
+/* path painting */
+
static void
-pdf_buffer_J(pdf_csi *csi, void *state_)
+pdf_out_S(fz_context *ctx, pdf_processor *proc)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "%d J\n", (int)csi->stack[0]);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "S\n");
}
static void
-pdf_buffer_K(pdf_csi *csi, void *state_)
+pdf_out_s(fz_context *ctx, pdf_processor *proc)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "%f %f %f %f K\n", csi->stack[0],
- csi->stack[1], csi->stack[2], csi->stack[3]);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "s\n");
}
static void
-pdf_buffer_M(pdf_csi *csi, void *state_)
+pdf_out_F(fz_context *ctx, pdf_processor *proc)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "%f M\n", csi->stack[0]);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "F\n");
}
static void
-pdf_buffer_MP(pdf_csi *csi, void *state_)
+pdf_out_f(fz_context *ctx, pdf_processor *proc)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "/%s MP\n", csi->name);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "f\n");
}
static void
-pdf_buffer_Q(pdf_csi *csi, void *state_)
+pdf_out_fstar(fz_context *ctx, pdf_processor *proc)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "Q\n");
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "f*\n");
}
static void
-pdf_buffer_RG(pdf_csi *csi, void *state_)
+pdf_out_B(fz_context *ctx, pdf_processor *proc)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "%f %f %f RG\n", csi->stack[0], csi->stack[1], csi->stack[2]);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "B\n");
}
static void
-pdf_buffer_S(pdf_csi *csi, void *state_)
+pdf_out_Bstar(fz_context *ctx, pdf_processor *proc)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "S\n");
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "B*\n");
}
static void
-pdf_buffer_SC(pdf_csi *csi, void *state_)
+pdf_out_b(fz_context *ctx, pdf_processor *proc)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
- int i;
-
- for (i = 0; i < csi->top; i++)
- fz_printf(state->ctx, state->out, "%f ", csi->stack[i]);
- fz_printf(state->ctx, state->out, "SC\n");
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "b\n");
}
static void
-pdf_buffer_SCN(pdf_csi *csi, void *state_)
+pdf_out_bstar(fz_context *ctx, pdf_processor *proc)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
- int i;
-
- for (i = 0; i < csi->top; i++)
- fz_printf(state->ctx, state->out, "%f ", csi->stack[i]);
- if (csi->name[0])
- fz_printf(state->ctx, state->out, "/%s ", csi->name);
- fz_printf(state->ctx, state->out, "SCN\n");
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "b*\n");
}
static void
-pdf_buffer_Tstar(pdf_csi *csi, void *state_)
+pdf_out_n(fz_context *ctx, pdf_processor *proc)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "T*\n");
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "n\n");
}
+/* clipping paths */
+
static void
-pdf_buffer_TD(pdf_csi *csi, void *state_)
+pdf_out_W(fz_context *ctx, pdf_processor *proc)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "%f %f TD\n", csi->stack[0], csi->stack[1]);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "W\n");
}
static void
-pdf_buffer_TJ(pdf_csi *csi, void *state_)
+pdf_out_Wstar(fz_context *ctx, pdf_processor *proc)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- pdf_output_obj(state->ctx, state->out, csi->obj, 1);
- fz_printf(state->ctx, state->out, " TJ\n");
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "W*\n");
}
+/* text objects */
+
static void
-pdf_buffer_TL(pdf_csi *csi, void *state_)
+pdf_out_BT(fz_context *ctx, pdf_processor *proc)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "%f TL\n", csi->stack[0]);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "BT\n");
}
static void
-pdf_buffer_Tc(pdf_csi *csi, void *state_)
+pdf_out_ET(fz_context *ctx, pdf_processor *proc)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "%f Tc\n", csi->stack[0]);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "ET\n");
}
+/* text state */
+
static void
-pdf_buffer_Td(pdf_csi *csi, void *state_)
+pdf_out_Tc(fz_context *ctx, pdf_processor *proc, float charspace)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "%f %f Td\n", csi->stack[0], csi->stack[1]);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "%f Tc\n", charspace);
}
static void
-pdf_buffer_Tj(pdf_csi *csi, void *state_)
+pdf_out_Tw(fz_context *ctx, pdf_processor *proc, float wordspace)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- put_string_or_obj(state->ctx, state->out, csi);
- fz_printf(state->ctx, state->out, " Tj\n");
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "%f Tw\n", wordspace);
}
static void
-pdf_buffer_Tm(pdf_csi *csi, void *state_)
+pdf_out_Tz(fz_context *ctx, pdf_processor *proc, float scale)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "%f %f %f %f %f %f Tm\n",
- csi->stack[0], csi->stack[1], csi->stack[2],
- csi->stack[3], csi->stack[4], csi->stack[5]);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "%f Tz\n", scale);
}
static void
-pdf_buffer_Tr(pdf_csi *csi, void *state_)
+pdf_out_TL(fz_context *ctx, pdf_processor *proc, float leading)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "%f Tr\n", csi->stack[0]);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "%f TL\n", leading);
}
static void
-pdf_buffer_Ts(pdf_csi *csi, void *state_)
+pdf_out_Tf(fz_context *ctx, pdf_processor *proc, const char *name, pdf_font_desc *font, float size)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "%f Ts\n", csi->stack[0]);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ if (!((pdf_output_processor*)proc)->extgstate)
+ fz_printf(ctx, out, "/%s %f Tf\n", name, size);
}
static void
-pdf_buffer_Tw(pdf_csi *csi, void *state_)
+pdf_out_Tr(fz_context *ctx, pdf_processor *proc, int render)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "%f Tw\n", csi->stack[0]);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "%d Tr\n", render);
}
static void
-pdf_buffer_Tz(pdf_csi *csi, void *state_)
+pdf_out_Ts(fz_context *ctx, pdf_processor *proc, float rise)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "%f Tz\n", csi->stack[0]);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "%f Ts\n", rise);
}
+/* text positioning */
+
static void
-pdf_buffer_W(pdf_csi *csi, void *state_)
+pdf_out_Td(fz_context *ctx, pdf_processor *proc, float tx, float ty)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "W\n");
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "%f %f Td\n", tx, ty);
}
static void
-pdf_buffer_Wstar(pdf_csi *csi, void *state_)
+pdf_out_TD(fz_context *ctx, pdf_processor *proc, float tx, float ty)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "W*\n");
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "%f %f TD\n", tx, ty);
}
static void
-pdf_buffer_b(pdf_csi *csi, void *state_)
+pdf_out_Tm(fz_context *ctx, pdf_processor *proc, float a, float b, float c, float d, float e, float f)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "b\n");
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "%f %f %f %f %f %f Tm\n", a, b, c, d, e, f);
}
static void
-pdf_buffer_bstar(pdf_csi *csi, void *state_)
+pdf_out_Tstar(fz_context *ctx, pdf_processor *proc)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "b*\n");
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "T*\n");
}
+/* text showing */
+
static void
-pdf_buffer_c(pdf_csi *csi, void *state_)
+put_string(fz_context *ctx, fz_output *out, const unsigned char *str, int len)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
+ int i;
+
+ for (i = 0; i < len; ++i)
+ if (str[i] < 32 || str[i] >= 127)
+ break;
- fz_printf(state->ctx, state->out, "%f %f %f %f %f %f c\n",
- csi->stack[0], csi->stack[1], csi->stack[2],
- csi->stack[3], csi->stack[4], csi->stack[5]);
+ if (i < len)
+ {
+ fz_printf(ctx, out, "<");
+ for (i = 0; i < len; ++i)
+ fz_printf(ctx, out, "%02x", str[i]);
+ fz_printf(ctx, out, ">");
+ }
+ else
+ {
+ fz_printf(ctx, out, "(");
+ for (i = 0; i < len; ++i)
+ {
+ unsigned char c = str[i];
+ if (c == '(' || c == ')' || c == '\\')
+ fz_putc(ctx, out, '\\');
+ fz_putc(ctx, out, c);
+ }
+ fz_printf(ctx, out, ")");
+ }
}
static void
-pdf_buffer_cm(pdf_csi *csi, void *state_)
+pdf_out_TJ(fz_context *ctx, pdf_processor *proc, pdf_obj *array)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "%f %f %f %f %f %f cm\n",
- csi->stack[0], csi->stack[1], csi->stack[2],
- csi->stack[3], csi->stack[4], csi->stack[5]);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ pdf_output_obj(ctx, out, array, 1);
+ fz_printf(ctx, out, " TJ\n");
}
static void
-pdf_buffer_cs(pdf_csi *csi, void *state_)
+pdf_out_Tj(fz_context *ctx, pdf_processor *proc, char *str, int len)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "/%s cs\n", csi->name);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ put_string(ctx, out, (const unsigned char *)str, len);
+ fz_printf(ctx, out, " Tj\n");
}
static void
-pdf_buffer_d(pdf_csi *csi, void *state_)
+pdf_out_squote(fz_context *ctx, pdf_processor *proc, char *str, int len)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- pdf_output_obj(state->ctx, state->out, csi->obj, 1);
- fz_printf(state->ctx, state->out, " %f d\n", csi->stack[0]);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ put_string(ctx, out, (const unsigned char *)str, len);
+ fz_printf(ctx, out, " '\n");
}
static void
-pdf_buffer_d0(pdf_csi *csi, void *state_)
+pdf_out_dquote(fz_context *ctx, pdf_processor *proc, float aw, float ac, char *str, int len)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "%f %f d0\n", csi->stack[0], csi->stack[1]);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "%f %f ", aw, ac);
+ put_string(ctx, out, (const unsigned char *)str, len);
+ fz_printf(ctx, out, " \"\n");
}
+/* type 3 fonts */
+
static void
-pdf_buffer_d1(pdf_csi *csi, void *state_)
+pdf_out_d0(fz_context *ctx, pdf_processor *proc, float wx, float wy)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "%f %f %f %f %f %f d1\n",
- csi->stack[0], csi->stack[1], csi->stack[2],
- csi->stack[3], csi->stack[4], csi->stack[5]);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "%f %f d0\n", wx, wy);
}
static void
-pdf_buffer_f(pdf_csi *csi, void *state_)
+pdf_out_d1(fz_context *ctx, pdf_processor *proc, float wx, float wy, float llx, float lly, float urx, float ury)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "f\n");
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "%f %f %f %f %f %f d1\n", wx, wy, llx, lly, urx, ury);
}
+/* color */
+
static void
-pdf_buffer_fstar(pdf_csi *csi, void *state_)
+pdf_out_CS(fz_context *ctx, pdf_processor *proc, const char *name, fz_colorspace *cs)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "f*\n");
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "/%s CS\n", name);
}
static void
-pdf_buffer_g(pdf_csi *csi, void *state_)
+pdf_out_cs(fz_context *ctx, pdf_processor *proc, const char *name, fz_colorspace *cs)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "%f g\n", csi->stack[0]);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "/%s cs\n", name);
}
static void
-pdf_buffer_h(pdf_csi *csi, void *state_)
+pdf_out_SC_pattern(fz_context *ctx, pdf_processor *proc, const char *name, pdf_pattern *pat, int n, float *color)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "h\n");
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ int i;
+ for (i = 0; i < n; ++i)
+ fz_printf(ctx, out, "%f ", color[i]);
+ fz_printf(ctx, out, "/%s SCN\n", name);
}
static void
-pdf_buffer_i(pdf_csi *csi, void *state_)
+pdf_out_sc_pattern(fz_context *ctx, pdf_processor *proc, const char *name, pdf_pattern *pat, int n, float *color)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "%f i\n", csi->stack[0]);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ int i;
+ for (i = 0; i < n; ++i)
+ fz_printf(ctx, out, "%f ", color[i]);
+ fz_printf(ctx, out, "/%s scn\n", name);
}
static void
-pdf_buffer_j(pdf_csi *csi, void *state_)
+pdf_out_SC_shade(fz_context *ctx, pdf_processor *proc, const char *name, fz_shade *shade)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "%d j\n", (int)csi->stack[0]);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "/%s SCN\n", name);
}
static void
-pdf_buffer_k(pdf_csi *csi, void *state_)
+pdf_out_sc_shade(fz_context *ctx, pdf_processor *proc, const char *name, fz_shade *shade)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "%f %f %f %f k\n", csi->stack[0],
- csi->stack[1], csi->stack[2], csi->stack[3]);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "/%s scn\n", name);
}
static void
-pdf_buffer_l(pdf_csi *csi, void *state_)
+pdf_out_SC_color(fz_context *ctx, pdf_processor *proc, int n, float *color)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "%f %f l\n", csi->stack[0], csi->stack[1]);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ int i;
+ for (i = 0; i < n; ++i)
+ fz_printf(ctx, out, "%f ", color[i]);
+ fz_printf(ctx, out, "SCN\n");
}
static void
-pdf_buffer_m(pdf_csi *csi, void *state_)
+pdf_out_sc_color(fz_context *ctx, pdf_processor *proc, int n, float *color)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "%f %f m\n", csi->stack[0], csi->stack[1]);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ int i;
+ for (i = 0; i < n; ++i)
+ fz_printf(ctx, out, "%f ", color[i]);
+ fz_printf(ctx, out, "scn\n");
}
static void
-pdf_buffer_n(pdf_csi *csi, void *state_)
+pdf_out_G(fz_context *ctx, pdf_processor *proc, float g)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "n\n");
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "%f G\n", g);
}
static void
-pdf_buffer_q(pdf_csi *csi, void *state_)
+pdf_out_g(fz_context *ctx, pdf_processor *proc, float g)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "q\n");
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "%f g\n", g);
}
static void
-pdf_buffer_re(pdf_csi *csi, void *state_)
+pdf_out_RG(fz_context *ctx, pdf_processor *proc, float r, float g, float b)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "%f %f %f %f re\n", csi->stack[0],
- csi->stack[1], csi->stack[2], csi->stack[3]);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "%f %f %f RG\n", r, g, b);
}
static void
-pdf_buffer_rg(pdf_csi *csi, void *state_)
+pdf_out_rg(fz_context *ctx, pdf_processor *proc, float r, float g, float b)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "%f %f %f rg\n",
- csi->stack[0], csi->stack[1], csi->stack[2]);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "%f %f %f rg\n", r, g, b);
}
static void
-pdf_buffer_ri(pdf_csi *csi, void *state_)
+pdf_out_K(fz_context *ctx, pdf_processor *proc, float c, float m, float y, float k)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "/%s ri\n", csi->name);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "%f %f %f %f K\n", c, m, y, k);
}
static void
-pdf_buffer_s(pdf_csi *csi, void *state_)
+pdf_out_k(fz_context *ctx, pdf_processor *proc, float c, float m, float y, float k)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "s\n");
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "%f %f %f %f k\n", c, m, y, k);
}
+/* shadings, images, xobjects */
+
static void
-pdf_buffer_sc(pdf_csi *csi, void *state_)
+pdf_out_BI(fz_context *ctx, pdf_processor *proc, fz_image *img)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_compressed_buffer *cbuf;
+ fz_buffer *buf;
int i;
- for (i = 0; i < csi->top; i++)
- fz_printf(state->ctx, state->out, "%f ", csi->stack[i]);
- fz_printf(state->ctx, state->out, "sc\n");
-}
+ if (img == NULL)
+ return;
+ cbuf = img->buffer;
+ if (cbuf == NULL)
+ return;
+ buf = cbuf->buffer;
+ if (buf == NULL)
+ return;
-static void
-pdf_buffer_scn(pdf_csi *csi, void *state_)
-{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
- int i;
+ fz_printf(ctx, out, "BI\n");
+ fz_printf(ctx, out, "/W %d\n", img->w);
+ fz_printf(ctx, out, "/H %d\n", img->h);
+ fz_printf(ctx, out, "/BPC %d\n", img->bpc);
+ if (img->imagemask)
+ fz_printf(ctx, out, "/IM true\n");
+ else if (img->colorspace == fz_device_gray(ctx))
+ fz_printf(ctx, out, "/CS/G\n");
+ else if (img->colorspace == fz_device_rgb(ctx))
+ fz_printf(ctx, out, "/CS/RGB\n");
+ else if (img->colorspace == fz_device_cmyk(ctx))
+ fz_printf(ctx, out, "/CS/CMYK\n");
+ else if (fz_colorspace_is_indexed(ctx, img->colorspace))
+ fz_printf(ctx, out, "/CS/I\n");
+ if (img->interpolate)
+ fz_printf(ctx, out, "/I true\n");
+ fz_printf(ctx, out, "/D[");
+ for (i = 0; i < img->n * 2; ++i)
+ {
+ if (i > 0)
+ fz_putc(ctx, out, ' ');
+ fz_printf(ctx, out, "%g", img->decode[i]);
+ }
+ fz_printf(ctx, out, "]\n");
- for (i = 0; i < csi->top; i++)
- fz_printf(state->ctx, state->out, "%f ", csi->stack[i]);
- if (csi->name[0])
- fz_printf(state->ctx, state->out, "/%s ", csi->name);
- fz_printf(state->ctx, state->out, "scn\n");
-}
+ switch (cbuf->params.type)
+ {
+ default:
+ fz_throw(ctx, FZ_ERROR_GENERIC, "unknown compressed buffer type");
+ break;
-static void
-pdf_buffer_v(pdf_csi *csi, void *state_)
-{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
+ case FZ_IMAGE_JPEG:
+ fz_printf(ctx, out, "/F/DCT\n");
+ if (cbuf->params.u.jpeg.color_transform != -1)
+ fz_printf(ctx, out, "/DP<</ColorTransform %d>>\n",
+ cbuf->params.u.jpeg.color_transform);
+ break;
+
+ case FZ_IMAGE_FAX:
+ fz_printf(ctx, out, "/F/CCF\n");
+ fz_printf(ctx, out, "/DP<<\n");
+ fz_printf(ctx, out, "/K %d\n", cbuf->params.u.fax.k);
+ if (cbuf->params.u.fax.columns != 1728)
+ fz_printf(ctx, out, "/Columns %d\n", cbuf->params.u.fax.columns);
+ if (cbuf->params.u.fax.rows > 0)
+ fz_printf(ctx, out, "/Rows %d\n", cbuf->params.u.fax.rows);
+ if (cbuf->params.u.fax.end_of_line)
+ fz_printf(ctx, out, "/EndOfLine true\n");
+ if (cbuf->params.u.fax.encoded_byte_align)
+ fz_printf(ctx, out, "/EncodedByteAlign true\n");
+ if (!cbuf->params.u.fax.end_of_block)
+ fz_printf(ctx, out, "/EndOfBlock false\n");
+ if (cbuf->params.u.fax.black_is_1)
+ fz_printf(ctx, out, "/BlackIs1 true\n");
+ if (cbuf->params.u.fax.damaged_rows_before_error > 0)
+ fz_printf(ctx, out, "/DamagedRowsBeforeError %d\n",
+ cbuf->params.u.fax.damaged_rows_before_error);
+ fz_printf(ctx, out, ">>\n");
+ break;
+
+ case FZ_IMAGE_RAW:
+ break;
+
+ case FZ_IMAGE_RLD:
+ fz_printf(ctx, out, "/F/RL\n");
+ break;
+
+ case FZ_IMAGE_FLATE:
+ fz_printf(ctx, out, "/F/Fl\n");
+ if (cbuf->params.u.flate.predictor > 1)
+ {
+ fz_printf(ctx, out, "/DP<<\n");
+ fz_printf(ctx, out, "/Predictor %d\n", cbuf->params.u.flate.predictor);
+ if (cbuf->params.u.flate.columns != 1)
+ fz_printf(ctx, out, "/Columns %d\n", cbuf->params.u.flate.columns);
+ if (cbuf->params.u.flate.colors != 1)
+ fz_printf(ctx, out, "/Colors %d\n", cbuf->params.u.flate.colors);
+ if (cbuf->params.u.flate.bpc != 8)
+ fz_printf(ctx, out, "/BitsPerComponent %d\n", cbuf->params.u.flate.bpc);
+ fz_printf(ctx, out, ">>\n");
+ }
+ break;
+
+ case FZ_IMAGE_LZW:
+ fz_printf(ctx, out, "/F/LZW\n");
+ if (cbuf->params.u.lzw.predictor > 1)
+ {
+ fz_printf(ctx, out, "/DP<<\n");
+ fz_printf(ctx, out, "/Predictor %d\n", cbuf->params.u.lzw.predictor);
+ if (cbuf->params.u.lzw.columns != 1)
+ fz_printf(ctx, out, "/Columns %d\n", cbuf->params.u.lzw.columns);
+ if (cbuf->params.u.lzw.colors != 1)
+ fz_printf(ctx, out, "/Colors %d\n", cbuf->params.u.lzw.colors);
+ if (cbuf->params.u.lzw.bpc != 8)
+ fz_printf(ctx, out, "/BitsPerComponent %d\n", cbuf->params.u.lzw.bpc);
+ if (cbuf->params.u.lzw.early_change != 1)
+ fz_printf(ctx, out, "/EarlyChange %d\n", cbuf->params.u.lzw.early_change);
+ fz_printf(ctx, out, ">>\n");
+ }
+ break;
+ }
- fz_printf(state->ctx, state->out, "%f %f %f %f v\n", csi->stack[0],
- csi->stack[1], csi->stack[2], csi->stack[3]);
+ fz_printf(ctx, out, "ID\n");
+ fz_write(ctx, out, buf->data, buf->len);
+ fz_printf(ctx, out, "\nEI\n");
}
static void
-pdf_buffer_w(pdf_csi *csi, void *state_)
+pdf_out_sh(fz_context *ctx, pdf_processor *proc, const char *name, fz_shade *shade)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "%f w\n", csi->stack[0]);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "/%s sh\n", name);
}
static void
-pdf_buffer_y(pdf_csi *csi, void *state_)
+pdf_out_Do_image(fz_context *ctx, pdf_processor *proc, const char *name, fz_image *image)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "%f %f %f %f y\n", csi->stack[0],
- csi->stack[1], csi->stack[2], csi->stack[3]);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "/%s Do\n", name);
}
static void
-pdf_buffer_Do(pdf_csi *csi, void *state_)
+pdf_out_Do_form(fz_context *ctx, pdf_processor *proc, const char *name, pdf_xobject *xobj, pdf_obj *page_resources)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "/%s Do\n", csi->name);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "/%s Do\n", name);
}
+/* marked content */
+
static void
-pdf_buffer_Tf(pdf_csi *csi, void *state_)
+pdf_out_MP(fz_context *ctx, pdf_processor *proc, const char *tag)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "/%s %f Tf\n", csi->name, csi->stack[0]);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "/%s MP\n", tag);
}
static void
-pdf_buffer_gs(pdf_csi *csi, void *state_)
+pdf_out_DP(fz_context *ctx, pdf_processor *proc, const char *tag, pdf_obj *properties)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "/%s gs\n", csi->name);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "/%s ", tag);
+ pdf_output_obj(ctx, out, properties, 1);
+ fz_printf(ctx, out, " DP\n");
}
static void
-pdf_buffer_sh(pdf_csi *csi, void *state_)
+pdf_out_BMC(fz_context *ctx, pdf_processor *proc, const char *tag)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_printf(state->ctx, state->out, "/%s sh\n", csi->name);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "/%s BMC\n", tag);
}
static void
-free_processor_buffer(pdf_csi *csi, void *state_)
+pdf_out_BDC(fz_context *ctx, pdf_processor *proc, const char *tag, pdf_obj *properties)
{
- pdf_buffer_state *state = (pdf_buffer_state *)state_;
-
- fz_drop_output(state->ctx, state->out);
- fz_free(state->ctx, state);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "/%s ", tag);
+ pdf_output_obj(ctx, out, properties, 1);
+ fz_printf(ctx, out, " BDC\n");
}
static void
-process_annot(pdf_csi *csi, void *state, pdf_obj *resources, pdf_annot *annot)
+pdf_out_EMC(fz_context *ctx, pdf_processor *proc)
{
- fz_context *ctx = csi->ctx;
- pdf_xobject *xobj = annot->ap;
-
- /* Avoid infinite recursion */
- if (xobj == NULL || pdf_mark_obj(ctx, xobj->me))
- return;
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "EMC\n");
+}
- fz_try(ctx)
- {
- if (xobj->resources)
- resources = xobj->resources;
+/* compatibility */
- pdf_process_contents_object(csi, resources, xobj->contents);
- }
- fz_always(ctx)
- {
- pdf_unmark_obj(ctx, xobj->me);
- }
- fz_catch(ctx)
- {
- fz_rethrow(ctx);
- }
+static void
+pdf_out_BX(fz_context *ctx, pdf_processor *proc)
+{
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "BX\n");
}
static void
-process_stream(pdf_csi *csi, void *state, pdf_lexbuf *buf)
+pdf_out_EX(fz_context *ctx, pdf_processor *proc)
{
- pdf_process_stream(csi, buf);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_printf(ctx, out, "EX\n");
}
static void
-process_contents(pdf_csi *csi, void *state, pdf_obj *resources, pdf_obj *contents)
+pdf_drop_imp_output_processor(fz_context *ctx, pdf_processor *proc)
{
- pdf_process_contents_object(csi, resources, contents);
+ fz_output *out = ((pdf_output_processor*)proc)->out;
+ fz_drop_output(ctx, out);
}
-static const pdf_processor pdf_processor_buffer =
+static pdf_processor *
+pdf_new_output_processor(fz_context *ctx, fz_output *out)
{
+ pdf_output_processor *proc = pdf_new_processor(ctx, sizeof *proc);
{
- pdf_buffer_dquote,
- pdf_buffer_squote,
- pdf_buffer_B,
- pdf_buffer_Bstar,
- pdf_buffer_BDC,
- pdf_buffer_BI,
- pdf_buffer_BMC,
- pdf_buffer_BT,
- pdf_buffer_BX,
- pdf_buffer_CS,
- pdf_buffer_DP,
- pdf_buffer_EMC,
- pdf_buffer_ET,
- pdf_buffer_EX,
- pdf_buffer_F,
- pdf_buffer_G,
- pdf_buffer_J,
- pdf_buffer_K,
- pdf_buffer_M,
- pdf_buffer_MP,
- pdf_buffer_Q,
- pdf_buffer_RG,
- pdf_buffer_S,
- pdf_buffer_SC,
- pdf_buffer_SCN,
- pdf_buffer_Tstar,
- pdf_buffer_TD,
- pdf_buffer_TJ,
- pdf_buffer_TL,
- pdf_buffer_Tc,
- pdf_buffer_Td,
- pdf_buffer_Tj,
- pdf_buffer_Tm,
- pdf_buffer_Tr,
- pdf_buffer_Ts,
- pdf_buffer_Tw,
- pdf_buffer_Tz,
- pdf_buffer_W,
- pdf_buffer_Wstar,
- pdf_buffer_b,
- pdf_buffer_bstar,
- pdf_buffer_c,
- pdf_buffer_cm,
- pdf_buffer_cs,
- pdf_buffer_d,
- pdf_buffer_d0,
- pdf_buffer_d1,
- pdf_buffer_f,
- pdf_buffer_fstar,
- pdf_buffer_g,
- pdf_buffer_h,
- pdf_buffer_i,
- pdf_buffer_j,
- pdf_buffer_k,
- pdf_buffer_l,
- pdf_buffer_m,
- pdf_buffer_n,
- pdf_buffer_q,
- pdf_buffer_re,
- pdf_buffer_rg,
- pdf_buffer_ri,
- pdf_buffer_s,
- pdf_buffer_sc,
- pdf_buffer_scn,
- pdf_buffer_v,
- pdf_buffer_w,
- pdf_buffer_y,
- pdf_buffer_Do,
- pdf_buffer_Tf,
- pdf_buffer_gs,
- pdf_buffer_sh,
- free_processor_buffer
- },
- process_annot,
- process_stream,
- process_contents
-};
+ proc->super.drop_imp = pdf_drop_imp_output_processor;
+
+ /* general graphics state */
+ proc->super.op_w = pdf_out_w;
+ proc->super.op_j = pdf_out_j;
+ proc->super.op_J = pdf_out_J;
+ proc->super.op_M = pdf_out_M;
+ proc->super.op_d = pdf_out_d;
+ proc->super.op_ri = pdf_out_ri;
+ proc->super.op_i = pdf_out_i;
+ proc->super.op_gs_begin = pdf_out_gs_begin;
+ proc->super.op_gs_end = pdf_out_gs_end;
+
+ /* transparency graphics state */
+ proc->super.op_gs_BM = NULL;
+ proc->super.op_gs_CA = NULL;
+ proc->super.op_gs_ca = NULL;
+ proc->super.op_gs_SMask = NULL;
+
+ /* special graphics state */
+ proc->super.op_q = pdf_out_q;
+ proc->super.op_Q = pdf_out_Q;
+ proc->super.op_cm = pdf_out_cm;
+
+ /* path construction */
+ proc->super.op_m = pdf_out_m;
+ proc->super.op_l = pdf_out_l;
+ proc->super.op_c = pdf_out_c;
+ proc->super.op_v = pdf_out_v;
+ proc->super.op_y = pdf_out_y;
+ proc->super.op_h = pdf_out_h;
+ proc->super.op_re = pdf_out_re;
+
+ /* path painting */
+ proc->super.op_S = pdf_out_S;
+ proc->super.op_s = pdf_out_s;
+ proc->super.op_F = pdf_out_F;
+ proc->super.op_f = pdf_out_f;
+ proc->super.op_fstar = pdf_out_fstar;
+ proc->super.op_B = pdf_out_B;
+ proc->super.op_Bstar = pdf_out_Bstar;
+ proc->super.op_b = pdf_out_b;
+ proc->super.op_bstar = pdf_out_bstar;
+ proc->super.op_n = pdf_out_n;
+
+ /* clipping paths */
+ proc->super.op_W = pdf_out_W;
+ proc->super.op_Wstar = pdf_out_Wstar;
+
+ /* text objects */
+ proc->super.op_BT = pdf_out_BT;
+ proc->super.op_ET = pdf_out_ET;
+
+ /* text state */
+ proc->super.op_Tc = pdf_out_Tc;
+ proc->super.op_Tw = pdf_out_Tw;
+ proc->super.op_Tz = pdf_out_Tz;
+ proc->super.op_TL = pdf_out_TL;
+ proc->super.op_Tf = pdf_out_Tf;
+ proc->super.op_Tr = pdf_out_Tr;
+ proc->super.op_Ts = pdf_out_Ts;
+
+ /* text positioning */
+ proc->super.op_Td = pdf_out_Td;
+ proc->super.op_TD = pdf_out_TD;
+ proc->super.op_Tm = pdf_out_Tm;
+ proc->super.op_Tstar = pdf_out_Tstar;
+
+ /* text showing */
+ proc->super.op_TJ = pdf_out_TJ;
+ proc->super.op_Tj = pdf_out_Tj;
+ proc->super.op_squote = pdf_out_squote;
+ proc->super.op_dquote = pdf_out_dquote;
+
+ /* type 3 fonts */
+ proc->super.op_d0 = pdf_out_d0;
+ proc->super.op_d1 = pdf_out_d1;
+
+ /* color */
+ proc->super.op_CS = pdf_out_CS;
+ proc->super.op_cs = pdf_out_cs;
+ proc->super.op_SC_color = pdf_out_SC_color;
+ proc->super.op_sc_color = pdf_out_sc_color;
+ proc->super.op_SC_pattern = pdf_out_SC_pattern;
+ proc->super.op_sc_pattern = pdf_out_sc_pattern;
+ proc->super.op_SC_shade = pdf_out_SC_shade;
+ proc->super.op_sc_shade = pdf_out_sc_shade;
+
+ proc->super.op_G = pdf_out_G;
+ proc->super.op_g = pdf_out_g;
+ proc->super.op_RG = pdf_out_RG;
+ proc->super.op_rg = pdf_out_rg;
+ proc->super.op_K = pdf_out_K;
+ proc->super.op_k = pdf_out_k;
+
+ /* shadings, images, xobjects */
+ proc->super.op_BI = pdf_out_BI;
+ proc->super.op_sh = pdf_out_sh;
+ proc->super.op_Do_image = pdf_out_Do_image;
+ proc->super.op_Do_form = pdf_out_Do_form;
+
+ /* marked content */
+ proc->super.op_MP = pdf_out_MP;
+ proc->super.op_DP = pdf_out_DP;
+ proc->super.op_BMC = pdf_out_BMC;
+ proc->super.op_BDC = pdf_out_BDC;
+ proc->super.op_EMC = pdf_out_EMC;
+
+ /* compatibility */
+ proc->super.op_BX = pdf_out_BX;
+ proc->super.op_EX = pdf_out_EX;
+ }
-pdf_process *pdf_init_process_buffer(fz_context *ctx, pdf_process *process, fz_buffer *buffer)
-{
- fz_output *out = fz_new_output_with_buffer(ctx, buffer);
- pdf_buffer_state *p = NULL;
+ proc->out = out;
- fz_var(p);
+ return (pdf_processor*)proc;
+}
+pdf_processor *
+pdf_new_buffer_processor(fz_context *ctx, fz_buffer *buffer)
+{
+ pdf_processor *proc;
+ fz_output *out = fz_new_output_with_buffer(ctx, buffer);
fz_try(ctx)
{
- p = fz_malloc_struct(ctx, pdf_buffer_state);
- p->buffer = buffer;
- p->out = out;
- p->ctx = ctx;
+ proc = pdf_new_output_processor(ctx, out);
}
fz_catch(ctx)
{
fz_drop_output(ctx, out);
fz_rethrow(ctx);
}
-
- process->state = p;
- process->processor = &pdf_processor_buffer;
- return process;
+ return proc;
}
diff --git a/source/pdf/pdf-op-filter.c b/source/pdf/pdf-op-filter.c
index ec08b305..c030f468 100644
--- a/source/pdf/pdf-op-filter.c
+++ b/source/pdf/pdf-op-filter.c
@@ -1,11 +1,11 @@
-#include "pdf-interpret-imp.h"
+#include "mupdf/pdf.h"
typedef struct filter_gstate_s filter_gstate;
typedef enum
{
FLUSH_CTM = 1,
- FLUSH_COLOR = 2,
+ FLUSH_COLOR_F = 2,
FLUSH_COLOR_S = 4,
FLUSH_ALL = 7,
@@ -19,76 +19,74 @@ struct filter_gstate_s
int pushed;
fz_matrix ctm;
fz_matrix current_ctm;
- float color[FZ_MAX_COLORS];
- int color_n;
- float current_color[FZ_MAX_COLORS];
- int current_color_n;
- float color_s[FZ_MAX_COLORS];
- int color_s_n;
- float current_color_s[FZ_MAX_COLORS];
- int current_color_s_n;
- char cs[256];
- char cs_s[256];
- char cs_name[256];
- char cs_name_s[256];
- char current_cs[256];
- char current_cs_s[256];
- char current_cs_name[256];
- char current_cs_name_s[256];
+ struct
+ {
+ char name[256];
+ fz_colorspace *cs;
+ } cs, CS, current_cs, current_CS;
+ struct
+ {
+ char name[256];
+ pdf_pattern *pat;
+ fz_shade *shd;
+ int n;
+ float c[FZ_MAX_COLORS];
+ } sc, SC, current_sc, current_SC;
+ struct
+ {
+ fz_linecap linecap;
+ fz_linejoin linejoin;
+ float linewidth;
+ float miterlimit;
+ } stroke, current_stroke;
};
-typedef struct pdf_filter_state_s
+typedef struct pdf_filter_processor_s
{
- pdf_process process;
- fz_context *ctx;
+ pdf_processor super;
+ pdf_processor *chain;
filter_gstate *gstate;
- pdf_obj *resources;
-} pdf_filter_state;
+ pdf_document *doc;
+ pdf_obj *old_rdb, *new_rdb;
+} pdf_filter_processor;
-static void insert_resource_name(pdf_csi *csi, pdf_filter_state *state, const char *key, const char *name)
+static void
+copy_resource(fz_context *ctx, pdf_filter_processor *p, const char *key, const char *name)
{
- fz_context *ctx = csi->ctx;
- pdf_obj *xobj;
- pdf_obj *obj;
+ pdf_obj *res, *obj;
- if (!state->resources || !name || name[0] == 0)
+ if (!name || name[0] == 0)
return;
- xobj = pdf_dict_gets(ctx, csi->rdb, key);
- obj = pdf_dict_gets(ctx, xobj, name);
-
- xobj = pdf_dict_gets(ctx, state->resources, key);
- if (xobj == NULL) {
- xobj = pdf_new_dict(csi->ctx, csi->doc, 1);
- pdf_dict_puts_drop(ctx, state->resources, key, xobj);
+ res = pdf_dict_gets(ctx, p->old_rdb, key);
+ obj = pdf_dict_gets(ctx, res, name);
+ if (obj)
+ {
+ res = pdf_dict_gets(ctx, p->new_rdb, key);
+ if (!res)
+ {
+ res = pdf_new_dict(ctx, p->doc, 1);
+ pdf_dict_puts_drop(ctx, p->new_rdb, key, res);
+ }
+ pdf_dict_putp(ctx, res, name, obj);
}
- pdf_dict_putp(ctx, xobj, name, obj);
}
-static void insert_resource(pdf_csi *csi, pdf_filter_state *state, const char *key)
-{
- insert_resource_name(csi, state, key, csi->name);
-}
-
-static inline void call_op(pdf_csi *csi, pdf_filter_state *state, int op)
-{
- pdf_process_op(csi, op, &state->process);
-}
-
-static void filter_push(pdf_csi *csi, pdf_filter_state *state)
+static void
+filter_push(fz_context *ctx, pdf_filter_processor *p)
{
- filter_gstate *gstate = state->gstate;
- filter_gstate *new_gstate = fz_malloc_struct(state->ctx, filter_gstate);
-
+ filter_gstate *gstate = p->gstate;
+ filter_gstate *new_gstate = fz_malloc_struct(ctx, filter_gstate);
*new_gstate = *gstate;
new_gstate->pushed = 0;
new_gstate->next = gstate;
- state->gstate = new_gstate;
+ p->gstate = new_gstate;
}
-static int filter_pop(pdf_csi *csi, pdf_filter_state *state)
+static int
+filter_pop(fz_context *ctx, pdf_filter_processor *p)
{
- filter_gstate *gstate = state->gstate;
+ filter_gstate *gstate = p->gstate;
filter_gstate *old = gstate->next;
/* We are at the top, so nothing to pop! */
@@ -96,88 +94,47 @@ static int filter_pop(pdf_csi *csi, pdf_filter_state *state)
return 1;
if (gstate->pushed)
- call_op(csi, state, PDF_OP_Q);
+ if (p->chain->op_Q)
+ p->chain->op_Q(ctx, p->chain);
- fz_free(state->ctx, gstate);
- state->gstate = old;
+ fz_free(ctx, gstate);
+ p->gstate = old;
return 0;
}
-static void forward(pdf_csi *csi, pdf_filter_state *state, int op, float *f_argv, int f_argc, char *arg)
-{
- int top = csi->top;
- int to_save = top;
- float save_f[FZ_MAX_COLORS];
- char save_name[sizeof(csi->name)];
- int i;
-
- /* Store the stack */
- if (to_save > f_argc)
- to_save = 6;
- for (i = 0; i < to_save; i++)
- {
- save_f[i] = csi->stack[i];
- csi->stack[i] = f_argv[i];
- }
- for (;i < f_argc; i++)
- {
- csi->stack[i] = f_argv[i];
- }
- csi->top = f_argc;
-
- /* Store the name */
- fz_strlcpy(save_name, csi->name, sizeof(csi->name));
- if (arg)
- {
- fz_strlcpy(csi->name, arg, sizeof(csi->name));
- }
- else
- {
- csi->name[0] = 0;
- }
-
- call_op(csi, state, op);
-
- /* Restore the name */
- fz_strlcpy(csi->name, save_name, sizeof(save_name));
-
- /* Restore the stack */
- for (i = 0; i < to_save; i++)
- csi->stack[i] = save_f[i];
- csi->top = top;
-}
-
/* We never allow the topmost gstate to be changed. This allows us
* to pop back to the zeroth level and be sure that our gstate is
* sane. This is important for being able to add new operators at
* the end of pages in a sane way. */
static filter_gstate *
-gstate_to_update(pdf_csi *csi, pdf_filter_state *state)
+gstate_to_update(fz_context *ctx, pdf_filter_processor *p)
{
- filter_gstate *gstate = state->gstate;
+ filter_gstate *gstate = p->gstate;
/* If we're not the top, that's fine */
if (gstate->next != NULL)
return gstate;
/* We are the top. Push a group, so we're not */
- filter_push(csi, state);
- gstate = state->gstate;
+ filter_push(ctx, p);
+ gstate = p->gstate;
gstate->pushed = 1;
- call_op(csi, state, PDF_OP_q);
+ if (p->chain->op_q)
+ p->chain->op_q(ctx, p->chain);
- return state->gstate;
+ return p->gstate;
}
-static void filter_flush(pdf_csi *csi, pdf_filter_state *state, int flush)
+static void filter_flush(fz_context *ctx, pdf_filter_processor *p, int flush)
{
- filter_gstate *gstate = state->gstate;
+ filter_gstate *gstate = gstate_to_update(ctx, p);
int i;
if (gstate->pushed == 0)
{
gstate->pushed = 1;
- call_op(csi, state, PDF_OP_q);
+ if (p->chain->op_q)
+ p->chain->op_q(ctx, p->chain);
}
if (flush & FLUSH_CTM)
@@ -188,7 +145,15 @@ static void filter_flush(pdf_csi *csi, pdf_filter_state *state, int flush)
{
fz_matrix current = gstate->current_ctm;
- forward(csi, state, PDF_OP_cm, (float *)&gstate->ctm.a, 6, NULL);
+ if (p->chain->op_cm)
+ p->chain->op_cm(ctx, p->chain,
+ gstate->ctm.a,
+ gstate->ctm.b,
+ gstate->ctm.c,
+ gstate->ctm.d,
+ gstate->ctm.e,
+ gstate->ctm.f);
+
fz_concat(&gstate->current_ctm, &current, &gstate->ctm);
gstate->ctm.a = 1;
gstate->ctm.b = 0;
@@ -198,1036 +163,1094 @@ static void filter_flush(pdf_csi *csi, pdf_filter_state *state, int flush)
gstate->ctm.f = 0;
}
}
- if (flush & FLUSH_COLOR)
+
+ if (flush & FLUSH_COLOR_F)
{
- if (strcmp(gstate->cs, gstate->current_cs) ||
- gstate->color_n != gstate->current_color_n)
+ if (gstate->cs.cs == fz_device_gray(ctx) && !gstate->sc.pat && !gstate->sc.shd && gstate->sc.n == 1)
{
- /* Colorspace has changed. Send both colorspace (and
- * color if we have it. */
- if (!strcmp(gstate->cs, "DeviceRGB"))
- {
- forward(csi, state, PDF_OP_rg, gstate->color, 3, NULL);
- }
- else if (!strcmp(gstate->cs, "DeviceGray"))
- {
- forward(csi, state, PDF_OP_g, gstate->color, 1, NULL);
- }
- else if (!strcmp(gstate->cs, "DeviceCMYK"))
- {
- forward(csi, state, PDF_OP_k, gstate->color, 4, NULL);
- }
- else if (gstate->cs_name[0])
- {
- if (strcmp(gstate->cs, gstate->current_cs))
- {
- forward(csi, state, PDF_OP_cs, NULL, 0, gstate->cs);
- }
- forward(csi, state, PDF_OP_scn, gstate->color, gstate->color_n, gstate->cs_name);
- }
- else if (gstate->color_n > 0)
- {
- if (strcmp(gstate->cs, gstate->current_cs))
- {
- forward(csi, state, PDF_OP_cs, NULL, 0, gstate->cs);
- }
- forward(csi, state, PDF_OP_scn, gstate->color, gstate->color_n, NULL);
- }
- else
- {
- forward(csi, state, PDF_OP_cs, NULL, 0, gstate->cs);
- }
- strcpy(gstate->current_cs, gstate->cs);
- strcpy(gstate->current_cs_name, gstate->cs_name);
- gstate->current_color_n = gstate->color_n;
- for (i = 0; i < gstate->color_n; i++)
- gstate->current_color[i] = gstate->color[i];
+ if (p->chain->op_g)
+ p->chain->op_g(ctx, p->chain, gstate->sc.c[0]);
+ goto done_sc;
}
- else if (strcmp(gstate->cs_name, gstate->current_cs_name))
+ if (gstate->cs.cs == fz_device_rgb(ctx) && !gstate->sc.pat && !gstate->sc.shd && gstate->sc.n == 3)
{
- /* Pattern name has changed */
- forward(csi, state, PDF_OP_scn, gstate->color, gstate->color_n, gstate->cs_name);
- strcpy(gstate->current_cs_name, gstate->cs_name);
+ if (p->chain->op_rg)
+ p->chain->op_rg(ctx, p->chain, gstate->sc.c[0], gstate->sc.c[1], gstate->sc.c[2]);
+ goto done_sc;
}
- else
+ if (gstate->cs.cs == fz_device_cmyk(ctx) && !gstate->sc.pat && !gstate->sc.shd && gstate->sc.n == 4)
{
- /* Has the color changed? */
- for (i = 0; i < gstate->color_n; i++)
- {
- if (gstate->color[i] != gstate->current_color[i])
- break;
- }
- if (i == gstate->color_n)
- {
- /* The color has not changed. Do nothing. */
- }
- else if (!strcmp(gstate->cs, "DeviceRGB"))
- {
- forward(csi, state, PDF_OP_rg, gstate->color, 3, NULL);
- }
- else if (!strcmp(gstate->cs, "DeviceGray"))
- {
- forward(csi, state, PDF_OP_g, gstate->color, 1, NULL);
- }
- else if (!strcmp(gstate->cs, "DeviceCMYK"))
+ if (p->chain->op_k)
+ p->chain->op_k(ctx, p->chain, gstate->sc.c[0], gstate->sc.c[1], gstate->sc.c[2], gstate->sc.c[3]);
+ goto done_sc;
+ }
+
+ if (strcmp(gstate->cs.name, gstate->current_cs.name))
+ {
+ if (p->chain->op_cs)
+ p->chain->op_cs(ctx, p->chain, gstate->cs.name, gstate->cs.cs);
+ }
+
+ /* pattern or shading */
+ if (gstate->sc.name[0])
+ {
+ int emit = 0;
+ if (strcmp(gstate->sc.name, gstate->current_sc.name))
+ emit = 1;
+ if (gstate->sc.n != gstate->current_sc.n)
+ emit = 1;
+ else
+ for (i = 0; i < gstate->sc.n; ++i)
+ if (gstate->sc.c[i] != gstate->current_sc.c[i])
+ emit = 1;
+ if (emit)
{
- forward(csi, state, PDF_OP_k, gstate->color, 4, NULL);
+ if (gstate->sc.pat)
+ if (p->chain->op_sc_pattern)
+ p->chain->op_sc_pattern(ctx, p->chain, gstate->sc.name, gstate->sc.pat, gstate->sc.n, gstate->sc.c);
+ if (gstate->sc.shd)
+ if (p->chain->op_sc_shade)
+ p->chain->op_sc_shade(ctx, p->chain, gstate->sc.name, gstate->sc.shd);
}
+ }
+
+ /* plain color */
+ else
+ {
+ int emit = 0;
+ if (gstate->sc.n != gstate->current_sc.n)
+ emit = 1;
else
+ for (i = 0; i < gstate->sc.n; ++i)
+ if (gstate->sc.c[i] != gstate->current_sc.c[i])
+ emit = 1;
+ if (emit)
{
- forward(csi, state, PDF_OP_scn, gstate->color, gstate->color_n, NULL);
+ if (p->chain->op_sc_color)
+ p->chain->op_sc_color(ctx, p->chain, gstate->sc.n, gstate->sc.c);
}
- for (; i < gstate->color_n; i++)
- gstate->current_color[i] = gstate->color[i];
}
+
+done_sc:
+ gstate->current_cs = gstate->cs;
+ gstate->current_sc = gstate->sc;
}
+
if (flush & FLUSH_COLOR_S)
{
- if (strcmp(gstate->cs_s, gstate->current_cs_s) ||
- gstate->color_s_n != gstate->current_color_s_n)
+ if (gstate->CS.cs == fz_device_gray(ctx) && !gstate->SC.pat && !gstate->SC.shd && gstate->SC.n == 1)
{
- /* Colorspace has changed. Send both colorspace (and
- * color if we have it. */
- if (!strcmp(gstate->cs_s, "DeviceRGB"))
- {
- forward(csi, state, PDF_OP_RG, gstate->color_s, 3, NULL);
- }
- else if (!strcmp(gstate->cs_s, "DeviceGray"))
- {
- forward(csi, state, PDF_OP_G, gstate->color_s, 1, NULL);
- }
- else if (!strcmp(gstate->cs_s, "DeviceCMYK"))
- {
- forward(csi, state, PDF_OP_K, gstate->color_s, 4, NULL);
- }
- else if (gstate->cs_name_s[0])
- {
- if (strcmp(gstate->cs_s, gstate->current_cs_s))
- {
- forward(csi, state, PDF_OP_CS, NULL, 0, gstate->cs_s);
- }
- forward(csi, state, PDF_OP_SCN, gstate->color_s, gstate->color_s_n, gstate->cs_name_s);
- }
- else if (gstate->color_s_n > 0)
- {
- if (strcmp(gstate->cs_s, gstate->current_cs_s))
- {
- forward(csi, state, PDF_OP_CS, NULL, 0, gstate->cs_s);
- }
- forward(csi, state, PDF_OP_SCN, gstate->color_s, gstate->color_s_n, NULL);
- }
- else
- {
- forward(csi, state, PDF_OP_CS, NULL, 0, gstate->cs_s);
- }
- strcpy(gstate->current_cs_s, gstate->cs_s);
- strcpy(gstate->current_cs_name_s, gstate->cs_name_s);
- gstate->current_color_s_n = gstate->color_s_n;
- for (i = 0; i < gstate->color_s_n; i++)
- gstate->current_color_s[i] = gstate->color_s[i];
+ if (p->chain->op_G)
+ p->chain->op_G(ctx, p->chain, gstate->SC.c[0]);
+ goto done_SC;
}
- else if (strcmp(gstate->cs_name_s, gstate->current_cs_name_s))
+ if (gstate->CS.cs == fz_device_rgb(ctx) && !gstate->SC.pat && !gstate->SC.shd && gstate->SC.n == 3)
{
- /* Pattern name has changed */
- forward(csi, state, PDF_OP_SCN, gstate->color_s, gstate->color_s_n, gstate->cs_name_s);
- strcpy(gstate->current_cs_name_s, gstate->cs_name_s);
+ if (p->chain->op_RG)
+ p->chain->op_RG(ctx, p->chain, gstate->SC.c[0], gstate->SC.c[1], gstate->SC.c[2]);
+ goto done_SC;
}
- else
+ if (gstate->CS.cs == fz_device_cmyk(ctx) && !gstate->SC.pat && !gstate->SC.shd && gstate->SC.n == 4)
{
- /* Has the color changed? */
- int i;
+ if (p->chain->op_K)
+ p->chain->op_K(ctx, p->chain, gstate->SC.c[0], gstate->SC.c[1], gstate->SC.c[2], gstate->SC.c[3]);
+ goto done_SC;
+ }
- for (i = 0; i < gstate->color_s_n; i++)
- {
- if (gstate->color_s[i] != gstate->current_color_s[i])
- break;
- }
- if (i == gstate->color_s_n)
- {
- /* The color has not changed. Do nothing. */
- }
- else if (!strcmp(gstate->cs_s, "DeviceRGB"))
- {
- forward(csi, state, PDF_OP_RG, gstate->color_s, 3, NULL);
- }
- else if (!strcmp(gstate->cs_s, "DeviceGray"))
- {
- forward(csi, state, PDF_OP_G, gstate->color_s, 1, NULL);
- }
- else if (!strcmp(gstate->cs_s, "DeviceCMYK"))
+ if (strcmp(gstate->CS.name, gstate->current_CS.name))
+ {
+ if (p->chain->op_CS)
+ p->chain->op_CS(ctx, p->chain, gstate->CS.name, gstate->CS.cs);
+ }
+
+ /* pattern or shading */
+ if (gstate->SC.name[0])
+ {
+ int emit = 0;
+ if (strcmp(gstate->SC.name, gstate->current_SC.name))
+ emit = 1;
+ if (gstate->SC.n != gstate->current_SC.n)
+ emit = 1;
+ else
+ for (i = 0; i < gstate->SC.n; ++i)
+ if (gstate->SC.c[i] != gstate->current_SC.c[i])
+ emit = 1;
+ if (emit)
{
- forward(csi, state, PDF_OP_K, gstate->color_s, 4, NULL);
+ if (gstate->SC.pat)
+ if (p->chain->op_SC_pattern)
+ p->chain->op_SC_pattern(ctx, p->chain, gstate->SC.name, gstate->SC.pat, gstate->SC.n, gstate->SC.c);
+ if (gstate->SC.shd)
+ if (p->chain->op_SC_shade)
+ p->chain->op_SC_shade(ctx, p->chain, gstate->SC.name, gstate->SC.shd);
}
+ }
+
+ /* plain color */
+ else
+ {
+ int emit = 0;
+ if (gstate->SC.n != gstate->current_SC.n)
+ emit = 1;
else
+ for (i = 0; i < gstate->SC.n; ++i)
+ if (gstate->SC.c[i] != gstate->current_SC.c[i])
+ emit = 1;
+ if (emit)
{
- forward(csi, state, PDF_OP_SCN, gstate->color_s, gstate->color_s_n, NULL);
+ if (p->chain->op_SC_color)
+ p->chain->op_SC_color(ctx, p->chain, gstate->SC.n, gstate->SC.c);
}
- for (; i < gstate->color_s_n; i++)
- gstate->current_color_s[i] = gstate->color_s[i];
}
+
+done_SC:
+ gstate->current_CS = gstate->CS;
+ gstate->current_SC = gstate->SC;
+ }
+
+ if (flush & FLUSH_STROKE)
+ {
+ if (gstate->stroke.linecap != gstate->current_stroke.linecap)
+ {
+ if (p->chain->op_J)
+ p->chain->op_J(ctx, p->chain, gstate->stroke.linecap);
+ }
+ if (gstate->stroke.linejoin != gstate->current_stroke.linejoin)
+ {
+ if (p->chain->op_j)
+ p->chain->op_j(ctx, p->chain, gstate->stroke.linejoin);
+ }
+ if (gstate->stroke.linewidth != gstate->current_stroke.linewidth)
+ {
+ if (p->chain->op_w)
+ p->chain->op_w(ctx, p->chain, gstate->stroke.linewidth);
+ }
+ if (gstate->stroke.miterlimit != gstate->current_stroke.miterlimit)
+ {
+ if (p->chain->op_M)
+ p->chain->op_M(ctx, p->chain, gstate->stroke.linewidth);
+ }
+ gstate->current_stroke = gstate->stroke;
}
}
+/* general graphics state */
+
static void
-pdf_filter_dquote(pdf_csi *csi, void *state_)
+pdf_filter_w(fz_context *ctx, pdf_processor *proc, float linewidth)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, FLUSH_ALL);
- call_op(csi, state, PDF_OP_dquote);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_gstate *gstate = gstate_to_update(ctx, p);
+ gstate->stroke.linewidth = linewidth;
}
static void
-pdf_filter_squote(pdf_csi *csi, void *state_)
+pdf_filter_j(fz_context *ctx, pdf_processor *proc, int linejoin)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, FLUSH_ALL);
- call_op(csi, state, PDF_OP_squote);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_gstate *gstate = gstate_to_update(ctx, p);
+ gstate->stroke.linejoin = linejoin;
}
static void
-pdf_filter_B(pdf_csi *csi, void *state_)
+pdf_filter_J(fz_context *ctx, pdf_processor *proc, int linecap)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, FLUSH_ALL);
- call_op(csi, state, PDF_OP_B);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_gstate *gstate = gstate_to_update(ctx, p);
+ gstate->stroke.linecap = linecap;
}
static void
-pdf_filter_Bstar(pdf_csi *csi, void *state_)
+pdf_filter_M(fz_context *ctx, pdf_processor *proc, float miterlimit)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, FLUSH_ALL);
- call_op(csi, state, PDF_OP_Bstar);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_gstate *gstate = gstate_to_update(ctx, p);
+ gstate->stroke.miterlimit = miterlimit;
}
static void
-pdf_filter_BDC(pdf_csi *csi, void *state_)
+pdf_filter_d(fz_context *ctx, pdf_processor *proc, pdf_obj *array, float phase)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- insert_resource_name(csi, state, "Properties", pdf_to_name(csi->ctx, csi->obj));
-
- filter_flush(csi, state, 0);
- call_op(csi, state, PDF_OP_BDC);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, 0);
+ if (p->chain->op_d)
+ p->chain->op_d(ctx, p->chain, array, phase);
}
static void
-pdf_filter_BI(pdf_csi *csi, void *state_)
+pdf_filter_ri(fz_context *ctx, pdf_processor *proc, const char *intent)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, FLUSH_FILL);
- call_op(csi, state, PDF_OP_BI);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, 0);
+ if (p->chain->op_ri)
+ p->chain->op_ri(ctx, p->chain, intent);
}
static void
-pdf_filter_BMC(pdf_csi *csi, void *state_)
+pdf_filter_i(fz_context *ctx, pdf_processor *proc, float flatness)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, 0);
- call_op(csi, state, PDF_OP_BMC);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, 0);
+ if (p->chain->op_i)
+ p->chain->op_i(ctx, p->chain, flatness);
}
static void
-pdf_filter_BT(pdf_csi *csi, void *state_)
+pdf_filter_gs_begin(fz_context *ctx, pdf_processor *proc, const char *name, pdf_obj *extgstate)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, 0);
- call_op(csi, state, PDF_OP_BT);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, FLUSH_ALL);
+ if (p->chain->op_gs_begin)
+ p->chain->op_gs_begin(ctx, p->chain, name, extgstate);
+ copy_resource(ctx, p, "ExtGState", name);
}
static void
-pdf_filter_BX(pdf_csi *csi, void *state_)
+pdf_filter_gs_BM(fz_context *ctx, pdf_processor *proc, const char *blendmode)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, 0);
- call_op(csi, state, PDF_OP_BX);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ if (p->chain->op_gs_BM)
+ p->chain->op_gs_BM(ctx, p->chain, blendmode);
}
static void
-pdf_filter_CS(pdf_csi *csi, void *state_)
+pdf_filter_gs_CA(fz_context *ctx, pdf_processor *proc, float alpha)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
- filter_gstate *gstate = gstate_to_update(csi, state);
-
- insert_resource(csi, state, "ColorSpace");
-
- fz_strlcpy(gstate->cs_s, csi->name, sizeof(gstate->cs_s));
- gstate->current_color_s_n = 0;
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ if (p->chain->op_gs_CA)
+ p->chain->op_gs_CA(ctx, p->chain, alpha);
}
static void
-pdf_filter_DP(pdf_csi *csi, void *state_)
+pdf_filter_gs_ca(fz_context *ctx, pdf_processor *proc, float alpha)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- insert_resource_name(csi, state, "Properties", pdf_to_name(csi->ctx, csi->obj));
-
- filter_flush(csi, state, 0);
- call_op(csi, state, PDF_OP_DP);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ if (p->chain->op_gs_ca)
+ p->chain->op_gs_ca(ctx, p->chain, alpha);
}
static void
-pdf_filter_EMC(pdf_csi *csi, void *state_)
+pdf_filter_gs_SMask(fz_context *ctx, pdf_processor *proc, pdf_xobject *smask, pdf_obj *page_resources, float *bc, int luminosity)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, 0);
- call_op(csi, state, PDF_OP_EMC);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ if (p->chain->op_gs_SMask)
+ p->chain->op_gs_SMask(ctx, p->chain, smask, page_resources, bc, luminosity);
}
static void
-pdf_filter_ET(pdf_csi *csi, void *state_)
+pdf_filter_gs_end(fz_context *ctx, pdf_processor *proc)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, 0);
- call_op(csi, state, PDF_OP_ET);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ if (p->chain->op_gs_end)
+ p->chain->op_gs_end(ctx, p->chain);
}
+/* special graphics state */
+
static void
-pdf_filter_EX(pdf_csi *csi, void *state_)
+pdf_filter_q(fz_context *ctx, pdf_processor *proc)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, 0);
- call_op(csi, state, PDF_OP_EX);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_push(ctx, p);
}
static void
-pdf_filter_F(pdf_csi *csi, void *state_)
+pdf_filter_Q(fz_context *ctx, pdf_processor *proc)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, FLUSH_FILL);
- call_op(csi, state, PDF_OP_F);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_pop(ctx, p);
}
static void
-pdf_filter_G(pdf_csi *csi, void *state_)
+pdf_filter_cm(fz_context *ctx, pdf_processor *proc, float a, float b, float c, float d, float e, float f)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
- filter_gstate *gstate = gstate_to_update(csi, state);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_gstate *gstate = gstate_to_update(ctx, p);
+ fz_matrix old, ctm;
- strcpy(gstate->cs_s, "DeviceGray");
- strcpy(gstate->cs_name_s, "");
- gstate->color_s[0] = csi->stack[0];
- gstate->color_s_n = 1;
-}
+ /* If we're being given an identity matrix, don't bother sending it */
+ if (a == 1 && b == 0 && c == 0 && d == 1 && e == 0 && f == 0)
+ return;
-static void
-pdf_filter_J(pdf_csi *csi, void *state_)
-{
- pdf_filter_state *state = (pdf_filter_state *)state_;
+ ctm.a = a;
+ ctm.b = b;
+ ctm.c = c;
+ ctm.d = d;
+ ctm.e = e;
+ ctm.f = f;
- filter_flush(csi, state, 0);
- call_op(csi, state, PDF_OP_J);
+ old = gstate->ctm;
+ fz_concat(&gstate->ctm, &ctm, &old);
}
+/* path construction */
+
static void
-pdf_filter_K(pdf_csi *csi, void *state_)
+pdf_filter_m(fz_context *ctx, pdf_processor *proc, float x, float y)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
- filter_gstate *gstate = gstate_to_update(csi, state);
-
- strcpy(gstate->cs_s, "DeviceCMYK");
- strcpy(gstate->cs_name_s, "");
- gstate->color_s[0] = csi->stack[0];
- gstate->color_s[1] = csi->stack[1];
- gstate->color_s[2] = csi->stack[2];
- gstate->color_s[3] = csi->stack[3];
- gstate->color_s_n = 4;
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, FLUSH_CTM);
+ if (p->chain->op_m)
+ p->chain->op_m(ctx, p->chain, x, y);
}
static void
-pdf_filter_M(pdf_csi *csi, void *state_)
+pdf_filter_l(fz_context *ctx, pdf_processor *proc, float x, float y)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, 0);
- call_op(csi, state, PDF_OP_M);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, FLUSH_CTM);
+ if (p->chain->op_l)
+ p->chain->op_l(ctx, p->chain, x, y);
}
static void
-pdf_filter_MP(pdf_csi *csi, void *state_)
+pdf_filter_c(fz_context *ctx, pdf_processor *proc, float x1, float y1, float x2, float y2, float x3, float y3)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, 0);
- call_op(csi, state, PDF_OP_MP);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, FLUSH_CTM);
+ if (p->chain->op_c)
+ p->chain->op_c(ctx, p->chain, x1, y1, x2, y2, x3, y3);
}
static void
-pdf_filter_Q(pdf_csi *csi, void *state_)
+pdf_filter_v(fz_context *ctx, pdf_processor *proc, float x2, float y2, float x3, float y3)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_pop(csi, state);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, FLUSH_CTM);
+ if (p->chain->op_v)
+ p->chain->op_v(ctx, p->chain, x2, y2, x3, y3);
}
static void
-pdf_filter_RG(pdf_csi *csi, void *state_)
+pdf_filter_y(fz_context *ctx, pdf_processor *proc, float x1, float y1, float x3, float y3)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
- filter_gstate *gstate = gstate_to_update(csi, state);
-
- strcpy(gstate->cs_s, "DeviceRGB");
- strcpy(gstate->cs_name_s, "");
- gstate->color_s[0] = csi->stack[0];
- gstate->color_s[1] = csi->stack[1];
- gstate->color_s[2] = csi->stack[2];
- gstate->color_s_n = 3;
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, FLUSH_CTM);
+ if (p->chain->op_y)
+ p->chain->op_y(ctx, p->chain, x1, y1, x3, y3);
}
static void
-pdf_filter_S(pdf_csi *csi, void *state_)
+pdf_filter_h(fz_context *ctx, pdf_processor *proc)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, FLUSH_STROKE);
- call_op(csi, state, PDF_OP_S);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, FLUSH_CTM);
+ if (p->chain->op_h)
+ p->chain->op_h(ctx, p->chain);
}
static void
-pdf_filter_SCN(pdf_csi *csi, void *state_)
+pdf_filter_re(fz_context *ctx, pdf_processor *proc, float x, float y, float w, float h)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
- filter_gstate *gstate = gstate_to_update(csi, state);
- int i;
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, FLUSH_CTM);
+ if (p->chain->op_re)
+ p->chain->op_re(ctx, p->chain, x, y, w, h);
+}
- if (csi->name[0])
- insert_resource(csi, state, "Pattern");
+/* path painting */
- fz_strlcpy(gstate->cs_name_s, csi->name, sizeof(csi->name));
- for (i = 0; i < csi->top; i++)
- {
- gstate->color_s[i] = csi->stack[i];
- }
- gstate->color_s_n = csi->top;
+static void
+pdf_filter_S(fz_context *ctx, pdf_processor *proc)
+{
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, FLUSH_STROKE);
+ if (p->chain->op_S)
+ p->chain->op_S(ctx, p->chain);
}
static void
-pdf_filter_Tstar(pdf_csi *csi, void *state_)
+pdf_filter_s(fz_context *ctx, pdf_processor *proc)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, FLUSH_CTM);
- call_op(csi, state, PDF_OP_Tstar);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, FLUSH_STROKE);
+ if (p->chain->op_s)
+ p->chain->op_s(ctx, p->chain);
}
static void
-pdf_filter_TD(pdf_csi *csi, void *state_)
+pdf_filter_F(fz_context *ctx, pdf_processor *proc)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, FLUSH_CTM);
- call_op(csi, state, PDF_OP_TD);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, FLUSH_FILL);
+ if (p->chain->op_F)
+ p->chain->op_F(ctx, p->chain);
}
static void
-pdf_filter_TJ(pdf_csi *csi, void *state_)
+pdf_filter_f(fz_context *ctx, pdf_processor *proc)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, FLUSH_ALL);
- call_op(csi, state, PDF_OP_TJ);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, FLUSH_FILL);
+ if (p->chain->op_f)
+ p->chain->op_f(ctx, p->chain);
}
static void
-pdf_filter_TL(pdf_csi *csi, void *state_)
+pdf_filter_fstar(fz_context *ctx, pdf_processor *proc)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, 0);
- call_op(csi, state, PDF_OP_TL);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, FLUSH_FILL);
+ if (p->chain->op_fstar)
+ p->chain->op_fstar(ctx, p->chain);
}
static void
-pdf_filter_Tc(pdf_csi *csi, void *state_)
+pdf_filter_B(fz_context *ctx, pdf_processor *proc)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, 0);
- call_op(csi, state, PDF_OP_Tc);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, FLUSH_ALL);
+ if (p->chain->op_B)
+ p->chain->op_B(ctx, p->chain);
}
static void
-pdf_filter_Td(pdf_csi *csi, void *state_)
+pdf_filter_Bstar(fz_context *ctx, pdf_processor *proc)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, FLUSH_CTM);
- call_op(csi, state, PDF_OP_Td);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, FLUSH_ALL);
+ if (p->chain->op_Bstar)
+ p->chain->op_Bstar(ctx, p->chain);
}
static void
-pdf_filter_Tj(pdf_csi *csi, void *state_)
+pdf_filter_b(fz_context *ctx, pdf_processor *proc)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, FLUSH_ALL);
- call_op(csi, state, PDF_OP_Tj);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, FLUSH_ALL);
+ if (p->chain->op_b)
+ p->chain->op_b(ctx, p->chain);
}
static void
-pdf_filter_Tm(pdf_csi *csi, void *state_)
+pdf_filter_bstar(fz_context *ctx, pdf_processor *proc)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, FLUSH_CTM);
- call_op(csi, state, PDF_OP_Tm);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, FLUSH_ALL);
+ if (p->chain->op_bstar)
+ p->chain->op_bstar(ctx, p->chain);
}
static void
-pdf_filter_Tr(pdf_csi *csi, void *state_)
+pdf_filter_n(fz_context *ctx, pdf_processor *proc)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, 0);
- call_op(csi, state, PDF_OP_Tr);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, FLUSH_CTM);
+ if (p->chain->op_n)
+ p->chain->op_n(ctx, p->chain);
}
+/* clipping paths */
+
static void
-pdf_filter_Ts(pdf_csi *csi, void *state_)
+pdf_filter_W(fz_context *ctx, pdf_processor *proc)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, 0);
- call_op(csi, state, PDF_OP_Ts);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, FLUSH_CTM);
+ if (p->chain->op_W)
+ p->chain->op_W(ctx, p->chain);
}
static void
-pdf_filter_Tw(pdf_csi *csi, void *state_)
+pdf_filter_Wstar(fz_context *ctx, pdf_processor *proc)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, 0);
- call_op(csi, state, PDF_OP_Tw);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, FLUSH_CTM);
+ if (p->chain->op_Wstar)
+ p->chain->op_Wstar(ctx, p->chain);
}
+/* text objects */
+
static void
-pdf_filter_Tz(pdf_csi *csi, void *state_)
+pdf_filter_BT(fz_context *ctx, pdf_processor *proc)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, 0);
- call_op(csi, state, PDF_OP_Tz);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, 0);
+ if (p->chain->op_BT)
+ p->chain->op_BT(ctx, p->chain);
}
static void
-pdf_filter_W(pdf_csi *csi, void *state_)
+pdf_filter_ET(fz_context *ctx, pdf_processor *proc)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, FLUSH_CTM);
- call_op(csi, state, PDF_OP_W);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, 0);
+ if (p->chain->op_ET)
+ p->chain->op_ET(ctx, p->chain);
}
+/* text state */
+
static void
-pdf_filter_Wstar(pdf_csi *csi, void *state_)
+pdf_filter_Tc(fz_context *ctx, pdf_processor *proc, float charspace)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, FLUSH_CTM);
- call_op(csi, state, PDF_OP_Wstar);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, 0);
+ if (p->chain->op_Tc)
+ p->chain->op_Tc(ctx, p->chain, charspace);
}
static void
-pdf_filter_b(pdf_csi *csi, void *state_)
+pdf_filter_Tw(fz_context *ctx, pdf_processor *proc, float wordspace)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, FLUSH_ALL);
- call_op(csi, state, PDF_OP_b);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, 0);
+ if (p->chain->op_Tw)
+ p->chain->op_Tw(ctx, p->chain, wordspace);
}
static void
-pdf_filter_bstar(pdf_csi *csi, void *state_)
+pdf_filter_Tz(fz_context *ctx, pdf_processor *proc, float scale)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, FLUSH_ALL);
- call_op(csi, state, PDF_OP_bstar);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, 0);
+ if (p->chain->op_Tz)
+ p->chain->op_Tz(ctx, p->chain, scale);
}
static void
-pdf_filter_c(pdf_csi *csi, void *state_)
+pdf_filter_TL(fz_context *ctx, pdf_processor *proc, float leading)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, FLUSH_CTM);
- call_op(csi, state, PDF_OP_c);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, 0);
+ if (p->chain->op_TL)
+ p->chain->op_TL(ctx, p->chain, leading);
}
static void
-pdf_filter_cm(pdf_csi *csi, void *state_)
+pdf_filter_Tf(fz_context *ctx, pdf_processor *proc, const char *name, pdf_font_desc *font, float size)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
- filter_gstate *gstate = gstate_to_update(csi, state);
- fz_matrix old, ctm;
-
- ctm.a = (csi->top > 0 ? csi->stack[0] : 0.0);
- ctm.b = (csi->top > 1 ? csi->stack[1] : 0.0);
- ctm.c = (csi->top > 2 ? csi->stack[2] : 0.0);
- ctm.d = (csi->top > 3 ? csi->stack[3] : 0.0);
- ctm.e = (csi->top > 4 ? csi->stack[4] : 0.0);
- ctm.f = (csi->top > 5 ? csi->stack[5] : 0.0);
-
- /* If we're being given an identity matrix, don't bother sending it */
- if (ctm.a == 1 && ctm.b == 0 && ctm.c == 0 && ctm.d == 1 &&
- ctm.e == 0.0f && ctm.f == 0)
- return;
-
- old = gstate->ctm;
- fz_concat(&gstate->ctm, &ctm, &old);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, 0);
+ if (p->chain->op_Tf)
+ p->chain->op_Tf(ctx, p->chain, name, font, size);
+ copy_resource(ctx, p, "Font", name);
}
static void
-pdf_filter_cs(pdf_csi *csi, void *state_)
+pdf_filter_Tr(fz_context *ctx, pdf_processor *proc, int render)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
- filter_gstate *gstate = gstate_to_update(csi, state);
-
- insert_resource(csi, state, "ColorSpace");
-
- fz_strlcpy(gstate->cs, csi->name, sizeof(csi->name));
- gstate->color_n = 0;
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, 0);
+ if (p->chain->op_Tr)
+ p->chain->op_Tr(ctx, p->chain, render);
}
static void
-pdf_filter_d(pdf_csi *csi, void *state_)
+pdf_filter_Ts(fz_context *ctx, pdf_processor *proc, float rise)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, 0);
- call_op(csi, state, PDF_OP_d);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, 0);
+ if (p->chain->op_Ts)
+ p->chain->op_Ts(ctx, p->chain, rise);
}
+/* text positioning */
+
static void
-pdf_filter_d0(pdf_csi *csi, void *state_)
+pdf_filter_Td(fz_context *ctx, pdf_processor *proc, float tx, float ty)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- call_op(csi, state, PDF_OP_d0);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, FLUSH_CTM);
+ if (p->chain->op_Td)
+ p->chain->op_Td(ctx, p->chain, tx, ty);
}
static void
-pdf_filter_d1(pdf_csi *csi, void *state_)
+pdf_filter_TD(fz_context *ctx, pdf_processor *proc, float tx, float ty)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- call_op(csi, state, PDF_OP_d1);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, FLUSH_CTM);
+ if (p->chain->op_TD)
+ p->chain->op_TD(ctx, p->chain, tx, ty);
}
static void
-pdf_filter_f(pdf_csi *csi, void *state_)
+pdf_filter_Tm(fz_context *ctx, pdf_processor *proc, float a, float b, float c, float d, float e, float f)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, FLUSH_FILL);
- call_op(csi, state, PDF_OP_f);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, FLUSH_CTM);
+ if (p->chain->op_Tm)
+ p->chain->op_Tm(ctx, p->chain, a, b, c, d, e, f);
}
static void
-pdf_filter_fstar(pdf_csi *csi, void *state_)
+pdf_filter_Tstar(fz_context *ctx, pdf_processor *proc)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, FLUSH_FILL);
- call_op(csi, state, PDF_OP_fstar);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, FLUSH_CTM);
+ if (p->chain->op_Tstar)
+ p->chain->op_Tstar(ctx, p->chain);
}
+/* text showing */
+
static void
-pdf_filter_g(pdf_csi *csi, void *state_)
+pdf_filter_TJ(fz_context *ctx, pdf_processor *proc, pdf_obj *array)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
- filter_gstate *gstate = gstate_to_update(csi, state);
-
- strcpy(gstate->cs, "DeviceGray");
- strcpy(gstate->cs_name, "");
- gstate->color[0] = csi->stack[0];
- gstate->color_n = 1;
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, FLUSH_ALL);
+ if (p->chain->op_TJ)
+ p->chain->op_TJ(ctx, p->chain, array);
}
static void
-pdf_filter_h(pdf_csi *csi, void *state_)
+pdf_filter_Tj(fz_context *ctx, pdf_processor *proc, char *str, int len)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, FLUSH_CTM);
- call_op(csi, state, PDF_OP_h);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, FLUSH_ALL);
+ if (p->chain->op_Tj)
+ p->chain->op_Tj(ctx, p->chain, str, len);
}
static void
-pdf_filter_i(pdf_csi *csi, void *state_)
+pdf_filter_squote(fz_context *ctx, pdf_processor *proc, char *str, int len)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, 0);
- call_op(csi, state, PDF_OP_i);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, FLUSH_ALL);
+ if (p->chain->op_squote)
+ p->chain->op_squote(ctx, p->chain, str, len);
}
static void
-pdf_filter_j(pdf_csi *csi, void *state_)
+pdf_filter_dquote(fz_context *ctx, pdf_processor *proc, float aw, float ac, char *str, int len)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, 0);
- call_op(csi, state, PDF_OP_j);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, FLUSH_ALL);
+ if (p->chain->op_dquote)
+ p->chain->op_dquote(ctx, p->chain, aw, ac, str, len);
}
+/* type 3 fonts */
+
static void
-pdf_filter_k(pdf_csi *csi, void *state_)
+pdf_filter_d0(fz_context *ctx, pdf_processor *proc, float wx, float wy)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
- filter_gstate *gstate = gstate_to_update(csi, state);
-
- strcpy(gstate->cs, "DeviceCMYK");
- strcpy(gstate->cs_name, "");
- gstate->color[0] = csi->stack[0];
- gstate->color[1] = csi->stack[1];
- gstate->color[2] = csi->stack[2];
- gstate->color[3] = csi->stack[3];
- gstate->color_n = 4;
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, 0);
+ if (p->chain->op_d0)
+ p->chain->op_d0(ctx, p->chain, wx, wy);
}
static void
-pdf_filter_l(pdf_csi *csi, void *state_)
+pdf_filter_d1(fz_context *ctx, pdf_processor *proc, float wx, float wy, float llx, float lly, float urx, float ury)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, FLUSH_CTM);
- call_op(csi, state, PDF_OP_l);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, 0);
+ if (p->chain->op_d1)
+ p->chain->op_d1(ctx, p->chain, wx, wy, llx, lly, urx, ury);
}
+/* color */
+
static void
-pdf_filter_m(pdf_csi *csi, void *state_)
+pdf_filter_CS(fz_context *ctx, pdf_processor *proc, const char *name, fz_colorspace *cs)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, FLUSH_CTM);
- call_op(csi, state, PDF_OP_m);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_gstate *gstate = gstate_to_update(ctx, p);
+ fz_strlcpy(gstate->CS.name, name, sizeof gstate->CS.name);
+ gstate->CS.cs = cs;
+ copy_resource(ctx, p, "ColorSpace", name);
}
static void
-pdf_filter_n(pdf_csi *csi, void *state_)
+pdf_filter_cs(fz_context *ctx, pdf_processor *proc, const char *name, fz_colorspace *cs)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, FLUSH_CTM);
- call_op(csi, state, PDF_OP_n);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_gstate *gstate = gstate_to_update(ctx, p);
+ fz_strlcpy(gstate->cs.name, name, sizeof gstate->cs.name);
+ gstate->cs.cs = cs;
+ copy_resource(ctx, p, "ColorSpace", name);
}
static void
-pdf_filter_q(pdf_csi *csi, void *state_)
+pdf_filter_SC_pattern(fz_context *ctx, pdf_processor *proc, const char *name, pdf_pattern *pat, int n, float *color)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_push(csi, state);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_gstate *gstate = gstate_to_update(ctx, p);
+ int i;
+ fz_strlcpy(gstate->SC.name, name, sizeof gstate->SC.name);
+ gstate->SC.pat = pat;
+ gstate->SC.shd = NULL;
+ gstate->SC.n = n;
+ for (i = 0; i < n; ++i)
+ gstate->SC.c[i] = color[i];
+ copy_resource(ctx, p, "Pattern", name);
}
static void
-pdf_filter_re(pdf_csi *csi, void *state_)
+pdf_filter_sc_pattern(fz_context *ctx, pdf_processor *proc, const char *name, pdf_pattern *pat, int n, float *color)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, FLUSH_CTM);
- call_op(csi, state, PDF_OP_re);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_gstate *gstate = gstate_to_update(ctx, p);
+ int i;
+ fz_strlcpy(gstate->sc.name, name, sizeof gstate->sc.name);
+ gstate->sc.pat = pat;
+ gstate->sc.shd = NULL;
+ gstate->sc.n = n;
+ for (i = 0; i < n; ++i)
+ gstate->sc.c[i] = color[i];
+ copy_resource(ctx, p, "Pattern", name);
}
static void
-pdf_filter_rg(pdf_csi *csi, void *state_)
+pdf_filter_SC_shade(fz_context *ctx, pdf_processor *proc, const char *name, fz_shade *shade)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
- filter_gstate *gstate = gstate_to_update(csi, state);
-
- strcpy(gstate->cs, "DeviceRGB");
- strcpy(gstate->cs_name, "");
- gstate->color[0] = csi->stack[0];
- gstate->color[1] = csi->stack[1];
- gstate->color[2] = csi->stack[2];
- gstate->color_n = 3;
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_gstate *gstate = gstate_to_update(ctx, p);
+ fz_strlcpy(gstate->SC.name, name, sizeof gstate->SC.name);
+ gstate->SC.pat = NULL;
+ gstate->SC.shd = shade;
+ gstate->SC.n = 0;
+ copy_resource(ctx, p, "Pattern", name);
}
static void
-pdf_filter_ri(pdf_csi *csi, void *state_)
+pdf_filter_sc_shade(fz_context *ctx, pdf_processor *proc, const char *name, fz_shade *shade)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, 0);
- call_op(csi, state, PDF_OP_ri);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_gstate *gstate = gstate_to_update(ctx, p);
+ fz_strlcpy(gstate->sc.name, name, sizeof gstate->sc.name);
+ gstate->sc.pat = NULL;
+ gstate->sc.shd = shade;
+ gstate->sc.n = 0;
+ copy_resource(ctx, p, "Pattern", name);
}
static void
-pdf_filter_s(pdf_csi *csi, void *state_)
+pdf_filter_SC_color(fz_context *ctx, pdf_processor *proc, int n, float *color)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, FLUSH_STROKE);
- call_op(csi, state, PDF_OP_s);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_gstate *gstate = gstate_to_update(ctx, p);
+ int i;
+ gstate->SC.name[0] = 0;
+ gstate->SC.pat = NULL;
+ gstate->SC.shd = NULL;
+ gstate->SC.n = n;
+ for (i = 0; i < n; ++i)
+ gstate->SC.c[i] = color[i];
}
static void
-pdf_filter_scn(pdf_csi *csi, void *state_)
+pdf_filter_sc_color(fz_context *ctx, pdf_processor *proc, int n, float *color)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
- filter_gstate *gstate = gstate_to_update(csi, state);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_gstate *gstate = gstate_to_update(ctx, p);
int i;
-
- if (csi->name[0])
- insert_resource(csi, state, "Pattern");
-
- fz_strlcpy(gstate->cs_name, csi->name, sizeof(csi->name));
- for (i = 0; i < csi->top; i++)
- {
- gstate->color[i] = csi->stack[i];
- }
- gstate->color_n = csi->top;
+ gstate->sc.name[0] = 0;
+ gstate->sc.pat = NULL;
+ gstate->sc.shd = NULL;
+ gstate->sc.n = n;
+ for (i = 0; i < n; ++i)
+ gstate->sc.c[i] = color[i];
}
static void
-pdf_filter_v(pdf_csi *csi, void *state_)
+pdf_filter_G(fz_context *ctx, pdf_processor *proc, float g)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, FLUSH_CTM);
- call_op(csi, state, PDF_OP_v);
+ float color[1] = { g };
+ pdf_filter_CS(ctx, proc, "DeviceGray", fz_device_gray(ctx));
+ pdf_filter_SC_color(ctx, proc, 1, color);
}
static void
-pdf_filter_w(pdf_csi *csi, void *state_)
+pdf_filter_g(fz_context *ctx, pdf_processor *proc, float g)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, 0);
- call_op(csi, state, PDF_OP_w);
+ float color[1] = { g };
+ pdf_filter_cs(ctx, proc, "DeviceGray", fz_device_gray(ctx));
+ pdf_filter_sc_color(ctx, proc, 1, color);
}
static void
-pdf_filter_y(pdf_csi *csi, void *state_)
+pdf_filter_RG(fz_context *ctx, pdf_processor *proc, float r, float g, float b)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- filter_flush(csi, state, FLUSH_CTM);
- call_op(csi, state, PDF_OP_y);
+ float color[3] = { r, g, b };
+ pdf_filter_CS(ctx, proc, "DeviceRGB", fz_device_rgb(ctx));
+ pdf_filter_SC_color(ctx, proc, 3, color);
}
static void
-pdf_filter_Do(pdf_csi *csi, void *state_)
+pdf_filter_rg(fz_context *ctx, pdf_processor *proc, float r, float g, float b)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- insert_resource(csi, state, "XObject");
-
- filter_flush(csi, state, FLUSH_ALL);
- call_op(csi, state, PDF_OP_Do);
+ float color[3] = { r, g, b };
+ pdf_filter_cs(ctx, proc, "DeviceRGB", fz_device_rgb(ctx));
+ pdf_filter_sc_color(ctx, proc, 3, color);
}
static void
-pdf_filter_Tf(pdf_csi *csi, void *state_)
+pdf_filter_K(fz_context *ctx, pdf_processor *proc, float c, float m, float y, float k)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- insert_resource(csi, state, "Font");
-
- filter_flush(csi, state, 0);
- call_op(csi, state, PDF_OP_Tf);
+ float color[4] = { c, m, y, k };
+ pdf_filter_CS(ctx, proc, "DeviceCMYK", fz_device_cmyk(ctx));
+ pdf_filter_SC_color(ctx, proc, 4, color);
}
static void
-pdf_filter_gs(pdf_csi *csi, void *state_)
+pdf_filter_k(fz_context *ctx, pdf_processor *proc, float c, float m, float y, float k)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
+ float color[4] = { c, m, y, k };
+ pdf_filter_cs(ctx, proc, "DeviceCMYK", fz_device_cmyk(ctx));
+ pdf_filter_sc_color(ctx, proc, 4, color);
+}
- insert_resource(csi, state, "ExtGState");
+/* shadings, images, xobjects */
- filter_flush(csi, state, FLUSH_ALL);
- call_op(csi, state, PDF_OP_gs);
+static void
+pdf_filter_BI(fz_context *ctx, pdf_processor *proc, fz_image *img)
+{
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, FLUSH_ALL);
+ if (p->chain->op_BI)
+ p->chain->op_BI(ctx, p->chain, img);
}
static void
-pdf_filter_sh(pdf_csi *csi, void *state_)
+pdf_filter_sh(fz_context *ctx, pdf_processor *proc, const char *name, fz_shade *shade)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
-
- insert_resource(csi, state, "Shading");
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, FLUSH_ALL);
+ if (p->chain->op_sh)
+ p->chain->op_sh(ctx, p->chain, name, shade);
+ copy_resource(ctx, p, "Shading", name);
+}
- filter_flush(csi, state, FLUSH_ALL);
- call_op(csi, state, PDF_OP_sh);
+static void
+pdf_filter_Do_image(fz_context *ctx, pdf_processor *proc, const char *name, fz_image *image)
+{
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, FLUSH_ALL);
+ if (p->chain->op_Do_image)
+ p->chain->op_Do_image(ctx, p->chain, name, image);
+ copy_resource(ctx, p, "XObject", name);
}
static void
-free_processor_filter(pdf_csi *csi, void *state_)
+pdf_filter_Do_form(fz_context *ctx, pdf_processor *proc, const char *name, pdf_xobject *xobj, pdf_obj *page_resources)
{
- pdf_filter_state *state = (pdf_filter_state *)state_;
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, FLUSH_ALL);
+ if (p->chain->op_Do_form)
+ p->chain->op_Do_form(ctx, p->chain, name, xobj, page_resources);
+ copy_resource(ctx, p, "XObject", name);
+}
- /* csi can permissibly be NULL, but only in the case when we have
- * failed while setting up csi. So there is nothing to pop. */
- if (csi)
- {
- while (!filter_pop(csi, state))
- {
- /* Nothing to do in the loop, all work done above */
- }
- }
+/* marked content */
- call_op(csi, state, PDF_OP_END);
- fz_free(state->ctx, state->gstate);
- fz_free(state->ctx, state);
+static void
+pdf_filter_MP(fz_context *ctx, pdf_processor *proc, const char *tag)
+{
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, 0);
+ if (p->chain->op_MP)
+ p->chain->op_MP(ctx, p->chain, tag);
}
static void
-process_annot(pdf_csi *csi, void *state, pdf_obj *resources, pdf_annot *annot)
+pdf_filter_DP(fz_context *ctx, pdf_processor *proc, const char *tag, pdf_obj *properties)
{
- fz_context *ctx = csi->ctx;
- pdf_xobject *xobj = annot->ap;
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, 0);
+ if (p->chain->op_DP)
+ p->chain->op_DP(ctx, p->chain, tag, properties);
+}
- /* Avoid infinite recursion */
- if (xobj == NULL || pdf_mark_obj(ctx, xobj->me))
- return;
+static void
+pdf_filter_BMC(fz_context *ctx, pdf_processor *proc, const char *tag)
+{
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, 0);
+ if (p->chain->op_BMC)
+ p->chain->op_BMC(ctx, p->chain, tag);
+}
- fz_try(ctx)
- {
- if (xobj->resources)
- resources = xobj->resources;
+static void
+pdf_filter_BDC(fz_context *ctx, pdf_processor *proc, const char *tag, pdf_obj *properties)
+{
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, 0);
+ if (p->chain->op_BDC)
+ p->chain->op_BDC(ctx, p->chain, tag, properties);
+}
- pdf_process_contents_object(csi, resources, xobj->contents);
- }
- fz_always(ctx)
- {
- pdf_unmark_obj(ctx, xobj->me);
- }
- fz_catch(ctx)
- {
- fz_rethrow(ctx);
- }
+static void
+pdf_filter_EMC(fz_context *ctx, pdf_processor *proc)
+{
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, 0);
+ if (p->chain->op_EMC)
+ p->chain->op_EMC(ctx, p->chain);
}
+/* compatibility */
+
static void
-process_stream(pdf_csi *csi, void *state, pdf_lexbuf *buf)
+pdf_filter_BX(fz_context *ctx, pdf_processor *proc)
{
- pdf_process_stream(csi, buf);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, 0);
+ if (p->chain->op_BX)
+ p->chain->op_BX(ctx, p->chain);
}
static void
-process_contents(pdf_csi *csi, void *state, pdf_obj *resources, pdf_obj *contents)
+pdf_filter_EX(fz_context *ctx, pdf_processor *proc)
{
- pdf_process_contents_object(csi, resources, contents);
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ filter_flush(ctx, p, 0);
+ if (p->chain->op_EX)
+ p->chain->op_EX(ctx, p->chain);
}
-static const pdf_processor pdf_processor_filter =
+static void
+pdf_filter_END(fz_context *ctx, pdf_processor *proc)
{
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ while (!filter_pop(ctx, p))
{
- pdf_filter_dquote,
- pdf_filter_squote,
- pdf_filter_B,
- pdf_filter_Bstar,
- pdf_filter_BDC,
- pdf_filter_BI,
- pdf_filter_BMC,
- pdf_filter_BT,
- pdf_filter_BX,
- pdf_filter_CS,
- pdf_filter_DP,
- pdf_filter_EMC,
- pdf_filter_ET,
- pdf_filter_EX,
- pdf_filter_F,
- pdf_filter_G,
- pdf_filter_J,
- pdf_filter_K,
- pdf_filter_M,
- pdf_filter_MP,
- pdf_filter_Q,
- pdf_filter_RG,
- pdf_filter_S,
- pdf_filter_SCN,
- pdf_filter_SCN,
- pdf_filter_Tstar,
- pdf_filter_TD,
- pdf_filter_TJ,
- pdf_filter_TL,
- pdf_filter_Tc,
- pdf_filter_Td,
- pdf_filter_Tj,
- pdf_filter_Tm,
- pdf_filter_Tr,
- pdf_filter_Ts,
- pdf_filter_Tw,
- pdf_filter_Tz,
- pdf_filter_W,
- pdf_filter_Wstar,
- pdf_filter_b,
- pdf_filter_bstar,
- pdf_filter_c,
- pdf_filter_cm,
- pdf_filter_cs,
- pdf_filter_d,
- pdf_filter_d0,
- pdf_filter_d1,
- pdf_filter_f,
- pdf_filter_fstar,
- pdf_filter_g,
- pdf_filter_h,
- pdf_filter_i,
- pdf_filter_j,
- pdf_filter_k,
- pdf_filter_l,
- pdf_filter_m,
- pdf_filter_n,
- pdf_filter_q,
- pdf_filter_re,
- pdf_filter_rg,
- pdf_filter_ri,
- pdf_filter_s,
- pdf_filter_scn,
- pdf_filter_scn,
- pdf_filter_v,
- pdf_filter_w,
- pdf_filter_y,
- pdf_filter_Do,
- pdf_filter_Tf,
- pdf_filter_gs,
- pdf_filter_sh,
- free_processor_filter
- },
- process_annot,
- process_stream,
- process_contents
-};
+ /* Nothing to do in the loop, all work done above */
+ }
+}
-pdf_process *
-pdf_init_process_filter(fz_context *ctx, pdf_process *process, pdf_process *underlying, pdf_obj *resources)
+static void
+pdf_drop_imp_filter_processor(fz_context *ctx, pdf_processor *proc)
{
- pdf_filter_state *p = NULL;
+ pdf_filter_processor *p = (pdf_filter_processor*)proc;
+ fz_free(ctx, p->gstate);
+}
- fz_var(p);
+pdf_processor *
+pdf_new_filter_processor(fz_context *ctx, pdf_processor *chain, pdf_document *doc, pdf_obj *old_rdb, pdf_obj *new_rdb)
+{
- fz_try(ctx)
- {
- p = fz_malloc_struct(ctx, pdf_filter_state);
- p->ctx = ctx;
- p->process = *underlying;
- p->gstate = fz_malloc_struct(ctx, filter_gstate);
- p->resources = resources;
- p->gstate->ctm = fz_identity;
- p->gstate->current_ctm = fz_identity;
- }
- fz_catch(ctx)
+ pdf_filter_processor *proc = pdf_new_processor(ctx, sizeof *proc);
{
- fz_free(ctx, p);
- pdf_process_op(NULL, PDF_OP_END, underlying);
- fz_rethrow(ctx);
+ proc->super.drop_imp = pdf_drop_imp_filter_processor;
+
+ /* general graphics state */
+ proc->super.op_w = pdf_filter_w;
+ proc->super.op_j = pdf_filter_j;
+ proc->super.op_J = pdf_filter_J;
+ proc->super.op_M = pdf_filter_M;
+ proc->super.op_d = pdf_filter_d;
+ proc->super.op_ri = pdf_filter_ri;
+ proc->super.op_i = pdf_filter_i;
+ proc->super.op_gs_begin = pdf_filter_gs_begin;
+ proc->super.op_gs_end = pdf_filter_gs_end;
+
+ /* transparency graphics state */
+ proc->super.op_gs_BM = pdf_filter_gs_BM;
+ proc->super.op_gs_CA = pdf_filter_gs_CA;
+ proc->super.op_gs_ca = pdf_filter_gs_ca;
+ proc->super.op_gs_SMask = pdf_filter_gs_SMask;
+
+ /* special graphics state */
+ proc->super.op_q = pdf_filter_q;
+ proc->super.op_Q = pdf_filter_Q;
+ proc->super.op_cm = pdf_filter_cm;
+
+ /* path construction */
+ proc->super.op_m = pdf_filter_m;
+ proc->super.op_l = pdf_filter_l;
+ proc->super.op_c = pdf_filter_c;
+ proc->super.op_v = pdf_filter_v;
+ proc->super.op_y = pdf_filter_y;
+ proc->super.op_h = pdf_filter_h;
+ proc->super.op_re = pdf_filter_re;
+
+ /* path painting */
+ proc->super.op_S = pdf_filter_S;
+ proc->super.op_s = pdf_filter_s;
+ proc->super.op_F = pdf_filter_F;
+ proc->super.op_f = pdf_filter_f;
+ proc->super.op_fstar = pdf_filter_fstar;
+ proc->super.op_B = pdf_filter_B;
+ proc->super.op_Bstar = pdf_filter_Bstar;
+ proc->super.op_b = pdf_filter_b;
+ proc->super.op_bstar = pdf_filter_bstar;
+ proc->super.op_n = pdf_filter_n;
+
+ /* clipping paths */
+ proc->super.op_W = pdf_filter_W;
+ proc->super.op_Wstar = pdf_filter_Wstar;
+
+ /* text objects */
+ proc->super.op_BT = pdf_filter_BT;
+ proc->super.op_ET = pdf_filter_ET;
+
+ /* text state */
+ proc->super.op_Tc = pdf_filter_Tc;
+ proc->super.op_Tw = pdf_filter_Tw;
+ proc->super.op_Tz = pdf_filter_Tz;
+ proc->super.op_TL = pdf_filter_TL;
+ proc->super.op_Tf = pdf_filter_Tf;
+ proc->super.op_Tr = pdf_filter_Tr;
+ proc->super.op_Ts = pdf_filter_Ts;
+
+ /* text positioning */
+ proc->super.op_Td = pdf_filter_Td;
+ proc->super.op_TD = pdf_filter_TD;
+ proc->super.op_Tm = pdf_filter_Tm;
+ proc->super.op_Tstar = pdf_filter_Tstar;
+
+ /* text showing */
+ proc->super.op_TJ = pdf_filter_TJ;
+ proc->super.op_Tj = pdf_filter_Tj;
+ proc->super.op_squote = pdf_filter_squote;
+ proc->super.op_dquote = pdf_filter_dquote;
+
+ /* type 3 fonts */
+ proc->super.op_d0 = pdf_filter_d0;
+ proc->super.op_d1 = pdf_filter_d1;
+
+ /* color */
+ proc->super.op_CS = pdf_filter_CS;
+ proc->super.op_cs = pdf_filter_cs;
+ proc->super.op_SC_color = pdf_filter_SC_color;
+ proc->super.op_sc_color = pdf_filter_sc_color;
+ proc->super.op_SC_pattern = pdf_filter_SC_pattern;
+ proc->super.op_sc_pattern = pdf_filter_sc_pattern;
+ proc->super.op_SC_shade = pdf_filter_SC_shade;
+ proc->super.op_sc_shade = pdf_filter_sc_shade;
+
+ proc->super.op_G = pdf_filter_G;
+ proc->super.op_g = pdf_filter_g;
+ proc->super.op_RG = pdf_filter_RG;
+ proc->super.op_rg = pdf_filter_rg;
+ proc->super.op_K = pdf_filter_K;
+ proc->super.op_k = pdf_filter_k;
+
+ /* shadings, images, xobjects */
+ proc->super.op_BI = pdf_filter_BI;
+ proc->super.op_sh = pdf_filter_sh;
+ proc->super.op_Do_image = pdf_filter_Do_image;
+ proc->super.op_Do_form = pdf_filter_Do_form;
+
+ /* marked content */
+ proc->super.op_MP = pdf_filter_MP;
+ proc->super.op_DP = pdf_filter_DP;
+ proc->super.op_BMC = pdf_filter_BMC;
+ proc->super.op_BDC = pdf_filter_BDC;
+ proc->super.op_EMC = pdf_filter_EMC;
+
+ /* compatibility */
+ proc->super.op_BX = pdf_filter_BX;
+ proc->super.op_EX = pdf_filter_EX;
+
+ proc->super.op_END = pdf_filter_END;
}
- process->state = p;
- process->processor = &pdf_processor_filter;
- return process;
+ proc->chain = chain;
+ proc->doc = doc;
+ proc->old_rdb = old_rdb;
+ proc->new_rdb = new_rdb;
+
+ proc->gstate = fz_malloc_struct(ctx, filter_gstate);
+ proc->gstate->ctm = fz_identity;
+ proc->gstate->current_ctm = fz_identity;
+
+ proc->gstate->stroke = proc->gstate->stroke;
+ proc->gstate->current_stroke = proc->gstate->stroke;
+
+ return (pdf_processor*)proc;
}
diff --git a/source/pdf/pdf-op-run.c b/source/pdf/pdf-op-run.c
index 204d3c23..2bdd3b55 100644
--- a/source/pdf/pdf-op-run.c
+++ b/source/pdf/pdf-op-run.c
@@ -1,4 +1,4 @@
-#include "pdf-interpret-imp.h"
+#include "mupdf/pdf.h"
#define TILE
@@ -7,6 +7,9 @@
*/
typedef struct pdf_material_s pdf_material;
+typedef struct pdf_run_processor_s pdf_run_processor;
+
+static void pdf_run_xobject(fz_context *ctx, pdf_run_processor *proc, pdf_xobject *xobj, pdf_obj *page_resources, const fz_matrix *transform);
enum
{
@@ -58,25 +61,23 @@ struct pdf_gstate_s
/* transparency */
int blendmode;
pdf_xobject *softmask;
+ pdf_obj *softmask_resources;
fz_matrix softmask_ctm;
float softmask_bc[FZ_MAX_COLORS];
int luminosity;
};
-typedef struct pdf_run_state_s
+struct pdf_run_processor_s
{
- fz_context *ctx;
+ pdf_processor super;
fz_device *dev;
- pdf_csi *csi;
int nested_depth;
- int in_hidden_ocg;
/* path object state */
fz_path *path;
int clip;
int clip_even_odd;
- const char *event;
/* text object state */
fz_text *text;
@@ -92,250 +93,33 @@ typedef struct pdf_run_state_s
int gtop;
int gbot;
int gparent;
-}
-pdf_run_state;
+};
typedef struct softmask_save_s softmask_save;
struct softmask_save_s
{
pdf_xobject *softmask;
+ pdf_obj *page_resources;
fz_matrix ctm;
};
-static void
-run_xobject(pdf_csi *csi, void *state, pdf_obj *resources, pdf_xobject *xobj, const fz_matrix *transform);
-
-static int
-ocg_intents_include(fz_context *ctx, pdf_ocg_descriptor *desc, char *name)
-{
- int i, len;
-
- if (strcmp(name, "All") == 0)
- return 1;
-
- /* In the absence of a specified intent, it's 'View' */
- if (!desc->intent)
- return (strcmp(name, "View") == 0);
-
- if (pdf_is_name(ctx, desc->intent))
- {
- char *intent = pdf_to_name(ctx, desc->intent);
- if (strcmp(intent, "All") == 0)
- return 1;
- return (strcmp(intent, name) == 0);
- }
- if (!pdf_is_array(ctx, desc->intent))
- return 0;
-
- len = pdf_array_len(ctx, desc->intent);
- for (i=0; i < len; i++)
- {
- char *intent = pdf_to_name(ctx, pdf_array_get(ctx, desc->intent, i));
- if (strcmp(intent, "All") == 0)
- return 1;
- if (strcmp(intent, name) == 0)
- return 1;
- }
- return 0;
-}
-
-int
-pdf_is_hidden_ocg(pdf_obj *ocg, pdf_csi *csi, pdf_run_state *pr, pdf_obj *rdb)
-{
- char event_state[16];
- pdf_obj *obj, *obj2;
- char *type;
- pdf_ocg_descriptor *desc = csi->doc->ocg;
- fz_context *ctx = csi->ctx;
-
- /* Avoid infinite recursions */
- if (pdf_obj_marked(ctx, ocg))
- return 0;
-
- /* If no ocg descriptor, everything is visible */
- if (!desc)
- return 0;
-
- /* If we've been handed a name, look it up in the properties. */
- if (pdf_is_name(ctx, ocg))
- {
- ocg = pdf_dict_gets(ctx, pdf_dict_gets(ctx, rdb, "Properties"), pdf_to_name(ctx, ocg));
- }
- /* If we haven't been given an ocg at all, then we're visible */
- if (!ocg)
- return 0;
-
- fz_strlcpy(event_state, pr->event, sizeof event_state);
- fz_strlcat(event_state, "State", sizeof event_state);
-
- type = pdf_to_name(ctx, pdf_dict_gets(ctx, ocg, "Type"));
-
- if (strcmp(type, "OCG") == 0)
- {
- /* An Optional Content Group */
- int default_value = 0;
- int num = pdf_to_num(ctx, ocg);
- int gen = pdf_to_gen(ctx, ocg);
- int len = desc->len;
- int i;
-
- /* by default an OCG is visible, unless it's explicitly hidden */
- for (i = 0; i < len; i++)
- {
- if (desc->ocgs[i].num == num && desc->ocgs[i].gen == gen)
- {
- default_value = desc->ocgs[i].state == 0;
- break;
- }
- }
-
- /* Check Intents; if our intent is not part of the set given
- * by the current config, we should ignore it. */
- obj = pdf_dict_gets(ctx, ocg, "Intent");
- if (pdf_is_name(ctx, obj))
- {
- /* If it doesn't match, it's hidden */
- if (ocg_intents_include(ctx, desc, pdf_to_name(ctx, obj)) == 0)
- return 1;
- }
- else if (pdf_is_array(ctx, obj))
- {
- int match = 0;
- len = pdf_array_len(ctx, obj);
- for (i=0; i<len; i++) {
- match |= ocg_intents_include(ctx, desc, pdf_to_name(ctx, pdf_array_get(ctx, obj, i)));
- if (match)
- break;
- }
- /* If we don't match any, it's hidden */
- if (match == 0)
- return 1;
- }
- else
- {
- /* If it doesn't match, it's hidden */
- if (ocg_intents_include(ctx, desc, "View") == 0)
- return 1;
- }
-
- /* FIXME: Currently we do a very simple check whereby we look
- * at the Usage object (an Optional Content Usage Dictionary)
- * and check to see if the corresponding 'event' key is on
- * or off.
- *
- * Really we should only look at Usage dictionaries that
- * correspond to entries in the AS list in the OCG config.
- * Given that we don't handle Zoom or User, or Language
- * dicts, this is not really a problem. */
- obj = pdf_dict_gets(ctx, ocg, "Usage");
- if (!pdf_is_dict(ctx, obj))
- return default_value;
- /* FIXME: Should look at Zoom (and return hidden if out of
- * max/min range) */
- /* FIXME: Could provide hooks to the caller to check if
- * User is appropriate - if not return hidden. */
- obj2 = pdf_dict_gets(ctx, obj, pr->event);
- if (strcmp(pdf_to_name(ctx, pdf_dict_gets(ctx, obj2, event_state)), "OFF") == 0)
- {
- return 1;
- }
- if (strcmp(pdf_to_name(ctx, pdf_dict_gets(ctx, obj2, event_state)), "ON") == 0)
- {
- return 0;
- }
- return default_value;
- }
- else if (strcmp(type, "OCMD") == 0)
- {
- /* An Optional Content Membership Dictionary */
- char *name;
- int combine, on;
-
- obj = pdf_dict_gets(ctx, ocg, "VE");
- if (pdf_is_array(ctx, obj)) {
- /* FIXME: Calculate visibility from array */
- return 0;
- }
- name = pdf_to_name(ctx, pdf_dict_gets(ctx, ocg, "P"));
- /* Set combine; Bit 0 set => AND, Bit 1 set => true means
- * Off, otherwise true means On */
- if (strcmp(name, "AllOn") == 0)
- {
- combine = 1;
- }
- else if (strcmp(name, "AnyOff") == 0)
- {
- combine = 2;
- }
- else if (strcmp(name, "AllOff") == 0)
- {
- combine = 3;
- }
- else /* Assume it's the default (AnyOn) */
- {
- combine = 0;
- }
-
- if (pdf_mark_obj(ctx, ocg))
- return 0; /* Should never happen */
- fz_try(ctx)
- {
- obj = pdf_dict_gets(ctx, ocg, "OCGs");
- on = combine & 1;
- if (pdf_is_array(ctx, obj)) {
- int i, len;
- len = pdf_array_len(ctx, obj);
- for (i = 0; i < len; i++)
- {
- int hidden;
- hidden = pdf_is_hidden_ocg(pdf_array_get(ctx, obj, i), csi, pr, rdb);
- if ((combine & 1) == 0)
- hidden = !hidden;
- if (combine & 2)
- on &= hidden;
- else
- on |= hidden;
- }
- }
- else
- {
- on = pdf_is_hidden_ocg(obj, csi, pr, rdb);
- if ((combine & 1) == 0)
- on = !on;
- }
- }
- fz_always(ctx)
- {
- pdf_unmark_obj(ctx, ocg);
- }
- fz_catch(ctx)
- {
- fz_rethrow(ctx);
- }
- return !on;
- }
- /* No idea what sort of object this is - be visible */
- return 0;
-}
-
static pdf_gstate *
-begin_softmask(pdf_csi *csi, pdf_run_state *pr, softmask_save *save)
+begin_softmask(fz_context *ctx, pdf_run_processor *pr, softmask_save *save)
{
pdf_gstate *gstate = pr->gstate + pr->gtop;
pdf_xobject *softmask = gstate->softmask;
fz_rect mask_bbox;
- fz_context *ctx;
fz_matrix save_tm, save_tlm, save_ctm;
save->softmask = softmask;
if (softmask == NULL)
return gstate;
+ save->page_resources = gstate->softmask_resources;
save->ctm = gstate->softmask_ctm;
save_ctm = gstate->ctm;
mask_bbox = softmask->bbox;
- ctx = pr->ctx;
save_tm = pr->tm;
save_tlm = pr->tlm;
@@ -347,21 +131,21 @@ begin_softmask(pdf_csi *csi, pdf_run_state *pr, softmask_save *save)
fz_transform_rect(&mask_bbox, &gstate->softmask_ctm);
}
gstate->softmask = NULL;
+ gstate->softmask_resources = NULL;
gstate->ctm = gstate->softmask_ctm;
fz_begin_mask(ctx, pr->dev, &mask_bbox, gstate->luminosity,
softmask->colorspace, gstate->softmask_bc);
fz_try(ctx)
{
- run_xobject(csi, pr, csi->rdb, softmask, &fz_identity);
+ pdf_run_xobject(ctx, pr, softmask, save->page_resources, &fz_identity);
}
fz_catch(ctx)
{
fz_rethrow_if(ctx, FZ_ERROR_TRYLATER);
/* FIXME: Ignore error - nasty, but if we throw from
* here the clip stack would be messed up. */
- if (csi->cookie)
- csi->cookie->errors++;
+ /* TODO: pass cookie here to increase the cookie error count */
}
fz_end_mask(ctx, pr->dev);
@@ -376,61 +160,60 @@ begin_softmask(pdf_csi *csi, pdf_run_state *pr, softmask_save *save)
}
static void
-end_softmask(pdf_csi *csi, pdf_run_state *pr, softmask_save *save)
+end_softmask(fz_context *ctx, pdf_run_processor *pr, softmask_save *save)
{
- fz_context *ctx = pr->ctx;
pdf_gstate *gstate = pr->gstate + pr->gtop;
if (save->softmask == NULL)
return;
gstate->softmask = save->softmask;
+ gstate->softmask_resources = save->page_resources;
gstate->softmask_ctm = save->ctm;
fz_pop_clip(ctx, pr->dev);
}
static pdf_gstate *
-pdf_begin_group(pdf_csi *csi, pdf_run_state *pr, const fz_rect *bbox, softmask_save *softmask)
+pdf_begin_group(fz_context *ctx, pdf_run_processor *pr, const fz_rect *bbox, softmask_save *softmask)
{
- pdf_gstate *gstate = begin_softmask(csi, pr, softmask);
+ pdf_gstate *gstate = begin_softmask(ctx, pr, softmask);
if (gstate->blendmode)
- fz_begin_group(pr->ctx, pr->dev, bbox, 1, 0, gstate->blendmode, 1);
+ fz_begin_group(ctx, pr->dev, bbox, 1, 0, gstate->blendmode, 1);
return pr->gstate + pr->gtop;
}
static void
-pdf_end_group(pdf_csi *csi, pdf_run_state *pr, softmask_save *softmask)
+pdf_end_group(fz_context *ctx, pdf_run_processor *pr, softmask_save *softmask)
{
pdf_gstate *gstate = pr->gstate + pr->gtop;
if (gstate->blendmode)
- fz_end_group(pr->ctx, pr->dev);
+ fz_end_group(ctx, pr->dev);
- end_softmask(csi, pr, softmask);
+ end_softmask(ctx, pr, softmask);
}
static void
-pdf_show_shade(pdf_csi *csi, pdf_run_state *pr, fz_shade *shd)
+pdf_show_shade(fz_context *ctx, pdf_run_processor *pr, fz_shade *shd)
{
- fz_context *ctx = pr->ctx;
pdf_gstate *gstate = pr->gstate + pr->gtop;
fz_rect bbox;
softmask_save softmask = { NULL };
- if (pr->in_hidden_ocg > 0)
+ if (pr->super.hidden)
return;
fz_bound_shade(ctx, shd, &gstate->ctm, &bbox);
- gstate = pdf_begin_group(csi, pr, &bbox, &softmask);
+ gstate = pdf_begin_group(ctx, pr, &bbox, &softmask);
/* FIXME: The gstate->ctm in the next line may be wrong; maybe
* it should be the parent gstates ctm? */
fz_fill_shade(ctx, pr->dev, shd, &gstate->ctm, gstate->fill.alpha);
- pdf_end_group(csi, pr, &softmask);
+ pdf_end_group(ctx, pr, &softmask);
}
static pdf_material *
@@ -473,9 +256,8 @@ pdf_copy_pattern_gstate(fz_context *ctx, pdf_gstate *gs, const pdf_gstate *old)
}
static void
-pdf_unset_pattern(pdf_run_state *pr, int what)
+pdf_unset_pattern(fz_context *ctx, pdf_run_processor *pr, int what)
{
- fz_context *ctx = pr->ctx;
pdf_gstate *gs = pr->gstate + pr->gtop;
pdf_material *mat;
mat = what == PDF_FILL ? &gs->fill : &gs->stroke;
@@ -497,6 +279,8 @@ pdf_keep_gstate(fz_context *ctx, pdf_gstate *gs)
pdf_keep_font(ctx, gs->font);
if (gs->softmask)
pdf_keep_xobject(ctx, gs->softmask);
+ if (gs->softmask_resources)
+ pdf_keep_obj(ctx, gs->softmask_resources);
fz_keep_stroke_state(ctx, gs->stroke_state);
}
@@ -509,14 +293,14 @@ pdf_drop_gstate(fz_context *ctx, pdf_gstate *gs)
pdf_drop_font(ctx, gs->font);
if (gs->softmask)
pdf_drop_xobject(ctx, gs->softmask);
+ if (gs->softmask_resources)
+ pdf_drop_obj(ctx, gs->softmask_resources);
fz_drop_stroke_state(ctx, gs->stroke_state);
}
static void
-pdf_gsave(pdf_run_state *pr)
+pdf_gsave(fz_context *ctx, pdf_run_processor *pr)
{
- fz_context *ctx = pr->ctx;
-
if (pr->gtop == pr->gcap-1)
{
pr->gstate = fz_resize_array(ctx, pr->gstate, pr->gcap*2, sizeof(pdf_gstate));
@@ -530,9 +314,8 @@ pdf_gsave(pdf_run_state *pr)
}
static void
-pdf_grestore(pdf_run_state *pr)
+pdf_grestore(fz_context *ctx, pdf_run_processor *pr)
{
- fz_context *ctx = pr->ctx;
pdf_gstate *gs = pr->gstate + pr->gtop;
int clip_depth = gs->clip_depth;
@@ -562,26 +345,25 @@ pdf_grestore(pdf_run_state *pr)
}
static void
-pdf_show_pattern(pdf_csi *csi, pdf_run_state *pr, pdf_pattern *pat, pdf_gstate *pat_gstate, const fz_rect *area, int what)
+pdf_show_pattern(fz_context *ctx, pdf_run_processor *pr, pdf_pattern *pat, pdf_gstate *pat_gstate, const fz_rect *area, int what)
{
- fz_context *ctx = pr->ctx;
pdf_gstate *gstate;
int gparent_save;
fz_matrix ptm, invptm, gparent_save_ctm;
int x0, y0, x1, y1;
float fx0, fy0, fx1, fy1;
- int oldtop;
fz_rect local_area;
- pdf_gsave(pr);
+ pdf_gsave(ctx, pr);
gstate = pr->gstate + pr->gtop;
+
/* Patterns are run with the gstate of the parent */
pdf_copy_pattern_gstate(ctx, gstate, pat_gstate);
if (pat->ismask)
{
- pdf_unset_pattern(pr, PDF_FILL);
- pdf_unset_pattern(pr, PDF_STROKE);
+ pdf_unset_pattern(ctx, pr, PDF_FILL);
+ pdf_unset_pattern(ctx, pr, PDF_STROKE);
if (what == PDF_FILL)
{
pdf_drop_material(ctx, &gstate->stroke);
@@ -598,7 +380,7 @@ pdf_show_pattern(pdf_csi *csi, pdf_run_state *pr, pdf_pattern *pat, pdf_gstate *
else
{
// TODO: unset only the current fill/stroke or both?
- pdf_unset_pattern(pr, what);
+ pdf_unset_pattern(ctx, pr, what);
}
/* don't apply soft masks to objects in the pattern as well */
@@ -638,8 +420,6 @@ pdf_show_pattern(pdf_csi *csi, pdf_run_state *pr, pdf_pattern *pat, pdf_gstate *
float t = fy0; fy0 = fy1; fy1 = t;
}
- oldtop = pr->gtop;
-
#ifdef TILE
/* We have tried various formulations in the past, but this one is
* best we've found; only use it as a tile if a whole repeat is
@@ -652,12 +432,20 @@ pdf_show_pattern(pdf_csi *csi, pdf_run_state *pr, pdf_pattern *pat, pdf_gstate *
{
fz_begin_tile(ctx, pr->dev, &local_area, &pat->bbox, pat->xstep, pat->ystep, &ptm);
gstate->ctm = ptm;
- pdf_gsave(pr);
- pdf_process_contents_object(csi, pat->resources, pat->contents);
- pdf_grestore(pr);
- while (oldtop < pr->gtop)
- pdf_grestore(pr);
- fz_end_tile(ctx, pr->dev);
+ pdf_gsave(ctx, pr);
+ fz_try(ctx)
+ {
+ pdf_process_contents(ctx, (pdf_processor*)pr, pat->document, pat->resources, pat->contents, NULL);
+ }
+ fz_always(ctx)
+ {
+ pdf_grestore(ctx, pr);
+ fz_end_tile(ctx, pr->dev);
+ }
+ fz_catch(ctx)
+ {
+ fz_rethrow(ctx);
+ }
}
else
{
@@ -686,21 +474,13 @@ pdf_show_pattern(pdf_csi *csi, pdf_run_state *pr, pdf_pattern *pat, pdf_gstate *
{
gstate->ctm = ptm;
fz_pre_translate(&gstate->ctm, x * pat->xstep, y * pat->ystep);
- pdf_gsave(pr);
+ pdf_gsave(ctx, pr);
fz_try(ctx)
- {
- pdf_process_contents_object(csi, pat->resources, pat->contents);
- }
+ pdf_process_contents(ctx, (pdf_processor*)pr, pat->document, pat->resources, pat->contents, NULL);
fz_always(ctx)
- {
- pdf_grestore(pr);
- while (oldtop < pr->gtop)
- pdf_grestore(pr);
- }
+ pdf_grestore(ctx, pr);
fz_catch(ctx)
- {
fz_rethrow_message(ctx, "cannot render pattern tile");
- }
}
}
}
@@ -715,19 +495,18 @@ pdf_show_pattern(pdf_csi *csi, pdf_run_state *pr, pdf_pattern *pat, pdf_gstate *
fz_rethrow(ctx);
}
- pdf_grestore(pr);
+ pdf_grestore(ctx, pr);
}
static void
-pdf_show_image(pdf_csi *csi, pdf_run_state *pr, fz_image *image)
+pdf_show_image(fz_context *ctx, pdf_run_processor *pr, fz_image *image)
{
- fz_context *ctx = pr->ctx;
pdf_gstate *gstate = pr->gstate + pr->gtop;
fz_matrix image_ctm;
fz_rect bbox;
softmask_save softmask = { NULL };
- if (pr->in_hidden_ocg > 0)
+ if (pr->super.hidden)
return;
/* PDF has images bottom-up, so flip them right side up here */
@@ -745,7 +524,7 @@ pdf_show_image(pdf_csi *csi, pdf_run_state *pr, fz_image *image)
fz_clip_image_mask(ctx, pr->dev, image->mask, &bbox, &image_ctm);
}
else
- gstate = pdf_begin_group(csi, pr, &bbox, &softmask);
+ gstate = pdf_begin_group(ctx, pr, &bbox, &softmask);
if (!image->colorspace)
{
@@ -762,7 +541,7 @@ pdf_show_image(pdf_csi *csi, pdf_run_state *pr, fz_image *image)
if (gstate->fill.pattern)
{
fz_clip_image_mask(ctx, pr->dev, image, &bbox, &image_ctm);
- pdf_show_pattern(csi, pr, gstate->fill.pattern, &pr->gstate[gstate->fill.gstate_num], &bbox, PDF_FILL);
+ pdf_show_pattern(ctx, pr, gstate->fill.pattern, &pr->gstate[gstate->fill.gstate_num], &bbox, PDF_FILL);
fz_pop_clip(ctx, pr->dev);
}
break;
@@ -788,13 +567,12 @@ pdf_show_image(pdf_csi *csi, pdf_run_state *pr, fz_image *image)
fz_end_group(ctx, pr->dev);
}
else
- pdf_end_group(csi, pr, &softmask);
+ pdf_end_group(ctx, pr, &softmask);
}
static void
-pdf_show_path(pdf_csi *csi, pdf_run_state *pr, int doclose, int dofill, int dostroke, int even_odd)
+pdf_show_path(fz_context *ctx, pdf_run_processor *pr, int doclose, int dofill, int dostroke, int even_odd)
{
- fz_context *ctx = pr->ctx;
pdf_gstate *gstate = pr->gstate + pr->gtop;
fz_path *path;
fz_rect bbox;
@@ -831,11 +609,11 @@ pdf_show_path(pdf_csi *csi, pdf_run_state *pr, int doclose, int dofill, int dost
pr->clip = 0;
}
- if (pr->in_hidden_ocg > 0)
+ if (pr->super.hidden)
dostroke = dofill = 0;
if (dofill || dostroke)
- gstate = pdf_begin_group(csi, pr, &bbox, &softmask);
+ gstate = pdf_begin_group(ctx, pr, &bbox, &softmask);
if (dofill && dostroke)
{
@@ -869,7 +647,7 @@ pdf_show_path(pdf_csi *csi, pdf_run_state *pr, int doclose, int dofill, int dost
if (gstate->fill.pattern)
{
fz_clip_path(ctx, pr->dev, path, &bbox, even_odd, &gstate->ctm);
- pdf_show_pattern(csi, pr, gstate->fill.pattern, &pr->gstate[gstate->fill.gstate_num], &bbox, PDF_FILL);
+ pdf_show_pattern(ctx, pr, gstate->fill.pattern, &pr->gstate[gstate->fill.gstate_num], &bbox, PDF_FILL);
fz_pop_clip(ctx, pr->dev);
}
break;
@@ -899,7 +677,7 @@ pdf_show_path(pdf_csi *csi, pdf_run_state *pr, int doclose, int dofill, int dost
if (gstate->stroke.pattern)
{
fz_clip_stroke_path(ctx, pr->dev, path, &bbox, gstate->stroke_state, &gstate->ctm);
- pdf_show_pattern(csi, pr, gstate->stroke.pattern, &pr->gstate[gstate->stroke.gstate_num], &bbox, PDF_STROKE);
+ pdf_show_pattern(ctx, pr, gstate->stroke.pattern, &pr->gstate[gstate->stroke.gstate_num], &bbox, PDF_STROKE);
fz_pop_clip(ctx, pr->dev);
}
break;
@@ -918,7 +696,7 @@ pdf_show_path(pdf_csi *csi, pdf_run_state *pr, int doclose, int dofill, int dost
fz_end_group(ctx, pr->dev);
if (dofill || dostroke)
- pdf_end_group(csi, pr, &softmask);
+ pdf_end_group(ctx, pr, &softmask);
}
fz_always(ctx)
{
@@ -935,7 +713,7 @@ pdf_show_path(pdf_csi *csi, pdf_run_state *pr, int doclose, int dofill, int dost
*/
static pdf_gstate *
-pdf_flush_text(pdf_csi *csi, pdf_run_state *pr)
+pdf_flush_text(fz_context *ctx, pdf_run_processor *pr)
{
pdf_gstate *gstate = pr->gstate + pr->gtop;
fz_text *text;
@@ -943,7 +721,6 @@ pdf_flush_text(pdf_csi *csi, pdf_run_state *pr)
int dostroke;
int doclip;
int doinvisible;
- fz_context *ctx = pr->ctx;
softmask_save softmask = { NULL };
if (!pr->text)
@@ -964,7 +741,7 @@ pdf_flush_text(pdf_csi *csi, pdf_run_state *pr)
case 7: doclip = 1; break;
}
- if (pr->in_hidden_ocg > 0)
+ if (pr->super.hidden)
dostroke = dofill = 0;
fz_try(ctx)
@@ -977,7 +754,7 @@ pdf_flush_text(pdf_csi *csi, pdf_run_state *pr)
if (text->len == 0)
break;
- gstate = pdf_begin_group(csi, pr, &tb, &softmask);
+ gstate = pdf_begin_group(ctx, pr, &tb, &softmask);
if (doinvisible)
fz_ignore_text(ctx, pr->dev, text, &gstate->ctm);
@@ -996,7 +773,7 @@ pdf_flush_text(pdf_csi *csi, pdf_run_state *pr)
if (gstate->fill.pattern)
{
fz_clip_text(ctx, pr->dev, text, &gstate->ctm, 0);
- pdf_show_pattern(csi, pr, gstate->fill.pattern, &pr->gstate[gstate->fill.gstate_num], &tb, PDF_FILL);
+ pdf_show_pattern(ctx, pr, gstate->fill.pattern, &pr->gstate[gstate->fill.gstate_num], &tb, PDF_FILL);
fz_pop_clip(ctx, pr->dev);
}
break;
@@ -1026,7 +803,7 @@ pdf_flush_text(pdf_csi *csi, pdf_run_state *pr)
if (gstate->stroke.pattern)
{
fz_clip_stroke_text(ctx, pr->dev, text, gstate->stroke_state, &gstate->ctm);
- pdf_show_pattern(csi, pr, gstate->stroke.pattern, &pr->gstate[gstate->stroke.gstate_num], &tb, PDF_STROKE);
+ pdf_show_pattern(ctx, pr, gstate->stroke.pattern, &pr->gstate[gstate->stroke.gstate_num], &tb, PDF_STROKE);
fz_pop_clip(ctx, pr->dev);
}
break;
@@ -1049,7 +826,7 @@ pdf_flush_text(pdf_csi *csi, pdf_run_state *pr)
pr->accumulate = 2;
}
- pdf_end_group(csi, pr, &softmask);
+ pdf_end_group(ctx, pr, &softmask);
}
fz_always(ctx)
{
@@ -1064,9 +841,8 @@ pdf_flush_text(pdf_csi *csi, pdf_run_state *pr)
}
static void
-pdf_show_char(pdf_csi *csi, pdf_run_state *pr, int cid)
+pdf_show_char(fz_context *ctx, pdf_run_processor *pr, int cid)
{
- fz_context *ctx = pr->ctx;
pdf_gstate *gstate = pr->gstate + pr->gtop;
pdf_font_desc *fontdesc = gstate->font;
fz_matrix tsm, trm;
@@ -1130,7 +906,7 @@ pdf_show_char(pdf_csi *csi, pdf_run_state *pr, int cid)
gstate->render != pr->text_mode ||
render_direct)
{
- gstate = pdf_flush_text(csi, pr);
+ gstate = pdf_flush_text(ctx, pr);
pr->text = fz_new_text(ctx, fontdesc->font, &trm, fontdesc->wmode);
pr->text->trm.e = 0;
@@ -1177,9 +953,8 @@ pdf_show_char(pdf_csi *csi, pdf_run_state *pr, int cid)
}
static void
-pdf_show_space(pdf_run_state *pr, float tadj)
+pdf_show_space(fz_context *ctx, pdf_run_processor *pr, float tadj)
{
- fz_context *ctx = pr->ctx;
pdf_gstate *gstate = pr->gstate + pr->gtop;
pdf_font_desc *fontdesc = gstate->font;
@@ -1196,9 +971,8 @@ pdf_show_space(pdf_run_state *pr, float tadj)
}
static void
-pdf_show_string(pdf_csi *csi, pdf_run_state *pr, unsigned char *buf, int len)
+pdf_show_string(fz_context *ctx, pdf_run_processor *pr, unsigned char *buf, int len)
{
- fz_context *ctx = pr->ctx;
pdf_gstate *gstate = pr->gstate + pr->gtop;
pdf_font_desc *fontdesc = gstate->font;
unsigned char *end = buf + len;
@@ -1218,18 +992,17 @@ pdf_show_string(pdf_csi *csi, pdf_run_state *pr, unsigned char *buf, int len)
cid = pdf_lookup_cmap(fontdesc->encoding, cpt);
if (cid >= 0)
- pdf_show_char(csi, pr, cid);
+ pdf_show_char(ctx, pr, cid);
else
fz_warn(ctx, "cannot encode character");
if (cpt == 32 && w == 1)
- pdf_show_space(pr, gstate->word_space);
+ pdf_show_space(ctx, pr, gstate->word_space);
}
}
static void
-pdf_show_text(pdf_csi *csi, pdf_run_state *pr, pdf_obj *text)
+pdf_show_text(fz_context *ctx, pdf_run_processor *pr, pdf_obj *text)
{
- fz_context *ctx = csi->ctx;
pdf_gstate *gstate = pr->gstate + pr->gtop;
int i;
@@ -1240,14 +1013,14 @@ pdf_show_text(pdf_csi *csi, pdf_run_state *pr, pdf_obj *text)
{
pdf_obj *item = pdf_array_get(ctx, text, i);
if (pdf_is_string(ctx, item))
- pdf_show_string(csi, pr, (unsigned char *)pdf_to_str_buf(ctx, item), pdf_to_str_len(ctx, item));
+ pdf_show_string(ctx, pr, (unsigned char *)pdf_to_str_buf(ctx, item), pdf_to_str_len(ctx, item));
else
- pdf_show_space(pr, - pdf_to_real(ctx, item) * gstate->size * 0.001f);
+ pdf_show_space(ctx, pr, - pdf_to_real(ctx, item) * gstate->size * 0.001f);
}
}
else if (pdf_is_string(ctx, text))
{
- pdf_show_string(csi, pr, (unsigned char *)pdf_to_str_buf(ctx, text), pdf_to_str_len(ctx, text));
+ pdf_show_string(ctx, pr, (unsigned char *)pdf_to_str_buf(ctx, text), pdf_to_str_len(ctx, text));
}
}
@@ -1290,6 +1063,7 @@ pdf_init_gstate(fz_context *ctx, pdf_gstate *gs, const fz_matrix *ctm)
gs->blendmode = 0;
gs->softmask = NULL;
+ gs->softmask_resources = NULL;
gs->softmask_ctm = fz_identity;
gs->luminosity = 0;
}
@@ -1307,15 +1081,14 @@ pdf_copy_gstate(fz_context *ctx, pdf_gstate *gs, pdf_gstate *old)
*/
static void
-pdf_set_colorspace(pdf_csi *csi, pdf_run_state *pr, int what, fz_colorspace *colorspace)
+pdf_set_colorspace(fz_context *ctx, pdf_run_processor *pr, int what, fz_colorspace *colorspace)
{
- fz_context *ctx = pr->ctx;
- pdf_gstate *gs;
+ pdf_gstate *gstate = pr->gstate + pr->gtop;
pdf_material *mat;
- gs = pdf_flush_text(csi, pr);
+ gstate = pdf_flush_text(ctx, pr);
- mat = what == PDF_FILL ? &gs->fill : &gs->stroke;
+ mat = what == PDF_FILL ? &gstate->fill : &gstate->stroke;
fz_drop_colorspace(ctx, mat->colorspace);
@@ -1336,16 +1109,15 @@ pdf_set_colorspace(pdf_csi *csi, pdf_run_state *pr, int what, fz_colorspace *col
}
static void
-pdf_set_color(pdf_csi *csi, pdf_run_state *pr, int what, float *v)
+pdf_set_color(fz_context *ctx, pdf_run_processor *pr, int what, float *v)
{
- fz_context *ctx = pr->ctx;
- pdf_gstate *gs;
+ pdf_gstate *gstate = pr->gstate + pr->gtop;
pdf_material *mat;
int i;
- gs = pdf_flush_text(csi, pr);
+ gstate = pdf_flush_text(ctx, pr);
- mat = what == PDF_FILL ? &gs->fill : &gs->stroke;
+ mat = what == PDF_FILL ? &gstate->fill : &gstate->stroke;
switch (mat->kind)
{
@@ -1362,16 +1134,17 @@ pdf_set_color(pdf_csi *csi, pdf_run_state *pr, int what, float *v)
default:
fz_warn(ctx, "color incompatible with material");
}
+
+ mat->gstate_num = pr->gparent;
}
static void
-pdf_set_shade(pdf_csi *csi, pdf_run_state *pr, int what, fz_shade *shade)
+pdf_set_shade(fz_context *ctx, pdf_run_processor *pr, int what, fz_shade *shade)
{
- fz_context *ctx = pr->ctx;
pdf_gstate *gs;
pdf_material *mat;
- gs = pdf_flush_text(csi, pr);
+ gs = pdf_flush_text(ctx, pr);
mat = what == PDF_FILL ? &gs->fill : &gs->stroke;
@@ -1380,16 +1153,17 @@ pdf_set_shade(pdf_csi *csi, pdf_run_state *pr, int what, fz_shade *shade)
mat->kind = PDF_MAT_SHADE;
mat->shade = fz_keep_shade(ctx, shade);
+
+ mat->gstate_num = pr->gparent;
}
static void
-pdf_set_pattern(pdf_csi *csi, pdf_run_state *pr, int what, pdf_pattern *pat, float *v)
+pdf_set_pattern(fz_context *ctx, pdf_run_processor *pr, int what, pdf_pattern *pat, float *v)
{
- fz_context *ctx = pr->ctx;
pdf_gstate *gs;
pdf_material *mat;
- gs = pdf_flush_text(csi, pr);
+ gs = pdf_flush_text(ctx, pr);
mat = what == PDF_FILL ? &gs->fill : &gs->stroke;
@@ -1401,216 +1175,26 @@ pdf_set_pattern(pdf_csi *csi, pdf_run_state *pr, int what, pdf_pattern *pat, flo
mat->pattern = pdf_keep_pattern(ctx, pat);
else
mat->pattern = NULL;
- mat->gstate_num = pr->gparent;
if (v)
- pdf_set_color(csi, pr, what, v);
-}
-
-static pdf_font_desc *
-load_font_or_hail_mary(pdf_csi *csi, pdf_obj *rdb, pdf_obj *font, int depth)
-{
- fz_context *ctx = csi->ctx;
- pdf_document *doc = csi->doc;
- pdf_font_desc *desc;
-
- fz_try(ctx)
- {
- desc = pdf_load_font(ctx, doc, rdb, font, depth);
- }
- fz_catch(ctx)
- {
- if (fz_caught(ctx) != FZ_ERROR_TRYLATER)
- fz_rethrow(ctx);
- if (!csi->cookie || !csi->cookie->incomplete_ok)
- fz_rethrow(ctx);
- desc = NULL;
- csi->cookie->incomplete++;
- }
- if (desc == NULL)
- desc = pdf_load_hail_mary_font(ctx, doc);
- return desc;
-}
-
-static void
-pdf_run_extgstate(pdf_csi *csi, pdf_run_state *pr, pdf_obj *rdb, pdf_obj *extgstate)
-{
- fz_context *ctx = pr->ctx;
- pdf_gstate *gstate;
- fz_colorspace *colorspace;
- int i, k, n;
-
- gstate = pdf_flush_text(csi, pr);
-
- n = pdf_dict_len(ctx, extgstate);
- for (i = 0; i < n; i++)
- {
- pdf_obj *key = pdf_dict_get_key(ctx, extgstate, i);
- pdf_obj *val = pdf_dict_get_val(ctx, extgstate, i);
- char *s = pdf_to_name(ctx, key);
-
- if (!strcmp(s, "Font"))
- {
- if (pdf_is_array(ctx, val) && pdf_array_len(ctx, val) == 2)
- {
- pdf_obj *font = pdf_array_get(ctx, val, 0);
-
- if (gstate->font)
- {
- pdf_drop_font(ctx, gstate->font);
- gstate->font = NULL;
- }
-
- gstate->font = load_font_or_hail_mary(csi, rdb, font, pr->nested_depth);
- if (!gstate->font)
- fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find font in store");
- gstate->size = pdf_to_real(ctx, pdf_array_get(ctx, val, 1));
- }
- else
- fz_throw(ctx, FZ_ERROR_GENERIC, "malformed /Font dictionary");
- }
-
- else if (!strcmp(s, "LC"))
- {
- pr->dev->flags &= ~(FZ_DEVFLAG_STARTCAP_UNDEFINED | FZ_DEVFLAG_DASHCAP_UNDEFINED | FZ_DEVFLAG_ENDCAP_UNDEFINED);
- gstate->stroke_state = fz_unshare_stroke_state(ctx, gstate->stroke_state);
- gstate->stroke_state->start_cap = pdf_to_int(ctx, val);
- gstate->stroke_state->dash_cap = pdf_to_int(ctx, val);
- gstate->stroke_state->end_cap = pdf_to_int(ctx, val);
- }
- else if (!strcmp(s, "LW"))
- {
- pr->dev->flags &= ~FZ_DEVFLAG_LINEWIDTH_UNDEFINED;
- gstate->stroke_state = fz_unshare_stroke_state(ctx, gstate->stroke_state);
- gstate->stroke_state->linewidth = pdf_to_real(ctx, val);
- }
- else if (!strcmp(s, "LJ"))
- {
- pr->dev->flags &= ~FZ_DEVFLAG_LINEJOIN_UNDEFINED;
- gstate->stroke_state = fz_unshare_stroke_state(ctx, gstate->stroke_state);
- gstate->stroke_state->linejoin = pdf_to_int(ctx, val);
- }
- else if (!strcmp(s, "ML"))
- {
- pr->dev->flags &= ~FZ_DEVFLAG_MITERLIMIT_UNDEFINED;
- gstate->stroke_state = fz_unshare_stroke_state(ctx, gstate->stroke_state);
- gstate->stroke_state->miterlimit = pdf_to_real(ctx, val);
- }
-
- else if (!strcmp(s, "D"))
- {
- if (pdf_is_array(ctx, val) && pdf_array_len(ctx, val) == 2)
- {
- pdf_obj *dashes = pdf_array_get(ctx, val, 0);
- int len = pdf_array_len(ctx, dashes);
- gstate->stroke_state = fz_unshare_stroke_state_with_dash_len(ctx, gstate->stroke_state, len);
- gstate->stroke_state->dash_len = len;
- for (k = 0; k < len; k++)
- gstate->stroke_state->dash_list[k] = pdf_to_real(ctx, pdf_array_get(ctx, dashes, k));
- gstate->stroke_state->dash_phase = pdf_to_real(ctx, pdf_array_get(ctx, val, 1));
- }
- else
- fz_throw(ctx, FZ_ERROR_GENERIC, "malformed /D");
- }
-
- else if (!strcmp(s, "CA"))
- gstate->stroke.alpha = fz_clamp(pdf_to_real(ctx, val), 0, 1);
-
- else if (!strcmp(s, "ca"))
- gstate->fill.alpha = fz_clamp(pdf_to_real(ctx, val), 0, 1);
-
- else if (!strcmp(s, "BM"))
- {
- if (pdf_is_array(ctx, val))
- val = pdf_array_get(ctx, val, 0);
- gstate->blendmode = fz_lookup_blendmode(pdf_to_name(ctx, val));
- }
-
- else if (!strcmp(s, "SMask"))
- {
- if (pdf_is_dict(ctx, val))
- {
- pdf_xobject *xobj;
- pdf_obj *group, *luminosity, *bc, *tr;
-
- if (gstate->softmask)
- {
- pdf_drop_xobject(ctx, gstate->softmask);
- gstate->softmask = NULL;
- }
-
- group = pdf_dict_gets(ctx, val, "G");
- if (!group)
- fz_throw(ctx, FZ_ERROR_GENERIC, "cannot load softmask xobject (%d %d R)", pdf_to_num(ctx, val), pdf_to_gen(ctx, val));
- xobj = pdf_load_xobject(ctx, csi->doc, group);
-
- colorspace = xobj->colorspace;
- if (!colorspace)
- colorspace = fz_device_gray(ctx);
+ pdf_set_color(ctx, pr, what, v);
- /* The softmask_ctm no longer has the softmask matrix rolled into it, as this
- * causes the softmask matrix to be applied twice. */
- gstate->softmask_ctm = gstate->ctm;
- gstate->softmask = xobj;
- for (k = 0; k < colorspace->n; k++)
- gstate->softmask_bc[k] = 0;
-
- bc = pdf_dict_gets(ctx, val, "BC");
- if (pdf_is_array(ctx, bc))
- {
- for (k = 0; k < colorspace->n; k++)
- gstate->softmask_bc[k] = pdf_to_real(ctx, pdf_array_get(ctx, bc, k));
- }
-
- luminosity = pdf_dict_gets(ctx, val, "S");
- if (pdf_is_name(ctx, luminosity) && !strcmp(pdf_to_name(ctx, luminosity), "Luminosity"))
- gstate->luminosity = 1;
- else
- gstate->luminosity = 0;
-
- tr = pdf_dict_gets(ctx, val, "TR");
- if (tr && strcmp(pdf_to_name(ctx, tr), "Identity"))
- fz_warn(ctx, "ignoring transfer function");
- }
- else if (pdf_is_name(ctx, val) && !strcmp(pdf_to_name(ctx, val), "None"))
- {
- if (gstate->softmask)
- {
- pdf_drop_xobject(ctx, gstate->softmask);
- gstate->softmask = NULL;
- }
- }
- }
-
- else if (!strcmp(s, "TR2"))
- {
- if (strcmp(pdf_to_name(ctx, val), "Identity") && strcmp(pdf_to_name(ctx, val), "Default"))
- fz_warn(ctx, "ignoring transfer function");
- }
-
- else if (!strcmp(s, "TR"))
- {
- /* TR is ignored in the presence of TR2 */
- pdf_obj *tr2 = pdf_dict_gets(ctx, extgstate, "TR2");
- if (tr2 && strcmp(pdf_to_name(ctx, val), "Identity"))
- fz_warn(ctx, "ignoring transfer function");
- }
- }
+ mat->gstate_num = pr->gparent;
}
static void
-run_xobject(pdf_csi *csi, void *state, pdf_obj *resources, pdf_xobject *xobj, const fz_matrix *transform)
+pdf_run_xobject(fz_context *ctx, pdf_run_processor *proc, pdf_xobject *xobj, pdf_obj *page_resources, const fz_matrix *transform)
{
- fz_context *ctx = csi->ctx;
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
pdf_gstate *gstate = NULL;
int oldtop = 0;
fz_matrix local_transform = *transform;
softmask_save softmask = { NULL };
int gparent_save;
fz_matrix gparent_save_ctm;
- pdf_run_state *pr = (pdf_run_state *)state;
int cleanup_state = 0;
char errmess[256] = "";
+ pdf_obj *resources;
/* Avoid infinite recursion */
if (xobj == NULL || pdf_mark_obj(ctx, xobj->me))
@@ -1625,7 +1209,7 @@ run_xobject(pdf_csi *csi, void *state, pdf_obj *resources, pdf_xobject *xobj, co
fz_try(ctx)
{
- pdf_gsave(pr);
+ pdf_gsave(ctx, pr);
gstate = pr->gstate + pr->gtop;
oldtop = pr->gtop;
@@ -1647,13 +1231,12 @@ run_xobject(pdf_csi *csi, void *state, pdf_obj *resources, pdf_xobject *xobj, co
/* Remember that we tried to call begin_softmask. Even
* if it throws an error, we must call end_softmask. */
cleanup_state = 1;
- gstate = begin_softmask(csi, pr, &softmask);
+ gstate = begin_softmask(ctx, pr, &softmask);
/* Remember that we tried to call fz_begin_group. Even
* if it throws an error, we must call fz_end_group. */
cleanup_state = 2;
- fz_begin_group(ctx, pr->dev, &bbox,
- xobj->isolated, xobj->knockout, gstate->blendmode, gstate->fill.alpha);
+ fz_begin_group(ctx, pr->dev, &bbox, xobj->isolated, xobj->knockout, gstate->blendmode, gstate->fill.alpha);
gstate->blendmode = 0;
gstate->stroke.alpha = 1;
@@ -1663,7 +1246,7 @@ run_xobject(pdf_csi *csi, void *state, pdf_obj *resources, pdf_xobject *xobj, co
/* Remember that we tried to save for the clippath. Even if it
* throws an error, we must pop it. */
cleanup_state = 3;
- pdf_gsave(pr); /* Save here so the clippath doesn't persist */
+ pdf_gsave(ctx, pr); /* Save here so the clippath doesn't persist */
/* clip to the bounds */
fz_moveto(ctx, pr->path, xobj->bbox.x0, xobj->bbox.y0);
@@ -1672,19 +1255,20 @@ run_xobject(pdf_csi *csi, void *state, pdf_obj *resources, pdf_xobject *xobj, co
fz_lineto(ctx, pr->path, xobj->bbox.x0, xobj->bbox.y1);
fz_closepath(ctx, pr->path);
pr->clip = 1;
- pdf_show_path(csi, pr, 0, 0, 0, 0);
+ pdf_show_path(ctx, pr, 0, 0, 0, 0);
/* run contents */
- if (xobj->resources)
- resources = xobj->resources;
+ resources = xobj->resources;
+ if (!resources)
+ resources = page_resources;
- pdf_process_contents_object(csi, resources, xobj->contents);
+ pdf_process_contents(ctx, (pdf_processor*)pr, xobj->document, resources, xobj->contents, NULL);
}
fz_always(ctx)
{
if (cleanup_state >= 3)
- pdf_grestore(pr); /* Remove the clippath */
+ pdf_grestore(ctx, pr); /* Remove the clippath */
/* wrap up transparency stacks */
if (xobj->transparency)
@@ -1705,7 +1289,7 @@ run_xobject(pdf_csi *csi, void *state, pdf_obj *resources, pdf_xobject *xobj, co
{
fz_try(ctx)
{
- end_softmask(csi, pr, &softmask);
+ end_softmask(ctx, pr, &softmask);
}
fz_catch(ctx)
{
@@ -1721,9 +1305,9 @@ run_xobject(pdf_csi *csi, void *state, pdf_obj *resources, pdf_xobject *xobj, co
if (gstate)
{
while (oldtop < pr->gtop)
- pdf_grestore(pr);
+ pdf_grestore(ctx, pr);
- pdf_grestore(pr);
+ pdf_grestore(ctx, pr);
}
pdf_unmark_obj(ctx, xobj->me);
@@ -1738,633 +1322,440 @@ run_xobject(pdf_csi *csi, void *state, pdf_obj *resources, pdf_xobject *xobj, co
fz_throw(ctx, FZ_ERROR_GENERIC, "%s", errmess);
}
-static void pdf_run_BDC(pdf_csi *csi, void *state)
-{
- fz_context *ctx = csi->ctx;
- pdf_run_state *pr = (pdf_run_state *)state;
- pdf_obj *ocg;
- pdf_obj *rdb = csi->rdb;
-
- /* We only understand OC groups so far */
- if (strcmp(csi->name, "OC") != 0)
- return;
+/* general graphics state */
- /* If we are already in a hidden OCG, then we'll still be hidden -
- * just increment the depth so we pop back to visibility when we've
- * seen enough EDCs. */
- if (pr->in_hidden_ocg > 0)
- {
- pr->in_hidden_ocg++;
- return;
- }
-
- if (pdf_is_name(ctx, csi->obj))
- {
- ocg = pdf_dict_gets(ctx, pdf_dict_gets(ctx, rdb, "Properties"), pdf_to_name(ctx, csi->obj));
- }
- else
- ocg = csi->obj;
+static void pdf_run_w(fz_context *ctx, pdf_processor *proc, float linewidth)
+{
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ pdf_gstate *gstate = pdf_flush_text(ctx, pr);
- if (!ocg)
- {
- /* No Properties array, or name not found in the properties
- * means visible. */
- return;
- }
- if (strcmp(pdf_to_name(ctx, pdf_dict_gets(ctx, ocg, "Type")), "OCG") != 0)
- {
- /* Wrong type of property */
- return;
- }
- if (pdf_is_hidden_ocg(ocg, csi, pr, rdb))
- pr->in_hidden_ocg++;
+ pr->dev->flags &= ~FZ_DEVFLAG_LINEWIDTH_UNDEFINED;
+ gstate->stroke_state = fz_unshare_stroke_state(ctx, gstate->stroke_state);
+ gstate->stroke_state->linewidth = linewidth;
}
-static void pdf_run_BI(pdf_csi *csi, void *state)
+static void pdf_run_j(fz_context *ctx, pdf_processor *proc, int linejoin)
{
- pdf_run_state *pr = (pdf_run_state *)state;
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ pdf_gstate *gstate = pdf_flush_text(ctx, pr);
- pdf_show_image(csi, pr, csi->img);
+ pr->dev->flags &= ~FZ_DEVFLAG_LINEJOIN_UNDEFINED;
+ gstate->stroke_state = fz_unshare_stroke_state(ctx, gstate->stroke_state);
+ gstate->stroke_state->linejoin = linejoin;
}
-static void pdf_run_B(pdf_csi *csi, void *state)
+static void pdf_run_J(fz_context *ctx, pdf_processor *proc, int linecap)
{
- pdf_run_state *pr = (pdf_run_state *)state;
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ pdf_gstate *gstate = pdf_flush_text(ctx, pr);
- pdf_show_path(csi, pr, 0, 1, 1, 0);
+ pr->dev->flags &= ~(FZ_DEVFLAG_STARTCAP_UNDEFINED | FZ_DEVFLAG_DASHCAP_UNDEFINED | FZ_DEVFLAG_ENDCAP_UNDEFINED);
+ gstate->stroke_state = fz_unshare_stroke_state(ctx, gstate->stroke_state);
+ gstate->stroke_state->start_cap = linecap;
+ gstate->stroke_state->dash_cap = linecap;
+ gstate->stroke_state->end_cap = linecap;
}
-static void pdf_run_BMC(pdf_csi *csi, void *state)
+static void pdf_run_M(fz_context *ctx, pdf_processor *proc, float miterlimit)
{
- pdf_run_state *pr = (pdf_run_state *)state;
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ pdf_gstate *gstate = pdf_flush_text(ctx, pr);
- /* If we are already in a hidden OCG, then we'll still be hidden -
- * just increment the depth so we pop back to visibility when we've
- * seen enough EDCs. */
- if (pr->in_hidden_ocg > 0)
- {
- pr->in_hidden_ocg++;
- }
+ pr->dev->flags &= ~FZ_DEVFLAG_MITERLIMIT_UNDEFINED;
+ gstate->stroke_state = fz_unshare_stroke_state(ctx, gstate->stroke_state);
+ gstate->stroke_state->miterlimit = miterlimit;
}
-static void pdf_run_BT(pdf_csi *csi, void *state)
+static void pdf_run_d(fz_context *ctx, pdf_processor *proc, pdf_obj *array, float phase)
{
- pdf_run_state *pr = (pdf_run_state *)state;
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ pdf_gstate *gstate = pdf_flush_text(ctx, pr);
+ int len, i;
- pr->tm = fz_identity;
- pr->tlm = fz_identity;
+ len = pdf_array_len(ctx, array);
+ gstate->stroke_state = fz_unshare_stroke_state_with_dash_len(ctx, gstate->stroke_state, len);
+ gstate->stroke_state->dash_len = len;
+ for (i = 0; i < len; i++)
+ gstate->stroke_state->dash_list[i] = pdf_to_real(ctx, pdf_array_get(ctx, array, i));
+ gstate->stroke_state->dash_phase = phase;
}
-static void pdf_run_BX(pdf_csi *csi, void *state)
+static void pdf_run_ri(fz_context *ctx, pdf_processor *proc, const char *intent)
{
}
-static void pdf_run_Bstar(pdf_csi *csi, void *state)
+static void pdf_run_i(fz_context *ctx, pdf_processor *proc, float flatness)
{
- pdf_run_state *pr = (pdf_run_state *)state;
-
- pdf_show_path(csi, pr, 0, 1, 1, 1);
}
-static void pdf_run_cs_imp(pdf_csi *csi, pdf_run_state *pr, int what)
+static void pdf_run_gs_begin(fz_context *ctx, pdf_processor *proc, const char *name, pdf_obj *extgstate)
{
- fz_context *ctx = pr->ctx;
- fz_colorspace *colorspace;
- pdf_obj *obj, *dict;
- pdf_obj *rdb = csi->rdb;
-
- if (!strcmp(csi->name, "Pattern"))
- {
- pdf_set_pattern(csi, pr, what, NULL, NULL);
- }
- else
- {
- if (!strcmp(csi->name, "DeviceGray"))
- colorspace = fz_device_gray(ctx); /* No fz_keep_colorspace as static */
- else if (!strcmp(csi->name, "DeviceRGB"))
- colorspace = fz_device_rgb(ctx); /* No fz_keep_colorspace as static */
- else if (!strcmp(csi->name, "DeviceCMYK"))
- colorspace = fz_device_cmyk(ctx); /* No fz_keep_colorspace as static */
- else
- {
- dict = pdf_dict_gets(ctx, rdb, "ColorSpace");
- if (!dict)
- fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find ColorSpace dictionary");
- obj = pdf_dict_gets(ctx, dict, csi->name);
- if (!obj)
- fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find colorspace resource '%s'", csi->name);
- colorspace = pdf_load_colorspace(ctx, csi->doc, obj);
- }
-
- pdf_set_colorspace(csi, pr, what, colorspace);
-
- fz_drop_colorspace(ctx, colorspace);
- }
}
-static void pdf_run_CS(pdf_csi *csi, void *state)
+static void pdf_run_gs_end(fz_context *ctx, pdf_processor *proc)
{
- pdf_run_state *pr = (pdf_run_state *)state;
+}
- pr->dev->flags &= ~FZ_DEVFLAG_STROKECOLOR_UNDEFINED;
+/* transparency graphics state */
- pdf_run_cs_imp(csi, pr, PDF_STROKE);
+static void pdf_run_gs_BM(fz_context *ctx, pdf_processor *proc, const char *blendmode)
+{
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ pdf_gstate *gstate = pdf_flush_text(ctx, pr);
+ gstate->blendmode = fz_lookup_blendmode(blendmode);
}
-static void pdf_run_cs(pdf_csi *csi, void *state)
+static void pdf_run_gs_CA(fz_context *ctx, pdf_processor *proc, float alpha)
{
- pdf_run_state *pr = (pdf_run_state *)state;
-
- pr->dev->flags &= ~FZ_DEVFLAG_FILLCOLOR_UNDEFINED;
-
- pdf_run_cs_imp(csi, pr, PDF_FILL);
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ pdf_gstate *gstate = pdf_flush_text(ctx, pr);
+ gstate->stroke.alpha = fz_clamp(alpha, 0, 1);
}
-static void pdf_run_DP(pdf_csi *csi, void *state)
+static void pdf_run_gs_ca(fz_context *ctx, pdf_processor *proc, float alpha)
{
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ pdf_gstate *gstate = pdf_flush_text(ctx, pr);
+ gstate->fill.alpha = fz_clamp(alpha, 0, 1);
}
-static void pdf_run_Do(pdf_csi *csi, void *state)
+static void pdf_run_gs_SMask(fz_context *ctx, pdf_processor *proc, pdf_xobject *smask, pdf_obj *page_resources, float *bc, int luminosity)
{
- pdf_run_state *pr = (pdf_run_state *)state;
- fz_context *ctx = csi->ctx;
- pdf_obj *dict;
- pdf_obj *obj;
- pdf_obj *subtype;
- pdf_obj *rdb = csi->rdb;
-
- dict = pdf_dict_gets(ctx, rdb, "XObject");
- if (!dict)
- fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find XObject dictionary when looking for: '%s'", csi->name);
-
- obj = pdf_dict_gets(ctx, dict, csi->name);
- if (!obj)
- fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find xobject resource: '%s'", csi->name);
-
- subtype = pdf_dict_gets(ctx, obj, "Subtype");
- if (!pdf_is_name(ctx, subtype))
- fz_throw(ctx, FZ_ERROR_GENERIC, "no XObject subtype specified");
-
- if (pdf_is_hidden_ocg(pdf_dict_gets(ctx, obj, "OC"), csi, pr, rdb))
- return;
-
- if (!strcmp(pdf_to_name(ctx, subtype), "Form") && pdf_dict_gets(ctx, obj, "Subtype2"))
- subtype = pdf_dict_gets(ctx, obj, "Subtype2");
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ pdf_gstate *gstate = pdf_flush_text(ctx, pr);
+ int i;
- if (!strcmp(pdf_to_name(ctx, subtype), "Form"))
+ if (gstate->softmask)
{
- pdf_xobject *xobj;
-
- xobj = pdf_load_xobject(ctx, csi->doc, obj);
-
- /* Inherit parent resources, in case this one was empty XXX check where it's loaded */
- if (!xobj->resources)
- xobj->resources = pdf_keep_obj(ctx, rdb);
-
- fz_try(ctx)
- {
- run_xobject(csi, state, xobj->resources, xobj, &fz_identity);
- }
- fz_always(ctx)
- {
- pdf_drop_xobject(ctx, xobj);
- }
- fz_catch(ctx)
- {
- fz_rethrow_message(ctx, "cannot draw xobject (%d %d R)", pdf_to_num(ctx, obj), pdf_to_gen(ctx, obj));
- }
+ pdf_drop_xobject(ctx, gstate->softmask);
+ gstate->softmask = NULL;
+ pdf_drop_obj(ctx, gstate->softmask_resources);
+ gstate->softmask_resources = NULL;
}
- else if (!strcmp(pdf_to_name(ctx, subtype), "Image"))
+ if (smask)
{
- if ((pr->dev->hints & FZ_IGNORE_IMAGE) == 0)
- {
- fz_image *img = pdf_load_image(ctx, csi->doc, obj);
-
- fz_try(ctx)
- {
- pdf_show_image(csi, pr, img);
- }
- fz_always(ctx)
- {
- fz_drop_image(ctx, img);
- }
- fz_catch(ctx)
- {
- fz_rethrow(ctx);
- }
- }
+ fz_colorspace *cs = smask->colorspace;
+ if (!cs)
+ cs = fz_device_gray(ctx);
+ gstate->softmask_ctm = gstate->ctm;
+ gstate->softmask = pdf_keep_xobject(ctx, smask);
+ gstate->softmask_resources = pdf_keep_obj(ctx, page_resources);
+ for (i = 0; i < cs->n; ++i)
+ gstate->softmask_bc[i] = bc[i];
+ gstate->luminosity = luminosity;
}
+}
- else if (!strcmp(pdf_to_name(ctx, subtype), "PS"))
- {
- fz_warn(ctx, "ignoring XObject with subtype PS");
- }
+/* special graphics state */
- else
- {
- fz_throw(ctx, FZ_ERROR_GENERIC, "unknown XObject subtype: '%s'", pdf_to_name(ctx, subtype));
- }
+static void pdf_run_q(fz_context *ctx, pdf_processor *proc)
+{
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ pdf_gsave(ctx, pr);
}
-static void pdf_run_EMC(pdf_csi *csi, void *state)
+static void pdf_run_Q(fz_context *ctx, pdf_processor *proc)
{
- pdf_run_state *pr = (pdf_run_state *)state;
-
- if (pr->in_hidden_ocg > 0)
- pr->in_hidden_ocg--;
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ pdf_grestore(ctx, pr);
}
-static void pdf_run_ET(pdf_csi *csi, void *state)
+static void pdf_run_cm(fz_context *ctx, pdf_processor *proc, float a, float b, float c, float d, float e, float f)
{
- pdf_run_state *pr = (pdf_run_state *)state;
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ pdf_gstate *gstate = pdf_flush_text(ctx, pr);
+ fz_matrix m;
- pdf_flush_text(csi, pr);
- pr->accumulate = 1;
+ m.a = a;
+ m.b = b;
+ m.c = c;
+ m.d = d;
+ m.e = e;
+ m.f = f;
+ fz_concat(&gstate->ctm, &m, &gstate->ctm);
}
-static void pdf_run_EX(pdf_csi *csi, void *state)
+/* path construction */
+
+static void pdf_run_m(fz_context *ctx, pdf_processor *proc, float x, float y)
{
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ fz_moveto(ctx, pr->path, x, y);
}
-static void pdf_run_F(pdf_csi *csi, void *state)
+static void pdf_run_l(fz_context *ctx, pdf_processor *proc, float x, float y)
{
- pdf_run_state *pr = (pdf_run_state *)state;
-
- pdf_show_path(csi, pr, 0, 1, 0, 0);
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ fz_lineto(ctx, pr->path, x, y);
}
-
-static void pdf_run_G(pdf_csi *csi, void *state)
+static void pdf_run_c(fz_context *ctx, pdf_processor *proc, float x1, float y1, float x2, float y2, float x3, float y3)
{
- pdf_run_state *pr = (pdf_run_state *)state;
-
- pr->dev->flags &= ~FZ_DEVFLAG_STROKECOLOR_UNDEFINED;
- pdf_set_colorspace(csi, pr, PDF_STROKE, fz_device_gray(csi->ctx));
- pdf_set_color(csi, pr, PDF_STROKE, csi->stack);
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ fz_curveto(ctx, pr->path, x1, y1, x2, y2, x3, y3);
}
-static void pdf_run_J(pdf_csi *csi, void *state)
+static void pdf_run_v(fz_context *ctx, pdf_processor *proc, float x2, float y2, float x3, float y3)
{
- pdf_run_state *pr = (pdf_run_state *)state;
- pdf_gstate *gstate = pr->gstate + pr->gtop;
-
- pr->dev->flags &= ~(FZ_DEVFLAG_STARTCAP_UNDEFINED | FZ_DEVFLAG_DASHCAP_UNDEFINED | FZ_DEVFLAG_ENDCAP_UNDEFINED);
- gstate->stroke_state = fz_unshare_stroke_state(csi->ctx, gstate->stroke_state);
- gstate->stroke_state->start_cap = csi->stack[0];
- gstate->stroke_state->dash_cap = csi->stack[0];
- gstate->stroke_state->end_cap = csi->stack[0];
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ fz_curvetov(ctx, pr->path, x2, y2, x3, y3);
}
-static void pdf_run_K(pdf_csi *csi, void *state)
+static void pdf_run_y(fz_context *ctx, pdf_processor *proc, float x1, float y1, float x3, float y3)
{
- pdf_run_state *pr = (pdf_run_state *)state;
-
- pr->dev->flags &= ~FZ_DEVFLAG_STROKECOLOR_UNDEFINED;
- pdf_set_colorspace(csi, pr, PDF_STROKE, fz_device_cmyk(csi->ctx));
- pdf_set_color(csi, pr, PDF_STROKE, csi->stack);
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ fz_curvetoy(ctx, pr->path, x1, y1, x3, y3);
}
-static void pdf_run_M(pdf_csi *csi, void *state)
+static void pdf_run_h(fz_context *ctx, pdf_processor *proc)
{
- pdf_run_state *pr = (pdf_run_state *)state;
- pdf_gstate *gstate = pr->gstate + pr->gtop;
-
- pr->dev->flags &= ~FZ_DEVFLAG_MITERLIMIT_UNDEFINED;
- gstate->stroke_state = fz_unshare_stroke_state(csi->ctx, gstate->stroke_state);
- gstate->stroke_state->miterlimit = csi->stack[0];
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ fz_closepath(ctx, pr->path);
}
-static void pdf_run_MP(pdf_csi *csi, void *state)
+static void pdf_run_re(fz_context *ctx, pdf_processor *proc, float x, float y, float w, float h)
{
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ fz_moveto(ctx, pr->path, x, y);
+ fz_lineto(ctx, pr->path, x + w, y);
+ fz_lineto(ctx, pr->path, x + w, y + h);
+ fz_lineto(ctx, pr->path, x, y + h);
+ fz_closepath(ctx, pr->path);
}
-static void pdf_run_Q(pdf_csi *csi, void *state)
-{
- pdf_run_state *pr = (pdf_run_state *)state;
+/* path painting */
- pdf_grestore(pr);
+static void pdf_run_S(fz_context *ctx, pdf_processor *proc)
+{
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ pdf_show_path(ctx, pr, 0, 0, 1, 0);
}
-static void pdf_run_RG(pdf_csi *csi, void *state)
+static void pdf_run_s(fz_context *ctx, pdf_processor *proc)
{
- pdf_run_state *pr = (pdf_run_state *)state;
-
- pr->dev->flags &= ~FZ_DEVFLAG_STROKECOLOR_UNDEFINED;
- pdf_set_colorspace(csi, pr, PDF_STROKE, fz_device_rgb(csi->ctx));
- pdf_set_color(csi, pr, PDF_STROKE, csi->stack);
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ pdf_show_path(ctx, pr, 1, 0, 1, 0);
}
-static void pdf_run_S(pdf_csi *csi, void *state)
+static void pdf_run_F(fz_context *ctx, pdf_processor *proc)
{
- pdf_run_state *pr = (pdf_run_state *)state;
-
- pdf_show_path(csi, pr, 0, 0, 1, 0);
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ pdf_show_path(ctx, pr, 0, 1, 0, 0);
}
-static void pdf_run_SC_imp(pdf_csi *csi, pdf_run_state *pr, int what, pdf_material *mat)
+static void pdf_run_f(fz_context *ctx, pdf_processor *proc)
{
- fz_context *ctx = pr->ctx;
- pdf_obj *patterntype;
- pdf_obj *dict;
- pdf_obj *obj;
- int kind;
- pdf_obj *rdb = csi->rdb;
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ pdf_show_path(ctx, pr, 0, 1, 0, 0);
+}
- kind = mat->kind;
- if (csi->name[0])
- kind = PDF_MAT_PATTERN;
+static void pdf_run_fstar(fz_context *ctx, pdf_processor *proc)
+{
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ pdf_show_path(ctx, pr, 0, 1, 0, 1);
+}
- switch (kind)
- {
- case PDF_MAT_NONE:
- fz_throw(ctx, FZ_ERROR_GENERIC, "cannot set color in mask objects");
+static void pdf_run_B(fz_context *ctx, pdf_processor *proc)
+{
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ pdf_show_path(ctx, pr, 0, 1, 1, 0);
+}
- case PDF_MAT_COLOR:
- pdf_set_color(csi, pr, what, csi->stack);
- break;
+static void pdf_run_Bstar(fz_context *ctx, pdf_processor *proc)
+{
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ pdf_show_path(ctx, pr, 0, 1, 1, 1);
+}
- case PDF_MAT_PATTERN:
- dict = pdf_dict_gets(ctx, rdb, "Pattern");
- if (!dict)
- fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find Pattern dictionary");
+static void pdf_run_b(fz_context *ctx, pdf_processor *proc)
+{
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ pdf_show_path(ctx, pr, 1, 1, 1, 0);
+}
- obj = pdf_dict_gets(ctx, dict, csi->name);
- if (!obj)
- fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find pattern resource '%s'", csi->name);
+static void pdf_run_bstar(fz_context *ctx, pdf_processor *proc)
+{
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ pdf_show_path(ctx, pr, 1, 1, 1, 1);
+}
- patterntype = pdf_dict_gets(ctx, obj, "PatternType");
+static void pdf_run_n(fz_context *ctx, pdf_processor *proc)
+{
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ pdf_show_path(ctx, pr, 0, 0, 0, 0);
+}
- if (pdf_to_int(ctx, patterntype) == 1)
- {
- pdf_pattern *pat;
- pat = pdf_load_pattern(ctx, csi->doc, obj);
- pdf_set_pattern(csi, pr, what, pat, csi->top > 0 ? csi->stack : NULL);
- pdf_drop_pattern(ctx, pat);
- }
- else if (pdf_to_int(ctx, patterntype) == 2)
- {
- fz_shade *shd;
- shd = pdf_load_shading(ctx, csi->doc, obj);
- pdf_set_shade(csi, pr, what, shd);
- fz_drop_shade(ctx, shd);
- }
- else
- {
- fz_throw(ctx, FZ_ERROR_GENERIC, "unknown pattern type: %d", pdf_to_int(ctx, patterntype));
- }
- break;
+/* clipping paths */
- case PDF_MAT_SHADE:
- fz_throw(ctx, FZ_ERROR_GENERIC, "cannot set color in shade objects");
- }
- mat->gstate_num = pr->gparent;
+static void pdf_run_W(fz_context *ctx, pdf_processor *proc)
+{
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ pr->clip = 1;
+ pr->clip_even_odd = 0;
}
-static void pdf_run_SC(pdf_csi *csi, void *state)
+static void pdf_run_Wstar(fz_context *ctx, pdf_processor *proc)
{
- pdf_run_state *pr = (pdf_run_state *)state;
- pdf_gstate *gstate = pr->gstate + pr->gtop;
-
- pr->dev->flags &= ~FZ_DEVFLAG_STROKECOLOR_UNDEFINED;
- pdf_run_SC_imp(csi, pr, PDF_STROKE, &gstate->stroke);
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ pr->clip = 1;
+ pr->clip_even_odd = 1;
}
-static void pdf_run_sc(pdf_csi *csi, void *state)
+/* text objects */
+
+static void pdf_run_BT(fz_context *ctx, pdf_processor *proc)
{
- pdf_run_state *pr = (pdf_run_state *)state;
- pdf_gstate *gstate = pr->gstate + pr->gtop;
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ pr->tm = fz_identity;
+ pr->tlm = fz_identity;
+}
- pr->dev->flags &= ~FZ_DEVFLAG_FILLCOLOR_UNDEFINED;
- pdf_run_SC_imp(csi, pr, PDF_FILL, &gstate->fill);
+static void pdf_run_ET(fz_context *ctx, pdf_processor *proc)
+{
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ pdf_flush_text(ctx, pr);
+ pr->accumulate = 1;
}
-static void pdf_run_Tc(pdf_csi *csi, void *state)
+/* text state */
+
+static void pdf_run_Tc(fz_context *ctx, pdf_processor *proc, float charspace)
{
- pdf_run_state *pr = (pdf_run_state *)state;
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
pdf_gstate *gstate = pr->gstate + pr->gtop;
-
- gstate->char_space = csi->stack[0];
+ gstate->char_space = charspace;
}
-static void pdf_run_Tw(pdf_csi *csi, void *state)
+static void pdf_run_Tw(fz_context *ctx, pdf_processor *proc, float wordspace)
{
- pdf_run_state *pr = (pdf_run_state *)state;
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
pdf_gstate *gstate = pr->gstate + pr->gtop;
-
- gstate->word_space = csi->stack[0];
+ gstate->word_space = wordspace;
}
-static void pdf_run_Tz(pdf_csi *csi, void *state)
+static void pdf_run_Tz(fz_context *ctx, pdf_processor *proc, float scale)
{
- pdf_run_state *pr = (pdf_run_state *)state;
- pdf_gstate *gstate;
- float a = csi->stack[0] / 100;
-
- gstate = pdf_flush_text(csi, pr);
- gstate->scale = a;
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ pdf_gstate *gstate = pdf_flush_text(ctx, pr);
+ gstate->scale = scale / 100;
}
-static void pdf_run_TL(pdf_csi *csi, void *state)
+static void pdf_run_TL(fz_context *ctx, pdf_processor *proc, float leading)
{
- pdf_run_state *pr = (pdf_run_state *)state;
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
pdf_gstate *gstate = pr->gstate + pr->gtop;
-
- gstate->leading = csi->stack[0];
+ gstate->leading = leading;
}
-static void pdf_run_Tf(pdf_csi *csi, void *state)
+static void pdf_run_Tf(fz_context *ctx, pdf_processor *proc, const char *name, pdf_font_desc *font, float size)
{
- pdf_run_state *pr = (pdf_run_state *)state;
- fz_context *ctx = csi->ctx;
- pdf_obj *rdb = csi->rdb;
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
pdf_gstate *gstate = pr->gstate + pr->gtop;
- pdf_obj *dict;
- pdf_obj *obj;
-
- gstate->size = csi->stack[0];
if (gstate->font)
pdf_drop_font(ctx, gstate->font);
- gstate->font = NULL;
-
- dict = pdf_dict_gets(ctx, rdb, "Font");
- if (!dict)
- fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find Font dictionary");
-
- obj = pdf_dict_gets(ctx, dict, csi->name);
- if (!obj)
- fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find font resource: '%s'", csi->name);
-
- gstate->font = load_font_or_hail_mary(csi, rdb, obj, pr->nested_depth);
+ gstate->font = pdf_keep_font(ctx, font);
+ gstate->size = size;
}
-static void pdf_run_Tr(pdf_csi *csi, void *state)
+static void pdf_run_Tr(fz_context *ctx, pdf_processor *proc, int render)
{
- pdf_run_state *pr = (pdf_run_state *)state;
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
pdf_gstate *gstate = pr->gstate + pr->gtop;
-
- gstate->render = csi->stack[0];
+ gstate->render = render;
}
-static void pdf_run_Ts(pdf_csi *csi, void *state)
+static void pdf_run_Ts(fz_context *ctx, pdf_processor *proc, float rise)
{
- pdf_run_state *pr = (pdf_run_state *)state;
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
pdf_gstate *gstate = pr->gstate + pr->gtop;
-
- gstate->rise = csi->stack[0];
+ gstate->rise = rise;
}
-static void pdf_run_Td(pdf_csi *csi, void *state)
-{
- pdf_run_state *pr = (pdf_run_state *)state;
+/* text positioning */
- fz_pre_translate(&pr->tlm, csi->stack[0], csi->stack[1]);
+static void pdf_run_Td(fz_context *ctx, pdf_processor *proc, float tx, float ty)
+{
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ fz_pre_translate(&pr->tlm, tx, ty);
pr->tm = pr->tlm;
}
-static void pdf_run_TD(pdf_csi *csi, void *state)
+static void pdf_run_TD(fz_context *ctx, pdf_processor *proc, float tx, float ty)
{
- pdf_run_state *pr = (pdf_run_state *)state;
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
pdf_gstate *gstate = pr->gstate + pr->gtop;
-
- gstate->leading = -csi->stack[1];
- fz_pre_translate(&pr->tlm, csi->stack[0], csi->stack[1]);
+ gstate->leading = -ty;
+ fz_pre_translate(&pr->tlm, tx, ty);
pr->tm = pr->tlm;
}
-static void pdf_run_Tm(pdf_csi *csi, void *state)
+static void pdf_run_Tm(fz_context *ctx, pdf_processor *proc, float a, float b, float c, float d, float e, float f)
{
- pdf_run_state *pr = (pdf_run_state *)state;
-
- pr->tm.a = csi->stack[0];
- pr->tm.b = csi->stack[1];
- pr->tm.c = csi->stack[2];
- pr->tm.d = csi->stack[3];
- pr->tm.e = csi->stack[4];
- pr->tm.f = csi->stack[5];
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ pr->tm.a = a;
+ pr->tm.b = b;
+ pr->tm.c = c;
+ pr->tm.d = d;
+ pr->tm.e = e;
+ pr->tm.f = f;
pr->tlm = pr->tm;
}
-static void pdf_run_Tstar(pdf_csi *csi, void *state)
+static void pdf_run_Tstar(fz_context *ctx, pdf_processor *proc)
{
- pdf_run_state *pr = (pdf_run_state *)state;
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
pdf_gstate *gstate = pr->gstate + pr->gtop;
-
fz_pre_translate(&pr->tlm, 0, -gstate->leading);
pr->tm = pr->tlm;
}
-static void pdf_run_Tj(pdf_csi *csi, void *state)
-{
- pdf_run_state *pr = (pdf_run_state *)state;
-
- if (csi->string_len)
- pdf_show_string(csi, pr, csi->string, csi->string_len);
- else
- pdf_show_text(csi, pr, csi->obj);
-}
-
-static void pdf_run_TJ(pdf_csi *csi, void *state)
-{
- pdf_run_state *pr = (pdf_run_state *)state;
-
- if (csi->string_len)
- pdf_show_string(csi, pr, csi->string, csi->string_len);
- else
- pdf_show_text(csi, pr, csi->obj);
-}
-
-static void pdf_run_W(pdf_csi *csi, void *state)
-{
- pdf_run_state *pr = (pdf_run_state *)state;
+/* text showing */
- pr->clip = 1;
- pr->clip_even_odd = 0;
-}
-
-static void pdf_run_Wstar(pdf_csi *csi, void *state)
+static void pdf_run_TJ(fz_context *ctx, pdf_processor *proc, pdf_obj *obj)
{
- pdf_run_state *pr = (pdf_run_state *)state;
-
- pr->clip = 1;
- pr->clip_even_odd = 1;
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ pdf_show_text(ctx, pr, obj);
}
-static void pdf_run_b(pdf_csi *csi, void *state)
+static void pdf_run_Tj(fz_context *ctx, pdf_processor *proc, char *string, int string_len)
{
- pdf_run_state *pr = (pdf_run_state *)state;
-
- pdf_show_path(csi, pr, 1, 1, 1, 0);
-}
-
-static void pdf_run_bstar(pdf_csi *csi, void *state)
-{
- pdf_run_state *pr = (pdf_run_state *)state;
-
- pdf_show_path(csi, pr, 1, 1, 1, 1);
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ pdf_show_string(ctx, pr, (unsigned char *)string, string_len);
}
-static void pdf_run_c(pdf_csi *csi, void *state)
+static void pdf_run_squote(fz_context *ctx, pdf_processor *proc, char *string, int string_len)
{
- pdf_run_state *pr = (pdf_run_state *)state;
- float a, b, c, d, e, f;
-
- a = csi->stack[0];
- b = csi->stack[1];
- c = csi->stack[2];
- d = csi->stack[3];
- e = csi->stack[4];
- f = csi->stack[5];
- fz_curveto(csi->ctx, pr->path, a, b, c, d, e, f);
-}
-
-static void pdf_run_cm(pdf_csi *csi, void *state)
-{
- pdf_run_state *pr = (pdf_run_state *)state;
- pdf_gstate *gstate;
- fz_matrix m;
-
- gstate = pdf_flush_text(csi, pr);
- m.a = csi->stack[0];
- m.b = csi->stack[1];
- m.c = csi->stack[2];
- m.d = csi->stack[3];
- m.e = csi->stack[4];
- m.f = csi->stack[5];
-
- fz_concat(&gstate->ctm, &m, &gstate->ctm);
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ pdf_gstate *gstate = pr->gstate + pr->gtop;
+ fz_pre_translate(&pr->tlm, 0, -gstate->leading);
+ pr->tm = pr->tlm;
+ pdf_show_string(ctx, pr, (unsigned char*)string, string_len);
}
-static void pdf_run_d(pdf_csi *csi, void *state)
+static void pdf_run_dquote(fz_context *ctx, pdf_processor *proc, float aw, float ac, char *string, int string_len)
{
- fz_context *ctx = csi->ctx;
- pdf_run_state *pr = (pdf_run_state *)state;
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
pdf_gstate *gstate = pr->gstate + pr->gtop;
- pdf_obj *array;
- int i;
- int len;
-
- array = csi->obj;
- len = pdf_array_len(ctx, array);
- gstate->stroke_state = fz_unshare_stroke_state_with_dash_len(csi->ctx, gstate->stroke_state, len);
- gstate->stroke_state->dash_len = len;
- for (i = 0; i < len; i++)
- gstate->stroke_state->dash_list[i] = pdf_to_real(ctx, pdf_array_get(ctx, array, i));
- gstate->stroke_state->dash_phase = csi->stack[0];
+ gstate->word_space = aw;
+ gstate->char_space = ac;
+ fz_pre_translate(&pr->tlm, 0, -gstate->leading);
+ pr->tm = pr->tlm;
+ pdf_show_string(ctx, pr, (unsigned char*)string, string_len);
}
-static void pdf_run_d0(pdf_csi *csi, void *state)
-{
- pdf_run_state *pr = (pdf_run_state *)state;
+/* type 3 fonts */
+static void pdf_run_d0(fz_context *ctx, pdf_processor *proc, float wx, float wy)
+{
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
if (pr->nested_depth > 1)
return;
pr->dev->flags |= FZ_DEVFLAG_COLOR;
}
-static void pdf_run_d1(pdf_csi *csi, void *state)
+static void pdf_run_d1(fz_context *ctx, pdf_processor *proc, float wx, float wy, float llx, float lly, float urx, float ury)
{
- pdf_run_state *pr = (pdf_run_state *)state;
-
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
if (pr->nested_depth > 1)
return;
pr->dev->flags |= FZ_DEVFLAG_MASK | FZ_DEVFLAG_BBOX_DEFINED;
@@ -2376,266 +1767,195 @@ static void pdf_run_d1(pdf_csi *csi, void *state)
FZ_DEVFLAG_LINEJOIN_UNDEFINED |
FZ_DEVFLAG_MITERLIMIT_UNDEFINED |
FZ_DEVFLAG_LINEWIDTH_UNDEFINED);
-
- pr->dev->d1_rect.x0 = fz_min(csi->stack[2], csi->stack[4]);
- pr->dev->d1_rect.y0 = fz_min(csi->stack[3], csi->stack[5]);
- pr->dev->d1_rect.x1 = fz_max(csi->stack[2], csi->stack[4]);
- pr->dev->d1_rect.y1 = fz_max(csi->stack[3], csi->stack[5]);
+ pr->dev->d1_rect.x0 = fz_min(llx, urx);
+ pr->dev->d1_rect.y0 = fz_min(lly, ury);
+ pr->dev->d1_rect.x1 = fz_max(llx, urx);
+ pr->dev->d1_rect.y1 = fz_max(lly, ury);
}
-static void pdf_run_f(pdf_csi *csi, void *state)
-{
- pdf_run_state *pr = (pdf_run_state *)state;
-
- pdf_show_path(csi, pr, 0, 1, 0, 0);
-}
+/* color */
-static void pdf_run_fstar(pdf_csi *csi, void *state)
+static void pdf_run_CS(fz_context *ctx, pdf_processor *proc, const char *name, fz_colorspace *colorspace)
{
- pdf_run_state *pr = (pdf_run_state *)state;
-
- pdf_show_path(csi, pr, 0, 1, 0, 1);
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ pr->dev->flags &= ~FZ_DEVFLAG_STROKECOLOR_UNDEFINED;
+ if (!strcmp(name, "Pattern"))
+ pdf_set_pattern(ctx, pr, PDF_STROKE, NULL, NULL);
+ else
+ pdf_set_colorspace(ctx, pr, PDF_STROKE, colorspace);
}
-static void pdf_run_g(pdf_csi *csi, void *state)
+static void pdf_run_cs(fz_context *ctx, pdf_processor *proc, const char *name, fz_colorspace *colorspace)
{
- pdf_run_state *pr = (pdf_run_state *)state;
-
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
pr->dev->flags &= ~FZ_DEVFLAG_FILLCOLOR_UNDEFINED;
- pdf_set_colorspace(csi, pr, PDF_FILL, fz_device_gray(csi->ctx));
- pdf_set_color(csi, pr, PDF_FILL, csi->stack);
+ if (!strcmp(name, "Pattern"))
+ pdf_set_pattern(ctx, pr, PDF_FILL, NULL, NULL);
+ else
+ pdf_set_colorspace(ctx, pr, PDF_FILL, colorspace);
}
-static void pdf_run_gs(pdf_csi *csi, void *state)
+static void pdf_run_SC_color(fz_context *ctx, pdf_processor *proc, int n, float *color)
{
- pdf_run_state *pr = (pdf_run_state *)state;
- pdf_obj *dict;
- pdf_obj *obj;
- fz_context *ctx = csi->ctx;
- pdf_obj *rdb = csi->rdb;
-
- dict = pdf_dict_gets(ctx, rdb, "ExtGState");
- if (!dict)
- fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find ExtGState dictionary");
-
- obj = pdf_dict_gets(ctx, dict, csi->name);
- if (!obj)
- fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find extgstate resource '%s'", csi->name);
-
- pdf_run_extgstate(csi, pr, rdb, obj);
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ pr->dev->flags &= ~FZ_DEVFLAG_STROKECOLOR_UNDEFINED;
+ pdf_set_color(ctx, pr, PDF_STROKE, color);
}
-static void pdf_run_h(pdf_csi *csi, void *state)
+static void pdf_run_sc_color(fz_context *ctx, pdf_processor *proc, int n, float *color)
{
- pdf_run_state *pr = (pdf_run_state *)state;
-
- fz_closepath(csi->ctx, pr->path);
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ pr->dev->flags &= ~FZ_DEVFLAG_FILLCOLOR_UNDEFINED;
+ pdf_set_color(ctx, pr, PDF_FILL, color);
}
-static void pdf_run_i(pdf_csi *csi, void *state)
+static void pdf_run_SC_pattern(fz_context *ctx, pdf_processor *proc, const char *name, pdf_pattern *pat, int n, float *color)
{
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ pr->dev->flags &= ~FZ_DEVFLAG_STROKECOLOR_UNDEFINED;
+ pdf_set_pattern(ctx, pr, PDF_STROKE, pat, color);
}
-static void pdf_run_j(pdf_csi *csi, void *state)
+static void pdf_run_sc_pattern(fz_context *ctx, pdf_processor *proc, const char *name, pdf_pattern *pat, int n, float *color)
{
- pdf_run_state *pr = (pdf_run_state *)state;
- pdf_gstate *gstate = pr->gstate + pr->gtop;
-
- pr->dev->flags &= ~FZ_DEVFLAG_LINEJOIN_UNDEFINED;
- gstate->stroke_state = fz_unshare_stroke_state(csi->ctx, gstate->stroke_state);
- gstate->stroke_state->linejoin = csi->stack[0];
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ pr->dev->flags &= ~FZ_DEVFLAG_FILLCOLOR_UNDEFINED;
+ pdf_set_pattern(ctx, pr, PDF_FILL, pat, color);
}
-static void pdf_run_k(pdf_csi *csi, void *state)
+static void pdf_run_SC_shade(fz_context *ctx, pdf_processor *proc, const char *name, fz_shade *shade)
{
- pdf_run_state *pr = (pdf_run_state *)state;
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ pr->dev->flags &= ~FZ_DEVFLAG_STROKECOLOR_UNDEFINED;
+ pdf_set_shade(ctx, pr, PDF_STROKE, shade);
+}
+static void pdf_run_sc_shade(fz_context *ctx, pdf_processor *proc, const char *name, fz_shade *shade)
+{
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
pr->dev->flags &= ~FZ_DEVFLAG_FILLCOLOR_UNDEFINED;
- pdf_set_colorspace(csi, pr, PDF_FILL, fz_device_cmyk(csi->ctx));
- pdf_set_color(csi, pr, PDF_FILL, csi->stack);
+ pdf_set_shade(ctx, pr, PDF_FILL, shade);
}
-static void pdf_run_l(pdf_csi *csi, void *state)
+static void pdf_run_G(fz_context *ctx, pdf_processor *proc, float g)
{
- pdf_run_state *pr = (pdf_run_state *)state;
- float a, b;
-
- a = csi->stack[0];
- b = csi->stack[1];
- fz_lineto(csi->ctx, pr->path, a, b);
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ pr->dev->flags &= ~FZ_DEVFLAG_STROKECOLOR_UNDEFINED;
+ pdf_set_colorspace(ctx, pr, PDF_STROKE, fz_device_gray(ctx));
+ pdf_set_color(ctx, pr, PDF_STROKE, &g);
}
-static void pdf_run_m(pdf_csi *csi, void *state)
+static void pdf_run_g(fz_context *ctx, pdf_processor *proc, float g)
{
- pdf_run_state *pr = (pdf_run_state *)state;
- float a, b;
-
- a = csi->stack[0];
- b = csi->stack[1];
- fz_moveto(csi->ctx, pr->path, a, b);
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ pr->dev->flags &= ~FZ_DEVFLAG_FILLCOLOR_UNDEFINED;
+ pdf_set_colorspace(ctx, pr, PDF_FILL, fz_device_gray(ctx));
+ pdf_set_color(ctx, pr, PDF_FILL, &g);
}
-static void pdf_run_n(pdf_csi *csi, void *state)
+static void pdf_run_K(fz_context *ctx, pdf_processor *proc, float c, float m, float y, float k)
{
- pdf_run_state *pr = (pdf_run_state *)state;
-
- pdf_show_path(csi, pr, 0, 0, 0, 0);
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ float color[4] = {c, m, y, k};
+ pr->dev->flags &= ~FZ_DEVFLAG_STROKECOLOR_UNDEFINED;
+ pdf_set_colorspace(ctx, pr, PDF_STROKE, fz_device_cmyk(ctx));
+ pdf_set_color(ctx, pr, PDF_STROKE, color);
}
-static void pdf_run_q(pdf_csi *csi, void *state)
+static void pdf_run_k(fz_context *ctx, pdf_processor *proc, float c, float m, float y, float k)
{
- pdf_run_state *pr = (pdf_run_state *)state;
-
- pdf_gsave(pr);
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ float color[4] = {c, m, y, k};
+ pr->dev->flags &= ~FZ_DEVFLAG_FILLCOLOR_UNDEFINED;
+ pdf_set_colorspace(ctx, pr, PDF_FILL, fz_device_cmyk(ctx));
+ pdf_set_color(ctx, pr, PDF_FILL, color);
}
-static void pdf_run_re(pdf_csi *csi, void *state)
+static void pdf_run_RG(fz_context *ctx, pdf_processor *proc, float r, float g, float b)
{
- pdf_run_state *pr = (pdf_run_state *)state;
- fz_context *ctx = csi->ctx;
- float x, y, w, h;
-
- x = csi->stack[0];
- y = csi->stack[1];
- w = csi->stack[2];
- h = csi->stack[3];
-
- fz_moveto(ctx, pr->path, x, y);
- fz_lineto(ctx, pr->path, x + w, y);
- fz_lineto(ctx, pr->path, x + w, y + h);
- fz_lineto(ctx, pr->path, x, y + h);
- fz_closepath(ctx, pr->path);
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ float color[3] = {r, g, b};
+ pr->dev->flags &= ~FZ_DEVFLAG_STROKECOLOR_UNDEFINED;
+ pdf_set_colorspace(ctx, pr, PDF_STROKE, fz_device_rgb(ctx));
+ pdf_set_color(ctx, pr, PDF_STROKE, color);
}
-static void pdf_run_rg(pdf_csi *csi, void *state)
+static void pdf_run_rg(fz_context *ctx, pdf_processor *proc, float r, float g, float b)
{
- pdf_run_state *pr = (pdf_run_state *)state;
-
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ float color[3] = {r, g, b};
pr->dev->flags &= ~FZ_DEVFLAG_FILLCOLOR_UNDEFINED;
- pdf_set_colorspace(csi, pr, PDF_FILL, fz_device_rgb(csi->ctx));
- pdf_set_color(csi, pr, PDF_FILL, csi->stack);
+ pdf_set_colorspace(ctx, pr, PDF_FILL, fz_device_rgb(ctx));
+ pdf_set_color(ctx, pr, PDF_FILL, color);
}
-static void pdf_run_ri(pdf_csi *csi, void *state)
+/* shadings, images, xobjects */
+
+static void pdf_run_BI(fz_context *ctx, pdf_processor *proc, fz_image *image)
{
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ if ((pr->dev->hints & FZ_IGNORE_IMAGE) == 0)
+ pdf_show_image(ctx, pr, image);
}
-static void pdf_run_s(pdf_csi *csi, void *state)
+static void pdf_run_sh(fz_context *ctx, pdf_processor *proc, const char *name, fz_shade *shade)
{
- pdf_run_state *pr = (pdf_run_state *)state;
-
- pdf_show_path(csi, pr, 1, 0, 1, 0);
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ if ((pr->dev->hints & FZ_IGNORE_SHADE) == 0)
+ pdf_show_shade(ctx, pr, shade);
}
-static void pdf_run_sh(pdf_csi *csi, void *state)
+static void pdf_run_Do_image(fz_context *ctx, pdf_processor *proc, const char *name, fz_image *image)
{
- pdf_run_state *pr = (pdf_run_state *)state;
- fz_context *ctx = csi->ctx;
- pdf_obj *rdb = csi->rdb;
- pdf_obj *dict;
- pdf_obj *obj;
- fz_shade *shd;
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
+ if ((pr->dev->hints & FZ_IGNORE_IMAGE) == 0)
+ pdf_show_image(ctx, pr, image);
+}
- dict = pdf_dict_gets(ctx, rdb, "Shading");
- if (!dict)
- fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find shading dictionary");
+static void pdf_run_Do_form(fz_context *ctx, pdf_processor *proc, const char *name, pdf_xobject *xobj, pdf_obj *page_resources)
+{
+ pdf_run_xobject(ctx, (pdf_run_processor*)proc, xobj, page_resources, &fz_identity);
+}
- obj = pdf_dict_gets(ctx, dict, csi->name);
- if (!obj)
- fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find shading resource: '%s'", csi->name);
+/* marked content */
- if ((pr->dev->hints & FZ_IGNORE_SHADE) == 0)
- {
- shd = pdf_load_shading(ctx, csi->doc, obj);
-
- fz_try(ctx)
- {
- pdf_show_shade(csi, pr, shd);
- }
- fz_always(ctx)
- {
- fz_drop_shade(ctx, shd);
- }
- fz_catch(ctx)
- {
- fz_rethrow(ctx);
- }
- }
+static void pdf_run_MP(fz_context *ctx, pdf_processor *proc, const char *tag)
+{
}
-static void pdf_run_v(pdf_csi *csi, void *state)
+static void pdf_run_DP(fz_context *ctx, pdf_processor *proc, const char *tag, pdf_obj *properties)
{
- pdf_run_state *pr = (pdf_run_state *)state;
- float a, b, c, d;
-
- a = csi->stack[0];
- b = csi->stack[1];
- c = csi->stack[2];
- d = csi->stack[3];
- fz_curvetov(csi->ctx, pr->path, a, b, c, d);
}
-static void pdf_run_w(pdf_csi *csi, void *state)
+static void pdf_run_BMC(fz_context *ctx, pdf_processor *proc, const char *tag)
{
- pdf_run_state *pr = (pdf_run_state *)state;
- pdf_gstate *gstate;
-
- gstate = pdf_flush_text(csi, pr); /* linewidth affects stroked text rendering mode */
- pr->dev->flags &= ~FZ_DEVFLAG_LINEWIDTH_UNDEFINED;
- gstate->stroke_state = fz_unshare_stroke_state(csi->ctx, gstate->stroke_state);
- gstate->stroke_state->linewidth = csi->stack[0];
}
-static void pdf_run_y(pdf_csi *csi, void *state)
+static void pdf_run_BDC(fz_context *ctx, pdf_processor *proc, const char *tag, pdf_obj *properties)
{
- pdf_run_state *pr = (pdf_run_state *)state;
- float a, b, c, d;
-
- a = csi->stack[0];
- b = csi->stack[1];
- c = csi->stack[2];
- d = csi->stack[3];
- fz_curvetoy(csi->ctx, pr->path, a, b, c, d);
}
-static void pdf_run_squote(pdf_csi *csi, void *state)
+static void pdf_run_EMC(fz_context *ctx, pdf_processor *proc)
{
- pdf_run_state *pr = (pdf_run_state *)state;
- pdf_gstate *gstate = pr->gstate + pr->gtop;
+}
- fz_pre_translate(&pr->tlm, 0, -gstate->leading);
- pr->tm = pr->tlm;
+/* compatibility */
- if (csi->string_len)
- pdf_show_string(csi, pr, csi->string, csi->string_len);
- else
- pdf_show_text(csi, pr, csi->obj);
+static void pdf_run_BX(fz_context *ctx, pdf_processor *proc)
+{
}
-static void pdf_run_dquote(pdf_csi *csi, void *state)
+static void pdf_run_EX(fz_context *ctx, pdf_processor *proc)
{
- pdf_run_state *pr = (pdf_run_state *)state;
- pdf_gstate *gstate = pr->gstate + pr->gtop;
-
- gstate->word_space = csi->stack[0];
- gstate->char_space = csi->stack[1];
-
- fz_pre_translate(&pr->tlm, 0, -gstate->leading);
- pr->tm = pr->tlm;
-
- if (csi->string_len)
- pdf_show_string(csi, pr, csi->string, csi->string_len);
- else
- pdf_show_text(csi, pr, csi->obj);
}
-static void free_processor_normal(pdf_csi *csi, void *state)
+static void
+pdf_run_drop_imp(fz_context *ctx, pdf_processor *proc)
{
- fz_context *ctx = csi->ctx;
- pdf_run_state *pr = (pdf_run_state *)state;
+ pdf_run_processor *pr = (pdf_run_processor *)proc;
while (pr->gtop)
- pdf_grestore(pr);
+ pdf_grestore(ctx, pr);
pdf_drop_material(ctx, &pr->gstate[0].fill);
pdf_drop_material(ctx, &pr->gstate[0].stroke);
@@ -2648,218 +1968,172 @@ static void free_processor_normal(pdf_csi *csi, void *state)
while (pr->gstate[0].clip_depth--)
fz_pop_clip(ctx, pr->dev);
- if (pr->path) fz_drop_path(ctx, pr->path);
- if (pr->text) fz_drop_text(ctx, pr->text);
+ fz_drop_path(ctx, pr->path);
+ fz_drop_text(ctx, pr->text);
fz_free(ctx, pr->gstate);
- fz_free(ctx, pr);
-}
-
-static void
-process_annot(pdf_csi *csi, void *state, pdf_obj *resources, pdf_annot *annot)
-{
- pdf_run_state *pr = (pdf_run_state *)state;
- fz_context *ctx = pr->ctx;
- int flags;
-
- if (pdf_is_hidden_ocg(pdf_dict_gets(ctx, annot->obj, "OC"), csi, pr, resources))
- return;
-
- flags = pdf_to_int(ctx, pdf_dict_gets(ctx, annot->obj, "F"));
- if (!strcmp(pr->event, "Print") && !(flags & (1 << 2))) /* Print */
- return;
- if (!strcmp(pr->event, "View") && (flags & (1 << 5))) /* NoView */
- return;
-
- fz_try(ctx)
- {
- /* We need to save an extra level here to allow for level 0
- * to be the 'parent' gstate level. */
- pdf_gsave(pr);
- run_xobject(csi, state, resources, annot->ap, &annot->matrix);
- }
- fz_catch(ctx)
- {
- while (pr->gtop > 0)
- pdf_grestore(pr);
- fz_rethrow(ctx);
- }
-}
-
-static void
-process_stream(pdf_csi *csi, void *state, pdf_lexbuf *buf)
-{
- pdf_run_state *pr = (pdf_run_state *)state;
- fz_context *ctx = pr->ctx;
- int save_gbot;
-
- save_gbot = pr->gbot;
- pr->gbot = pr->gtop;
- fz_try(ctx)
- {
- pdf_process_stream(csi, buf);
- }
- fz_always(ctx)
- {
- while (pr->gtop > pr->gbot)
- pdf_grestore(pr);
- pr->gbot = save_gbot;
- }
- fz_catch(ctx)
- {
- fz_rethrow(ctx);
- }
}
-static void
-process_contents(pdf_csi *csi, void *state, pdf_obj *resources, pdf_obj *contents)
-{
- pdf_run_state *pr = (pdf_run_state *)state;
- fz_context *ctx = pr->ctx;
+pdf_processor *
+pdf_new_run_processor(fz_context *ctx, fz_device *dev, const fz_matrix *ctm, const char *event, pdf_gstate *gstate, int nested)
+{
+ pdf_run_processor *proc = pdf_new_processor(ctx, sizeof *proc);
+ {
+ proc->super.event = event;
+
+ proc->super.drop_imp = pdf_run_drop_imp;
+
+ /* general graphics state */
+ proc->super.op_w = pdf_run_w;
+ proc->super.op_j = pdf_run_j;
+ proc->super.op_J = pdf_run_J;
+ proc->super.op_M = pdf_run_M;
+ proc->super.op_d = pdf_run_d;
+ proc->super.op_ri = pdf_run_ri;
+ proc->super.op_i = pdf_run_i;
+ proc->super.op_gs_begin = pdf_run_gs_begin;
+ proc->super.op_gs_end = pdf_run_gs_end;
+
+ /* transparency graphics state */
+ proc->super.op_gs_BM = pdf_run_gs_BM;
+ proc->super.op_gs_CA = pdf_run_gs_CA;
+ proc->super.op_gs_ca = pdf_run_gs_ca;
+ proc->super.op_gs_SMask = pdf_run_gs_SMask;
+
+ /* special graphics state */
+ proc->super.op_q = pdf_run_q;
+ proc->super.op_Q = pdf_run_Q;
+ proc->super.op_cm = pdf_run_cm;
+
+ /* path construction */
+ proc->super.op_m = pdf_run_m;
+ proc->super.op_l = pdf_run_l;
+ proc->super.op_c = pdf_run_c;
+ proc->super.op_v = pdf_run_v;
+ proc->super.op_y = pdf_run_y;
+ proc->super.op_h = pdf_run_h;
+ proc->super.op_re = pdf_run_re;
+
+ /* path painting */
+ proc->super.op_S = pdf_run_S;
+ proc->super.op_s = pdf_run_s;
+ proc->super.op_F = pdf_run_F;
+ proc->super.op_f = pdf_run_f;
+ proc->super.op_fstar = pdf_run_fstar;
+ proc->super.op_B = pdf_run_B;
+ proc->super.op_Bstar = pdf_run_Bstar;
+ proc->super.op_b = pdf_run_b;
+ proc->super.op_bstar = pdf_run_bstar;
+ proc->super.op_n = pdf_run_n;
+
+ /* clipping paths */
+ proc->super.op_W = pdf_run_W;
+ proc->super.op_Wstar = pdf_run_Wstar;
+
+ /* text objects */
+ proc->super.op_BT = pdf_run_BT;
+ proc->super.op_ET = pdf_run_ET;
+
+ /* text state */
+ proc->super.op_Tc = pdf_run_Tc;
+ proc->super.op_Tw = pdf_run_Tw;
+ proc->super.op_Tz = pdf_run_Tz;
+ proc->super.op_TL = pdf_run_TL;
+ proc->super.op_Tf = pdf_run_Tf;
+ proc->super.op_Tr = pdf_run_Tr;
+ proc->super.op_Ts = pdf_run_Ts;
+
+ /* text positioning */
+ proc->super.op_Td = pdf_run_Td;
+ proc->super.op_TD = pdf_run_TD;
+ proc->super.op_Tm = pdf_run_Tm;
+ proc->super.op_Tstar = pdf_run_Tstar;
+
+ /* text showing */
+ proc->super.op_TJ = pdf_run_TJ;
+ proc->super.op_Tj = pdf_run_Tj;
+ proc->super.op_squote = pdf_run_squote;
+ proc->super.op_dquote = pdf_run_dquote;
+
+ /* type 3 fonts */
+ proc->super.op_d0 = pdf_run_d0;
+ proc->super.op_d1 = pdf_run_d1;
+
+ /* color */
+ proc->super.op_CS = pdf_run_CS;
+ proc->super.op_cs = pdf_run_cs;
+ proc->super.op_SC_color = pdf_run_SC_color;
+ proc->super.op_sc_color = pdf_run_sc_color;
+ proc->super.op_SC_pattern = pdf_run_SC_pattern;
+ proc->super.op_sc_pattern = pdf_run_sc_pattern;
+ proc->super.op_SC_shade = pdf_run_SC_shade;
+ proc->super.op_sc_shade = pdf_run_sc_shade;
+
+ proc->super.op_G = pdf_run_G;
+ proc->super.op_g = pdf_run_g;
+ proc->super.op_RG = pdf_run_RG;
+ proc->super.op_rg = pdf_run_rg;
+ proc->super.op_K = pdf_run_K;
+ proc->super.op_k = pdf_run_k;
+
+ /* shadings, images, xobjects */
+ proc->super.op_BI = pdf_run_BI;
+ proc->super.op_sh = pdf_run_sh;
+ proc->super.op_Do_image = pdf_run_Do_image;
+ proc->super.op_Do_form = pdf_run_Do_form;
+
+ /* marked content */
+ proc->super.op_MP = pdf_run_MP;
+ proc->super.op_DP = pdf_run_DP;
+ proc->super.op_BMC = pdf_run_BMC;
+ proc->super.op_BDC = pdf_run_BDC;
+ proc->super.op_EMC = pdf_run_EMC;
+
+ /* compatibility */
+ proc->super.op_BX = pdf_run_BX;
+ proc->super.op_EX = pdf_run_EX;
+ }
+
+ proc->dev = dev;
+
+ proc->nested_depth = nested;
+
+ proc->path = NULL;
+ proc->clip = 0;
+ proc->clip_even_odd = 0;
+
+ proc->text = NULL;
+ proc->tlm = fz_identity;
+ proc->tm = fz_identity;
+ proc->text_mode = 0;
+ proc->accumulate = 1;
fz_try(ctx)
{
- /* We need to save an extra level here to allow for level 0
- * to be the 'parent' gstate level. */
- pdf_gsave(pr);
- pdf_process_contents_object(csi, resources, contents);
- }
- fz_always(ctx)
- {
- while (pr->gtop > 0)
- pdf_grestore(pr);
- }
- fz_catch(ctx)
- {
- fz_rethrow(ctx);
- }
-}
+ proc->path = fz_new_path(ctx);
-const pdf_processor pdf_processor_normal =
-{
- {
- pdf_run_dquote,
- pdf_run_squote,
- pdf_run_B,
- pdf_run_Bstar,
- pdf_run_BDC,
- pdf_run_BI,
- pdf_run_BMC,
- pdf_run_BT,
- pdf_run_BX,
- pdf_run_CS,
- pdf_run_DP,
- pdf_run_EMC,
- pdf_run_ET,
- pdf_run_EX,
- pdf_run_F,
- pdf_run_G,
- pdf_run_J,
- pdf_run_K,
- pdf_run_M,
- pdf_run_MP,
- pdf_run_Q,
- pdf_run_RG,
- pdf_run_S,
- pdf_run_SC,
- pdf_run_SC, /* SCN */
- pdf_run_Tstar,
- pdf_run_TD,
- pdf_run_TJ,
- pdf_run_TL,
- pdf_run_Tc,
- pdf_run_Td,
- pdf_run_Tj,
- pdf_run_Tm,
- pdf_run_Tr,
- pdf_run_Ts,
- pdf_run_Tw,
- pdf_run_Tz,
- pdf_run_W,
- pdf_run_Wstar,
- pdf_run_b,
- pdf_run_bstar,
- pdf_run_c,
- pdf_run_cm,
- pdf_run_cs,
- pdf_run_d,
- pdf_run_d0,
- pdf_run_d1,
- pdf_run_f,
- pdf_run_fstar,
- pdf_run_g,
- pdf_run_h,
- pdf_run_i,
- pdf_run_j,
- pdf_run_k,
- pdf_run_l,
- pdf_run_m,
- pdf_run_n,
- pdf_run_q,
- pdf_run_re,
- pdf_run_rg,
- pdf_run_ri,
- pdf_run_s,
- pdf_run_sc,
- pdf_run_sc, /* scn */
- pdf_run_v,
- pdf_run_w,
- pdf_run_y,
- pdf_run_Do,
- pdf_run_Tf,
- pdf_run_gs,
- pdf_run_sh,
- free_processor_normal
- },
- process_annot,
- process_stream,
- process_contents
-};
-
-pdf_process *pdf_init_process_run(fz_context *ctx, pdf_process *process, fz_device *dev, const fz_matrix *ctm, const char *event, pdf_gstate *gstate, int nested)
-{
- pdf_run_state *pr;
+ proc->gcap = 64;
+ proc->gstate = fz_malloc_array(ctx, proc->gcap, sizeof(pdf_gstate));
- pr = fz_malloc_struct(ctx, pdf_run_state);
- fz_try(ctx)
- {
- pr->ctx = ctx;
- pr->dev = dev;
- pr->in_hidden_ocg = 0;
- pr->event = event;
-
- pr->path = fz_new_path(ctx);
- pr->clip = 0;
- pr->clip_even_odd = 0;
-
- pr->text = NULL;
- pr->tlm = fz_identity;
- pr->tm = fz_identity;
- pr->text_mode = 0;
- pr->accumulate = 1;
-
- pr->gcap = 64;
- pr->gstate = fz_malloc_array(ctx, pr->gcap, sizeof(pdf_gstate));
-
- pr->nested_depth = nested;
- pdf_init_gstate(ctx, &pr->gstate[0], ctm);
+ pdf_init_gstate(ctx, &proc->gstate[0], ctm);
if (gstate)
{
- pdf_copy_gstate(ctx, &pr->gstate[0], gstate);
- pr->gstate[0].ctm = *ctm;
+ pdf_copy_gstate(ctx, &proc->gstate[0], gstate);
+ proc->gstate[0].ctm = *ctm;
}
- pr->gtop = 0;
- pr->gbot = 0;
- pr->gparent = 0;
+ proc->gtop = 0;
+ proc->gbot = 0;
+ proc->gparent = 0;
}
fz_catch(ctx)
{
- fz_drop_path(ctx, pr->path);
- fz_free(ctx, pr);
+ fz_drop_path(ctx, proc->path);
+ fz_free(ctx, proc);
fz_rethrow(ctx);
}
- process->state = pr;
- process->processor = &pdf_processor_normal;
- return process;
+ /* We need to save an extra level to allow for level 0 to be the parent gstate level. */
+ pdf_gsave(ctx, proc);
+
+ return (pdf_processor*)proc;
}
diff --git a/source/pdf/pdf-pattern.c b/source/pdf/pdf-pattern.c
index 93fbdd3e..32fd077c 100644
--- a/source/pdf/pdf-pattern.c
+++ b/source/pdf/pdf-pattern.c
@@ -16,7 +16,6 @@ static void
pdf_drop_pattern_imp(fz_context *ctx, fz_storable *pat_)
{
pdf_pattern *pat = (pdf_pattern *)pat_;
-
if (pat->resources)
pdf_drop_obj(ctx, pat->resources);
if (pat->contents)
@@ -45,38 +44,39 @@ pdf_load_pattern(fz_context *ctx, pdf_document *doc, pdf_obj *dict)
pat = fz_malloc_struct(ctx, pdf_pattern);
FZ_INIT_STORABLE(pat, 1, pdf_drop_pattern_imp);
+ pat->document = doc;
pat->resources = NULL;
pat->contents = NULL;
- /* Store pattern now, to avoid possible recursion if objects refer back to this one */
- pdf_store_item(ctx, dict, pat, pdf_pattern_size(pat));
+ fz_try(ctx)
+ {
+ /* Store pattern now, to avoid possible recursion if objects refer back to this one */
+ pdf_store_item(ctx, dict, pat, pdf_pattern_size(pat));
- pat->ismask = pdf_to_int(ctx, pdf_dict_gets(ctx, dict, "PaintType")) == 2;
- pat->xstep = pdf_to_real(ctx, pdf_dict_gets(ctx, dict, "XStep"));
- pat->ystep = pdf_to_real(ctx, pdf_dict_gets(ctx, dict, "YStep"));
+ pat->ismask = pdf_to_int(ctx, pdf_dict_gets(ctx, dict, "PaintType")) == 2;
+ pat->xstep = pdf_to_real(ctx, pdf_dict_gets(ctx, dict, "XStep"));
+ pat->ystep = pdf_to_real(ctx, pdf_dict_gets(ctx, dict, "YStep"));
- obj = pdf_dict_gets(ctx, dict, "BBox");
- pdf_to_rect(ctx, obj, &pat->bbox);
+ obj = pdf_dict_gets(ctx, dict, "BBox");
+ pdf_to_rect(ctx, obj, &pat->bbox);
- obj = pdf_dict_gets(ctx, dict, "Matrix");
- if (obj)
- pdf_to_matrix(ctx, obj, &pat->matrix);
- else
- pat->matrix = fz_identity;
+ obj = pdf_dict_gets(ctx, dict, "Matrix");
+ if (obj)
+ pdf_to_matrix(ctx, obj, &pat->matrix);
+ else
+ pat->matrix = fz_identity;
- pat->resources = pdf_dict_gets(ctx, dict, "Resources");
- if (pat->resources)
- pdf_keep_obj(ctx, pat->resources);
+ pat->resources = pdf_dict_gets(ctx, dict, "Resources");
+ if (pat->resources)
+ pdf_keep_obj(ctx, pat->resources);
- fz_try(ctx)
- {
pat->contents = pdf_keep_obj(ctx, dict);
}
fz_catch(ctx)
{
pdf_remove_item(ctx, pdf_drop_pattern_imp, dict);
pdf_drop_pattern(ctx, pat);
- fz_rethrow_message(ctx, "cannot load pattern stream (%d %d R)", pdf_to_num(ctx, dict), pdf_to_gen(ctx, dict));
+ fz_rethrow_message(ctx, "cannot load pattern (%d %d R)", pdf_to_num(ctx, dict), pdf_to_gen(ctx, dict));
}
return pat;
}
diff --git a/source/pdf/pdf-run.c b/source/pdf/pdf-run.c
index e6f3d5b9..57807cc2 100644
--- a/source/pdf/pdf-run.c
+++ b/source/pdf/pdf-run.c
@@ -1,22 +1,26 @@
-#include "pdf-interpret-imp.h"
+#include "mupdf/pdf.h"
static void
pdf_run_annot_with_usage(fz_context *ctx, pdf_document *doc, pdf_page *page, pdf_annot *annot, fz_device *dev, const fz_matrix *ctm, char *event, fz_cookie *cookie)
{
fz_matrix local_ctm;
- pdf_process process;
+ pdf_processor *proc;
fz_concat(&local_ctm, &page->ctm, ctm);
- pdf_init_process_run(ctx, &process, dev, &local_ctm, event, NULL, 0);
-
- pdf_process_annot(ctx, doc, page, annot, &process, cookie);
+ proc = pdf_new_run_processor(ctx, dev, &local_ctm, event, NULL, 0);
+ fz_try(ctx)
+ pdf_process_annot(ctx, proc, doc, page, annot, cookie);
+ fz_always(ctx)
+ pdf_drop_processor(ctx, proc);
+ fz_catch(ctx)
+ fz_rethrow(ctx);
}
static void pdf_run_page_contents_with_usage(fz_context *ctx, pdf_document *doc, pdf_page *page, fz_device *dev, const fz_matrix *ctm, char *event, fz_cookie *cookie)
{
fz_matrix local_ctm;
- pdf_process process;
+ pdf_processor *proc;
fz_concat(&local_ctm, &page->ctm, ctm);
@@ -26,9 +30,14 @@ static void pdf_run_page_contents_with_usage(fz_context *ctx, pdf_document *doc,
fz_begin_group(ctx, dev, fz_transform_rect(&mediabox, &local_ctm), 1, 0, 0, 1);
}
- pdf_init_process_run(ctx, &process, dev, &local_ctm, event, NULL, 0);
+ proc = pdf_new_run_processor(ctx, dev, &local_ctm, event, NULL, 0);
- pdf_process_stream_object(ctx, doc, page->contents, &process, page->resources, cookie);
+ fz_try(ctx)
+ pdf_process_contents(ctx, proc, doc, page->resources, page->contents, cookie);
+ fz_always(ctx)
+ pdf_drop_processor(ctx, proc);
+ fz_catch(ctx)
+ fz_rethrow(ctx);
if (page->transparency)
fz_end_group(ctx, dev);
@@ -147,12 +156,16 @@ pdf_run_page(fz_context *ctx, pdf_page *page, fz_device *dev, const fz_matrix *c
void
pdf_run_glyph(fz_context *ctx, pdf_document *doc, pdf_obj *resources, fz_buffer *contents, fz_device *dev, const fz_matrix *ctm, void *gstate, int nested_depth)
{
- pdf_process process;
+ pdf_processor *proc;
if (nested_depth > 10)
fz_throw(ctx, FZ_ERROR_GENERIC, "Too many nestings of Type3 glyphs");
- pdf_init_process_run(ctx, &process, dev, ctm, "View", gstate, nested_depth+1);
-
- pdf_process_glyph(ctx, doc, resources, contents, &process);
+ proc = pdf_new_run_processor(ctx, dev, ctm, "View", gstate, nested_depth+1);
+ fz_try(ctx)
+ pdf_process_glyph(ctx, proc, doc, resources, contents);
+ fz_always(ctx)
+ pdf_drop_processor(ctx, proc);
+ fz_catch(ctx)
+ fz_rethrow(ctx);
}
diff --git a/source/pdf/pdf-stream.c b/source/pdf/pdf-stream.c
index 2335e67a..15fdd29a 100644
--- a/source/pdf/pdf-stream.c
+++ b/source/pdf/pdf-stream.c
@@ -620,6 +620,5 @@ pdf_open_contents_stream(fz_context *ctx, pdf_document *doc, pdf_obj *obj)
if (pdf_is_stream(ctx, doc, num, gen))
return pdf_open_image_stream(ctx, doc, num, gen, num, gen, NULL);
- fz_warn(ctx, "pdf object stream missing (%d %d R)", num, gen);
- return NULL;
+ fz_throw(ctx, FZ_ERROR_GENERIC, "pdf object stream missing (%d %d R)", num, gen);
}
diff --git a/source/pdf/pdf-write.c b/source/pdf/pdf-write.c
index ac97e6e4..a9dd7423 100644
--- a/source/pdf/pdf-write.c
+++ b/source/pdf/pdf-write.c
@@ -2408,7 +2408,7 @@ make_hint_stream(fz_context *ctx, pdf_document *doc, pdf_write_options *opts)
fz_try(ctx)
{
make_page_offset_hints(ctx, doc, opts, buf);
- pdf_update_stream(ctx, doc, pdf_load_object(ctx, doc, pdf_xref_len(ctx, doc)-1, 0), buf, 0); // XXX
+ pdf_update_stream(ctx, doc, pdf_load_object(ctx, doc, pdf_xref_len(ctx, doc)-1, 0), buf, 0);
opts->hintstream_len = buf->len;
fz_drop_buffer(ctx, buf);
}
diff --git a/source/pdf/pdf-xobject.c b/source/pdf/pdf-xobject.c
index b9afa857..404616ae 100644
--- a/source/pdf/pdf-xobject.c
+++ b/source/pdf/pdf-xobject.c
@@ -46,6 +46,7 @@ pdf_load_xobject(fz_context *ctx, pdf_document *doc, pdf_obj *dict)
form = fz_malloc_struct(ctx, pdf_xobject);
FZ_INIT_STORABLE(form, 1, pdf_drop_xobject_imp);
+ form->document = doc;
form->resources = NULL;
form->contents = NULL;
form->colorspace = NULL;
@@ -181,6 +182,7 @@ pdf_new_xobject(fz_context *ctx, pdf_document *doc, const fz_rect *bbox, const f
form = fz_malloc_struct(ctx, pdf_xobject);
FZ_INIT_STORABLE(form, 1, pdf_drop_xobject_imp);
+ form->document = doc;
form->resources = NULL;
form->contents = NULL;
form->colorspace = NULL;