summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mupdf/fitz/document.h13
-rw-r--r--include/mupdf/pdf/object.h11
-rw-r--r--include/mupdf/pdf/page.h1
-rw-r--r--source/fitz/document.c7
-rw-r--r--source/pdf/pdf-object.c22
-rw-r--r--source/pdf/pdf-page.c106
-rw-r--r--source/tools/mudraw.c29
7 files changed, 164 insertions, 25 deletions
diff --git a/include/mupdf/fitz/document.h b/include/mupdf/fitz/document.h
index d3b9abd5..95e59632 100644
--- a/include/mupdf/fitz/document.h
+++ b/include/mupdf/fitz/document.h
@@ -178,6 +178,12 @@ typedef int (fz_page_separation_disabled_fn)(fz_context *ctx, fz_page *page, int
*/
typedef fz_separations *(fz_page_separations_fn)(fz_context *ctx, fz_page *page);
+/*
+ fz_page_uses_overprint_fn: Type for a function to retrieve
+ whether or not a given page uses overprint.
+*/
+typedef int (fz_page_uses_overprint_fn)(fz_context *ctx, fz_page *page);
+
typedef void (fz_annot_drop_fn)(fz_context *ctx, fz_annot *annot);
typedef fz_annot *(fz_annot_next_fn)(fz_context *ctx, fz_annot *annot);
typedef fz_rect *(fz_annot_bound_fn)(fz_context *ctx, fz_annot *annot, fz_rect *rect);
@@ -212,6 +218,7 @@ struct fz_page_s
fz_page_control_separation_fn *control_separation;
fz_page_separation_disabled_fn *separation_disabled;
fz_page_separations_fn *separations;
+ fz_page_uses_overprint_fn *overprint;
};
/*
@@ -610,6 +617,12 @@ fz_colorspace *fz_document_output_intent(fz_context *ctx, fz_document *doc);
fz_separations *fz_page_separations(fz_context *ctx, fz_page *page);
/*
+ fz_page_uses_overprint: Find out whether a given page requests
+ overprint.
+*/
+int fz_page_uses_overprint(fz_context *ctx, fz_page *page);
+
+/*
fz_save_gproof: Given a currently open document, create a
gproof skeleton file from that document.
diff --git a/include/mupdf/pdf/object.h b/include/mupdf/pdf/object.h
index 5ceab1f0..285acf4d 100644
--- a/include/mupdf/pdf/object.h
+++ b/include/mupdf/pdf/object.h
@@ -66,8 +66,15 @@ void pdf_unmark_obj(fz_context *ctx, pdf_obj *obj);
/* obj memo functions - allows us to secretly remember "a memo" (a bool) in
* an object, and to read back whether there was a memo, and if so, what it
* was. */
-void pdf_set_obj_memo(fz_context *ctx, pdf_obj *obj, int memo);
-int pdf_obj_memo(fz_context *ctx, pdf_obj *obj, int *memo);
+
+enum
+{
+ PDF_FLAGS_MEMO_BM = 0,
+ PDF_FLAGS_MEMO_OP = 1
+};
+
+void pdf_set_obj_memo(fz_context *ctx, pdf_obj *obj, int bit, int memo);
+int pdf_obj_memo(fz_context *ctx, pdf_obj *obj, int bit, int *memo);
/* obj dirty bit support. */
int pdf_obj_is_dirty(fz_context *ctx, pdf_obj *obj);
diff --git a/include/mupdf/pdf/page.h b/include/mupdf/pdf/page.h
index 13f61bfa..969aedf0 100644
--- a/include/mupdf/pdf/page.h
+++ b/include/mupdf/pdf/page.h
@@ -194,6 +194,7 @@ struct pdf_page_s
pdf_obj *obj;
int transparency;
+ int overprint;
int incomplete;
fz_link *links;
diff --git a/source/fitz/document.c b/source/fitz/document.c
index 0e511c05..6f9d1316 100644
--- a/source/fitz/document.c
+++ b/source/fitz/document.c
@@ -490,3 +490,10 @@ fz_page_separations(fz_context *ctx, fz_page *page)
return page->separations(ctx, page);
return NULL;
}
+
+int fz_page_uses_overprint(fz_context *ctx, fz_page *page)
+{
+ if (page && page->overprint)
+ return page->overprint(ctx, page);
+ return 0;
+}
diff --git a/source/pdf/pdf-object.c b/source/pdf/pdf-object.c
index 2d60edf1..def683d0 100644
--- a/source/pdf/pdf-object.c
+++ b/source/pdf/pdf-object.c
@@ -28,9 +28,9 @@ enum
{
PDF_FLAGS_MARKED = 1,
PDF_FLAGS_SORTED = 2,
- PDF_FLAGS_MEMO = 4,
- PDF_FLAGS_MEMO_BOOL = 8,
- PDF_FLAGS_DIRTY = 16
+ PDF_FLAGS_DIRTY = 4,
+ PDF_FLAGS_MEMO_BASE = 8,
+ PDF_FLAGS_MEMO_BASE_BOOL = 16
};
struct pdf_obj_s
@@ -1643,26 +1643,28 @@ pdf_unmark_obj(fz_context *ctx, pdf_obj *obj)
}
void
-pdf_set_obj_memo(fz_context *ctx, pdf_obj *obj, int memo)
+pdf_set_obj_memo(fz_context *ctx, pdf_obj *obj, int bit, int memo)
{
if (obj < PDF_OBJ__LIMIT)
return;
- obj->flags |= PDF_FLAGS_MEMO;
+ bit <<= 1;
+ obj->flags |= PDF_FLAGS_MEMO_BASE << bit;
if (memo)
- obj->flags |= PDF_FLAGS_MEMO_BOOL;
+ obj->flags |= PDF_FLAGS_MEMO_BASE_BOOL << bit;
else
- obj->flags &= ~PDF_FLAGS_MEMO_BOOL;
+ obj->flags &= ~(PDF_FLAGS_MEMO_BASE_BOOL << bit);
}
int
-pdf_obj_memo(fz_context *ctx, pdf_obj *obj, int *memo)
+pdf_obj_memo(fz_context *ctx, pdf_obj *obj, int bit, int *memo)
{
if (obj < PDF_OBJ__LIMIT)
return 0;
- if (!(obj->flags & PDF_FLAGS_MEMO))
+ bit <<= 1;
+ if (!(obj->flags & (PDF_FLAGS_MEMO_BASE<<bit)))
return 0;
- *memo = !!(obj->flags & PDF_FLAGS_MEMO_BOOL);
+ *memo = !!(obj->flags & (PDF_FLAGS_MEMO_BASE_BOOL<<bit));
return 1;
}
diff --git a/source/pdf/pdf-page.c b/source/pdf/pdf-page.c
index 12319678..da8a2394 100644
--- a/source/pdf/pdf-page.c
+++ b/source/pdf/pdf-page.c
@@ -436,7 +436,7 @@ pdf_resources_use_blending(fz_context *ctx, pdf_obj *rdb)
return 0;
/* Have we been here before and remembered an answer? */
- if (pdf_obj_memo(ctx, rdb, &useBM))
+ if (pdf_obj_memo(ctx, rdb, PDF_FLAGS_MEMO_BM, &useBM))
return useBM;
/* stop on cyclic resource dependencies */
@@ -477,10 +477,94 @@ found:
fz_rethrow(ctx);
}
- pdf_set_obj_memo(ctx, rdb, useBM);
+ pdf_set_obj_memo(ctx, rdb, PDF_FLAGS_MEMO_BM, useBM);
return useBM;
}
+static int pdf_resources_use_overprint(fz_context *ctx, pdf_obj *rdb);
+
+static int
+pdf_extgstate_uses_overprint(fz_context *ctx, pdf_obj *dict)
+{
+ pdf_obj *obj = pdf_dict_get(ctx, dict, PDF_NAME_OP);
+ if (obj && pdf_to_bool(ctx, obj))
+ return 1;
+ return 0;
+}
+
+static int
+pdf_pattern_uses_overprint(fz_context *ctx, pdf_obj *dict)
+{
+ pdf_obj *obj;
+ obj = pdf_dict_get(ctx, dict, PDF_NAME_Resources);
+ if (pdf_resources_use_overprint(ctx, obj))
+ return 1;
+ obj = pdf_dict_get(ctx, dict, PDF_NAME_ExtGState);
+ return pdf_extgstate_uses_overprint(ctx, obj);
+}
+
+static int
+pdf_xobject_uses_overprint(fz_context *ctx, pdf_obj *dict)
+{
+ pdf_obj *obj = pdf_dict_get(ctx, dict, PDF_NAME_Resources);
+ return pdf_resources_use_overprint(ctx, obj);
+}
+
+static int
+pdf_resources_use_overprint(fz_context *ctx, pdf_obj *rdb)
+{
+ pdf_obj *obj;
+ int i, n, useOP = 0;
+
+ if (!rdb)
+ return 0;
+
+ /* Have we been here before and remembered an answer? */
+ if (pdf_obj_memo(ctx, rdb, PDF_FLAGS_MEMO_OP, &useOP))
+ return useOP;
+
+ /* stop on cyclic resource dependencies */
+ if (pdf_mark_obj(ctx, rdb))
+ return 0;
+
+ fz_try(ctx)
+ {
+ obj = pdf_dict_get(ctx, rdb, PDF_NAME_ExtGState);
+ n = pdf_dict_len(ctx, obj);
+ for (i = 0; i < n; i++)
+ if (pdf_extgstate_uses_overprint(ctx, pdf_dict_get_val(ctx, obj, i)))
+ goto found;
+
+ obj = pdf_dict_get(ctx, rdb, PDF_NAME_Pattern);
+ n = pdf_dict_len(ctx, obj);
+ for (i = 0; i < n; i++)
+ if (pdf_pattern_uses_overprint(ctx, pdf_dict_get_val(ctx, obj, i)))
+ goto found;
+
+ obj = pdf_dict_get(ctx, rdb, PDF_NAME_XObject);
+ n = pdf_dict_len(ctx, obj);
+ for (i = 0; i < n; i++)
+ if (pdf_xobject_uses_overprint(ctx, pdf_dict_get_val(ctx, obj, i)))
+ goto found;
+ if (0)
+ {
+found:
+ useOP = 1;
+ }
+ }
+ fz_always(ctx)
+ {
+ pdf_unmark_obj(ctx, rdb);
+ }
+ fz_catch(ctx)
+ {
+ fz_rethrow(ctx);
+ }
+
+ pdf_set_obj_memo(ctx, rdb, PDF_FLAGS_MEMO_OP, useOP);
+ return useOP;
+}
+
fz_transition *
pdf_page_presentation(fz_context *ctx, pdf_page *page, fz_transition *transition, float *duration)
{
@@ -823,6 +907,12 @@ pdf_page_separations(fz_context *ctx, pdf_page *page)
return seps;
}
+int
+pdf_page_uses_overprint(fz_context *ctx, pdf_page *page)
+{
+ return page ? page->overprint : 0;
+}
+
static void
pdf_drop_page_imp(fz_context *ctx, pdf_page *page)
{
@@ -856,6 +946,7 @@ pdf_new_page(fz_context *ctx, pdf_document *doc)
page->super.run_page_contents = (fz_page_run_page_contents_fn*)pdf_run_page_contents;
page->super.page_presentation = (fz_page_page_presentation_fn*)pdf_page_presentation;
page->super.separations = (fz_page_separations_fn *)pdf_page_separations;
+ page->super.overprint = (fz_page_uses_overprint_fn *)pdf_page_uses_overprint;
page->obj = NULL;
@@ -1009,17 +1100,22 @@ pdf_load_page(fz_context *ctx, pdf_document *doc, int number)
page->links = NULL;
}
- /* Scan for transparency */
+ /* Scan for transparency and overprint */
fz_try(ctx)
{
pdf_obj *resources = pdf_page_resources(ctx, page);
- if (pdf_resources_use_blending(ctx, resources))
+ if (pdf_name_eq(ctx, pdf_dict_getp(ctx, pageobj, "Group/S"), PDF_NAME_Transparency))
page->transparency = 1;
- else if (pdf_name_eq(ctx, pdf_dict_getp(ctx, pageobj, "Group/S"), PDF_NAME_Transparency))
+ else if (pdf_resources_use_blending(ctx, resources))
page->transparency = 1;
for (annot = page->annots; annot && !page->transparency; annot = annot->next)
if (annot->ap && pdf_resources_use_blending(ctx, pdf_xobject_resources(ctx, annot->ap)))
page->transparency = 1;
+ if (pdf_resources_use_overprint(ctx, resources))
+ page->overprint = 1;
+ for (annot = page->annots; annot && !page->overprint; annot = annot->next)
+ if (annot->ap && pdf_resources_use_overprint(ctx, pdf_xobject_resources(ctx, annot->ap)))
+ page->overprint = 1;
}
fz_catch(ctx)
{
diff --git a/source/tools/mudraw.c b/source/tools/mudraw.c
index d3cef7a2..f7b87626 100644
--- a/source/tools/mudraw.c
+++ b/source/tools/mudraw.c
@@ -256,7 +256,12 @@ static int lowmemory = 0;
static int errored = 0;
static fz_colorspace *colorspace;
+static fz_colorspace *oi = NULL;
+#ifdef FZ_ENABLE_SPOT_RENDERING
+static int spots = SPOTS_OVERPRINT_SIM;
+#else
static int spots = SPOTS_NONE;
+#endif
static int alpha;
static char *filename;
static int files = 0;
@@ -352,12 +357,14 @@ static void usage(void)
"\t-P\tparallel interpretation/rendering (disabled in this non-threading build)\n"
#endif
"\t-N\tdisable ICC workflow (\"N\"o color management)\n"
- "\t-O -\tControl spot rendering\n"
+ "\t-O -\tControl spot/overprint rendering\n"
"\t\t 0 = No spot rendering\n"
#ifdef FZ_ENABLE_SPOT_RENDERING
- "\t\t 1 = Overprint simulation\n"
+ "\t\t 0 = No spot rendering\n"
+ "\t\t 1 = Overprint simulation (default)\n"
"\t\t 2 = Full spot rendering\n"
#else
+ "\t\t 0 = No spot rendering (default)\n"
"\t\t 1 = Overprint simulation (Disabled in this build)\n"
"\t\t 2 = Full spot rendering (Disabled in this build)\n"
#endif
@@ -1027,7 +1034,7 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum)
page = fz_load_page(ctx, doc, pagenum - 1);
- if (spots)
+ if (spots != SPOTS_NONE)
{
fz_try(ctx)
{
@@ -1042,11 +1049,18 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum)
for (i = 0; i < n; i++)
fz_set_separation_behavior(ctx, seps, i, FZ_SEPARATION_COMPOSITE);
}
- else
+ else if (fz_page_uses_overprint(ctx, page))
+ {
+ /* This page uses overprint, so we need an empty
+ * sep object to force the overprint simulation on. */
+ seps = fz_new_separations(ctx, 0);
+ }
+ else if (oi && fz_colorspace_n(ctx, oi) != fz_colorspace_n(ctx, colorspace))
{
- /* If we are doing spot rendering (or overprint simulation)
- * then we need (at least) an empty sep object to force the
- * overprint simulation in the draw device. */
+ /* We have an output intent, and it's incompatible
+ * with the colorspace our device needs. Force the
+ * overprint simulation on, because this ensures that
+ * we 'simulate' the output intent too. */
seps = fz_new_separations(ctx, 0);
}
}
@@ -1446,7 +1460,6 @@ int mudraw_main(int argc, char **argv)
trace_info info = { 0, 0, 0 };
fz_alloc_context alloc_ctx = { &info, trace_malloc, trace_realloc, trace_free };
fz_locks_context *locks = NULL;
- fz_colorspace *oi = NULL;
fz_var(doc);