summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fitz/fitz.h32
-rw-r--r--fitz/res_font.c56
-rw-r--r--pdf/mupdf.h2
-rw-r--r--pdf/pdf_interpret.c181
-rw-r--r--pdf/pdf_type3.c4
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 *