diff options
author | Robin Watts <robin.watts@artifex.com> | 2012-01-17 00:23:13 +0000 |
---|---|---|
committer | Robin Watts <robin@ghostscript.com> | 2012-01-18 13:11:52 +0000 |
commit | 2c836b57d5295b47655988cf8deaffda731e1c3c (patch) | |
tree | 01b0e51a30412ac90e53993f59c9cc649a8aa88d /fitz/res_font.c | |
parent | b2c87fcd70b3f069388755baf7baa6b3c2590123 (diff) | |
download | mupdf-2c836b57d5295b47655988cf8deaffda731e1c3c.tar.xz |
Better handling of 'uncacheable' Type3 glyphs. Bug 692745.
Some Type 3 fonts contain glyphs that rely on inheriting various
aspects of the graphics state from their calling code. (i.e. a
glyph might use d0, then fill an area without setting a color
first).
While the spec is vague on this point, we believe that technically
it is invalid. Previously mupdf defaulted all elements of the graphic
state back when beginning to draw the glyph. This does not match
what Acrobat does though, so we change the approach taken.
We now watch (by use of bits in the device flags word) for the use
of parts of the graphics state before it is set. If such use is
detected, then we note that the glyph is 'uncacheable' and render
it direct.
This seems to match Acrobats behaviour.
Diffstat (limited to 'fitz/res_font.c')
-rw-r--r-- | fitz/res_font.c | 56 |
1 files changed, 51 insertions, 5 deletions
diff --git a/fitz/res_font.c b/fitz/res_font.c index 4a1c9dfa..6db1f07d 100644 --- a/fitz/res_font.c +++ b/fitz/res_font.c @@ -636,7 +636,15 @@ fz_bound_t3_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm) ctm = fz_concat(font->t3matrix, trm); dev = fz_new_bbox_device(ctx, &bbox); - font->t3run(font->t3xref, font->t3resources, contents, dev, ctm); + dev->flags = FZ_DEVFLAG_FILLCOLOR_UNDEFINED | + FZ_DEVFLAG_STROKECOLOR_UNDEFINED | + FZ_DEVFLAG_STARTCAP_UNDEFINED | + FZ_DEVFLAG_DASHCAP_UNDEFINED | + FZ_DEVFLAG_ENDCAP_UNDEFINED | + FZ_DEVFLAG_LINEJOIN_UNDEFINED | + FZ_DEVFLAG_MITERLIMIT_UNDEFINED | + FZ_DEVFLAG_LINEWIDTH_UNDEFINED; + font->t3run(font->t3xref, font->t3resources, contents, dev, ctm, NULL); font->t3flags[gid] = dev->flags; fz_free_device(dev); @@ -664,13 +672,13 @@ fz_render_t3_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, fz_co if (!contents) return NULL; - if (font->t3flags[gid] & FZ_CHARPROC_MASK) + if (font->t3flags[gid] & FZ_DEVFLAG_MASK) { - if (font->t3flags[gid] & FZ_CHARPROC_COLOR) + if (font->t3flags[gid] & FZ_DEVFLAG_COLOR) fz_warn(ctx, "type3 glyph claims to be both masked and colored"); model = NULL; } - else if (font->t3flags[gid] & FZ_CHARPROC_COLOR) + else if (font->t3flags[gid] & FZ_DEVFLAG_COLOR) { if (!model) fz_warn(ctx, "colored type3 glyph wanted in masked context"); @@ -692,7 +700,7 @@ fz_render_t3_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, fz_co ctm = fz_concat(font->t3matrix, trm); dev = fz_new_draw_device_type3(ctx, glyph); - font->t3run(font->t3xref, font->t3resources, contents, dev, ctm); + font->t3run(font->t3xref, font->t3resources, contents, dev, ctm, NULL); /* RJW: "cannot draw type3 glyph" */ fz_free_device(dev); @@ -708,6 +716,37 @@ fz_render_t3_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, fz_co } void +fz_render_t3_glyph_direct(fz_context *ctx, fz_device *dev, fz_font *font, int gid, fz_matrix trm, void *gstate) +{ + fz_matrix ctm; + fz_buffer *contents; + + if (gid < 0 || gid > 255) + return; + + contents = font->t3procs[gid]; + if (!contents) + return; + + if (font->t3flags[gid] & FZ_DEVFLAG_MASK) + { + if (font->t3flags[gid] & FZ_DEVFLAG_COLOR) + fz_warn(ctx, "type3 glyph claims to be both masked and colored"); + } + else if (font->t3flags[gid] & FZ_DEVFLAG_COLOR) + { + } + else + { + fz_warn(ctx, "type3 glyph doesn't specify masked or colored"); + } + + ctm = fz_concat(font->t3matrix, trm); + font->t3run(font->t3xref, font->t3resources, contents, dev, ctm, gstate); + /* RJW: "cannot draw type3 glyph" */ +} + +void fz_debug_font(fz_font *font) { printf("font '%s' {\n", font->name); @@ -753,3 +792,10 @@ fz_bound_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm) /* fall back to font bbox */ return fz_transform_rect(trm, font->bbox); } + +int fz_glyph_cacheable(fz_font *font, int gid) +{ + if (!font->t3procs || !font->t3flags || gid < 0 || gid >= font->bbox_count) + return 1; + return (font->t3flags[gid] & FZ_DEVFLAG_UNCACHEABLE) == 0; +} |