summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mupdf/mupdf.h6
-rw-r--r--mupdf/pdf_interpret.c241
2 files changed, 131 insertions, 116 deletions
diff --git a/mupdf/mupdf.h b/mupdf/mupdf.h
index 28fa20c3..dd079473 100644
--- a/mupdf/mupdf.h
+++ b/mupdf/mupdf.h
@@ -599,10 +599,12 @@ struct pdf_csi_s
fz_device *dev;
pdf_xref *xref;
- fz_obj *stack[32];
+ fz_obj *obj, *array;
+ float stack[32];
+ int istack[32];
int top;
+
int xbalance;
- fz_obj *array;
/* path object state */
fz_path *path;
diff --git a/mupdf/pdf_interpret.c b/mupdf/pdf_interpret.c
index 9b19bdb3..c20d3594 100644
--- a/mupdf/pdf_interpret.c
+++ b/mupdf/pdf_interpret.c
@@ -11,8 +11,12 @@ pdf_newcsi(pdf_xref *xref, fz_device *dev, fz_matrix ctm)
csi->dev = dev;
csi->top = 0;
- csi->xbalance = 0;
+ csi->obj = nil;
csi->array = nil;
+ memset(csi->stack, 0, sizeof csi->stack);
+ memset(csi->istack, 0, sizeof csi->istack);
+
+ csi->xbalance = 0;
csi->path = fz_newpath();
csi->clip = 0;
@@ -35,8 +39,17 @@ static void
pdf_clearstack(pdf_csi *csi)
{
int i;
+
+ if (csi->obj)
+ fz_dropobj(csi->obj);
+ csi->obj = nil;
+
for (i = 0; i < csi->top; i++)
- fz_dropobj(csi->stack[i]);
+ {
+ csi->stack[i] = 0;
+ csi->istack[i] = 0;
+ }
+
csi->top = 0;
}
@@ -459,10 +472,10 @@ static void pdf_run_Bstar(pdf_csi *csi)
static fz_error pdf_run_cs_core(pdf_csi *csi, fz_obj *rdb, int what)
{
fz_colorspace *cs;
- fz_obj *obj;
+ fz_obj *obj, *dict, *res;
fz_error error;
- obj = csi->stack[0];
+ obj = csi->obj;
if (!fz_isname(obj))
return fz_throw("malformed CS");
@@ -482,16 +495,15 @@ static fz_error pdf_run_cs_core(pdf_csi *csi, fz_obj *rdb, int what)
cs = fz_keepcolorspace(fz_devicecmyk);
else
{
- fz_obj *dict = fz_dictgets(rdb, "ColorSpace");
+ 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);
+ res = fz_dictget(dict, obj);
+ if (!res)
+ return fz_throw("cannot find colorspace resource /%s", fz_toname(obj));
+ error = pdf_loadcolorspace(&cs, csi->xref, res);
if (error)
- return fz_rethrow(error, "cannot load colorspace (%d %d R)", fz_tonum(obj), fz_togen(obj));
+ return fz_rethrow(error, "cannot load colorspace (%d 0 R)", fz_tonum(res));
}
pdf_setcolorspace(csi, what, cs);
@@ -517,18 +529,21 @@ static void pdf_run_DP(pdf_csi *csi)
static fz_error pdf_run_Do(pdf_csi *csi, fz_obj *rdb)
{
+ fz_obj *name;
fz_obj *dict;
fz_obj *obj;
fz_obj *subtype;
fz_error error;
+ name = csi->obj;
+
dict = fz_dictgets(rdb, "XObject");
if (!dict)
- return fz_throw("cannot find XObject dictionary when looking for: '%s'", fz_toname(csi->stack[0]));
+ return fz_throw("cannot find XObject dictionary when looking for: '%s'", fz_toname(name));
- obj = fz_dictget(dict, csi->stack[0]);
+ obj = fz_dictget(dict, name);
if (!obj)
- return fz_throw("cannot find xobject resource: '%s'", fz_toname(csi->stack[0]));
+ return fz_throw("cannot find xobject resource: '%s'", fz_toname(name));
subtype = fz_dictgets(obj, "Subtype");
if (!fz_isname(subtype))
@@ -603,7 +618,7 @@ static void pdf_run_F(pdf_csi *csi)
static void pdf_run_G(pdf_csi *csi)
{
- float v = fz_toreal(csi->stack[0]);
+ float v = csi->stack[0];
pdf_setcolorspace(csi, PDF_MSTROKE, fz_devicegray);
pdf_setcolor(csi, PDF_MSTROKE, &v);
}
@@ -611,17 +626,17 @@ static void pdf_run_G(pdf_csi *csi)
static void pdf_run_J(pdf_csi *csi)
{
pdf_gstate *gstate = csi->gstate + csi->gtop;
- gstate->strokestate.linecap = fz_toint(csi->stack[0]);
+ gstate->strokestate.linecap = csi->istack[0];
}
static void pdf_run_K(pdf_csi *csi)
{
float v[4];
- 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]);
+ v[0] = csi->stack[0];
+ v[1] = csi->stack[1];
+ v[2] = csi->stack[2];
+ v[3] = csi->stack[3];
pdf_setcolorspace(csi, PDF_MSTROKE, fz_devicecmyk);
pdf_setcolor(csi, PDF_MSTROKE, v);
@@ -630,7 +645,7 @@ static void pdf_run_K(pdf_csi *csi)
static void pdf_run_M(pdf_csi *csi)
{
pdf_gstate *gstate = csi->gstate + csi->gtop;
- gstate->strokestate.miterlimit = fz_toreal(csi->stack[0]);
+ gstate->strokestate.miterlimit = csi->stack[0];
}
static void pdf_run_MP(pdf_csi *csi)
@@ -646,9 +661,9 @@ static void pdf_run_R(pdf_csi *csi)
{
float v[3];
- v[0] = fz_toreal(csi->stack[0]);
- v[1] = fz_toreal(csi->stack[1]);
- v[2] = fz_toreal(csi->stack[2]);
+ v[0] = csi->stack[0];
+ v[1] = csi->stack[1];
+ v[2] = csi->stack[2];
pdf_setcolorspace(csi, PDF_MSTROKE, fz_devicergb);
pdf_setcolor(csi, PDF_MSTROKE, v);
@@ -671,7 +686,7 @@ static fz_error pdf_run_SC_core(pdf_csi *csi, fz_obj *rdb, int what, pdf_materia
float v[FZ_MAXCOLORS];
kind = mat->kind;
- if (fz_isname(csi->stack[csi->top - 1]))
+ if (fz_isname(csi->obj))
kind = PDF_MPATTERN;
switch (kind)
@@ -683,22 +698,21 @@ static fz_error pdf_run_SC_core(pdf_csi *csi, fz_obj *rdb, int what, pdf_materia
if (csi->top < mat->cs->n)
goto syntaxerror;
for (i = 0; i < csi->top; i++)
- v[i] = fz_toreal(csi->stack[i]);
+ v[i] = csi->stack[i];
pdf_setcolor(csi, what, v);
break;
case PDF_MPATTERN:
for (i = 0; i < csi->top - 1; i++)
- v[i] = fz_toreal(csi->stack[i]);
+ v[i] = csi->stack[i];
dict = fz_dictgets(rdb, "Pattern");
if (!dict)
return fz_throw("cannot find Pattern dictionary");
- obj = fz_dictget(dict, csi->stack[csi->top - 1]);
+ obj = fz_dictget(dict, csi->obj);
if (!obj)
- return fz_throw("cannot find pattern resource /%s",
- fz_toname(csi->stack[csi->top - 1]));
+ return fz_throw("cannot find pattern resource /%s", fz_toname(csi->obj));
patterntype = fz_dictgets(obj, "PatternType");
@@ -751,19 +765,19 @@ static void pdf_run_sc(pdf_csi *csi, fz_obj *rdb)
static void pdf_run_Tc(pdf_csi *csi)
{
pdf_gstate *gstate = csi->gstate + csi->gtop;
- gstate->charspace = fz_toreal(csi->stack[0]);
+ gstate->charspace = csi->stack[0];
}
static void pdf_run_Tw(pdf_csi *csi)
{
pdf_gstate *gstate = csi->gstate + csi->gtop;
- gstate->wordspace = fz_toreal(csi->stack[0]);
+ gstate->wordspace = csi->stack[0];
}
static void pdf_run_Tz(pdf_csi *csi)
{
pdf_gstate *gstate = csi->gstate + csi->gtop;
- float a = fz_toreal(csi->stack[0]) / 100;
+ float a = csi->stack[0] / 100;
pdf_flushtext(csi);
gstate->scale = a;
}
@@ -771,7 +785,7 @@ static void pdf_run_Tz(pdf_csi *csi)
static void pdf_run_TL(pdf_csi *csi)
{
pdf_gstate *gstate = csi->gstate + csi->gtop;
- gstate->leading = fz_toreal(csi->stack[0]);
+ gstate->leading = csi->stack[0];
}
static fz_error pdf_run_Tf(pdf_csi *csi, fz_obj *rdb)
@@ -785,9 +799,9 @@ static fz_error pdf_run_Tf(pdf_csi *csi, fz_obj *rdb)
if (!dict)
return fz_throw("cannot find Font dictionary");
- obj = fz_dictget(dict, csi->stack[0]);
+ obj = fz_dictget(dict, csi->obj);
if (!obj)
- return fz_throw("cannot find font resource: %s", fz_toname(csi->stack[0]));
+ return fz_throw("cannot find font resource: %s", fz_toname(csi->obj));
if (gstate->font)
{
@@ -799,25 +813,25 @@ static fz_error pdf_run_Tf(pdf_csi *csi, fz_obj *rdb)
if (error)
return fz_rethrow(error, "cannot load font (%d %d R)", fz_tonum(obj), fz_togen(obj));
- gstate->size = fz_toreal(csi->stack[1]);
+ gstate->size = csi->stack[1];
return fz_okay;
}
static void pdf_run_Tr(pdf_csi *csi)
{
pdf_gstate *gstate = csi->gstate + csi->gtop;
- gstate->render = fz_toint(csi->stack[0]);
+ gstate->render = csi->istack[0];
}
static void pdf_run_Ts(pdf_csi *csi)
{
pdf_gstate *gstate = csi->gstate + csi->gtop;
- gstate->rise = fz_toreal(csi->stack[0]);
+ gstate->rise = csi->stack[0];
}
static void pdf_run_Td(pdf_csi *csi)
{
- fz_matrix m = fz_translate(fz_toreal(csi->stack[0]), fz_toreal(csi->stack[1]));
+ fz_matrix m = fz_translate(csi->stack[0], csi->stack[1]);
csi->tlm = fz_concat(m, csi->tlm);
csi->tm = csi->tlm;
}
@@ -827,27 +841,21 @@ static void pdf_run_TD(pdf_csi *csi)
pdf_gstate *gstate = csi->gstate + csi->gtop;
fz_matrix m;
- gstate->leading = -fz_toreal(csi->stack[1]);
- m = fz_translate(fz_toreal(csi->stack[0]), fz_toreal(csi->stack[1]));
+ 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;
}
static void pdf_run_Tm(pdf_csi *csi)
{
- fz_matrix m;
-
- 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);
-
- /* RJW: Inefficient. Why write to m then copy it? */
- csi->tm = m;
+ 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;
}
@@ -861,12 +869,12 @@ static void pdf_run_Tstar(pdf_csi *csi)
static void pdf_run_Tj(pdf_csi *csi)
{
- pdf_showtext(csi, csi->stack[0]);
+ pdf_showtext(csi, csi->obj);
}
static void pdf_run_TJ(pdf_csi *csi)
{
- pdf_showtext(csi, csi->stack[0]);
+ pdf_showtext(csi, csi->obj);
}
static void pdf_run_W(pdf_csi *csi)
@@ -894,12 +902,12 @@ static void pdf_run_bstar(pdf_csi *csi)
static void pdf_run_c(pdf_csi *csi)
{
float a, b, c, d, e, f;
- 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]);
+ 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);
}
@@ -908,12 +916,12 @@ static void pdf_run_cm(pdf_csi *csi)
pdf_gstate *gstate = csi->gstate + csi->gtop;
fz_matrix m;
- 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]);
+ 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];
gstate->ctm = fz_concat(m, gstate->ctm);
}
@@ -924,11 +932,11 @@ static void pdf_run_d(pdf_csi *csi)
fz_obj *array;
int i;
- array = csi->stack[0];
+ 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 = fz_toreal(csi->stack[1]);
+ gstate->strokestate.dashphase = csi->stack[1];
}
static void pdf_run_d0(pdf_csi *csi)
@@ -951,7 +959,7 @@ static void pdf_run_fstar(pdf_csi *csi)
static void pdf_run_g(pdf_csi *csi)
{
- float v = fz_toreal(csi->stack[0]);
+ float v = csi->stack[0];
pdf_setcolorspace(csi, PDF_MFILL, fz_devicegray);
pdf_setcolor(csi, PDF_MFILL, &v);
}
@@ -966,9 +974,9 @@ static fz_error pdf_run_gs(pdf_csi *csi, fz_obj *rdb)
if (!dict)
return fz_throw("cannot find ExtGState dictionary");
- obj = fz_dictget(dict, csi->stack[0]);
+ obj = fz_dictget(dict, csi->obj);
if (!obj)
- return fz_throw("cannot find extgstate resource /%s", fz_toname(csi->stack[0]));
+ return fz_throw("cannot find extgstate resource /%s", fz_toname(csi->obj));
error = pdf_runextgstate(csi, rdb, obj);
if (error)
@@ -988,17 +996,17 @@ static void pdf_run_i(pdf_csi *csi)
static void pdf_run_j(pdf_csi *csi)
{
pdf_gstate *gstate = csi->gstate + csi->gtop;
- gstate->strokestate.linejoin = fz_toint(csi->stack[0]);
+ gstate->strokestate.linejoin = csi->istack[0];
}
static void pdf_run_k(pdf_csi *csi)
{
float v[4];
- 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]);
+ v[0] = csi->stack[0];
+ v[1] = csi->stack[1];
+ v[2] = csi->stack[2];
+ v[3] = csi->stack[3];
pdf_setcolorspace(csi, PDF_MFILL, fz_devicecmyk);
pdf_setcolor(csi, PDF_MFILL, v);
@@ -1008,8 +1016,8 @@ static void pdf_run_l(pdf_csi *csi)
{
float a, b;
- a = fz_toreal(csi->stack[0]);
- b = fz_toreal(csi->stack[1]);
+ a = csi->stack[0];
+ b = csi->stack[1];
fz_lineto(csi->path, a, b);
}
@@ -1017,8 +1025,8 @@ static void pdf_run_m(pdf_csi *csi)
{
float a, b;
- a = fz_toreal(csi->stack[0]);
- b = fz_toreal(csi->stack[1]);
+ a = csi->stack[0];
+ b = csi->stack[1];
fz_moveto(csi->path, a, b);
}
@@ -1036,10 +1044,10 @@ static void pdf_run_re(pdf_csi *csi)
{
float x, y, w, h;
- x = fz_toreal(csi->stack[0]);
- y = fz_toreal(csi->stack[1]);
- w = fz_toreal(csi->stack[2]);
- h = fz_toreal(csi->stack[3]);
+ x = csi->stack[0];
+ y = csi->stack[1];
+ w = csi->stack[2];
+ h = csi->stack[3];
fz_moveto(csi->path, x, y);
fz_lineto(csi->path, x + w, y);
@@ -1052,9 +1060,9 @@ static void pdf_run_rg(pdf_csi *csi)
{
float v[3];
- v[0] = fz_toreal(csi->stack[0]);
- v[1] = fz_toreal(csi->stack[1]);
- v[2] = fz_toreal(csi->stack[2]);
+ v[0] = csi->stack[0];
+ v[1] = csi->stack[1];
+ v[2] = csi->stack[2];
pdf_setcolorspace(csi, PDF_MFILL, fz_devicergb);
pdf_setcolor(csi, PDF_MFILL, v);
@@ -1080,9 +1088,9 @@ static fz_error pdf_run_sh(pdf_csi *csi, fz_obj *rdb)
if (!dict)
return fz_throw("cannot find shading dictionary");
- obj = fz_dictget(dict, csi->stack[csi->top - 1]);
+ obj = fz_dictget(dict, csi->obj);
if (!obj)
- return fz_throw("cannot find shading resource: %s", fz_toname(csi->stack[csi->top - 1]));
+ return fz_throw("cannot find shading resource: %s", fz_toname(csi->obj));
if ((csi->dev->hints & FZ_IGNORESHADE) == 0)
{
@@ -1099,27 +1107,27 @@ static void pdf_run_v(pdf_csi *csi)
{
float a, b, c, d;
- a = fz_toreal(csi->stack[0]);
- b = fz_toreal(csi->stack[1]);
- c = fz_toreal(csi->stack[2]);
- d = fz_toreal(csi->stack[3]);
+ a = csi->stack[0];
+ b = csi->stack[1];
+ c = csi->stack[2];
+ d = csi->stack[3];
fz_curvetov(csi->path, a, b, c, d);
}
static void pdf_run_w(pdf_csi *csi)
{
pdf_gstate *gstate = csi->gstate + csi->gtop;
- gstate->strokestate.linewidth = fz_toreal(csi->stack[0]);
+ gstate->strokestate.linewidth = csi->stack[0];
}
static void pdf_run_y(pdf_csi *csi)
{
float a, b, c, d;
- a = fz_toreal(csi->stack[0]);
- b = fz_toreal(csi->stack[1]);
- c = fz_toreal(csi->stack[2]);
- d = fz_toreal(csi->stack[3]);
+ a = csi->stack[0];
+ b = csi->stack[1];
+ c = csi->stack[2];
+ d = csi->stack[3];
fz_curvetoy(csi->path, a, b, c, d);
}
@@ -1132,7 +1140,7 @@ static void pdf_run_squote(pdf_csi *csi)
csi->tlm = fz_concat(m, csi->tlm);
csi->tm = csi->tlm;
- pdf_showtext(csi, csi->stack[0]);
+ pdf_showtext(csi, csi->obj);
}
static void pdf_run_dquote(pdf_csi *csi)
@@ -1140,14 +1148,14 @@ static void pdf_run_dquote(pdf_csi *csi)
fz_matrix m;
pdf_gstate *gstate = csi->gstate + csi->gtop;
- gstate->wordspace = fz_toreal(csi->stack[0]);
- gstate->charspace = fz_toreal(csi->stack[1]);
+ 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;
- pdf_showtext(csi, csi->stack[2]);
+ pdf_showtext(csi, csi->obj);
}
static fz_error
@@ -1777,7 +1785,7 @@ pdf_runcsifile(pdf_csi *csi, fz_obj *rdb, fz_stream *file, char *buf, int buflen
{
if (tok == PDF_TCARRAY)
{
- csi->stack[csi->top] = csi->array;
+ csi->obj = csi->array;
csi->array = nil;
csi->top ++;
}
@@ -1810,50 +1818,55 @@ 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 */
+ /* TODO: optimize text-object array parsing */
case PDF_TOARRAY:
csi->array = fz_newarray(8);
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->obj = fz_newname(buf);
csi->top ++;
break;
case PDF_TINT:
- csi->stack[csi->top] = fz_newint(atoi(buf));
+ csi->istack[csi->top] = atoi(buf);
+ csi->stack[csi->top] = csi->istack[csi->top];
csi->top ++;
break;
case PDF_TREAL:
- csi->stack[csi->top] = fz_newreal(atof(buf));
+ csi->stack[csi->top] = atof(buf);
+ csi->istack[csi->top] = csi->stack[csi->top];
csi->top ++;
break;
case PDF_TSTRING:
- csi->stack[csi->top] = fz_newstring(buf, len);
+ csi->obj = fz_newstring(buf, len);
csi->top ++;
break;
case PDF_TTRUE:
- csi->stack[csi->top] = fz_newbool(1);
+ csi->istack[csi->top] = 1;
+ csi->stack[csi->top] = 1;
csi->top ++;
break;
case PDF_TFALSE:
- csi->stack[csi->top] = fz_newbool(0);
+ csi->istack[csi->top] = 0;
+ csi->stack[csi->top] = 0;
csi->top ++;
break;
case PDF_TNULL:
- csi->stack[csi->top] = fz_newnull();
+ csi->istack[csi->top] = 0;
+ csi->stack[csi->top] = 0;
csi->top ++;
break;