summaryrefslogtreecommitdiff
path: root/source/fitz
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2017-10-12 19:39:27 +0100
committerRobin Watts <robin.watts@artifex.com>2017-10-13 15:57:24 +0100
commit365b009b648700e90ed0c83791849ba86b3f3678 (patch)
tree1bffb9b021f22d5fe2db6dd7adf62e42135de236 /source/fitz
parentba68165a83f181848670b871dc07afb8dda4fb3a (diff)
downloadmupdf-365b009b648700e90ed0c83791849ba86b3f3678.tar.xz
Fix further problem seen in PDF_2.0_FTS/fts_23_2311.pdf
This file has a type 3 font in it. It first uses a 'd1' glyph, that uses a pattern. Accordingly, we we render that pattern to a mask tile and store that tile. Then it uses a 'd0' glyph, which uses the same pattern. The cache is checked, and we erroneously pick up the cached tile to reuse it - but this is not a colored rendering, so we assert on plotting. The fix is to ensure that the required colorspaces match. This requires us to add the colorspace to the tile key. Unfortunately, this means that colorspaces have to become key_storable, so the patch is slightly larger than would otherwise be the case.
Diffstat (limited to 'source/fitz')
-rw-r--r--source/fitz/colorspace-imp.h2
-rw-r--r--source/fitz/colorspace.c32
-rw-r--r--source/fitz/draw-device.c14
3 files changed, 34 insertions, 14 deletions
diff --git a/source/fitz/colorspace-imp.h b/source/fitz/colorspace-imp.h
index 0ca960a0..7f4ecef6 100644
--- a/source/fitz/colorspace-imp.h
+++ b/source/fitz/colorspace-imp.h
@@ -24,7 +24,7 @@ void fz_cmm_fin_profile(fz_context *ctx, fz_iccprofile *profile);
struct fz_colorspace_s
{
- fz_storable storable;
+ fz_key_storable key_storable;
size_t size;
char name[24];
unsigned char n;
diff --git a/source/fitz/colorspace.c b/source/fitz/colorspace.c
index 1441e233..7ec34f06 100644
--- a/source/fitz/colorspace.c
+++ b/source/fitz/colorspace.c
@@ -160,7 +160,7 @@ fz_colorspace *
fz_new_colorspace(fz_context *ctx, const char *name, int n, int is_subtractive, int is_device_n, fz_colorspace_convert_fn *to_ccs, fz_colorspace_convert_fn *from_ccs, fz_colorspace_base_fn *base, fz_colorspace_clamp_fn *clamp, fz_colorspace_destruct_fn *destruct, void *data, size_t size)
{
fz_colorspace *cs = fz_malloc_struct(ctx, fz_colorspace);
- FZ_INIT_STORABLE(cs, 1, fz_drop_colorspace_imp);
+ FZ_INIT_KEY_STORABLE(cs, 1, fz_drop_colorspace_imp);
cs->size = sizeof(fz_colorspace) + size;
fz_strlcpy(cs->name, name ? name : "UNKNOWN", sizeof cs->name);
cs->n = n;
@@ -183,13 +183,25 @@ fz_new_colorspace(fz_context *ctx, const char *name, int n, int is_subtractive,
fz_colorspace *
fz_keep_colorspace(fz_context *ctx, fz_colorspace *cs)
{
- return fz_keep_storable(ctx, &cs->storable);
+ return fz_keep_key_storable(ctx, &cs->key_storable);
}
void
fz_drop_colorspace(fz_context *ctx, fz_colorspace *cs)
{
- fz_drop_storable(ctx, &cs->storable);
+ fz_drop_key_storable(ctx, &cs->key_storable);
+}
+
+fz_colorspace *
+fz_keep_colorspace_store_key(fz_context *ctx, fz_colorspace *cs)
+{
+ return fz_keep_key_storable_key(ctx, &cs->key_storable);
+}
+
+void
+fz_drop_colorspace_store_key(fz_context *ctx, fz_colorspace *cs)
+{
+ fz_drop_key_storable_key(ctx, &cs->key_storable);
}
/* icc links */
@@ -679,11 +691,11 @@ fz_colorspace_is_subtractive(fz_context *ctx, const fz_colorspace *cs)
return (cs && cs->is_subtractive);
}
-static fz_colorspace k_default_gray = { {-1, fz_drop_colorspace_imp}, 0, "DeviceGray", 1, 0, 0, gray_to_rgb, rgb_to_gray, clamp_default, NULL, NULL, NULL, { "Gray" } };
-static fz_colorspace k_default_rgb = { {-1, fz_drop_colorspace_imp}, 0, "DeviceRGB", 3, 0, 0, rgb_to_rgb, rgb_to_rgb, clamp_default, NULL, NULL, NULL, { "Red", "Green", "Blue" } };
-static fz_colorspace k_default_bgr = { {-1, fz_drop_colorspace_imp}, 0, "DeviceBGR", 3, 0, 0, bgr_to_rgb, rgb_to_bgr, clamp_default, NULL, NULL, NULL, { "Blue", "Green", "Red" } };
-static fz_colorspace k_default_cmyk = { {-1, fz_drop_colorspace_imp}, 0, "DeviceCMYK", 4, 1, 0, cmyk_to_rgb, rgb_to_cmyk, clamp_default, NULL, NULL, NULL, { "Cyan", "Magenta", "Yellow", "Black" } };
-static fz_colorspace k_default_lab = { {-1, fz_drop_colorspace_imp}, 0, "Lab", 3, 0, 0, lab_to_rgb, rgb_to_lab, clamp_lab, NULL, NULL, NULL, { "L*", "a*", "b*" } };
+static fz_colorspace k_default_gray = { { {-1, fz_drop_colorspace_imp}, 0 },0, "DeviceGray", 1, 0, 0, gray_to_rgb, rgb_to_gray, clamp_default, NULL, NULL, NULL, { "Gray" } };
+static fz_colorspace k_default_rgb = { { {-1, fz_drop_colorspace_imp}, 0 },0, "DeviceRGB", 3, 0, 0, rgb_to_rgb, rgb_to_rgb, clamp_default, NULL, NULL, NULL, { "Red", "Green", "Blue" } };
+static fz_colorspace k_default_bgr = { { {-1, fz_drop_colorspace_imp}, 0 },0, "DeviceBGR", 3, 0, 0, bgr_to_rgb, rgb_to_bgr, clamp_default, NULL, NULL, NULL, { "Blue", "Green", "Red" } };
+static fz_colorspace k_default_cmyk = { { {-1, fz_drop_colorspace_imp}, 0 },0, "DeviceCMYK", 4, 1, 0, cmyk_to_rgb, rgb_to_cmyk, clamp_default, NULL, NULL, NULL, { "Cyan", "Magenta", "Yellow", "Black" } };
+static fz_colorspace k_default_lab = { { {-1, fz_drop_colorspace_imp}, 0 }, 0, "Lab", 3, 0, 0, lab_to_rgb, rgb_to_lab, clamp_lab, NULL, NULL, NULL, { "L*", "a*", "b*" } };
static fz_color_params k_default_color_params = { FZ_RI_RELATIVE_COLORIMETRIC, 1, 0, 0 };
static fz_colorspace *default_gray = &k_default_gray;
@@ -3526,13 +3538,13 @@ void fz_init_cached_color_converter(fz_context *ctx, fz_color_converter *cc, fz_
cc->opaque = cached;
cc->convert = fz_cached_color_convert;
- cc->ds = ds;
+ cc->ds = ds ? ds : fz_device_gray(ctx);
cc->ss = ss;
cc->is = is;
fz_try(ctx)
{
- fz_find_color_converter(ctx, &cached->base, is, ds, ss, params);
+ fz_find_color_converter(ctx, &cached->base, is, cc->ds, ss, params);
cached->hash = fz_new_hash_table(ctx, 256, n * sizeof(float), -1, fz_free);
}
fz_catch(ctx)
diff --git a/source/fitz/draw-device.c b/source/fitz/draw-device.c
index 9180e360..fdc9cd20 100644
--- a/source/fitz/draw-device.c
+++ b/source/fitz/draw-device.c
@@ -2022,6 +2022,7 @@ typedef struct
int refs;
float ctm[4];
int id;
+ fz_colorspace *cs;
} tile_key;
typedef struct
@@ -2041,6 +2042,7 @@ fz_make_hash_tile_key(fz_context *ctx, fz_store_hash *hash, void *key_)
hash->u.im.m[1] = key->ctm[1];
hash->u.im.m[2] = key->ctm[2];
hash->u.im.m[3] = key->ctm[3];
+ hash->u.im.ptr = key->cs;
return 1;
}
@@ -2056,7 +2058,10 @@ fz_drop_tile_key(fz_context *ctx, void *key_)
{
tile_key *key = key_;
if (fz_drop_imp(ctx, key, &key->refs))
+ {
+ fz_drop_colorspace_store_key(ctx, key->cs);
fz_free(ctx, key);
+ }
}
static int
@@ -2068,15 +2073,16 @@ fz_cmp_tile_key(fz_context *ctx, void *k0_, void *k1_)
k0->ctm[0] == k1->ctm[0] &&
k0->ctm[1] == k1->ctm[1] &&
k0->ctm[2] == k1->ctm[2] &&
- k0->ctm[3] == k1->ctm[3];
+ k0->ctm[3] == k1->ctm[3] &&
+ k0->cs == k1->cs;
}
static void
fz_format_tile_key(fz_context *ctx, char *s, int n, void *key_)
{
tile_key *key = (tile_key *)key_;
- fz_snprintf(s, n, "(tile id=%x, ctm=%g %g %g %g)",
- key->id, key->ctm[0], key->ctm[1], key->ctm[2], key->ctm[3]);
+ fz_snprintf(s, n, "(tile id=%x, ctm=%g %g %g %g, cs=%x)",
+ key->id, key->ctm[0], key->ctm[1], key->ctm[2], key->ctm[3], key->cs);
}
static const fz_store_type fz_tile_store_type =
@@ -2164,6 +2170,7 @@ fz_draw_begin_tile(fz_context *ctx, fz_device *devp, const fz_rect *area, const
tk.ctm[2] = ctm.c;
tk.ctm[3] = ctm.d;
tk.id = id;
+ tk.cs = state[1].dest->colorspace;
tile = fz_find_item(ctx, fz_drop_tile_record_imp, &tk, &fz_tile_store_type);
if (tile)
@@ -2345,6 +2352,7 @@ fz_draw_end_tile(fz_context *ctx, fz_device *devp)
key->ctm[1] = ctm.b;
key->ctm[2] = ctm.c;
key->ctm[3] = ctm.d;
+ key->cs = fz_keep_colorspace_store_key(ctx, state[1].dest->colorspace);
existing_tile = fz_store_item(ctx, key, tile, fz_tile_size(ctx, tile), &fz_tile_store_type);
if (existing_tile)
{