summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--draw/meshdraw.c10
-rw-r--r--fitz/dev_draw.c27
-rw-r--r--fitz/dev_null.c2
-rw-r--r--fitz/filt_faxd.c5
-rw-r--r--fitz/fitz.h8
-rw-r--r--fitz/res_shade.c12
-rw-r--r--mupdf/mupdf.h14
-rw-r--r--mupdf/pdf_build.c79
-rw-r--r--mupdf/pdf_colorspace.c2
-rw-r--r--mupdf/pdf_crypt.c8
-rw-r--r--mupdf/pdf_interpret.c1709
-rw-r--r--mupdf/pdf_shade.c26
-rw-r--r--xps/xps_gradient.c4
13 files changed, 903 insertions, 1003 deletions
diff --git a/draw/meshdraw.c b/draw/meshdraw.c
index 71c0bdb7..79437505 100644
--- a/draw/meshdraw.c
+++ b/draw/meshdraw.c
@@ -498,7 +498,7 @@ fz_paintmesh(fz_shade *shade, fz_matrix ctm, fz_pixmap *dest, fz_bbox bbox)
if (shade->usefunction)
ntris = shade->meshlen / 9;
else
- ntris = shade->meshlen / ((2 + shade->cs->n) * 3);
+ ntris = shade->meshlen / ((2 + shade->colorspace->n) * 3);
while (ntris--)
{
@@ -513,10 +513,10 @@ fz_paintmesh(fz_shade *shade, fz_matrix ctm, fz_pixmap *dest, fz_bbox bbox)
tri[k][2] = *mesh++ * 255;
else
{
- fz_convertcolor(shade->cs, mesh, dest->colorspace, tri[k] + 2);
+ fz_convertcolor(shade->colorspace, mesh, dest->colorspace, tri[k] + 2);
for (i = 0; i < dest->colorspace->n; i++)
tri[k][i + 2] *= 255;
- mesh += shade->cs->n;
+ mesh += shade->colorspace->n;
}
}
fz_painttriangle(dest, tri[0], tri[1], tri[2], 2 + dest->colorspace->n, bbox);
@@ -537,10 +537,10 @@ fz_paintshade(fz_shade *shade, fz_matrix ctm, fz_pixmap *dest, fz_bbox bbox)
{
for (i = 0; i < 256; i++)
{
- fz_convertcolor(shade->cs, shade->function[i], dest->colorspace, color);
+ fz_convertcolor(shade->colorspace, shade->function[i], dest->colorspace, color);
for (k = 0; k < dest->colorspace->n; k++)
clut[i][k] = color[k] * 255;
- clut[i][k] = shade->function[i][shade->cs->n] * 255;
+ clut[i][k] = shade->function[i][shade->colorspace->n] * 255;
}
conv = fz_newpixmapwithrect(dest->colorspace, bbox);
temp = fz_newpixmapwithrect(fz_devicegray, bbox);
diff --git a/fitz/dev_draw.c b/fitz/dev_draw.c
index 4d3c94f2..e9cb74fc 100644
--- a/fitz/dev_draw.c
+++ b/fitz/dev_draw.c
@@ -499,7 +499,7 @@ fz_drawfillshade(void *user, fz_shade *shade, fz_matrix ctm, float alpha)
{
unsigned char *s;
int x, y, n, i;
- fz_convertcolor(shade->cs, shade->background, model, colorfv);
+ fz_convertcolor(shade->colorspace, shade->background, model, colorfv);
for (i = 0; i < model->n; i++)
colorbv[i] = colorfv[i] * 255;
colorbv[i] = 255;
@@ -580,6 +580,7 @@ fz_drawfillimage(void *user, fz_pixmap *image, fz_matrix ctm, float alpha)
fz_colorspace *model = dev->dest->colorspace;
fz_pixmap *converted = nil;
fz_pixmap *scaled = nil;
+ int after;
int dx, dy;
if (!model)
@@ -591,7 +592,15 @@ fz_drawfillimage(void *user, fz_pixmap *image, fz_matrix ctm, float alpha)
if (image->w == 0 || image->h == 0)
return;
- if (image->colorspace != model)
+ /* convert images with more components (cmyk->rgb) before scaling */
+ /* convert images with fewer components (gray->rgb after scaling */
+ /* convert images with expensive colorspace transforms after scaling */
+
+ after = 0;
+ if (image->colorspace == fz_devicegray)
+ after = 1;
+
+ if (image->colorspace != model && !after)
{
converted = fz_newpixmap(model, image->x, image->y, image->w, image->h);
fz_convertpixmap(image, converted);
@@ -601,7 +610,7 @@ fz_drawfillimage(void *user, fz_pixmap *image, fz_matrix ctm, float alpha)
#ifdef SMOOTHSCALE
dx = sqrtf(ctm.a * ctm.a + ctm.b * ctm.b);
dy = sqrtf(ctm.c * ctm.c + ctm.d * ctm.d);
- if (dx < image->w || dy < image->h)
+ if (dx < image->w && dy < image->h)
{
scaled = fz_smoothtransformpixmap(image, &ctm, dev->dest->x, dev->dest->y, dx, dy);
if (scaled == nil)
@@ -623,6 +632,14 @@ fz_drawfillimage(void *user, fz_pixmap *image, fz_matrix ctm, float alpha)
}
#endif
+
+ if (image->colorspace != model && after)
+ {
+ converted = fz_newpixmap(model, image->x, image->y, image->w, image->h);
+ fz_convertpixmap(image, converted);
+ image = converted;
+ }
+
fz_paintimage(dev->dest, dev->scissor, image, ctm, alpha * 255);
if (scaled)
@@ -649,7 +666,7 @@ fz_drawfillimagemask(void *user, fz_pixmap *image, fz_matrix ctm,
#ifdef SMOOTHSCALE
dx = sqrtf(ctm.a * ctm.a + ctm.b * ctm.b);
dy = sqrtf(ctm.c * ctm.c + ctm.d * ctm.d);
- if (dx < image->w || dy < image->h)
+ if (dx < image->w && dy < image->h)
{
scaled = fz_smoothtransformpixmap(image, &ctm, dev->dest->x, dev->dest->y, dx, dy);
if (scaled == nil)
@@ -720,7 +737,7 @@ fz_drawclipimagemask(void *user, fz_pixmap *image, fz_matrix ctm)
#ifdef SMOOTHSCALE
dx = sqrtf(ctm.a * ctm.a + ctm.b * ctm.b);
dy = sqrtf(ctm.c * ctm.c + ctm.d * ctm.d);
- if (dx < image->w || dy < image->h)
+ if (dx < image->w && dy < image->h)
{
scaled = fz_smoothtransformpixmap(image, &ctm, dev->dest->x, dev->dest->y, dx, dy);
if (scaled == nil)
diff --git a/fitz/dev_null.c b/fitz/dev_null.c
index c48cc2aa..7c80b0ff 100644
--- a/fitz/dev_null.c
+++ b/fitz/dev_null.c
@@ -15,7 +15,7 @@ static void fz_nullfillshade(void *user, fz_shade *shade, fz_matrix ctm, float a
static void fz_nullfillimage(void *user, fz_pixmap *image, fz_matrix ctm, float alpha) {}
static void fz_nullfillimagemask(void *user, fz_pixmap *image, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha) {}
static void fz_nullclipimagemask(void *user, fz_pixmap *image, fz_matrix ctm) {}
-static void fz_nullbeginmask(void *user, fz_rect r, int luminosity, fz_colorspace *cs, float *bc) {}
+static void fz_nullbeginmask(void *user, fz_rect r, int luminosity, fz_colorspace *colorspace, float *bc) {}
static void fz_nullendmask(void *user) {}
static void fz_nullbegingroup(void *user, fz_rect r, int isolated, int knockout, fz_blendmode blendmode, float alpha) {}
static void fz_nullendgroup(void *user) {}
diff --git a/fitz/filt_faxd.c b/fitz/filt_faxd.c
index 5da826ae..714629e7 100644
--- a/fitz/filt_faxd.c
+++ b/fitz/filt_faxd.c
@@ -625,14 +625,15 @@ eol:
if (fax->rp < fax->wp)
return p - buf;
- fax->rp = fax->dst;
- fax->wp = fax->dst + fax->stride;
tmp = fax->ref;
fax->ref = fax->dst;
fax->dst = tmp;
memset(fax->dst, 0, fax->stride);
+ fax->rp = fax->dst;
+ fax->wp = fax->dst + fax->stride;
+
fax->stage = SNORMAL;
fax->c = 0;
fax->a = -1;
diff --git a/fitz/fitz.h b/fitz/fitz.h
index 39542c0d..d79e280e 100644
--- a/fitz/fitz.h
+++ b/fitz/fitz.h
@@ -720,8 +720,8 @@ struct fz_colorspace_s
};
fz_colorspace *fz_newcolorspace(char *name, int n);
-fz_colorspace *fz_keepcolorspace(fz_colorspace *cs);
-void fz_dropcolorspace(fz_colorspace *cs);
+fz_colorspace *fz_keepcolorspace(fz_colorspace *colorspace);
+void fz_dropcolorspace(fz_colorspace *colorspace);
void fz_convertcolor(fz_colorspace *srcs, float *srcv, fz_colorspace *dsts, float *dstv);
void fz_convertpixmap(fz_pixmap *src, fz_pixmap *dst);
@@ -894,7 +894,7 @@ struct fz_shade_s
int refs;
fz_rect bbox; /* can be fz_infiniterect */
- fz_colorspace *cs;
+ fz_colorspace *colorspace;
fz_matrix matrix; /* matrix from pattern dict */
int usebackground; /* background color for fills but not 'sh' */
@@ -1019,7 +1019,7 @@ struct fz_device_s
void (*popclip)(void *);
- void (*beginmask)(void *, fz_rect, int luminosity, fz_colorspace *cs, float *bc);
+ void (*beginmask)(void *, fz_rect, int luminosity, fz_colorspace *, float *bc);
void (*endmask)(void *);
void (*begingroup)(void *, fz_rect, int isolated, int knockout, fz_blendmode blendmode, float alpha);
void (*endgroup)(void *);
diff --git a/fitz/res_shade.c b/fitz/res_shade.c
index d6108236..e4afa14a 100644
--- a/fitz/res_shade.c
+++ b/fitz/res_shade.c
@@ -12,8 +12,8 @@ fz_dropshade(fz_shade *shade)
{
if (shade && --shade->refs == 0)
{
- if (shade->cs)
- fz_dropcolorspace(shade->cs);
+ if (shade->colorspace)
+ fz_dropcolorspace(shade->colorspace);
fz_free(shade->mesh);
fz_free(shade);
}
@@ -28,7 +28,7 @@ fz_boundshade(fz_shade *shade, fz_matrix ctm)
int i, ncomp, nvert;
ctm = fz_concat(shade->matrix, ctm);
- ncomp = shade->usefunction ? 3 : 2 + shade->cs->n;
+ ncomp = shade->usefunction ? 3 : 2 + shade->colorspace->n;
nvert = shade->meshlen / ncomp;
v = shade->mesh;
@@ -82,7 +82,7 @@ fz_debugshade(fz_shade *shade)
shade->bbox.x0, shade->bbox.y0,
shade->bbox.x1, shade->bbox.y1);
- printf("\tcolorspace %s\n", shade->cs->name);
+ printf("\tcolorspace %s\n", shade->colorspace->name);
printf("\tmatrix [%g %g %g %g %g %g]\n",
shade->matrix.a, shade->matrix.b, shade->matrix.c,
@@ -91,7 +91,7 @@ fz_debugshade(fz_shade *shade)
if (shade->usebackground)
{
printf("\tbackground [");
- for (i = 0; i < shade->cs->n; i++)
+ for (i = 0; i < shade->colorspace->n; i++)
printf("%s%g", i == 0 ? "" : " ", shade->background[i]);
printf("]\n");
}
@@ -102,7 +102,7 @@ fz_debugshade(fz_shade *shade)
n = 3;
}
else
- n = 2 + shade->cs->n;
+ n = 2 + shade->colorspace->n;
printf("\tvertices: %d\n", shade->meshlen);
diff --git a/mupdf/mupdf.h b/mupdf/mupdf.h
index a9a2a2ea..fe4cfee3 100644
--- a/mupdf/mupdf.h
+++ b/mupdf/mupdf.h
@@ -555,7 +555,7 @@ enum
struct pdf_material_s
{
int kind;
- fz_colorspace *cs;
+ fz_colorspace *colorspace;
pdf_pattern *pattern;
fz_shade *shade;
float alpha;
@@ -597,10 +597,16 @@ struct pdf_csi_s
fz_device *dev;
pdf_xref *xref;
- fz_obj *stack[32];
+ fz_obj *obj;
+ char name[256];
+ unsigned char string[256];
+ int stringlen;
+ float stack[32];
int top;
+
int xbalance;
- fz_obj *array;
+ int intext;
+ int inarray;
/* path object state */
fz_path *path;
@@ -627,6 +633,8 @@ void pdf_setcolor(pdf_csi *csi, int what, float *v);
void pdf_setpattern(pdf_csi *csi, int what, pdf_pattern *pat, float *v);
void pdf_setshade(pdf_csi *csi, int what, fz_shade *shade);
void pdf_showpath(pdf_csi*, int close, int fill, int stroke, int evenodd);
+void pdf_showspace(pdf_csi *csi, float tadj);
+void pdf_showstring(pdf_csi *csi, unsigned char *buf, int len);
void pdf_showtext(pdf_csi*, fz_obj *text);
void pdf_flushtext(pdf_csi*);
void pdf_showimage(pdf_csi*, fz_pixmap *image);
diff --git a/mupdf/pdf_build.c b/mupdf/pdf_build.c
index 739ec976..4e19db92 100644
--- a/mupdf/pdf_build.c
+++ b/mupdf/pdf_build.c
@@ -16,14 +16,14 @@ pdf_initgstate(pdf_gstate *gs, fz_matrix ctm)
memset(gs->strokestate.dashlist, 0, sizeof(gs->strokestate.dashlist));
gs->stroke.kind = PDF_MCOLOR;
- gs->stroke.cs = fz_keepcolorspace(fz_devicegray);
+ gs->stroke.colorspace = fz_keepcolorspace(fz_devicegray);
gs->stroke.v[0] = 0;
gs->stroke.pattern = nil;
gs->stroke.shade = nil;
gs->stroke.alpha = 1;
gs->fill.kind = PDF_MCOLOR;
- gs->fill.cs = fz_keepcolorspace(fz_devicegray);
+ gs->fill.colorspace = fz_keepcolorspace(fz_devicegray);
gs->fill.v[0] = 0;
gs->fill.pattern = nil;
gs->fill.shade = nil;
@@ -45,7 +45,7 @@ pdf_initgstate(pdf_gstate *gs, fz_matrix ctm)
}
void
-pdf_setcolorspace(pdf_csi *csi, int what, fz_colorspace *cs)
+pdf_setcolorspace(pdf_csi *csi, int what, fz_colorspace *colorspace)
{
pdf_gstate *gs = csi->gstate + csi->gtop;
pdf_material *mat;
@@ -54,10 +54,10 @@ pdf_setcolorspace(pdf_csi *csi, int what, fz_colorspace *cs)
mat = what == PDF_MFILL ? &gs->fill : &gs->stroke;
- fz_dropcolorspace(mat->cs);
+ fz_dropcolorspace(mat->colorspace);
mat->kind = PDF_MCOLOR;
- mat->cs = fz_keepcolorspace(cs);
+ mat->colorspace = fz_keepcolorspace(colorspace);
mat->v[0] = 0;
mat->v[1] = 0;
@@ -80,13 +80,13 @@ pdf_setcolor(pdf_csi *csi, int what, float *v)
{
case PDF_MPATTERN:
case PDF_MCOLOR:
- if (!strcmp(mat->cs->name, "Lab"))
+ if (!strcmp(mat->colorspace->name, "Lab"))
{
mat->v[0] = v[0] / 100;
mat->v[1] = (v[1] + 100) / 200;
mat->v[2] = (v[2] + 100) / 200;
}
- for (i = 0; i < mat->cs->n; i++)
+ for (i = 0; i < mat->colorspace->n; i++)
mat->v[i] = v[i];
break;
default:
@@ -310,7 +310,7 @@ pdf_showimage(pdf_csi *csi, fz_pixmap *image)
break;
case PDF_MCOLOR:
csi->dev->fillimagemask(csi->dev->user, image, gstate->ctm,
- gstate->fill.cs, gstate->fill.v, gstate->fill.alpha);
+ gstate->fill.colorspace, gstate->fill.v, gstate->fill.alpha);
break;
case PDF_MPATTERN:
if (gstate->fill.pattern)
@@ -380,7 +380,7 @@ pdf_showpath(pdf_csi *csi, int doclose, int dofill, int dostroke, int evenodd)
break;
case PDF_MCOLOR:
csi->dev->fillpath(csi->dev->user, path, evenodd, gstate->ctm,
- gstate->fill.cs, gstate->fill.v, gstate->fill.alpha);
+ gstate->fill.colorspace, gstate->fill.v, gstate->fill.alpha);
break;
case PDF_MPATTERN:
if (gstate->fill.pattern)
@@ -409,7 +409,7 @@ pdf_showpath(pdf_csi *csi, int doclose, int dofill, int dostroke, int evenodd)
break;
case PDF_MCOLOR:
csi->dev->strokepath(csi->dev->user, path, &gstate->strokestate, gstate->ctm,
- gstate->stroke.cs, gstate->stroke.v, gstate->stroke.alpha);
+ gstate->stroke.colorspace, gstate->stroke.v, gstate->stroke.alpha);
break;
case PDF_MPATTERN:
if (gstate->stroke.pattern)
@@ -487,7 +487,7 @@ pdf_flushtext(pdf_csi *csi)
break;
case PDF_MCOLOR:
csi->dev->filltext(csi->dev->user, text, gstate->ctm,
- gstate->fill.cs, gstate->fill.v, gstate->fill.alpha);
+ gstate->fill.colorspace, gstate->fill.v, gstate->fill.alpha);
break;
case PDF_MPATTERN:
if (gstate->fill.pattern)
@@ -516,7 +516,7 @@ pdf_flushtext(pdf_csi *csi)
break;
case PDF_MCOLOR:
csi->dev->stroketext(csi->dev->user, text, &gstate->strokestate, gstate->ctm,
- gstate->stroke.cs, gstate->stroke.v, gstate->stroke.alpha);
+ gstate->stroke.colorspace, gstate->stroke.v, gstate->stroke.alpha);
break;
case PDF_MPATTERN:
if (gstate->stroke.pattern)
@@ -629,11 +629,18 @@ pdf_showglyph(pdf_csi *csi, int cid)
}
}
-static void
+void
pdf_showspace(pdf_csi *csi, float tadj)
{
pdf_gstate *gstate = csi->gstate + csi->gtop;
pdf_fontdesc *fontdesc = gstate->font;
+
+ if (!fontdesc)
+ {
+ fz_warn("cannot draw text since font and size not set");
+ return;
+ }
+
if (fontdesc->wmode == 0)
csi->tm = fz_concat(fz_translate(tadj * gstate->scale, 0), csi->tm);
else
@@ -641,13 +648,11 @@ pdf_showspace(pdf_csi *csi, float tadj)
}
void
-pdf_showtext(pdf_csi *csi, fz_obj *text)
+pdf_showstring(pdf_csi *csi, unsigned char *buf, int len)
{
pdf_gstate *gstate = csi->gstate + csi->gtop;
pdf_fontdesc *fontdesc = gstate->font;
- unsigned char *buf;
- unsigned char *end;
- int i, len;
+ unsigned char *end = buf + len;
int cpt, cid;
if (!fontdesc)
@@ -656,34 +661,38 @@ pdf_showtext(pdf_csi *csi, fz_obj *text)
return;
}
+ while (buf < end)
+ {
+ buf = pdf_decodecmap(fontdesc->encoding, buf, &cpt);
+ cid = pdf_lookupcmap(fontdesc->encoding, cpt);
+ if (cid >= 0)
+ pdf_showglyph(csi, cid);
+ else
+ fz_warn("cannot encode character with code point %#x", cpt);
+ if (cpt == 32)
+ pdf_showspace(csi, gstate->wordspace);
+ }
+}
+
+void
+pdf_showtext(pdf_csi *csi, fz_obj *text)
+{
+ pdf_gstate *gstate = csi->gstate + csi->gtop;
+ int i;
+
if (fz_isarray(text))
{
for (i = 0; i < fz_arraylen(text); i++)
{
fz_obj *item = fz_arrayget(text, i);
if (fz_isstring(item))
- pdf_showtext(csi, item);
+ pdf_showstring(csi, (unsigned char *)fz_tostrbuf(item), fz_tostrlen(item));
else
pdf_showspace(csi, - fz_toreal(item) * gstate->size * 0.001f);
}
}
-
- if (fz_isstring(text))
+ else if (fz_isstring(text))
{
- buf = (unsigned char *)fz_tostrbuf(text);
- len = fz_tostrlen(text);
- end = buf + len;
-
- while (buf < end)
- {
- buf = pdf_decodecmap(fontdesc->encoding, buf, &cpt);
- cid = pdf_lookupcmap(fontdesc->encoding, cpt);
- if (cid >= 0)
- pdf_showglyph(csi, cid);
- else
- fz_warn("cannot encode character with code point %#x", cpt);
- if (cpt == 32)
- pdf_showspace(csi, gstate->wordspace);
- }
+ pdf_showstring(csi, (unsigned char *)fz_tostrbuf(text), fz_tostrlen(text));
}
}
diff --git a/mupdf/pdf_colorspace.c b/mupdf/pdf_colorspace.c
index 765b3c68..6203e1bb 100644
--- a/mupdf/pdf_colorspace.c
+++ b/mupdf/pdf_colorspace.c
@@ -246,8 +246,10 @@ loadindexed(fz_colorspace **csp, pdf_xref *xref, fz_obj *array)
idx = fz_malloc(sizeof(struct indexed));
idx->base = base;
idx->high = fz_toint(highobj);
+ idx->high = CLAMP(idx->high, 0, 255);
n = base->n * (idx->high + 1);
idx->lookup = fz_malloc(n);
+ memset(idx->lookup, 0, n);
cs = fz_newcolorspace("Indexed", 1);
cs->toxyz = indexedtoxyz;
diff --git a/mupdf/pdf_crypt.c b/mupdf/pdf_crypt.c
index 25cb1d8d..6266e188 100644
--- a/mupdf/pdf_crypt.c
+++ b/mupdf/pdf_crypt.c
@@ -120,6 +120,10 @@ pdf_newcrypt(pdf_crypt **cryptp, fz_obj *dict, fz_obj *id)
}
}
}
+
+ /* in crypt revision 4, the crypt filter determines the key length */
+ if (crypt->strf.method != PDF_CRYPT_NONE)
+ crypt->length = crypt->stmf.length;
}
}
@@ -251,6 +255,10 @@ pdf_parsecryptfilter(pdf_cryptfilter *cf, fz_obj *dict, int defaultlength)
if (fz_isint(obj))
cf->length = fz_toint(obj);
+ /* the length for crypt filters is supposed to be in bytes not bits */
+ if (cf->length < 40)
+ cf->length = cf->length * 8;
+
if ((cf->length % 8) != 0)
return fz_throw("invalid key length: %d", cf->length);
diff --git a/mupdf/pdf_interpret.c b/mupdf/pdf_interpret.c
index db5fcf93..6de24e74 100644
--- a/mupdf/pdf_interpret.c
+++ b/mupdf/pdf_interpret.c
@@ -11,8 +11,14 @@ pdf_newcsi(pdf_xref *xref, fz_device *dev, fz_matrix ctm)
csi->dev = dev;
csi->top = 0;
+ csi->obj = nil;
+ csi->name[0] = 0;
+ csi->stringlen = 0;
+ memset(csi->stack, 0, sizeof csi->stack);
+
csi->xbalance = 0;
- csi->array = nil;
+ csi->intext = 0;
+ csi->inarray = 0;
csi->path = fz_newpath();
csi->clip = 0;
@@ -35,16 +41,24 @@ static void
pdf_clearstack(pdf_csi *csi)
{
int i;
+
+ if (csi->obj)
+ fz_dropobj(csi->obj);
+ csi->obj = nil;
+
+ csi->name[0] = 0;
+ csi->stringlen = 0;
for (i = 0; i < csi->top; i++)
- fz_dropobj(csi->stack[i]);
+ csi->stack[i] = 0;
+
csi->top = 0;
}
pdf_material *
pdf_keepmaterial(pdf_material *mat)
{
- if (mat->cs)
- fz_keepcolorspace(mat->cs);
+ if (mat->colorspace)
+ fz_keepcolorspace(mat->colorspace);
if (mat->pattern)
pdf_keeppattern(mat->pattern);
if (mat->shade)
@@ -55,8 +69,8 @@ pdf_keepmaterial(pdf_material *mat)
pdf_material *
pdf_dropmaterial(pdf_material *mat)
{
- if (mat->cs)
- fz_dropcolorspace(mat->cs);
+ if (mat->colorspace)
+ fz_dropcolorspace(mat->colorspace);
if (mat->pattern)
pdf_droppattern(mat->pattern);
if (mat->shade)
@@ -134,7 +148,6 @@ pdf_freecsi(pdf_csi *csi)
if (csi->path) fz_freepath(csi->path);
if (csi->text) fz_freetext(csi->text);
- if (csi->array) fz_dropobj(csi->array);
pdf_clearstack(csi);
@@ -260,8 +273,9 @@ pdf_runinlineimage(pdf_csi *csi, fz_obj *rdb, fz_stream *file, fz_obj *dict)
}
static fz_error
-pdf_runextgstate(pdf_csi *csi, pdf_gstate *gstate, fz_obj *rdb, fz_obj *extgstate)
+pdf_runextgstate(pdf_csi *csi, fz_obj *rdb, fz_obj *extgstate)
{
+ pdf_gstate *gstate = csi->gstate + csi->gtop;
fz_colorspace *colorspace;
int i, k;
@@ -400,962 +414,843 @@ pdf_runextgstate(pdf_csi *csi, pdf_gstate *gstate, fz_obj *rdb, fz_obj *extgstat
return fz_okay;
}
-/* TODO: split pdf_runkeyword into more manageable pieces */
+static void pdf_run_BDC(pdf_csi *csi)
+{
+}
-static fz_error
-pdf_runkeyword(pdf_csi *csi, fz_obj *rdb, char *buf)
+static fz_error pdf_run_BI(pdf_csi *csi, fz_obj *rdb, fz_stream *file)
{
- pdf_gstate *gstate = csi->gstate + csi->gtop;
+ int ch;
fz_error error;
- float a, b, c, d, e, f;
- float x, y, w, h;
- fz_matrix m;
- float v[FZ_MAXCOLORS];
- int what;
- int i;
+ char *buf = csi->xref->scratch;
+ int buflen = sizeof(csi->xref->scratch);
+ fz_obj *obj;
+
+ error = pdf_parsedict(&obj, csi->xref, file, buf, buflen);
+ if (error)
+ return fz_rethrow(error, "cannot parse inline image dictionary");
+
+ /* read whitespace after ID keyword */
+ ch = fz_readbyte(file);
+ if (ch == '\r')
+ if (fz_peekbyte(file) == '\n')
+ fz_readbyte(file);
+
+ error = pdf_runinlineimage(csi, rdb, file, obj);
+ fz_dropobj(obj);
+ if (error)
+ return fz_rethrow(error, "cannot parse inline image");
+
+ return fz_okay;
+}
+
+static void pdf_run_B(pdf_csi *csi)
+{
+ pdf_showpath(csi, 0, 1, 1, 0);
+}
+
+static void pdf_run_BMC(pdf_csi *csi)
+{
+}
+
+static void pdf_run_BT(pdf_csi *csi)
+{
+ csi->intext = 1;
+ csi->tm = fz_identity;
+ csi->tlm = fz_identity;
+}
+
+static void pdf_run_BX(pdf_csi *csi)
+{
+ csi->xbalance ++;
+}
- switch (buf[0])
+static void pdf_run_Bstar(pdf_csi *csi)
+{
+ pdf_showpath(csi, 0, 1, 1, 1);
+}
+
+static fz_error pdf_run_cs_imp(pdf_csi *csi, fz_obj *rdb, int what)
+{
+ fz_colorspace *colorspace;
+ fz_obj *obj, *dict;
+ fz_error error;
+
+ if (!strcmp(csi->name, "Pattern"))
+ {
+ pdf_setpattern(csi, what, nil, nil);
+ }
+ else
{
- case 'B':
- switch(buf[1])
+ if (!strcmp(csi->name, "DeviceGray"))
+ colorspace = fz_keepcolorspace(fz_devicegray);
+ else if (!strcmp(csi->name, "DeviceRGB"))
+ colorspace = fz_keepcolorspace(fz_devicergb);
+ else if (!strcmp(csi->name, "DeviceCMYK"))
+ colorspace = fz_keepcolorspace(fz_devicecmyk);
+ else
{
- case 0: /* "B" */
- if (csi->top < 0)
- goto syntaxerror;
- pdf_showpath(csi, 0, 1, 1, 0);
- break;
- case 'D': /* "BDC" */
- if ((buf[2] != 'C') || (buf[3] != 0))
- goto defaultcase;
- if (csi->top < 2)
- goto syntaxerror;
- break;
- case 'M': /* "BMC" */
- if ((buf[2] != 'C') || (buf[3] != 0))
- goto defaultcase;
- if (csi->top < 1)
- goto syntaxerror;
- break;
- case 'T': /* "BT" */
- if (buf[2] != 0)
- goto defaultcase;
- if (csi->top < 0)
- goto syntaxerror;
- csi->tm = fz_identity;
- csi->tlm = fz_identity;
- break;
- case 'X': /* "BX" */
- if (buf[2] != 0)
- goto defaultcase;
- if (csi->top < 0)
- goto syntaxerror;
- csi->xbalance ++;
- break;
- case '*': /* "B*" */
- if (buf[2] != 0)
- goto defaultcase;
- if (csi->top < 0)
- goto syntaxerror;
- pdf_showpath(csi, 0, 1, 1, 1);
- break;
- default:
- goto defaultcase;
+ dict = fz_dictgets(rdb, "ColorSpace");
+ if (!dict)
+ return fz_throw("cannot find ColorSpace dictionary");
+ obj = fz_dictgets(dict, csi->name);
+ if (!obj)
+ return fz_throw("cannot find colorspace resource '%s'", csi->name);
+ error = pdf_loadcolorspace(&colorspace, csi->xref, obj);
+ if (error)
+ return fz_rethrow(error, "cannot load colorspace (%d 0 R)", fz_tonum(obj));
}
- break;
- case 'C': /* "CS" */
- if ((buf[1] == 'S') && (buf[2] == 0))
- {
- fz_colorspace *cs;
- fz_obj *obj;
+ pdf_setcolorspace(csi, what, colorspace);
+
+ fz_dropcolorspace(colorspace);
+ }
+ return fz_okay;
+}
+
+static void pdf_run_CS(pdf_csi *csi, fz_obj *rdb)
+{
+ fz_error error;
+ error = pdf_run_cs_imp(csi, rdb, PDF_MSTROKE);
+ if (error)
+ fz_catch(error, "cannot set colorspace");
+}
- what = PDF_MSTROKE;
+static void pdf_run_cs(pdf_csi *csi, fz_obj *rdb)
+{
+ fz_error error;
+ error = pdf_run_cs_imp(csi, rdb, PDF_MFILL);
+ if (error)
+ fz_catch(error, "cannot set colorspace");
+}
-Lsetcolorspace:
- if (csi->top < 1)
- goto syntaxerror;
+static void pdf_run_DP(pdf_csi *csi)
+{
+}
- obj = csi->stack[0];
+static fz_error pdf_run_Do(pdf_csi *csi, fz_obj *rdb)
+{
+ fz_obj *dict;
+ fz_obj *obj;
+ fz_obj *subtype;
+ fz_error error;
- if (!fz_isname(obj))
- return fz_throw("malformed CS");
+ dict = fz_dictgets(rdb, "XObject");
+ if (!dict)
+ return fz_throw("cannot find XObject dictionary when looking for: '%s'", csi->name);
- if (!strcmp(fz_toname(obj), "Pattern"))
- {
- pdf_setpattern(csi, what, nil, nil);
- }
+ obj = fz_dictgets(dict, csi->name);
+ if (!obj)
+ return fz_throw("cannot find xobject resource: '%s'", csi->name);
- else
- {
- if (!strcmp(fz_toname(obj), "DeviceGray"))
- cs = fz_keepcolorspace(fz_devicegray);
- else if (!strcmp(fz_toname(obj), "DeviceRGB"))
- cs = fz_keepcolorspace(fz_devicergb);
- else if (!strcmp(fz_toname(obj), "DeviceCMYK"))
- cs = fz_keepcolorspace(fz_devicecmyk);
- else
- {
- fz_obj *dict = fz_dictgets(rdb, "ColorSpace");
- if (!dict)
- return fz_throw("cannot find ColorSpace dictionary");
- obj = fz_dictget(dict, obj);
- if (!obj)
- return fz_throw("cannot find colorspace resource /%s", fz_toname(csi->stack[0]));
-
- error = pdf_loadcolorspace(&cs, csi->xref, obj);
- if (error)
- return fz_rethrow(error, "cannot load colorspace (%d %d R)", fz_tonum(obj), fz_togen(obj));
- }
+ subtype = fz_dictgets(obj, "Subtype");
+ if (!fz_isname(subtype))
+ return fz_throw("no XObject subtype specified");
- pdf_setcolorspace(csi, what, cs);
+ if (!strcmp(fz_toname(subtype), "Form") && fz_dictgets(obj, "Subtype2"))
+ subtype = fz_dictgets(obj, "Subtype2");
- fz_dropcolorspace(cs);
- }
- }
- else
- goto defaultcase;
- break;
+ if (!strcmp(fz_toname(subtype), "Form"))
+ {
+ pdf_xobject *xobj;
- case 'D':
- switch (buf[1])
- {
- case 'P': /* "Dp" */
- if (buf[2] != 0)
- goto defaultcase;
- if (csi->top < 2)
- goto syntaxerror;
- break;
- case 'o': /* "Do" */
+ error = pdf_loadxobject(&xobj, csi->xref, obj);
+ if (error)
+ return fz_rethrow(error, "cannot load xobject (%d %d R)", fz_tonum(obj), fz_togen(obj));
+
+ /* Inherit parent resources, in case this one was empty XXX check where it's loaded */
+ if (!xobj->resources)
+ xobj->resources = fz_keepobj(rdb);
+
+ error = pdf_runxobject(csi, xobj->resources, xobj, fz_identity);
+ if (error)
+ return fz_rethrow(error, "cannot draw xobject (%d %d R)", fz_tonum(obj), fz_togen(obj));
+
+ pdf_dropxobject(xobj);
+ }
+
+ else if (!strcmp(fz_toname(subtype), "Image"))
+ {
+ if ((csi->dev->hints & FZ_IGNOREIMAGE) == 0)
{
- fz_obj *dict;
- fz_obj *obj;
- fz_obj *subtype;
+ fz_pixmap *img;
+ error = pdf_loadimage(&img, csi->xref, obj);
+ if (error)
+ return fz_rethrow(error, "cannot load image (%d %d R)", fz_tonum(obj), fz_togen(obj));
+ pdf_showimage(csi, img);
+ fz_droppixmap(img);
+ }
+ }
- if (buf[2] != 0)
- goto defaultcase;
- if (csi->top < 1)
- goto syntaxerror;
+ else if (!strcmp(fz_toname(subtype), "PS"))
+ {
+ fz_warn("ignoring XObject with subtype PS");
+ }
- dict = fz_dictgets(rdb, "XObject");
- if (!dict)
- return fz_throw("cannot find XObject dictionary when looking for: '%s'", fz_toname(csi->stack[0]));
+ else
+ {
+ return fz_throw("unknown XObject subtype: '%s'", fz_toname(subtype));
+ }
- obj = fz_dictget(dict, csi->stack[0]);
- if (!obj)
- return fz_throw("cannot find xobject resource: '%s'", fz_toname(csi->stack[0]));
+ return fz_okay;
+}
- subtype = fz_dictgets(obj, "Subtype");
- if (!fz_isname(subtype))
- return fz_throw("no XObject subtype specified");
+static void pdf_run_EMC(pdf_csi *csi)
+{
+}
- if (!strcmp(fz_toname(subtype), "Form") && fz_dictgets(obj, "Subtype2"))
- subtype = fz_dictgets(obj, "Subtype2");
+static void pdf_run_ET(pdf_csi *csi)
+{
+ pdf_flushtext(csi);
+ csi->accumulate = 1;
+ csi->intext = 0;
+}
- if (!strcmp(fz_toname(subtype), "Form"))
- {
- pdf_xobject *xobj;
+static void pdf_run_EX(pdf_csi *csi)
+{
+ csi->xbalance --;
+}
- error = pdf_loadxobject(&xobj, csi->xref, obj);
- if (error)
- return fz_rethrow(error, "cannot load xobject (%d %d R)", fz_tonum(obj), fz_togen(obj));
+static void pdf_run_F(pdf_csi *csi)
+{
+ pdf_showpath(csi, 0, 1, 0, 0);
+}
- /* Inherit parent resources, in case this one was empty XXX check where it's loaded */
- if (!xobj->resources)
- xobj->resources = fz_keepobj(rdb);
+static void pdf_run_G(pdf_csi *csi)
+{
+ pdf_setcolorspace(csi, PDF_MSTROKE, fz_devicegray);
+ pdf_setcolor(csi, PDF_MSTROKE, csi->stack);
+}
- error = pdf_runxobject(csi, rdb, xobj, fz_identity);
- if (error)
- return fz_rethrow(error, "cannot draw xobject (%d %d R)", fz_tonum(obj), fz_togen(obj));
+static void pdf_run_J(pdf_csi *csi)
+{
+ pdf_gstate *gstate = csi->gstate + csi->gtop;
+ gstate->strokestate.linecap = csi->stack[0];
+}
- pdf_dropxobject(xobj);
- }
+static void pdf_run_K(pdf_csi *csi)
+{
+ pdf_setcolorspace(csi, PDF_MSTROKE, fz_devicecmyk);
+ pdf_setcolor(csi, PDF_MSTROKE, csi->stack);
+}
- else if (!strcmp(fz_toname(subtype), "Image"))
- {
- if ((csi->dev->hints & FZ_IGNOREIMAGE) == 0)
- {
- fz_pixmap *img;
- error = pdf_loadimage(&img, csi->xref, obj);
- if (error)
- return fz_rethrow(error, "cannot load image (%d %d R)", fz_tonum(obj), fz_togen(obj));
- pdf_showimage(csi, img);
- fz_droppixmap(img);
- }
- }
+static void pdf_run_M(pdf_csi *csi)
+{
+ pdf_gstate *gstate = csi->gstate + csi->gtop;
+ gstate->strokestate.miterlimit = csi->stack[0];
+}
- else if (!strcmp(fz_toname(subtype), "PS"))
- {
- fz_warn("ignoring XObject with subtype PS");
- }
+static void pdf_run_MP(pdf_csi *csi)
+{
+}
- else
- {
- return fz_throw("unknown XObject subtype: %s", fz_toname(subtype));
- }
- break;
- }
- default:
- goto defaultcase;
- }
- break;
+static void pdf_run_Q(pdf_csi *csi)
+{
+ pdf_grestore(csi);
+}
- case 'E':
- switch (buf[1])
- {
- case 'X': /* "EX" */
- if (buf[2] != 0)
- goto defaultcase;
- if (csi->top < 0)
- goto syntaxerror;
- csi->xbalance --;
- break;
- case 'M': /* "EW" */
- if ((buf[2] != 'C') || (buf[3] != 0))
- goto defaultcase;
- if (csi->top < 0)
- goto syntaxerror;
- break;
- case 'T': /* "ET" */
- if (buf[2] != 0)
- goto defaultcase;
- if (csi->top < 0)
- goto syntaxerror;
- pdf_flushtext(csi);
- csi->accumulate = 1;
- break;
- default:
- goto defaultcase;
- }
- break;
+static void pdf_run_RG(pdf_csi *csi)
+{
+ pdf_setcolorspace(csi, PDF_MSTROKE, fz_devicergb);
+ pdf_setcolor(csi, PDF_MSTROKE, csi->stack);
+}
- case 'F': /* "F" */
- if (buf[1] != 0)
- goto defaultcase;
- if (csi->top < 0)
- goto syntaxerror;
- pdf_showpath(csi, 0, 1, 0, 0);
- break;
+static void pdf_run_S(pdf_csi *csi)
+{
+ pdf_showpath(csi, 0, 0, 1, 0);
+}
- case 'G': /* "G" */
- if (buf[1] != 0)
- goto defaultcase;
- if (csi->top < 1)
- goto syntaxerror;
+static fz_error pdf_run_SC_imp(pdf_csi *csi, fz_obj *rdb, int what, pdf_material *mat)
+{
+ fz_error error;
+ fz_obj *patterntype;
+ fz_obj *dict;
+ fz_obj *obj;
+ int kind;
- v[0] = fz_toreal(csi->stack[0]);
- pdf_setcolorspace(csi, PDF_MSTROKE, fz_devicegray);
- pdf_setcolor(csi, PDF_MSTROKE, v);
- break;
+ kind = mat->kind;
+ if (csi->name[0])
+ kind = PDF_MPATTERN;
+
+ switch (kind)
+ {
+ case PDF_MNONE:
+ return fz_throw("cannot set color in mask objects");
- case 'J': /* "J" */
- if (buf[1] != 0)
- goto defaultcase;
- if (csi->top < 1)
- goto syntaxerror;
- gstate->strokestate.linecap = fz_toint(csi->stack[0]);
+ case PDF_MCOLOR:
+ pdf_setcolor(csi, what, csi->stack);
break;
- case 'K': /* "K" */
- if (buf[1] != 0)
- goto defaultcase;
- if (csi->top < 4)
- goto syntaxerror;
+ case PDF_MPATTERN:
+ dict = fz_dictgets(rdb, "Pattern");
+ if (!dict)
+ return fz_throw("cannot find Pattern dictionary");
- v[0] = fz_toreal(csi->stack[0]);
- v[1] = fz_toreal(csi->stack[1]);
- v[2] = fz_toreal(csi->stack[2]);
- v[3] = fz_toreal(csi->stack[3]);
+ obj = fz_dictgets(dict, csi->name);
+ if (!obj)
+ return fz_throw("cannot find pattern resource '%s'", csi->name);
- pdf_setcolorspace(csi, PDF_MSTROKE, fz_devicecmyk);
- pdf_setcolor(csi, PDF_MSTROKE, v);
- break;
+ patterntype = fz_dictgets(obj, "PatternType");
- case 'M':
- switch (buf[1])
+ if (fz_toint(patterntype) == 1)
{
- case 0: /* "M" */
- if (csi->top < 1)
- goto syntaxerror;
- gstate->strokestate.miterlimit = fz_toreal(csi->stack[0]);
- break;
- case 'P': /* "Mp" */
- if (buf[2] != 0)
- goto defaultcase;
- if (csi->top < 1)
- goto syntaxerror;
- break;
- default:
- goto defaultcase;
+ pdf_pattern *pat;
+ error = pdf_loadpattern(&pat, csi->xref, obj);
+ if (error)
+ return fz_rethrow(error, "cannot load pattern (%d 0 R)", fz_tonum(obj));
+ pdf_setpattern(csi, what, pat, csi->top > 0 ? csi->stack : nil);
+ pdf_droppattern(pat);
+ }
+ else if (fz_toint(patterntype) == 2)
+ {
+ fz_shade *shd;
+ error = pdf_loadshading(&shd, csi->xref, obj);
+ if (error)
+ return fz_rethrow(error, "cannot load shading (%d 0 R)", fz_tonum(obj));
+ pdf_setshade(csi, what, shd);
+ fz_dropshade(shd);
+ }
+ else
+ {
+ return fz_throw("unknown pattern type: %d", fz_toint(patterntype));
}
break;
- case 'Q': /* "Q" */
- if (buf[1] != 0)
- goto defaultcase;
- if (csi->top < 0)
- goto syntaxerror;
- pdf_grestore(csi);
- break;
+ case PDF_MSHADE:
+ return fz_throw("cannot set color in shade objects");
+ }
- case 'R': /* "RG" */
- if ((buf[1] != 'G') || (buf[2] != 0))
- goto defaultcase;
- if (csi->top < 3)
- goto syntaxerror;
+ return fz_okay;
+}
- v[0] = fz_toreal(csi->stack[0]);
- v[1] = fz_toreal(csi->stack[1]);
- v[2] = fz_toreal(csi->stack[2]);
+static void pdf_run_SC(pdf_csi *csi, fz_obj *rdb)
+{
+ fz_error error;
+ pdf_gstate *gstate = csi->gstate + csi->gtop;
+ error = pdf_run_SC_imp(csi, rdb, PDF_MSTROKE, &gstate->stroke);
+ if (error)
+ fz_catch(error, "cannot set color and colorspace");
+}
- pdf_setcolorspace(csi, PDF_MSTROKE, fz_devicergb);
- pdf_setcolor(csi, PDF_MSTROKE, v);
- break;
+static void pdf_run_sc(pdf_csi *csi, fz_obj *rdb)
+{
+ fz_error error;
+ pdf_gstate *gstate = csi->gstate + csi->gtop;
+ error = pdf_run_SC_imp(csi, rdb, PDF_MFILL, &gstate->fill);
+ if (error)
+ fz_catch(error, "cannot set color and colorspace");
+}
- case 'S':
- switch (buf[1])
- {
- case 0: /* "S" */
- if (csi->top < 0)
- goto syntaxerror;
- pdf_showpath(csi, 0, 0, 1, 0);
- break;
- case 'C': /* "SC" or "SCN" */
- {
- pdf_material *mat;
- fz_obj *patterntype;
- fz_obj *dict;
- fz_obj *obj;
- int kind;
+static void pdf_run_Tc(pdf_csi *csi)
+{
+ pdf_gstate *gstate = csi->gstate + csi->gtop;
+ gstate->charspace = csi->stack[0];
+}
- if ((buf[2] != 0) && ((buf[2] != 'N') || (buf[3] != 0)))
- goto defaultcase;
+static void pdf_run_Tw(pdf_csi *csi)
+{
+ pdf_gstate *gstate = csi->gstate + csi->gtop;
+ gstate->wordspace = csi->stack[0];
+}
- what = PDF_MSTROKE;
+static void pdf_run_Tz(pdf_csi *csi)
+{
+ pdf_gstate *gstate = csi->gstate + csi->gtop;
+ float a = csi->stack[0] / 100;
+ pdf_flushtext(csi);
+ gstate->scale = a;
+}
-Lsetcolor:
- mat = what == PDF_MSTROKE ? &gstate->stroke : &gstate->fill;
+static void pdf_run_TL(pdf_csi *csi)
+{
+ pdf_gstate *gstate = csi->gstate + csi->gtop;
+ gstate->leading = csi->stack[0];
+}
- kind = mat->kind;
- if (fz_isname(csi->stack[csi->top - 1]))
- kind = PDF_MPATTERN;
+static fz_error pdf_run_Tf(pdf_csi *csi, fz_obj *rdb)
+{
+ pdf_gstate *gstate = csi->gstate + csi->gtop;
+ fz_error error;
+ fz_obj *dict;
+ fz_obj *obj;
- switch (kind)
- {
- case PDF_MNONE:
- return fz_throw("cannot set color in mask objects");
+ gstate->size = csi->stack[0];
+ if (gstate->font)
+ pdf_dropfont(gstate->font);
+ gstate->font = nil;
- case PDF_MCOLOR:
- if (csi->top < mat->cs->n)
- goto syntaxerror;
- for (i = 0; i < csi->top; i++)
- v[i] = fz_toreal(csi->stack[i]);
- pdf_setcolor(csi, what, v);
- break;
+ dict = fz_dictgets(rdb, "Font");
+ if (!dict)
+ return fz_throw("cannot find Font dictionary");
- case PDF_MPATTERN:
- for (i = 0; i < csi->top - 1; i++)
- v[i] = fz_toreal(csi->stack[i]);
+ obj = fz_dictgets(dict, csi->name);
+ if (!obj)
+ return fz_throw("cannot find font resource: '%s'", csi->name);
- dict = fz_dictgets(rdb, "Pattern");
- if (!dict)
- return fz_throw("cannot find Pattern dictionary");
+ error = pdf_loadfont(&gstate->font, csi->xref, rdb, obj);
+ if (error)
+ return fz_rethrow(error, "cannot load font (%d 0 R)", fz_tonum(obj));
- obj = fz_dictget(dict, csi->stack[csi->top - 1]);
- if (!obj)
- return fz_throw("cannot find pattern resource /%s",
- fz_toname(csi->stack[csi->top - 1]));
+ return fz_okay;
+}
- patterntype = fz_dictgets(obj, "PatternType");
+static void pdf_run_Tr(pdf_csi *csi)
+{
+ pdf_gstate *gstate = csi->gstate + csi->gtop;
+ gstate->render = csi->stack[0];
+}
- if (fz_toint(patterntype) == 1)
- {
- pdf_pattern *pat;
- error = pdf_loadpattern(&pat, csi->xref, obj);
- if (error)
- return fz_rethrow(error, "cannot load pattern (%d %d R)", fz_tonum(obj), fz_togen(obj));
- pdf_setpattern(csi, what, pat, csi->top == 1 ? nil : v);
- pdf_droppattern(pat);
- }
+static void pdf_run_Ts(pdf_csi *csi)
+{
+ pdf_gstate *gstate = csi->gstate + csi->gtop;
+ gstate->rise = csi->stack[0];
+}
- else if (fz_toint(patterntype) == 2)
- {
- fz_shade *shd;
- error = pdf_loadshading(&shd, csi->xref, obj);
- if (error)
- return fz_rethrow(error, "cannot load shading (%d %d R)", fz_tonum(obj), fz_togen(obj));
- pdf_setshade(csi, what, shd);
- fz_dropshade(shd);
- }
+static void pdf_run_Td(pdf_csi *csi)
+{
+ fz_matrix m = fz_translate(csi->stack[0], csi->stack[1]);
+ csi->tlm = fz_concat(m, csi->tlm);
+ csi->tm = csi->tlm;
+}
- else
- {
- return fz_throw("unknown pattern type: %d", fz_toint(patterntype));
- }
+static void pdf_run_TD(pdf_csi *csi)
+{
+ pdf_gstate *gstate = csi->gstate + csi->gtop;
+ fz_matrix m;
- break;
+ gstate->leading = -csi->stack[1];
+ m = fz_translate(csi->stack[0], csi->stack[1]);
+ csi->tlm = fz_concat(m, csi->tlm);
+ csi->tm = csi->tlm;
+}
- case PDF_MSHADE:
- return fz_throw("cannot set color in shade objects");
- }
- break;
- }
- default:
- goto defaultcase;
- }
- break;
+static void pdf_run_Tm(pdf_csi *csi)
+{
+ pdf_flushtext(csi);
+ csi->tm.a = csi->stack[0];
+ csi->tm.b = csi->stack[1];
+ csi->tm.c = csi->stack[2];
+ csi->tm.d = csi->stack[3];
+ csi->tm.e = csi->stack[4];
+ csi->tm.f = csi->stack[5];
+ csi->tlm = csi->tm;
+}
- case 'T':
- switch (buf[1])
- {
- case 'c': /* "Tc" */
- if (buf[2] != 0)
- goto defaultcase;
- if (csi->top < 1)
- goto syntaxerror;
- gstate->charspace = fz_toreal(csi->stack[0]);
- break;
- case 'w': /* "Tw" */
- if (buf[2] != 0)
- goto defaultcase;
- if (csi->top < 1)
- goto syntaxerror;
- gstate->wordspace = fz_toreal(csi->stack[0]);
- break;
- case 'z': /* "Tz" */
- if (buf[2] != 0)
- goto defaultcase;
- if (csi->top < 1)
- goto syntaxerror;
- a = fz_toreal(csi->stack[0]) / 100;
- pdf_flushtext(csi);
- gstate->scale = a;
- break;
- case 'L': /* "TL" */
- if (buf[2] != 0)
- goto defaultcase;
- if (csi->top < 1)
- goto syntaxerror;
- gstate->leading = fz_toreal(csi->stack[0]);
- break;
- case 'f': /* "Tf" */
- {
- fz_obj *dict;
- fz_obj *obj;
+static void pdf_run_Tstar(pdf_csi *csi)
+{
+ pdf_gstate *gstate = csi->gstate + csi->gtop;
+ fz_matrix m = fz_translate(0, -gstate->leading);
+ csi->tlm = fz_concat(m, csi->tlm);
+ csi->tm = csi->tlm;
+}
+
+static void pdf_run_Tj(pdf_csi *csi)
+{
+ if (csi->stringlen)
+ pdf_showstring(csi, csi->string, csi->stringlen);
+ else
+ pdf_showtext(csi, csi->obj);
+}
- if (buf[2] != 0)
- goto defaultcase;
- if (csi->top < 2)
- goto syntaxerror;
+static void pdf_run_TJ(pdf_csi *csi)
+{
+ if (csi->stringlen)
+ pdf_showstring(csi, csi->string, csi->stringlen);
+ else
+ pdf_showtext(csi, csi->obj);
+}
- dict = fz_dictgets(rdb, "Font");
- if (!dict)
- return fz_throw("cannot find Font dictionary");
+static void pdf_run_W(pdf_csi *csi)
+{
+ csi->clip = 1;
+ csi->clipevenodd = 0;
+}
- obj = fz_dictget(dict, csi->stack[0]);
- if (!obj)
- return fz_throw("cannot find font resource: %s", fz_toname(csi->stack[0]));
+static void pdf_run_Wstar(pdf_csi *csi)
+{
+ csi->clip = 1;
+ csi->clipevenodd = 1;
+}
- if (gstate->font)
- {
- pdf_dropfont(gstate->font);
- gstate->font = nil;
- }
+static void pdf_run_b(pdf_csi *csi)
+{
+ pdf_showpath(csi, 1, 1, 1, 0);
+}
- error = pdf_loadfont(&gstate->font, csi->xref, rdb, obj);
- if (error)
- return fz_rethrow(error, "cannot load font (%d %d R)", fz_tonum(obj), fz_togen(obj));
+static void pdf_run_bstar(pdf_csi *csi)
+{
+ pdf_showpath(csi, 1, 1, 1, 1);
+}
- gstate->size = fz_toreal(csi->stack[1]);
+static void pdf_run_c(pdf_csi *csi)
+{
+ float a, b, c, d, e, f;
+ a = csi->stack[0];
+ b = csi->stack[1];
+ c = csi->stack[2];
+ d = csi->stack[3];
+ e = csi->stack[4];
+ f = csi->stack[5];
+ fz_curveto(csi->path, a, b, c, d, e, f);
+}
- break;
- }
- case 'r': /* "Tr" */
- if (buf[2] != 0)
- goto defaultcase;
- if (csi->top < 1)
- goto syntaxerror;
- gstate->render = fz_toint(csi->stack[0]);
- break;
- case 's': /* "Ts" */
- if (buf[2] != 0)
- goto defaultcase;
- if (csi->top < 1)
- goto syntaxerror;
- gstate->rise = fz_toreal(csi->stack[0]);
- break;
- case 'd': /* "Td" */
- if (buf[2] != 0)
- goto defaultcase;
- if (csi->top < 2)
- goto syntaxerror;
- m = fz_translate(fz_toreal(csi->stack[0]), fz_toreal(csi->stack[1]));
- csi->tlm = fz_concat(m, csi->tlm);
- csi->tm = csi->tlm;
- break;
- case 'D': /* "TD" */
- if (buf[2] != 0)
- goto defaultcase;
- if (csi->top < 2)
- goto syntaxerror;
- gstate->leading = -fz_toreal(csi->stack[1]);
- m = fz_translate(fz_toreal(csi->stack[0]), fz_toreal(csi->stack[1]));
- csi->tlm = fz_concat(m, csi->tlm);
- csi->tm = csi->tlm;
- break;
- case 'm': /* "Tm" */
- if (buf[2] != 0)
- goto defaultcase;
- if (csi->top < 6)
- goto syntaxerror;
-
- m.a = fz_toreal(csi->stack[0]);
- m.b = fz_toreal(csi->stack[1]);
- m.c = fz_toreal(csi->stack[2]);
- m.d = fz_toreal(csi->stack[3]);
- m.e = fz_toreal(csi->stack[4]);
- m.f = fz_toreal(csi->stack[5]);
-
- pdf_flushtext(csi);
-
- csi->tm = m;
- csi->tlm = csi->tm;
- break;
- case '*': /* "T*" */
- if (buf[2] != 0)
- goto defaultcase;
- if (csi->top < 0)
- goto syntaxerror;
- m = fz_translate(0, -gstate->leading);
- csi->tlm = fz_concat(m, csi->tlm);
- csi->tm = csi->tlm;
- break;
- case 'j': /* "Tj" */
- if (buf[2] != 0)
- goto defaultcase;
- if (csi->top < 1)
- goto syntaxerror;
- pdf_showtext(csi, csi->stack[0]);
- break;
- case 'J': /* "TJ" */
- if (buf[2] != 0)
- goto defaultcase;
- if (csi->top < 1)
- goto syntaxerror;
- pdf_showtext(csi, csi->stack[0]);
- break;
- default:
- goto defaultcase;
- }
- break;
+static void pdf_run_cm(pdf_csi *csi)
+{
+ pdf_gstate *gstate = csi->gstate + csi->gtop;
+ fz_matrix m;
- case 'W':
- switch (buf[1])
- {
- case 0: /* "W" */
- if (csi->top < 0)
- goto syntaxerror;
- csi->clip = 1;
- csi->clipevenodd = 0;
- break;
- case '*': /* "W*" */
- if (buf[2] != 0)
- goto defaultcase;
- if (csi->top < 0)
- goto syntaxerror;
- csi->clip = 1;
- csi->clipevenodd = 1;
- break;
- default:
- goto defaultcase;
- }
- break;
+ m.a = csi->stack[0];
+ m.b = csi->stack[1];
+ m.c = csi->stack[2];
+ m.d = csi->stack[3];
+ m.e = csi->stack[4];
+ m.f = csi->stack[5];
- case 'b':
- switch (buf[1])
- {
- case 0: /* "b" */
- if (csi->top < 0)
- goto syntaxerror;
- pdf_showpath(csi, 1, 1, 1, 0);
- break;
- case '*': /* "b*" */
- if (buf[2] != 0)
- goto defaultcase;
- if (csi->top < 0)
- goto syntaxerror;
- pdf_showpath(csi, 1, 1, 1, 1);
- break;
- default:
- goto defaultcase;
- }
- break;
+ gstate->ctm = fz_concat(m, gstate->ctm);
+}
- case 'c':
- switch (buf[1])
- {
- case 0: /* "c" */
- if (csi->top < 6)
- goto syntaxerror;
- a = fz_toreal(csi->stack[0]);
- b = fz_toreal(csi->stack[1]);
- c = fz_toreal(csi->stack[2]);
- d = fz_toreal(csi->stack[3]);
- e = fz_toreal(csi->stack[4]);
- f = fz_toreal(csi->stack[5]);
- fz_curveto(csi->path, a, b, c, d, e, f);
- break;
- case 'm': /* "cm" */
- {
- if (buf[2] != 0)
- goto defaultcase;
- if (csi->top < 6)
- goto syntaxerror;
-
- m.a = fz_toreal(csi->stack[0]);
- m.b = fz_toreal(csi->stack[1]);
- m.c = fz_toreal(csi->stack[2]);
- m.d = fz_toreal(csi->stack[3]);
- m.e = fz_toreal(csi->stack[4]);
- m.f = fz_toreal(csi->stack[5]);
-
- gstate->ctm = fz_concat(m, gstate->ctm);
- break;
- }
- case 's': /* "cs" */
- if (buf[2] != 0)
- goto defaultcase;
- what = PDF_MFILL;
- goto Lsetcolorspace;
- default:
- goto defaultcase;
- }
- break;
+static void pdf_run_d(pdf_csi *csi)
+{
+ pdf_gstate *gstate = csi->gstate + csi->gtop;
+ fz_obj *array;
+ int i;
- case 'd':
- switch (buf[1])
- {
- case 0: /* "d" */
- {
- fz_obj *array;
- if (csi->top < 2)
- goto syntaxerror;
- array = csi->stack[0];
- gstate->strokestate.dashlen = fz_arraylen(array);
- if (gstate->strokestate.dashlen > 32)
- return fz_throw("assert: dash pattern too big");
- for (i = 0; i < gstate->strokestate.dashlen; i++)
- gstate->strokestate.dashlist[i] = fz_toreal(fz_arrayget(array, i));
- gstate->strokestate.dashphase = fz_toreal(csi->stack[1]);
- break;
- }
- case '0': /* "d0" */
- case '1': /* "d1" */
- if (buf[2] != 0)
- goto defaultcase;
- /* we don't care about setcharwidth and setcachedevice */
- break;
- default:
- goto defaultcase;
- }
- break;
+ array = csi->obj;
+ gstate->strokestate.dashlen = MIN(fz_arraylen(array), nelem(gstate->strokestate.dashlist));
+ for (i = 0; i < gstate->strokestate.dashlen; i++)
+ gstate->strokestate.dashlist[i] = fz_toreal(fz_arrayget(array, i));
+ gstate->strokestate.dashphase = csi->stack[0];
+}
- case 'f':
- switch (buf[1])
- {
- case 0: /* "f" */
- if (csi->top < 0)
- goto syntaxerror;
- pdf_showpath(csi, 0, 1, 0, 0);
- break;
- case '*': /* "f*" */
- if (buf[2] != 0)
- goto defaultcase;
- if (csi->top < 0)
- goto syntaxerror;
- pdf_showpath(csi, 0, 1, 0, 1);
- break;
- default:
- goto defaultcase;
- }
- break;
+static void pdf_run_d0(pdf_csi *csi)
+{
+}
- case 'g':
- switch (buf[1])
- {
- case 0: /* "g" */
- if (csi->top < 1)
- goto syntaxerror;
+static void pdf_run_d1(pdf_csi *csi)
+{
+}
- v[0] = fz_toreal(csi->stack[0]);
- pdf_setcolorspace(csi, PDF_MFILL, fz_devicegray);
- pdf_setcolor(csi, PDF_MFILL, v);
- break;
- case 's': /* "gs" */
- {
- fz_obj *dict;
- fz_obj *obj;
+static void pdf_run_f(pdf_csi *csi)
+{
+ pdf_showpath(csi, 0, 1, 0, 0);
+}
- if (buf[2] != 0)
- goto defaultcase;
- if (csi->top < 1)
- goto syntaxerror;
+static void pdf_run_fstar(pdf_csi *csi)
+{
+ pdf_showpath(csi, 0, 1, 0, 1);
+}
- dict = fz_dictgets(rdb, "ExtGState");
- if (!dict)
- return fz_throw("cannot find ExtGState dictionary");
+static void pdf_run_g(pdf_csi *csi)
+{
+ pdf_setcolorspace(csi, PDF_MFILL, fz_devicegray);
+ pdf_setcolor(csi, PDF_MFILL, csi->stack);
+}
- obj = fz_dictget(dict, csi->stack[0]);
- if (!obj)
- return fz_throw("cannot find extgstate resource /%s", fz_toname(csi->stack[0]));
+static fz_error pdf_run_gs(pdf_csi *csi, fz_obj *rdb)
+{
+ fz_error error;
+ fz_obj *dict;
+ fz_obj *obj;
- error = pdf_runextgstate(csi, gstate, rdb, obj);
- if (error)
- return fz_rethrow(error, "cannot set ExtGState (%d %d R)", fz_tonum(obj), fz_togen(obj));
- break;
- }
- default:
- goto defaultcase;
- }
- break;
+ dict = fz_dictgets(rdb, "ExtGState");
+ if (!dict)
+ return fz_throw("cannot find ExtGState dictionary");
- case 'h': /* "h" */
- if (buf[1] != 0)
- goto defaultcase;
- if (csi->top < 0)
- goto syntaxerror;
- fz_closepath(csi->path);
- break;
+ obj = fz_dictgets(dict, csi->name);
+ if (!obj)
+ return fz_throw("cannot find extgstate resource '%s'", csi->name);
- case 'i': /* "i" */
- if (buf[1] != 0)
- goto defaultcase;
- if (csi->top < 1)
- goto syntaxerror;
- /* flatness */
- break;
+ error = pdf_runextgstate(csi, rdb, obj);
+ if (error)
+ return fz_rethrow(error, "cannot set ExtGState (%d 0 R)", fz_tonum(obj));
+ return fz_okay;
+}
- case 'j': /* "j" */
- if (buf[1] != 0)
- goto defaultcase;
- if (csi->top < 1)
- goto syntaxerror;
- gstate->strokestate.linejoin = fz_toint(csi->stack[0]);
- break;
+static void pdf_run_h(pdf_csi *csi)
+{
+ fz_closepath(csi->path);
+}
- case 'k': /* "k" */
- if (buf[1] != 0)
- goto defaultcase;
- if (csi->top < 4)
- goto syntaxerror;
+static void pdf_run_i(pdf_csi *csi)
+{
+}
- v[0] = fz_toreal(csi->stack[0]);
- v[1] = fz_toreal(csi->stack[1]);
- v[2] = fz_toreal(csi->stack[2]);
- v[3] = fz_toreal(csi->stack[3]);
+static void pdf_run_j(pdf_csi *csi)
+{
+ pdf_gstate *gstate = csi->gstate + csi->gtop;
+ gstate->strokestate.linejoin = csi->stack[0];
+}
- pdf_setcolorspace(csi, PDF_MFILL, fz_devicecmyk);
- pdf_setcolor(csi, PDF_MFILL, v);
- break;
+static void pdf_run_k(pdf_csi *csi)
+{
+ pdf_setcolorspace(csi, PDF_MFILL, fz_devicecmyk);
+ pdf_setcolor(csi, PDF_MFILL, csi->stack);
+}
- case 'l': /* "l" */
- if (buf[1] != 0)
- goto defaultcase;
- if (csi->top < 2)
- goto syntaxerror;
- a = fz_toreal(csi->stack[0]);
- b = fz_toreal(csi->stack[1]);
- fz_lineto(csi->path, a, b);
- break;
+static void pdf_run_l(pdf_csi *csi)
+{
+ float a, b;
+ a = csi->stack[0];
+ b = csi->stack[1];
+ fz_lineto(csi->path, a, b);
+}
- case 'm': /* "m" */
- if (buf[1] != 0)
- goto defaultcase;
- if (csi->top < 2)
- goto syntaxerror;
- a = fz_toreal(csi->stack[0]);
- b = fz_toreal(csi->stack[1]);
- fz_moveto(csi->path, a, b);
- break;
+static void pdf_run_m(pdf_csi *csi)
+{
+ float a, b;
+ a = csi->stack[0];
+ b = csi->stack[1];
+ fz_moveto(csi->path, a, b);
+}
- case 'n': /* "n" */
- if (buf[1] != 0)
- goto defaultcase;
- if (csi->top < 0)
- goto syntaxerror;
- pdf_showpath(csi, 0, 0, 0, csi->clipevenodd);
- break;
+static void pdf_run_n(pdf_csi *csi)
+{
+ pdf_showpath(csi, 0, 0, 0, csi->clipevenodd);
+}
- case 'q': /* "q" */
- if (buf[1] != 0)
- goto defaultcase;
- if (csi->top < 0)
- goto syntaxerror;
- pdf_gsave(csi);
- break;
+static void pdf_run_q(pdf_csi *csi)
+{
+ pdf_gsave(csi);
+}
- case 'r':
- switch (buf[1])
- {
- case 'i': /* "ri" */
- if (buf[2] != 0)
- goto defaultcase;
- if (csi->top < 1)
- goto syntaxerror;
- break;
- case 'e': /* "re" */
- if (buf[2] != 0)
- goto defaultcase;
- if (csi->top < 4)
- goto syntaxerror;
-
- x = fz_toreal(csi->stack[0]);
- y = fz_toreal(csi->stack[1]);
- w = fz_toreal(csi->stack[2]);
- h = fz_toreal(csi->stack[3]);
-
- fz_moveto(csi->path, x, y);
- fz_lineto(csi->path, x + w, y);
- fz_lineto(csi->path, x + w, y + h);
- fz_lineto(csi->path, x, y + h);
- fz_closepath(csi->path);
- break;
- case 'g': /* "rg" */
- if (buf[2] != 0)
- goto defaultcase;
- if (csi->top < 3)
- goto syntaxerror;
-
- v[0] = fz_toreal(csi->stack[0]);
- v[1] = fz_toreal(csi->stack[1]);
- v[2] = fz_toreal(csi->stack[2]);
-
- pdf_setcolorspace(csi, PDF_MFILL, fz_devicergb);
- pdf_setcolor(csi, PDF_MFILL, v);
- break;
- default:
- goto defaultcase;
- }
- break;
+static void pdf_run_re(pdf_csi *csi)
+{
+ float x, y, w, h;
- case 's':
- switch (buf[1])
- {
- case 0: /* "s" */
- if (csi->top < 0)
- goto syntaxerror;
- pdf_showpath(csi, 1, 0, 1, 0);
- break;
- case 'c': /* "sc" or "scn" */
- if ((buf[2] != 0) && ((buf[2] != 'n') || (buf[3] != 0)))
- goto defaultcase;
- what = PDF_MFILL;
- goto Lsetcolor;
- case 'h': /* "sh" */
- {
- fz_obj *dict;
- fz_obj *obj;
- fz_shade *shd;
+ x = csi->stack[0];
+ y = csi->stack[1];
+ w = csi->stack[2];
+ h = csi->stack[3];
- if (buf[2] != 0)
- goto defaultcase;
- if (csi->top < 1)
- goto syntaxerror;
+ fz_moveto(csi->path, x, y);
+ fz_lineto(csi->path, x + w, y);
+ fz_lineto(csi->path, x + w, y + h);
+ fz_lineto(csi->path, x, y + h);
+ fz_closepath(csi->path);
+}
- dict = fz_dictgets(rdb, "Shading");
- if (!dict)
- return fz_throw("cannot find shading dictionary");
+static void pdf_run_rg(pdf_csi *csi)
+{
+ pdf_setcolorspace(csi, PDF_MFILL, fz_devicergb);
+ pdf_setcolor(csi, PDF_MFILL, csi->stack);
+}
- obj = fz_dictget(dict, csi->stack[csi->top - 1]);
- if (!obj)
- return fz_throw("cannot find shading resource: %s", fz_toname(csi->stack[csi->top - 1]));
+static void pdf_run_ri(pdf_csi *csi)
+{
+}
- if ((csi->dev->hints & FZ_IGNORESHADE) == 0)
- {
- error = pdf_loadshading(&shd, csi->xref, obj);
- if (error)
- return fz_rethrow(error, "cannot load shading (%d %d R)", fz_tonum(obj), fz_togen(obj));
- pdf_showshade(csi, shd);
- fz_dropshade(shd);
- }
- break;
- }
- default:
- goto defaultcase;
- }
- break;
+static void pdf_run_s(pdf_csi *csi)
+{
+ pdf_showpath(csi, 1, 0, 1, 0);
+}
- case 'v': /* "v" */
- if (buf[1] != 0)
- goto defaultcase;
- if (csi->top < 4)
- goto syntaxerror;
- a = fz_toreal(csi->stack[0]);
- b = fz_toreal(csi->stack[1]);
- c = fz_toreal(csi->stack[2]);
- d = fz_toreal(csi->stack[3]);
- fz_curvetov(csi->path, a, b, c, d);
- break;
+static fz_error pdf_run_sh(pdf_csi *csi, fz_obj *rdb)
+{
+ fz_obj *dict;
+ fz_obj *obj;
+ fz_shade *shd;
+ fz_error error;
- case 'w': /* "w" */
- if (buf[1] != 0)
- goto defaultcase;
- if (csi->top < 1)
- goto syntaxerror;
- gstate->strokestate.linewidth = fz_toreal(csi->stack[0]);
- break;
+ dict = fz_dictgets(rdb, "Shading");
+ if (!dict)
+ return fz_throw("cannot find shading dictionary");
- case 'y': /* "y" */
- if (buf[1] != 0)
- goto defaultcase;
- if (csi->top < 4)
- goto syntaxerror;
- a = fz_toreal(csi->stack[0]);
- b = fz_toreal(csi->stack[1]);
- c = fz_toreal(csi->stack[2]);
- d = fz_toreal(csi->stack[3]);
- fz_curvetoy(csi->path, a, b, c, d);
- break;
+ obj = fz_dictgets(dict, csi->name);
+ if (!obj)
+ return fz_throw("cannot find shading resource: '%s'", csi->name);
- case '\'': /* "'" */
- if (buf[1] != 0)
- goto defaultcase;
- if (csi->top < 1)
- goto syntaxerror;
+ if ((csi->dev->hints & FZ_IGNORESHADE) == 0)
+ {
+ error = pdf_loadshading(&shd, csi->xref, obj);
+ if (error)
+ return fz_rethrow(error, "cannot load shading (%d %d R)", fz_tonum(obj), fz_togen(obj));
+ pdf_showshade(csi, shd);
+ fz_dropshade(shd);
+ }
+ return fz_okay;
+}
- m = fz_translate(0, -gstate->leading);
- csi->tlm = fz_concat(m, csi->tlm);
- csi->tm = csi->tlm;
+static void pdf_run_v(pdf_csi *csi)
+{
+ float a, b, c, d;
+ a = csi->stack[0];
+ b = csi->stack[1];
+ c = csi->stack[2];
+ d = csi->stack[3];
+ fz_curvetov(csi->path, a, b, c, d);
+}
- pdf_showtext(csi, csi->stack[0]);
- break;
+static void pdf_run_w(pdf_csi *csi)
+{
+ pdf_gstate *gstate = csi->gstate + csi->gtop;
+ gstate->strokestate.linewidth = csi->stack[0];
+}
- case '"': /* """ */
- if (buf[1] != 0)
- goto defaultcase;
- if (csi->top < 3)
- goto syntaxerror;
+static void pdf_run_y(pdf_csi *csi)
+{
+ float a, b, c, d;
+ a = csi->stack[0];
+ b = csi->stack[1];
+ c = csi->stack[2];
+ d = csi->stack[3];
+ fz_curvetoy(csi->path, a, b, c, d);
+}
- gstate->wordspace = fz_toreal(csi->stack[0]);
- gstate->charspace = fz_toreal(csi->stack[1]);
+static void pdf_run_squote(pdf_csi *csi)
+{
+ fz_matrix m;
+ pdf_gstate *gstate = csi->gstate + csi->gtop;
+
+ m = fz_translate(0, -gstate->leading);
+ csi->tlm = fz_concat(m, csi->tlm);
+ csi->tm = csi->tlm;
+
+ if (csi->stringlen)
+ pdf_showstring(csi, csi->string, csi->stringlen);
+ else
+ pdf_showtext(csi, csi->obj);
+}
+
+static void pdf_run_dquote(pdf_csi *csi)
+{
+ fz_matrix m;
+ pdf_gstate *gstate = csi->gstate + csi->gtop;
+
+ gstate->wordspace = csi->stack[0];
+ gstate->charspace = csi->stack[1];
+
+ m = fz_translate(0, -gstate->leading);
+ csi->tlm = fz_concat(m, csi->tlm);
+ csi->tm = csi->tlm;
- m = fz_translate(0, -gstate->leading);
- csi->tlm = fz_concat(m, csi->tlm);
- csi->tm = csi->tlm;
+ if (csi->stringlen)
+ pdf_showstring(csi, csi->string, csi->stringlen);
+ else
+ pdf_showtext(csi, csi->obj);
+}
+
+#define A(a) (a)
+#define B(a,b) (a | b << 8)
+#define C(a,b,c) (a | b << 8 | c << 16)
- pdf_showtext(csi, csi->stack[2]);
+static fz_error
+pdf_runkeyword(pdf_csi *csi, fz_obj *rdb, fz_stream *file, char *buf)
+{
+ fz_error error;
+ int key;
+
+ key = buf[0];
+ if (buf[1])
+ {
+ key |= buf[1] << 8;
+ if (buf[2])
+ {
+ key |= buf[2] << 16;
+ if (buf[3])
+ key = 0;
+ }
+ }
+
+ switch (key)
+ {
+ case A('"'): pdf_run_dquote(csi); break;
+ case A('\''): pdf_run_squote(csi); break;
+ case A('B'): pdf_run_B(csi); break;
+ case B('B','*'): pdf_run_Bstar(csi); break;
+ case C('B','D','C'): pdf_run_BDC(csi); break;
+ case B('B','I'):
+ error = pdf_run_BI(csi, rdb, file);
+ if (error)
+ return fz_rethrow(error, "cannot draw inline image");
+ break;
+ case C('B','M','C'): pdf_run_BMC(csi); break;
+ case B('B','T'): pdf_run_BT(csi); break;
+ case B('B','X'): pdf_run_BX(csi); break;
+ case B('C','S'): pdf_run_CS(csi, rdb); break;
+ case B('D','P'): pdf_run_DP(csi); break;
+ case B('D','o'):
+ error = pdf_run_Do(csi, rdb);
+ if (error)
+ fz_catch(error, "cannot draw xobject/image");
+ break;
+ case C('E','M','C'): pdf_run_EMC(csi); break;
+ case B('E','T'): pdf_run_ET(csi); break;
+ case B('E','X'): pdf_run_EX(csi); break;
+ case A('F'): pdf_run_F(csi); break;
+ case A('G'): pdf_run_G(csi); break;
+ case A('J'): pdf_run_J(csi); break;
+ case A('K'): pdf_run_K(csi); break;
+ case A('M'): pdf_run_M(csi); break;
+ case B('M','P'): pdf_run_MP(csi); break;
+ case A('Q'): pdf_run_Q(csi); break;
+ case B('R','G'): pdf_run_RG(csi); break;
+ case A('S'): pdf_run_S(csi); break;
+ case B('S','C'): pdf_run_SC(csi, rdb); break;
+ case C('S','C','N'): pdf_run_SC(csi, rdb); break;
+ case B('T','*'): pdf_run_Tstar(csi); break;
+ case B('T','D'): pdf_run_TD(csi); break;
+ case B('T','J'): pdf_run_TJ(csi); break;
+ case B('T','L'): pdf_run_TL(csi); break;
+ case B('T','c'): pdf_run_Tc(csi); break;
+ case B('T','d'): pdf_run_Td(csi); break;
+ case B('T','f'):
+ error = pdf_run_Tf(csi, rdb);
+ if (error)
+ fz_catch(error, "cannot set font");
+ break;
+ case B('T','j'): pdf_run_Tj(csi); break;
+ case B('T','m'): pdf_run_Tm(csi); break;
+ case B('T','r'): pdf_run_Tr(csi); break;
+ case B('T','s'): pdf_run_Ts(csi); break;
+ case B('T','w'): pdf_run_Tw(csi); break;
+ case B('T','z'): pdf_run_Tz(csi); break;
+ case A('W'): pdf_run_W(csi); break;
+ case B('W','*'): pdf_run_Wstar(csi); break;
+ case A('b'): pdf_run_b(csi); break;
+ case B('b','*'): pdf_run_bstar(csi); break;
+ case A('c'): pdf_run_c(csi); break;
+ case B('c','m'): pdf_run_cm(csi); break;
+ case B('c','s'): pdf_run_cs(csi, rdb); break;
+ case A('d'): pdf_run_d(csi); break;
+ case B('d','0'): pdf_run_d0(csi); break;
+ case B('d','1'): pdf_run_d1(csi); break;
+ case A('f'): pdf_run_f(csi); break;
+ case B('f','*'): pdf_run_fstar(csi); break;
+ case A('g'): pdf_run_g(csi); break;
+ case B('g','s'):
+ error = pdf_run_gs(csi, rdb);
+ if (error)
+ fz_catch(error, "cannot set graphics state");
+ break;
+ case A('h'): pdf_run_h(csi); break;
+ case A('i'): pdf_run_i(csi); break;
+ case A('j'): pdf_run_j(csi); break;
+ case A('k'): pdf_run_k(csi); break;
+ case A('l'): pdf_run_l(csi); break;
+ case A('m'): pdf_run_m(csi); break;
+ case A('n'): pdf_run_n(csi); break;
+ case A('q'): pdf_run_q(csi); break;
+ case B('r','e'): pdf_run_re(csi); break;
+ case B('r','g'): pdf_run_rg(csi); break;
+ case B('r','i'): pdf_run_ri(csi); break;
+ case A('s'): pdf_run_s(csi); break;
+ case B('s','c'): pdf_run_sc(csi, rdb); break;
+ case C('s','c','n'): pdf_run_sc(csi, rdb); break;
+ case B('s','h'):
+ error = pdf_run_sh(csi, rdb);
+ if (error)
+ fz_catch(error, "cannot draw shading");
break;
+ case A('v'): pdf_run_v(csi); break;
+ case A('w'): pdf_run_w(csi); break;
+ case A('y'): pdf_run_y(csi); break;
default:
-defaultcase:
- /* don't fail on unknown keywords if braced by BX/EX */
if (!csi->xbalance)
- fz_warn("unknown keyword: %s", buf);
+ fz_warn("unknown keyword: '%s'", buf);
break;
}
return fz_okay;
-
-syntaxerror:
- return fz_throw("syntax error near '%s' with %d items on the stack", buf, csi->top);
}
static fz_error
@@ -1364,7 +1259,6 @@ pdf_runcsifile(pdf_csi *csi, fz_obj *rdb, fz_stream *file, char *buf, int buflen
fz_error error;
int tok;
int len;
- fz_obj *obj;
pdf_clearstack(csi);
@@ -1377,45 +1271,32 @@ pdf_runcsifile(pdf_csi *csi, fz_obj *rdb, fz_stream *file, char *buf, int buflen
if (error)
return fz_rethrow(error, "lexical error in content stream");
- if (csi->array)
+ if (csi->inarray)
{
if (tok == PDF_TCARRAY)
{
- csi->stack[csi->top] = csi->array;
- csi->array = nil;
- csi->top ++;
+ csi->inarray = 0;
}
else if (tok == PDF_TINT || tok == PDF_TREAL)
{
- obj = fz_newreal(atof(buf));
- fz_arraypush(csi->array, obj);
- fz_dropobj(obj);
+ pdf_gstate *gstate = csi->gstate + csi->gtop;
+ pdf_showspace(csi, -atof(buf) * gstate->size * 0.001f);
}
else if (tok == PDF_TSTRING)
{
- obj = fz_newstring(buf, len);
- fz_arraypush(csi->array, obj);
- fz_dropobj(obj);
+ pdf_showstring(csi, (unsigned char *)buf, len);
}
else if (tok == PDF_TKEYWORD)
{
- /* some producers try to put Tw and Tc commands in the TJ array */
- fz_warn("ignoring keyword '%s' inside array", buf);
if (!strcmp(buf, "Tw") || !strcmp(buf, "Tc"))
- {
- if (fz_arraylen(csi->array) > 0)
- fz_arraydrop(csi->array);
- }
+ fz_warn("ignoring keyword '%s' inside array", buf);
+ else
+ return fz_throw("syntax error in array");
}
else if (tok == PDF_TEOF)
- {
return fz_okay;
- }
else
- {
- pdf_clearstack(csi);
- return fz_throw("syntaxerror in array");
- }
+ return fz_throw("syntax error in array");
}
else switch (tok)
@@ -1424,85 +1305,60 @@ pdf_runcsifile(pdf_csi *csi, fz_obj *rdb, fz_stream *file, char *buf, int buflen
case PDF_TEOF:
return fz_okay;
- /* optimize text-object array parsing */
case PDF_TOARRAY:
- csi->array = fz_newarray(8);
+ if (!csi->intext)
+ {
+ error = pdf_parsearray(&csi->obj, csi->xref, file, buf, buflen);
+ if (error)
+ return fz_rethrow(error, "cannot parse array");
+ }
+ else
+ {
+ csi->inarray = 1;
+ }
break;
case PDF_TODICT:
- error = pdf_parsedict(&csi->stack[csi->top], csi->xref, file, buf, buflen);
+ error = pdf_parsedict(&csi->obj, csi->xref, file, buf, buflen);
if (error)
return fz_rethrow(error, "cannot parse dictionary");
- csi->top ++;
break;
case PDF_TNAME:
- csi->stack[csi->top] = fz_newname(buf);
- csi->top ++;
+ fz_strlcpy(csi->name, buf, sizeof(csi->name));
break;
case PDF_TINT:
- csi->stack[csi->top] = fz_newint(atoi(buf));
+ csi->stack[csi->top] = atoi(buf);
csi->top ++;
break;
case PDF_TREAL:
- csi->stack[csi->top] = fz_newreal(atof(buf));
+ csi->stack[csi->top] = atof(buf);
csi->top ++;
break;
case PDF_TSTRING:
- csi->stack[csi->top] = fz_newstring(buf, len);
- csi->top ++;
- break;
-
- case PDF_TTRUE:
- csi->stack[csi->top] = fz_newbool(1);
- csi->top ++;
- break;
-
- case PDF_TFALSE:
- csi->stack[csi->top] = fz_newbool(0);
- csi->top ++;
- break;
-
- case PDF_TNULL:
- csi->stack[csi->top] = fz_newnull();
- csi->top ++;
- break;
-
- case PDF_TKEYWORD:
- if (!strcmp(buf, "BI"))
+ if (len <= sizeof(csi->string))
{
- int ch;
-
- error = pdf_parsedict(&obj, csi->xref, file, buf, buflen);
- if (error)
- return fz_rethrow(error, "cannot parse inline image dictionary");
-
- /* read whitespace after ID keyword */
- ch = fz_readbyte(file);
- if (ch == '\r')
- if (fz_peekbyte(file) == '\n')
- fz_readbyte(file);
-
- error = pdf_runinlineimage(csi, rdb, file, obj);
- fz_dropobj(obj);
- if (error)
- return fz_rethrow(error, "cannot parse inline image");
+ memcpy(csi->string, buf, len);
+ csi->stringlen = len;
}
else
{
- error = pdf_runkeyword(csi, rdb, buf);
- if (error)
- fz_catch(error, "cannot run keyword '%s'", buf);
- pdf_clearstack(csi);
+ csi->obj = fz_newstring(buf, len);
}
break;
- default:
+ case PDF_TKEYWORD:
+ error = pdf_runkeyword(csi, rdb, file, buf);
+ if (error)
+ return fz_rethrow(error, "cannot run keyword");
pdf_clearstack(csi);
- return fz_throw("syntaxerror in content stream");
+ break;
+
+ default:
+ return fz_throw("syntax error in content stream");
}
}
}
@@ -1539,9 +1395,6 @@ pdf_runpage(pdf_xref *xref, pdf_page *page, fz_device *dev, fz_matrix ctm)
if (error)
return fz_rethrow(error, "cannot parse page content stream");
- if (page->transparency)
- dev->endgroup(dev->user);
-
for (annot = page->annots; annot; annot = annot->next)
{
flags = fz_toint(fz_dictgets(annot->obj, "F"));
@@ -1561,12 +1414,14 @@ pdf_runpage(pdf_xref *xref, pdf_page *page, fz_device *dev, fz_matrix ctm)
return fz_rethrow(error, "cannot parse annotation appearance stream");
}
+ if (page->transparency)
+ dev->endgroup(dev->user);
+
return fz_okay;
}
fz_error
-pdf_runglyph(pdf_xref *xref, fz_obj *resources, fz_buffer *contents,
- fz_device *dev, fz_matrix ctm)
+pdf_runglyph(pdf_xref *xref, fz_obj *resources, fz_buffer *contents, fz_device *dev, fz_matrix ctm)
{
pdf_csi *csi = pdf_newcsi(xref, dev, ctm);
fz_error error = pdf_runcsibuffer(csi, resources, contents);
diff --git a/mupdf/pdf_shade.c b/mupdf/pdf_shade.c
index 9c4d8d09..1b301724 100644
--- a/mupdf/pdf_shade.c
+++ b/mupdf/pdf_shade.c
@@ -30,7 +30,7 @@ pdf_growmesh(fz_shade *shade, int amount)
static void
pdf_addvertex(fz_shade *shade, struct vertex *v)
{
- int ncomp = shade->usefunction ? 1 : shade->cs->n;
+ int ncomp = shade->usefunction ? 1 : shade->colorspace->n;
int i;
pdf_growmesh(shade, 2 + ncomp);
shade->mesh[shade->meshlen++] = v->x;
@@ -331,8 +331,8 @@ pdf_samplecompositeshadefunction(fz_shade *shade, pdf_function *func, float t0,
for (i = 0; i < 256; i++)
{
t = t0 + (i / 255.0f) * (t1 - t0);
- pdf_evalfunction(func, &t, 1, shade->function[i], shade->cs->n);
- shade->function[i][shade->cs->n] = 1;
+ pdf_evalfunction(func, &t, 1, shade->function[i], shade->colorspace->n);
+ shade->function[i][shade->colorspace->n] = 1;
}
}
@@ -415,7 +415,7 @@ pdf_loadfunctionbasedshading(fz_shade *shade, pdf_xref *xref, fz_obj *dict, pdf_
fv[0] = v[i].x;
fv[1] = v[i].y;
- pdf_evalfunction(func, fv, 2, v[i].c, shade->cs->n);
+ pdf_evalfunction(func, fv, 2, v[i].c, shade->colorspace->n);
pt.x = v[i].x;
pt.y = v[i].y;
@@ -627,7 +627,7 @@ pdf_loadtype4shade(fz_shade *shade, pdf_xref *xref, fz_obj *dict,
pdf_sampleshadefunction(shade, funcs, func, p.c0[0], p.c1[0]);
}
else
- ncomp = shade->cs->n;
+ ncomp = shade->colorspace->n;
while (!fz_iseofbits(stream))
{
@@ -693,7 +693,7 @@ pdf_loadtype5shade(fz_shade *shade, pdf_xref *xref, fz_obj *dict,
pdf_sampleshadefunction(shade, funcs, func, p.c0[0], p.c1[0]);
}
else
- ncomp = shade->cs->n;
+ ncomp = shade->colorspace->n;
ref = fz_calloc(p.vprow, sizeof(struct vertex));
buf = fz_calloc(p.vprow, sizeof(struct vertex));
@@ -745,7 +745,7 @@ pdf_loadtype6shade(fz_shade *shade, pdf_xref *xref, fz_obj *dict,
pdf_sampleshadefunction(shade, funcs, func, p.c0[0], p.c1[0]);
}
else
- ncomp = shade->cs->n;
+ ncomp = shade->colorspace->n;
hasprevpatch = 0;
@@ -865,7 +865,7 @@ pdf_loadtype7shade(fz_shade *shade, pdf_xref *xref, fz_obj *dict,
pdf_sampleshadefunction(shade, funcs, func, p.c0[0], p.c1[0]);
}
else
- ncomp = shade->cs->n;
+ ncomp = shade->colorspace->n;
hasprevpatch = 0;
@@ -994,7 +994,7 @@ pdf_loadshadingdict(fz_shade **shadep, pdf_xref *xref, fz_obj *dict, fz_matrix t
shade->meshcap = 0;
shade->mesh = nil;
- shade->cs = nil;
+ shade->colorspace = nil;
funcs = 0;
@@ -1007,20 +1007,20 @@ pdf_loadshadingdict(fz_shade **shadep, pdf_xref *xref, fz_obj *dict, fz_matrix t
fz_dropshade(shade);
return fz_throw("shading colorspace is missing");
}
- error = pdf_loadcolorspace(&shade->cs, xref, obj);
+ error = pdf_loadcolorspace(&shade->colorspace, xref, obj);
if (error)
{
fz_dropshade(shade);
return fz_rethrow(error, "cannot load colorspace (%d %d R)", fz_tonum(obj), fz_togen(obj));
}
- pdf_logshade("colorspace %s\n", shade->cs->name);
+ pdf_logshade("colorspace %s\n", shade->colorspace->name);
obj = fz_dictgets(dict, "Background");
if (obj)
{
pdf_logshade("background\n");
shade->usebackground = 1;
- for (i = 0; i < shade->cs->n; i++)
+ for (i = 0; i < shade->colorspace->n; i++)
shade->background[i] = fz_toreal(fz_arrayget(obj, i));
}
@@ -1045,7 +1045,7 @@ pdf_loadshadingdict(fz_shade **shadep, pdf_xref *xref, fz_obj *dict, fz_matrix t
else if (fz_isarray(obj))
{
funcs = fz_arraylen(obj);
- if (funcs != 1 && funcs != shade->cs->n)
+ if (funcs != 1 && funcs != shade->colorspace->n)
{
error = fz_throw("incorrect number of shading functions");
goto cleanup;
diff --git a/xps/xps_gradient.c b/xps/xps_gradient.c
index 3342112c..b23098bd 100644
--- a/xps/xps_gradient.c
+++ b/xps/xps_gradient.c
@@ -214,7 +214,7 @@ xps_draw_one_radial_gradient(xps_context *ctx, fz_matrix ctm,
/* TODO: this (and the stuff in pdf_shade) should move to res_shade.c */
shade = fz_malloc(sizeof(fz_shade));
shade->refs = 1;
- shade->cs = fz_devicergb;
+ shade->colorspace = fz_devicergb;
shade->bbox = fz_infiniterect;
shade->matrix = fz_identity;
shade->usebackground = 0;
@@ -255,7 +255,7 @@ xps_draw_one_linear_gradient(xps_context *ctx, fz_matrix ctm,
/* TODO: this (and the stuff in pdf_shade) should move to res_shade.c */
shade = fz_malloc(sizeof(fz_shade));
shade->refs = 1;
- shade->cs = fz_devicergb;
+ shade->colorspace = fz_devicergb;
shade->bbox = fz_infiniterect;
shade->matrix = fz_identity;
shade->usebackground = 0;