summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mupdf/fitz/device.h30
-rw-r--r--source/fitz/test-device.c496
-rw-r--r--source/tools/mudraw.c2
3 files changed, 385 insertions, 143 deletions
diff --git a/include/mupdf/fitz/device.h b/include/mupdf/fitz/device.h
index caa01cb2..d0a8f0ed 100644
--- a/include/mupdf/fitz/device.h
+++ b/include/mupdf/fitz/device.h
@@ -296,11 +296,39 @@ fz_device *fz_new_bbox_device(fz_context *ctx, fz_rect *rectp);
Currently only tests for the presence of non-grayscale colors.
+ is_color: Possible values returned:
+ 0: Definitely greyscale
+ 1: Probably color (all colors were grey, but there
+ were images or shadings in a non grey colorspace).
+ 2: Definitely color
+
threshold: The difference from grayscale that will be tolerated.
Typical values to use are either 0 (be exact) and 0.02 (allow an
imperceptible amount of slop).
+
+ options: A set of bitfield options, from the FZ_TEST_OPT set.
+
+ passthrough: A device to pass all calls through to, or NULL.
+ If set, then the test device can both test and pass through to
+ an underlying device (like, say, the display list device). This
+ means that a display list can be created and at the end we'll
+ know if it's color or not.
+
+ In the absence of a passthrough device, the device will throw
+ an exception to stop page interpretation when color is found.
*/
-fz_device *fz_new_test_device(fz_context *ctx, int *is_color, float threshold);
+fz_device *fz_new_test_device(fz_context *ctx, int *is_color, float threshold, int options, fz_device *passthrough);
+
+enum
+{
+ /* If set, test every pixel of images exhaustively.
+ * If clear, just look at colorspaces for images. */
+ FZ_TEST_OPT_IMAGES = 1,
+
+ /* If set, test every pixel of shadings. */
+ /* If clear, just look at colorspaces for shadings. */
+ FZ_TEST_OPT_SHADINGS = 2
+};
/*
fz_new_draw_device: Create a device to draw on a pixmap.
diff --git a/source/fitz/test-device.c b/source/fitz/test-device.c
index 15e6a3ff..1c1aa628 100644
--- a/source/fitz/test-device.c
+++ b/source/fitz/test-device.c
@@ -5,6 +5,9 @@ typedef struct fz_test_device_s
fz_device super;
int *is_color;
float threshold;
+ int options;
+ fz_device *passthrough;
+ int resolved;
} fz_test_device;
static int
@@ -26,19 +29,18 @@ is_rgb_color_u8(int threshold_u8, int r, int g, int b)
}
static void
-fz_test_color(fz_context *ctx, fz_device *dev, fz_colorspace *colorspace, const float *color)
+fz_test_color(fz_context *ctx, fz_test_device *t, fz_colorspace *colorspace, const float *color)
{
- fz_test_device *t = (fz_test_device*)dev;
-
if (!*t->is_color && colorspace && colorspace != fz_device_gray(ctx))
{
if (colorspace == fz_device_rgb(ctx))
{
if (is_rgb_color(t->threshold, color[0], color[1], color[2]))
{
- *t->is_color = 1;
- dev->hints |= FZ_IGNORE_IMAGE;
- fz_throw(ctx, FZ_ERROR_ABORT, "Page found as color; stopping interpretation");
+ *t->is_color = 2;
+ t->resolved = 1;
+ if (t->passthrough == NULL)
+ fz_throw(ctx, FZ_ERROR_ABORT, "Page found as color; stopping interpretation");
}
}
else
@@ -47,49 +49,81 @@ fz_test_color(fz_context *ctx, fz_device *dev, fz_colorspace *colorspace, const
fz_convert_color(ctx, fz_device_rgb(ctx), rgb, colorspace, color);
if (is_rgb_color(t->threshold, rgb[0], rgb[1], rgb[2]))
{
- *t->is_color = 1;
- dev->hints |= FZ_IGNORE_IMAGE;
- fz_throw(ctx, FZ_ERROR_ABORT, "Page found as color; stopping interpretation");
+ *t->is_color = 2;
+ t->resolved = 1;
+ if (t->passthrough == NULL)
+ {
+ t->super.hints |= FZ_IGNORE_IMAGE;
+ fz_throw(ctx, FZ_ERROR_ABORT, "Page found as color; stopping interpretation");
+ }
}
}
}
}
static void
-fz_test_fill_path(fz_context *ctx, fz_device *dev, const fz_path *path, int even_odd, const fz_matrix *ctm,
+fz_test_fill_path(fz_context *ctx, fz_device *dev_, const fz_path *path, int even_odd, const fz_matrix *ctm,
fz_colorspace *colorspace, const float *color, float alpha)
{
- if (alpha != 0.0f)
- fz_test_color(ctx, dev, colorspace, color);
+ fz_test_device *dev = (fz_test_device*)dev_;
+
+ if (dev->resolved == 0)
+ {
+ if (alpha != 0.0f)
+ fz_test_color(ctx, dev, colorspace, color);
+ }
+ if (dev->passthrough)
+ fz_fill_path(ctx, dev->passthrough, path, even_odd, ctm, colorspace, color, alpha);
}
static void
-fz_test_stroke_path(fz_context *ctx, fz_device *dev, const fz_path *path, const fz_stroke_state *stroke,
+fz_test_stroke_path(fz_context *ctx, fz_device *dev_, const fz_path *path, const fz_stroke_state *stroke,
const fz_matrix *ctm, fz_colorspace *colorspace, const float *color, float alpha)
{
- if (alpha != 0.0f)
- fz_test_color(ctx, dev, colorspace, color);
+ fz_test_device *dev = (fz_test_device*)dev_;
+
+ if (dev->resolved == 0)
+ {
+ if (alpha != 0.0f)
+ fz_test_color(ctx, dev, colorspace, color);
+ }
+ if (dev->passthrough)
+ fz_stroke_path(ctx, dev->passthrough, path, stroke, ctm, colorspace, color, alpha);
}
static void
-fz_test_fill_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_matrix *ctm,
+fz_test_fill_text(fz_context *ctx, fz_device *dev_, const fz_text *text, const fz_matrix *ctm,
fz_colorspace *colorspace, const float *color, float alpha)
{
- if (alpha != 0.0f)
- fz_test_color(ctx, dev, colorspace, color);
+ fz_test_device *dev = (fz_test_device*)dev_;
+
+ if (dev->resolved == 0)
+ {
+ if (alpha != 0.0f)
+ fz_test_color(ctx, dev, colorspace, color);
+ }
+ if (dev->passthrough)
+ fz_fill_text(ctx, dev->passthrough, text, ctm, colorspace, color, alpha);
}
static void
-fz_test_stroke_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_stroke_state *stroke,
+fz_test_stroke_text(fz_context *ctx, fz_device *dev_, const fz_text *text, const fz_stroke_state *stroke,
const fz_matrix *ctm, fz_colorspace *colorspace, const float *color, float alpha)
{
- if (alpha != 0.0f)
- fz_test_color(ctx, dev, colorspace, color);
+ fz_test_device *dev = (fz_test_device*)dev_;
+
+ if (dev->resolved == 0)
+ {
+ if (alpha != 0.0f)
+ fz_test_color(ctx, dev, colorspace, color);
+ }
+ if (dev->passthrough)
+ fz_stroke_text(ctx, dev->passthrough, text, stroke, ctm, colorspace, color, alpha);
}
struct shadearg
{
- fz_device *dev;
+ fz_test_device *dev;
fz_shade *shade;
};
@@ -97,176 +131,336 @@ static void
prepare_vertex(fz_context *ctx, void *arg_, fz_vertex *v, const float *color)
{
struct shadearg *arg = arg_;
- fz_device *dev = arg->dev;
+ fz_test_device *dev = arg->dev;
fz_shade *shade = arg->shade;
if (!shade->use_function)
fz_test_color(ctx, dev, shade->colorspace, color);
}
static void
-fz_test_fill_shade(fz_context *ctx, fz_device *dev, fz_shade *shade, const fz_matrix *ctm, float alpha)
+fz_test_fill_shade(fz_context *ctx, fz_device *dev_, fz_shade *shade, const fz_matrix *ctm, float alpha)
{
- if (shade->use_function)
- {
- int i;
- for (i = 0; i < 256; i++)
- fz_test_color(ctx, dev, shade->colorspace, shade->function[i]);
- }
- else
+ fz_test_device *dev = (fz_test_device*)dev_;
+
+ if (dev->resolved == 0)
{
- struct shadearg arg;
- arg.dev = dev;
- arg.shade = shade;
- fz_process_mesh(ctx, shade, ctm, prepare_vertex, NULL, &arg);
+ if ((dev->options & FZ_TEST_OPT_SHADINGS) == 0)
+ {
+ if (shade->colorspace != fz_device_gray(ctx))
+ {
+ /* Don't test every pixel. Upgrade us from "black and white" to "probably color" */
+ if (*dev->is_color == 0)
+ *dev->is_color = 1;
+ dev->resolved = 1;
+ if (dev->passthrough == NULL)
+ fz_throw(ctx, FZ_ERROR_ABORT, "Page found as color; stopping interpretation");
+ }
+ }
+ else
+ {
+ if (shade->use_function)
+ {
+ int i;
+ for (i = 0; i < 256; i++)
+ fz_test_color(ctx, dev, shade->colorspace, shade->function[i]);
+ }
+ else
+ {
+ struct shadearg arg;
+ arg.dev = dev;
+ arg.shade = shade;
+ fz_process_mesh(ctx, shade, ctm, prepare_vertex, NULL, &arg);
+ }
+ }
}
+ if (dev->passthrough)
+ fz_fill_shade(ctx, dev->passthrough, shade, ctm, alpha);
}
static void
-fz_test_fill_image(fz_context *ctx, fz_device *dev, fz_image *image, const fz_matrix *ctm, float alpha)
+fz_test_fill_image(fz_context *ctx, fz_device *dev_, fz_image *image, const fz_matrix *ctm, float alpha)
{
- fz_test_device *t = (fz_test_device*)dev;
+ fz_test_device *dev = (fz_test_device*)dev_;
- fz_pixmap *pix;
- unsigned int count, i, k, h, sa, ss;
- unsigned char *s;
- fz_compressed_buffer *buffer;
+ while (dev->resolved == 0) /* So we can break out */
+ {
+ fz_pixmap *pix;
+ unsigned int count, i, k, h, sa, ss;
+ unsigned char *s;
+ fz_compressed_buffer *buffer;
- if (*t->is_color || !image->colorspace || image->colorspace == fz_device_gray(ctx))
- return;
+ if (*dev->is_color || !image->colorspace || image->colorspace == fz_device_gray(ctx))
+ break;
- buffer = fz_compressed_image_buffer(ctx, image);
- if (buffer && image->bpc == 8)
- {
- fz_stream *stream = fz_open_compressed_buffer(ctx, buffer);
- count = (unsigned int)image->w * (unsigned int)image->h;
- if (image->colorspace == fz_device_rgb(ctx))
+ if ((dev->options & FZ_TEST_OPT_IMAGES) == 0)
{
- int threshold_u8 = t->threshold * 255;
- for (i = 0; i < count; i++)
+ /* Don't test every pixel. Upgrade us from "black and white" to "probably color" */
+ if (*dev->is_color == 0)
+ *dev->is_color = 1;
+ dev->resolved = 1;
+ if (dev->passthrough == NULL)
+ fz_throw(ctx, FZ_ERROR_ABORT, "Page found as color; stopping interpretation");
+ break;
+ }
+
+ buffer = fz_compressed_image_buffer(ctx, image);
+ if (buffer && image->bpc == 8)
+ {
+ fz_stream *stream = fz_open_compressed_buffer(ctx, buffer);
+ count = (unsigned int)image->w * (unsigned int)image->h;
+ if (image->colorspace == fz_device_rgb(ctx))
{
- int r = fz_read_byte(ctx, stream);
- int g = fz_read_byte(ctx, stream);
- int b = fz_read_byte(ctx, stream);
- if (is_rgb_color_u8(threshold_u8, r, g, b))
+ int threshold_u8 = dev->threshold * 255;
+ for (i = 0; i < count; i++)
{
- *t->is_color = 1;
- dev->hints |= FZ_IGNORE_IMAGE;
- fz_drop_stream(ctx, stream);
- fz_throw(ctx, FZ_ERROR_ABORT, "Page found as color; stopping interpretation");
- break;
+ int r = fz_read_byte(ctx, stream);
+ int g = fz_read_byte(ctx, stream);
+ int b = fz_read_byte(ctx, stream);
+ if (is_rgb_color_u8(threshold_u8, r, g, b))
+ {
+ *dev->is_color = 1;
+ dev->resolved = 1;
+ fz_drop_stream(ctx, stream);
+ if (dev->passthrough == NULL)
+ fz_throw(ctx, FZ_ERROR_ABORT, "Page found as color; stopping interpretation");
+ break;
+ }
}
}
- }
- else
- {
- fz_color_converter cc;
- unsigned int n = (unsigned int)image->n;
-
- fz_init_cached_color_converter(ctx, &cc, fz_device_rgb(ctx), image->colorspace);
- for (i = 0; i < count; i++)
+ else
{
- float cs[FZ_MAX_COLORS];
- float ds[FZ_MAX_COLORS];
+ fz_color_converter cc;
+ unsigned int n = (unsigned int)image->n;
- for (k = 0; k < n; k++)
- cs[k] = fz_read_byte(ctx, stream) / 255.0f;
-
- cc.convert(ctx, &cc, ds, cs);
-
- if (is_rgb_color(t->threshold, ds[0], ds[1], ds[2]))
+ fz_init_cached_color_converter(ctx, &cc, fz_device_rgb(ctx), image->colorspace);
+ for (i = 0; i < count; i++)
{
- *t->is_color = 1;
- dev->hints |= FZ_IGNORE_IMAGE;
- fz_drop_stream(ctx, stream);
- fz_fin_cached_color_converter(ctx, &cc);
- fz_throw(ctx, FZ_ERROR_ABORT, "Page found as color; stopping interpretation");
- break;
+ float cs[FZ_MAX_COLORS];
+ float ds[FZ_MAX_COLORS];
+
+ for (k = 0; k < n; k++)
+ cs[k] = fz_read_byte(ctx, stream) / 255.0f;
+
+ cc.convert(ctx, &cc, ds, cs);
+
+ if (is_rgb_color(dev->threshold, ds[0], ds[1], ds[2]))
+ {
+ *dev->is_color = 1;
+ dev->resolved = 1;
+ if (dev->passthrough == NULL)
+ {
+ fz_drop_stream(ctx, stream);
+ fz_fin_cached_color_converter(ctx, &cc);
+ fz_throw(ctx, FZ_ERROR_ABORT, "Page found as color; stopping interpretation");
+ }
+ break;
+ }
}
+ fz_fin_cached_color_converter(ctx, &cc);
}
- fz_fin_cached_color_converter(ctx, &cc);
+ fz_drop_stream(ctx, stream);
+ break;
}
- fz_drop_stream(ctx, stream);
- return;
- }
- pix = fz_get_pixmap_from_image(ctx, image, NULL, NULL, 0, 0);
- if (pix == NULL) /* Should never happen really, but... */
- return;
+ pix = fz_get_pixmap_from_image(ctx, image, NULL, NULL, 0, 0);
+ if (pix == NULL) /* Should never happen really, but... */
+ break;
- count = pix->w;
- h = pix->h;
- s = pix->samples;
- sa = pix->alpha;
- ss = pix->stride - pix->w * pix->n;
+ count = pix->w;
+ h = pix->h;
+ s = pix->samples;
+ sa = pix->alpha;
+ ss = pix->stride - pix->w * pix->n;
- if (pix->colorspace == fz_device_rgb(ctx))
- {
- int threshold_u8 = t->threshold * 255;
- while (h--)
+ if (pix->colorspace == fz_device_rgb(ctx))
{
- for (i = 0; i < count; i++)
+ int threshold_u8 = dev->threshold * 255;
+ while (h--)
{
- if ((!sa || s[3] != 0) && is_rgb_color_u8(threshold_u8, s[0], s[1], s[2]))
+ for (i = 0; i < count; i++)
{
- *t->is_color = 1;
- dev->hints |= FZ_IGNORE_IMAGE;
- fz_drop_pixmap(ctx, pix);
- fz_throw(ctx, FZ_ERROR_ABORT, "Page found as color; stopping interpretation");
- break;
+ if ((!sa || s[3] != 0) && is_rgb_color_u8(threshold_u8, s[0], s[1], s[2]))
+ {
+ *dev->is_color = 1;
+ dev->resolved = 1;
+ if (dev->passthrough == NULL)
+ {
+ fz_drop_pixmap(ctx, pix);
+ fz_throw(ctx, FZ_ERROR_ABORT, "Page found as color; stopping interpretation");
+ }
+ break;
+ }
+ s += 3 + sa;
}
- s += 3 + sa;
+ s += ss;
}
- s += ss;
}
- }
- else
- {
- fz_color_converter cc;
- unsigned int n = (unsigned int)pix->n-1;
-
- fz_init_cached_color_converter(ctx, &cc, fz_device_rgb(ctx), pix->colorspace);
- while (h--)
+ else
{
- for (i = 0; i < count; i++)
- {
- float cs[FZ_MAX_COLORS];
- float ds[FZ_MAX_COLORS];
-
- for (k = 0; k < n; k++)
- cs[k] = (*s++) / 255.0f;
- if (sa && *s++ == 0)
- continue;
-
- cc.convert(ctx, &cc, ds, cs);
+ fz_color_converter cc;
+ unsigned int n = (unsigned int)pix->n-1;
- if (is_rgb_color(t->threshold, ds[0], ds[1], ds[2]))
+ fz_init_cached_color_converter(ctx, &cc, fz_device_rgb(ctx), pix->colorspace);
+ while (h--)
+ {
+ for (i = 0; i < count; i++)
{
- *t->is_color = 1;
- dev->hints |= FZ_IGNORE_IMAGE;
- fz_fin_cached_color_converter(ctx, &cc);
- fz_drop_pixmap(ctx, pix);
- fz_throw(ctx, FZ_ERROR_ABORT, "Page found as color; stopping interpretation");
- break;
+ float cs[FZ_MAX_COLORS];
+ float ds[FZ_MAX_COLORS];
+
+ for (k = 0; k < n; k++)
+ cs[k] = (*s++) / 255.0f;
+ if (sa && *s++ == 0)
+ continue;
+
+ cc.convert(ctx, &cc, ds, cs);
+
+ if (is_rgb_color(dev->threshold, ds[0], ds[1], ds[2]))
+ {
+ *dev->is_color = 1;
+ dev->resolved = 1;
+ if (dev->passthrough == NULL)
+ {
+ fz_fin_cached_color_converter(ctx, &cc);
+ fz_drop_pixmap(ctx, pix);
+ fz_throw(ctx, FZ_ERROR_ABORT, "Page found as color; stopping interpretation");
+ }
+ break;
+ }
}
+ s += ss;
}
- s += ss;
+ fz_fin_cached_color_converter(ctx, &cc);
}
- fz_fin_cached_color_converter(ctx, &cc);
- }
- fz_drop_pixmap(ctx, pix);
+ fz_drop_pixmap(ctx, pix);
+ break;
+ }
+ if (dev->passthrough)
+ fz_fill_image(ctx, dev->passthrough, image, ctm, alpha);
}
static void
-fz_test_fill_image_mask(fz_context *ctx, fz_device *dev, fz_image *image, const fz_matrix *ctm,
+fz_test_fill_image_mask(fz_context *ctx, fz_device *dev_, fz_image *image, const fz_matrix *ctm,
fz_colorspace *colorspace, const float *color, float alpha)
{
- /* We assume that at least some of the image pixels are non-zero */
- fz_test_color(ctx, dev, colorspace, color);
+ fz_test_device *dev = (fz_test_device*)dev_;
+
+ if (dev->resolved == 0)
+ {
+ /* We assume that at least some of the image pixels are non-zero */
+ fz_test_color(ctx, dev, colorspace, color);
+ }
+ if (dev->passthrough)
+ fz_fill_image_mask(ctx, dev->passthrough, image, ctm, colorspace, color, alpha);
+}
+
+static void
+fz_test_clip_path(fz_context *ctx, fz_device *dev_, const fz_path *path, int even_odd, const fz_matrix *ctm, const fz_rect *scissor)
+{
+ fz_test_device *dev = (fz_test_device*)dev_;
+
+ fz_clip_path(ctx, dev->passthrough, path, even_odd, ctm, scissor);
+}
+
+static void
+fz_test_clip_stroke_path(fz_context *ctx, fz_device *dev_, const fz_path *path, const fz_stroke_state *stroke, const fz_matrix *ctm, const fz_rect *scissor)
+{
+ fz_test_device *dev = (fz_test_device*)dev_;
+
+ fz_clip_stroke_path(ctx, dev->passthrough, path, stroke, ctm, scissor);
+}
+
+static void
+fz_test_clip_text(fz_context *ctx, fz_device *dev_, const fz_text *text, const fz_matrix *ctm, const fz_rect *scissor)
+{
+ fz_test_device *dev = (fz_test_device*)dev_;
+
+ fz_clip_text(ctx, dev->passthrough, text, ctm, scissor);
+}
+
+static void
+fz_test_clip_stroke_text(fz_context *ctx, fz_device *dev_, const fz_text *text, const fz_stroke_state *stroke, const fz_matrix *ctm, const fz_rect *scissor)
+{
+ fz_test_device *dev = (fz_test_device*)dev_;
+
+ fz_clip_stroke_text(ctx, dev->passthrough, text, stroke, ctm, scissor);
+}
+
+static void
+fz_test_ignore_text(fz_context *ctx, fz_device *dev_, const fz_text *text, const fz_matrix *ctm)
+{
+ fz_test_device *dev = (fz_test_device*)dev_;
+
+ fz_ignore_text(ctx, dev->passthrough, text, ctm);
+}
+
+static void
+fz_test_clip_image_mask(fz_context *ctx, fz_device *dev_, fz_image *img, const fz_matrix *ctm, const fz_rect *scissor)
+{
+ fz_test_device *dev = (fz_test_device*)dev_;
+
+ fz_clip_image_mask(ctx, dev->passthrough, img, ctm, scissor);
+}
+
+static void
+fz_test_pop_clip(fz_context *ctx, fz_device *dev_)
+{
+ fz_test_device *dev = (fz_test_device*)dev_;
+
+ fz_pop_clip(ctx, dev->passthrough);
+}
+
+static void
+fz_test_begin_mask(fz_context *ctx, fz_device *dev_, const fz_rect *rect, int luminosity, fz_colorspace *cs, const float *bc)
+{
+ fz_test_device *dev = (fz_test_device*)dev_;
+
+ fz_begin_mask(ctx, dev->passthrough, rect, luminosity, cs, bc);
+}
+
+static void
+fz_test_end_mask(fz_context *ctx, fz_device *dev_)
+{
+ fz_test_device *dev = (fz_test_device*)dev_;
+
+ fz_end_mask(ctx, dev->passthrough);
+}
+
+static void
+fz_test_begin_group(fz_context *ctx, fz_device *dev_, const fz_rect *rect, int isolated, int knockout, int blendmode, float alpha)
+{
+ fz_test_device *dev = (fz_test_device*)dev_;
+
+ fz_begin_group(ctx, dev->passthrough, rect, isolated, knockout, blendmode, alpha);
+}
+
+static void
+fz_test_end_group(fz_context *ctx, fz_device *dev_)
+{
+ fz_test_device *dev = (fz_test_device*)dev_;
+
+ fz_end_group(ctx, dev->passthrough);
+}
+
+static int
+fz_test_begin_tile(fz_context *ctx, fz_device *dev_, const fz_rect *area, const fz_rect *view, float xstep, float ystep, const fz_matrix *ctm, int id)
+{
+ fz_test_device *dev = (fz_test_device*)dev_;
+
+ return fz_begin_tile_id(ctx, dev->passthrough, area, view, xstep, ystep, ctm, id);
+}
+
+static void
+fz_test_end_tile(fz_context *ctx, fz_device *dev_)
+{
+ fz_test_device *dev = (fz_test_device*)dev_;
+
+ fz_end_tile(ctx, dev->passthrough);
}
fz_device *
-fz_new_test_device(fz_context *ctx, int *is_color, float threshold)
+fz_new_test_device(fz_context *ctx, int *is_color, float threshold, int options, fz_device *passthrough)
{
fz_test_device *dev = fz_new_device(ctx, sizeof *dev);
@@ -278,8 +472,28 @@ fz_new_test_device(fz_context *ctx, int *is_color, float threshold)
dev->super.fill_image = fz_test_fill_image;
dev->super.fill_image_mask = fz_test_fill_image_mask;
+ if (passthrough)
+ {
+ dev->super.clip_path = fz_test_clip_path;
+ dev->super.clip_stroke_path = fz_test_clip_stroke_path;
+ dev->super.clip_text = fz_test_clip_text;
+ dev->super.clip_stroke_text = fz_test_clip_stroke_text;
+ dev->super.ignore_text = fz_test_ignore_text;
+ dev->super.clip_image_mask = fz_test_clip_image_mask;
+ dev->super.pop_clip = fz_test_pop_clip;
+ dev->super.begin_mask = fz_test_begin_mask;
+ dev->super.end_mask = fz_test_end_mask;
+ dev->super.begin_group = fz_test_begin_group;
+ dev->super.end_group = fz_test_end_group;
+ dev->super.begin_tile = fz_test_begin_tile;
+ dev->super.end_tile = fz_test_end_tile;
+ }
+
dev->is_color = is_color;
+ dev->options = options;
dev->threshold = threshold;
+ dev->passthrough = passthrough;
+ dev->resolved = 0;
*dev->is_color = 0;
diff --git a/source/tools/mudraw.c b/source/tools/mudraw.c
index 85553ea8..12d5247a 100644
--- a/source/tools/mudraw.c
+++ b/source/tools/mudraw.c
@@ -1147,7 +1147,7 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum)
if (showfeatures)
{
int iscolor;
- dev = fz_new_test_device(ctx, &iscolor, 0.02f);
+ dev = fz_new_test_device(ctx, &iscolor, 0.02f, 0, NULL);
if (lowmemory)
fz_enable_device_hints(ctx, dev, FZ_NO_CACHE);
fz_try(ctx)