diff options
-rw-r--r-- | fitz/fitz.h | 32 | ||||
-rw-r--r-- | fitz/res_font.c | 56 | ||||
-rw-r--r-- | pdf/mupdf.h | 2 | ||||
-rw-r--r-- | pdf/pdf_interpret.c | 181 | ||||
-rw-r--r-- | pdf/pdf_type3.c | 4 |
5 files changed, 212 insertions, 63 deletions
diff --git a/fitz/fitz.h b/fitz/fitz.h index 769111e3..ccfa0bd6 100644 --- a/fitz/fitz.h +++ b/fitz/fitz.h @@ -200,9 +200,9 @@ The macro based nature of this system has 3 main limitations: start of fz_try and something in fz_try throwing an exception may become undefined as part of the process of throwing that exception. -As a way of mitigating this problem, we provide an fz_var() macro that -tells the compiler to ensure that that variable is not unset by the -act of throwing the exception. + As a way of mitigating this problem, we provide an fz_var() macro that + tells the compiler to ensure that that variable is not unset by the + act of throwing the exception. A model piece of code using these macros then might be: @@ -1052,7 +1052,7 @@ struct fz_font_s char *t3flags; /* has 256 entries if used */ void *t3xref; /* a pdf_xref for the callback */ void (*t3run)(void *xref, fz_obj *resources, fz_buffer *contents, - struct fz_device_s *dev, fz_matrix ctm); + struct fz_device_s *dev, fz_matrix ctm, void *gstate); fz_rect bbox; /* font bbox is used only for t3 fonts */ @@ -1063,7 +1063,7 @@ struct fz_font_s /* substitute metrics */ int width_count; - int *width_table; // in 1000 units + int *width_table; /* in 1000 units */ }; void fz_new_font_context(fz_context *ctx); @@ -1081,6 +1081,7 @@ void fz_debug_font(fz_font *font); void fz_set_font_bbox(fz_font *font, float xmin, float ymin, float xmax, float ymax); fz_rect fz_bound_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm); +int fz_glyph_cacheable(fz_font *font, int gid); /* * Vector path buffer. @@ -1164,6 +1165,8 @@ void fz_debug_path(fz_path *, int indent); * Glyph cache */ +typedef struct fz_device_s fz_device; + void fz_new_glyph_cache_context(fz_context *ctx); void fz_free_glyph_cache_context(fz_context *ctx); @@ -1172,6 +1175,7 @@ fz_pixmap *fz_render_t3_glyph(fz_context *ctx, fz_font *font, int cid, fz_matrix fz_pixmap *fz_render_ft_stroked_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, fz_matrix ctm, fz_stroke_state *state); fz_pixmap *fz_render_glyph(fz_context *ctx, fz_font*, int, fz_matrix, fz_colorspace *model); fz_pixmap *fz_render_stroked_glyph(fz_context *ctx, fz_font*, int, fz_matrix, fz_matrix, fz_stroke_state *stroke); +void fz_render_t3_glyph_direct(fz_context *ctx, fz_device *dev, fz_font *font, int gid, fz_matrix trm, void *gstate); /* * Text buffer. @@ -1288,12 +1292,22 @@ enum FZ_IGNORE_SHADE = 2, /* Flags */ - FZ_CHARPROC_MASK = 1, - FZ_CHARPROC_COLOR = 2, + FZ_DEVFLAG_MASK = 1, + FZ_DEVFLAG_COLOR = 2, + FZ_DEVFLAG_UNCACHEABLE = 4, + FZ_DEVFLAG_FILLCOLOR_UNDEFINED = 8, + FZ_DEVFLAG_STROKECOLOR_UNDEFINED = 16, + FZ_DEVFLAG_STARTCAP_UNDEFINED = 32, + FZ_DEVFLAG_DASHCAP_UNDEFINED = 64, + FZ_DEVFLAG_ENDCAP_UNDEFINED = 128, + FZ_DEVFLAG_LINEJOIN_UNDEFINED = 256, + FZ_DEVFLAG_MITERLIMIT_UNDEFINED = 512, + FZ_DEVFLAG_LINEWIDTH_UNDEFINED = 1024, + /* Arguably we should have a bit for the dash pattern itself being + * undefined, but that causes problems; do we assume that it should + * always be set to non-dashing at the start of every glyph? */ }; -typedef struct fz_device_s fz_device; - struct fz_device_s { int hints; 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; +} diff --git a/pdf/mupdf.h b/pdf/mupdf.h index fa7cd2f8..0e21f930 100644 --- a/pdf/mupdf.h +++ b/pdf/mupdf.h @@ -465,6 +465,6 @@ void pdf_free_page(fz_context *ctx, pdf_page *page); void pdf_run_page_with_usage(pdf_xref *xref, pdf_page *page, fz_device *dev, fz_matrix ctm, char *event, fz_cookie *cookie); void pdf_run_page(pdf_xref *xref, pdf_page *page, fz_device *dev, fz_matrix ctm, fz_cookie *cookie); -void pdf_run_glyph(pdf_xref *xref, fz_obj *resources, fz_buffer *contents, fz_device *dev, fz_matrix ctm); +void pdf_run_glyph(pdf_xref *xref, fz_obj *resources, fz_buffer *contents, fz_device *dev, fz_matrix ctm, void *gstate); #endif diff --git a/pdf/pdf_interpret.c b/pdf/pdf_interpret.c index 2cfa5d99..7bb2da9c 100644 --- a/pdf/pdf_interpret.c +++ b/pdf/pdf_interpret.c @@ -88,6 +88,7 @@ struct pdf_csi_s /* text object state */ fz_text *text; + fz_rect text_bbox; fz_matrix tlm; fz_matrix tm; int text_mode; @@ -432,6 +433,19 @@ pdf_show_path(pdf_csi *csi, int doclose, int dofill, int dostroke, int even_odd) fz_path *path; fz_rect bbox; + if (dostroke) { + if (csi->dev->flags & (FZ_DEVFLAG_STROKECOLOR_UNDEFINED | FZ_DEVFLAG_LINEJOIN_UNDEFINED | FZ_DEVFLAG_LINEWIDTH_UNDEFINED)) + csi->dev->flags |= FZ_DEVFLAG_UNCACHEABLE; + else if (gstate->stroke_state.dash_len != 0 && csi->dev->flags & (FZ_DEVFLAG_STARTCAP_UNDEFINED | FZ_DEVFLAG_DASHCAP_UNDEFINED | FZ_DEVFLAG_ENDCAP_UNDEFINED)) + csi->dev->flags |= FZ_DEVFLAG_UNCACHEABLE; + else if (gstate->stroke_state.linejoin == FZ_LINEJOIN_MITER && (csi->dev->flags & FZ_DEVFLAG_MITERLIMIT_UNDEFINED)) + csi->dev->flags |= FZ_DEVFLAG_UNCACHEABLE; + } + if (dofill) { + if (csi->dev->flags & FZ_DEVFLAG_FILLCOLOR_UNDEFINED) + csi->dev->flags |= FZ_DEVFLAG_UNCACHEABLE; + } + path = csi->path; csi->path = fz_new_path(ctx); @@ -540,7 +554,6 @@ pdf_flush_text(pdf_csi *csi) int dostroke = 0; int doclip = 0; int doinvisible = 0; - fz_rect bbox; fz_context *ctx = csi->dev->ctx; if (!csi->text) @@ -566,9 +579,7 @@ pdf_flush_text(pdf_csi *csi) fz_try(ctx) { - bbox = fz_bound_text(ctx, text, gstate->ctm); - - pdf_begin_group(csi, bbox); + pdf_begin_group(csi, csi->text_bbox); if (doinvisible) fz_ignore_text(csi->dev, text, gstate->ctm); @@ -595,7 +606,7 @@ pdf_flush_text(pdf_csi *csi) if (gstate->fill.pattern) { fz_clip_text(csi->dev, text, gstate->ctm, 0); - pdf_show_pattern(csi, gstate->fill.pattern, bbox, PDF_FILL); + pdf_show_pattern(csi, gstate->fill.pattern, csi->text_bbox, PDF_FILL); fz_pop_clip(csi->dev); } break; @@ -624,7 +635,7 @@ pdf_flush_text(pdf_csi *csi) if (gstate->stroke.pattern) { fz_clip_stroke_text(csi->dev, text, &gstate->stroke_state, gstate->ctm); - pdf_show_pattern(csi, gstate->stroke.pattern, bbox, PDF_STROKE); + pdf_show_pattern(csi, gstate->stroke.pattern, csi->text_bbox, PDF_STROKE); fz_pop_clip(csi->dev); } break; @@ -664,6 +675,8 @@ pdf_show_char(pdf_csi *csi, int cid) int ucsbuf[8]; int ucslen; int i; + fz_rect bbox; + int render_direct; tsm.a = gstate->size * gstate->scale; tsm.b = 0; @@ -697,6 +710,15 @@ pdf_show_char(pdf_csi *csi, int cid) trm = fz_concat(tsm, csi->tm); + bbox = fz_bound_glyph(ctx, fontdesc->font, gid, trm); + /* Compensate for the glyph cache limited positioning precision */ + bbox.x0 -= 1; + bbox.y0 -= 1; + bbox.x1 += 1; + bbox.y1 += 1; + + render_direct = !fz_glyph_cacheable(fontdesc->font, gid); + /* flush buffered text if face or matrix or rendermode has changed */ if (!csi->text || fontdesc->font != csi->text->font || @@ -705,7 +727,8 @@ pdf_show_char(pdf_csi *csi, int cid) fabsf(trm.b - csi->text->trm.b) > FLT_EPSILON || fabsf(trm.c - csi->text->trm.c) > FLT_EPSILON || fabsf(trm.d - csi->text->trm.d) > FLT_EPSILON || - gstate->render != csi->text_mode) + gstate->render != csi->text_mode || + render_direct) { pdf_flush_text(csi); @@ -713,14 +736,28 @@ pdf_show_char(pdf_csi *csi, int cid) csi->text->trm.e = 0; csi->text->trm.f = 0; csi->text_mode = gstate->render; + csi->text_bbox = fz_empty_rect; } - /* add glyph to textobject */ - fz_add_text(ctx, csi->text, gid, ucsbuf[0], trm.e, trm.f); + if (render_direct) + { + /* Render the glyph stream direct here (only happens for + * type3 glyphs that seem to inherit current graphics + * attributes) */ + fz_matrix composed = fz_concat(trm, gstate->ctm); + fz_render_t3_glyph_direct(ctx, csi->dev, fontdesc->font, gid, composed, gstate); + } + else + { + csi->text_bbox = fz_union_rect(csi->text_bbox, bbox); + + /* add glyph to textobject */ + fz_add_text(ctx, csi->text, gid, ucsbuf[0], trm.e, trm.f); - /* add filler glyphs for one-to-many unicode mapping */ - for (i = 1; i < ucslen; i++) - fz_add_text(ctx, csi->text, -1, ucsbuf[i], trm.e, trm.f); + /* add filler glyphs for one-to-many unicode mapping */ + for (i = 1; i < ucslen; i++) + fz_add_text(ctx, csi->text, -1, ucsbuf[i], trm.e, trm.f); + } if (fontdesc->wmode == 0) { @@ -858,8 +895,49 @@ pdf_init_gstate(pdf_gstate *gs, fz_matrix ctm) gs->luminosity = 0; } +static pdf_material * +pdf_keep_material(pdf_material *mat) +{ + if (mat->colorspace) + fz_keep_colorspace(mat->colorspace); + if (mat->pattern) + pdf_keep_pattern(mat->pattern); + if (mat->shade) + fz_keep_shade(mat->shade); + return mat; +} + +static pdf_material * +pdf_drop_material(fz_context *ctx, pdf_material *mat) +{ + if (mat->colorspace) + fz_drop_colorspace(ctx, mat->colorspace); + if (mat->pattern) + pdf_drop_pattern(ctx, mat->pattern); + if (mat->shade) + fz_drop_shade(ctx, mat->shade); + return mat; +} + +static void +copy_state(pdf_gstate *gs, pdf_gstate *old) +{ + gs->stroke = old->stroke; + gs->fill = old->fill; + gs->font = old->font; + gs->softmask = old->softmask; + + pdf_keep_material(&gs->stroke); + pdf_keep_material(&gs->fill); + if (gs->font) + pdf_keep_font(gs->font); + if (gs->softmask) + pdf_keep_xobject(gs->softmask); +} + + static pdf_csi * -pdf_new_csi(pdf_xref *xref, fz_device *dev, fz_matrix ctm, char *event, fz_cookie *cookie) +pdf_new_csi(pdf_xref *xref, fz_device *dev, fz_matrix ctm, char *event, fz_cookie *cookie, pdf_gstate *gstate) { pdf_csi *csi; fz_context *ctx = dev->ctx; @@ -896,6 +974,8 @@ pdf_new_csi(pdf_xref *xref, fz_device *dev, fz_matrix ctm, char *event, fz_cooki csi->top_ctm = ctm; pdf_init_gstate(&csi->gstate[0], ctm); + if (gstate) + copy_state(&csi->gstate[0], gstate); csi->gtop = 0; csi->cookie = cookie; @@ -927,30 +1007,6 @@ pdf_clear_stack(pdf_csi *csi) csi->top = 0; } -static pdf_material * -pdf_keep_material(pdf_material *mat) -{ - if (mat->colorspace) - fz_keep_colorspace(mat->colorspace); - if (mat->pattern) - pdf_keep_pattern(mat->pattern); - if (mat->shade) - fz_keep_shade(mat->shade); - return mat; -} - -static pdf_material * -pdf_drop_material(fz_context *ctx, pdf_material *mat) -{ - if (mat->colorspace) - fz_drop_colorspace(ctx, mat->colorspace); - if (mat->pattern) - pdf_drop_pattern(ctx, mat->pattern); - if (mat->shade) - fz_drop_shade(ctx, mat->shade); - return mat; -} - static void pdf_gsave(pdf_csi *csi) { @@ -962,12 +1018,11 @@ pdf_gsave(pdf_csi *csi) csi->gstate = fz_resize_array(ctx, csi->gstate, csi->gcap*2, sizeof(pdf_gstate)); csi->gcap *= 2; } - gs = csi->gstate + csi->gtop; memcpy(&csi->gstate[csi->gtop + 1], &csi->gstate[csi->gtop], sizeof(pdf_gstate)); - csi->gtop ++; - + csi->gtop++; + gs = &csi->gstate[csi->gtop]; pdf_keep_material(&gs->stroke); pdf_keep_material(&gs->fill); if (gs->font) @@ -1419,16 +1474,26 @@ pdf_run_extgstate(pdf_csi *csi, fz_obj *rdb, fz_obj *extgstate) else if (!strcmp(s, "LC")) { + csi->dev->flags &= ~(FZ_DEVFLAG_STARTCAP_UNDEFINED | FZ_DEVFLAG_DASHCAP_UNDEFINED | FZ_DEVFLAG_ENDCAP_UNDEFINED); gstate->stroke_state.start_cap = fz_to_int(val); gstate->stroke_state.dash_cap = fz_to_int(val); gstate->stroke_state.end_cap = fz_to_int(val); } else if (!strcmp(s, "LW")) + { + csi->dev->flags &= ~FZ_DEVFLAG_LINEWIDTH_UNDEFINED; gstate->stroke_state.linewidth = fz_to_real(val); + } else if (!strcmp(s, "LJ")) + { + csi->dev->flags &= ~FZ_DEVFLAG_LINEJOIN_UNDEFINED; gstate->stroke_state.linejoin = fz_to_int(val); + } else if (!strcmp(s, "ML")) + { + csi->dev->flags &= ~FZ_DEVFLAG_MITERLIMIT_UNDEFINED; gstate->stroke_state.miterlimit = fz_to_real(val); + } else if (!strcmp(s, "D")) { @@ -1655,12 +1720,16 @@ static void pdf_run_cs_imp(pdf_csi *csi, fz_obj *rdb, int what) static void pdf_run_CS(pdf_csi *csi, fz_obj *rdb) { + csi->dev->flags &= ~FZ_DEVFLAG_STROKECOLOR_UNDEFINED; + pdf_run_cs_imp(csi, rdb, PDF_STROKE); /* RJW: "cannot set colorspace" */ } static void pdf_run_cs(pdf_csi *csi, fz_obj *rdb) { + csi->dev->flags &= ~FZ_DEVFLAG_FILLCOLOR_UNDEFINED; + pdf_run_cs_imp(csi, rdb, PDF_FILL); /* RJW: "cannot set colorspace" */ } @@ -1774,6 +1843,7 @@ static void pdf_run_F(pdf_csi *csi) static void pdf_run_G(pdf_csi *csi) { + csi->dev->flags &= ~FZ_DEVFLAG_STROKECOLOR_UNDEFINED; pdf_set_colorspace(csi, PDF_STROKE, fz_device_gray); pdf_set_color(csi, PDF_STROKE, csi->stack); } @@ -1781,6 +1851,7 @@ static void pdf_run_G(pdf_csi *csi) static void pdf_run_J(pdf_csi *csi) { pdf_gstate *gstate = csi->gstate + csi->gtop; + csi->dev->flags &= ~(FZ_DEVFLAG_STARTCAP_UNDEFINED | FZ_DEVFLAG_DASHCAP_UNDEFINED | FZ_DEVFLAG_ENDCAP_UNDEFINED); gstate->stroke_state.start_cap = csi->stack[0]; gstate->stroke_state.dash_cap = csi->stack[0]; gstate->stroke_state.end_cap = csi->stack[0]; @@ -1788,6 +1859,7 @@ static void pdf_run_J(pdf_csi *csi) static void pdf_run_K(pdf_csi *csi) { + csi->dev->flags &= ~FZ_DEVFLAG_STROKECOLOR_UNDEFINED; pdf_set_colorspace(csi, PDF_STROKE, fz_device_cmyk); pdf_set_color(csi, PDF_STROKE, csi->stack); } @@ -1795,6 +1867,7 @@ static void pdf_run_K(pdf_csi *csi) static void pdf_run_M(pdf_csi *csi) { pdf_gstate *gstate = csi->gstate + csi->gtop; + csi->dev->flags &= ~FZ_DEVFLAG_MITERLIMIT_UNDEFINED; gstate->stroke_state.miterlimit = csi->stack[0]; } @@ -1809,6 +1882,7 @@ static void pdf_run_Q(pdf_csi *csi) static void pdf_run_RG(pdf_csi *csi) { + csi->dev->flags &= ~FZ_DEVFLAG_STROKECOLOR_UNDEFINED; pdf_set_colorspace(csi, PDF_STROKE, fz_device_rgb); pdf_set_color(csi, PDF_STROKE, csi->stack); } @@ -1880,6 +1954,7 @@ static void pdf_run_SC_imp(pdf_csi *csi, fz_obj *rdb, int what, pdf_material *ma static void pdf_run_SC(pdf_csi *csi, fz_obj *rdb) { pdf_gstate *gstate = csi->gstate + csi->gtop; + csi->dev->flags &= ~FZ_DEVFLAG_STROKECOLOR_UNDEFINED; pdf_run_SC_imp(csi, rdb, PDF_STROKE, &gstate->stroke); /* RJW: "cannot set color and colorspace" */ } @@ -1887,6 +1962,7 @@ static void pdf_run_SC(pdf_csi *csi, fz_obj *rdb) static void pdf_run_sc(pdf_csi *csi, fz_obj *rdb) { pdf_gstate *gstate = csi->gstate + csi->gtop; + csi->dev->flags &= ~FZ_DEVFLAG_FILLCOLOR_UNDEFINED; pdf_run_SC_imp(csi, rdb, PDF_FILL, &gstate->fill); /* RJW: "cannot set color and colorspace" */ } @@ -2070,12 +2146,20 @@ static void pdf_run_d(pdf_csi *csi) static void pdf_run_d0(pdf_csi *csi) { - csi->dev->flags |= FZ_CHARPROC_COLOR; + csi->dev->flags |= FZ_DEVFLAG_COLOR; } static void pdf_run_d1(pdf_csi *csi) { - csi->dev->flags |= FZ_CHARPROC_MASK; + csi->dev->flags |= FZ_DEVFLAG_MASK; + csi->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); } static void pdf_run_f(pdf_csi *csi) @@ -2090,6 +2174,7 @@ static void pdf_run_fstar(pdf_csi *csi) static void pdf_run_g(pdf_csi *csi) { + csi->dev->flags &= ~FZ_DEVFLAG_FILLCOLOR_UNDEFINED; pdf_set_colorspace(csi, PDF_FILL, fz_device_gray); pdf_set_color(csi, PDF_FILL, csi->stack); } @@ -2124,11 +2209,13 @@ static void pdf_run_i(pdf_csi *csi) static void pdf_run_j(pdf_csi *csi) { pdf_gstate *gstate = csi->gstate + csi->gtop; + csi->dev->flags &= ~FZ_DEVFLAG_LINEJOIN_UNDEFINED; gstate->stroke_state.linejoin = csi->stack[0]; } static void pdf_run_k(pdf_csi *csi) { + csi->dev->flags &= ~FZ_DEVFLAG_FILLCOLOR_UNDEFINED; pdf_set_colorspace(csi, PDF_FILL, fz_device_cmyk); pdf_set_color(csi, PDF_FILL, csi->stack); } @@ -2178,6 +2265,7 @@ static void pdf_run_re(pdf_csi *csi) static void pdf_run_rg(pdf_csi *csi) { + csi->dev->flags &= ~FZ_DEVFLAG_FILLCOLOR_UNDEFINED; pdf_set_colorspace(csi, PDF_FILL, fz_device_rgb); pdf_set_color(csi, PDF_FILL, csi->stack); } @@ -2237,6 +2325,7 @@ static void pdf_run_w(pdf_csi *csi) { pdf_gstate *gstate = csi->gstate + csi->gtop; pdf_flush_text(csi); /* linewidth affects stroked text rendering mode */ + csi->dev->flags &= ~FZ_DEVFLAG_LINEWIDTH_UNDEFINED; gstate->stroke_state.linewidth = csi->stack[0]; } @@ -2607,7 +2696,7 @@ pdf_run_page_with_usage(pdf_xref *xref, pdf_page *page, fz_device *dev, fz_matri if (page->transparency) fz_begin_group(dev, fz_transform_rect(ctm, page->mediabox), 1, 0, 0, 1); - csi = pdf_new_csi(xref, dev, ctm, event, cookie); + csi = pdf_new_csi(xref, dev, ctm, event, cookie, NULL); fz_try(ctx) { pdf_run_buffer(csi, page->resources, page->contents); @@ -2649,7 +2738,7 @@ pdf_run_page_with_usage(pdf_xref *xref, pdf_page *page, fz_device *dev, fz_matri if (!strcmp(event, "View") && (flags & (1 << 5))) /* NoView */ continue; - csi = pdf_new_csi(xref, dev, ctm, event, cookie); + csi = pdf_new_csi(xref, dev, ctm, event, cookie, NULL); if (!pdf_is_hidden_ocg(fz_dict_gets(annot->obj, "OC"), csi, page->resources)) { fz_try(ctx) @@ -2676,9 +2765,9 @@ pdf_run_page(pdf_xref *xref, pdf_page *page, fz_device *dev, fz_matrix ctm, fz_c } void -pdf_run_glyph(pdf_xref *xref, fz_obj *resources, fz_buffer *contents, fz_device *dev, fz_matrix ctm) +pdf_run_glyph(pdf_xref *xref, fz_obj *resources, fz_buffer *contents, fz_device *dev, fz_matrix ctm, void *gstate) { - pdf_csi *csi = pdf_new_csi(xref, dev, ctm, "View", NULL); + pdf_csi *csi = pdf_new_csi(xref, dev, ctm, "View", NULL, gstate); fz_context *ctx = xref->ctx; fz_try(ctx) diff --git a/pdf/pdf_type3.c b/pdf/pdf_type3.c index f43170c4..d9bf528e 100644 --- a/pdf/pdf_type3.c +++ b/pdf/pdf_type3.c @@ -2,9 +2,9 @@ #include "mupdf.h" static void -pdf_run_glyph_func(void *xref, fz_obj *rdb, fz_buffer *contents, fz_device *dev, fz_matrix ctm) +pdf_run_glyph_func(void *xref, fz_obj *rdb, fz_buffer *contents, fz_device *dev, fz_matrix ctm, void *gstate) { - pdf_run_glyph(xref, rdb, contents, dev, ctm); + pdf_run_glyph(xref, rdb, contents, dev, ctm, gstate); } pdf_font_desc * |