summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Jamfile1
-rw-r--r--Makefile2
-rw-r--r--base/matrix.c6
-rw-r--r--mupdf/shade.c5
-rw-r--r--mupdf/shade1.c4
-rw-r--r--mupdf/shade4.c157
-rw-r--r--tree/shade.c4
7 files changed, 177 insertions, 2 deletions
diff --git a/Jamfile b/Jamfile
index 6b452ddf..51c268f5 100644
--- a/Jamfile
+++ b/Jamfile
@@ -131,6 +131,7 @@ Library libmupdf :
mupdf/shade1.c
mupdf/shade2.c
mupdf/shade3.c
+ mupdf/shade4.c
mupdf/cmap.c
mupdf/unicode.c
mupdf/fontagl.c
diff --git a/Makefile b/Makefile
index 04032402..9896588c 100644
--- a/Makefile
+++ b/Makefile
@@ -102,8 +102,10 @@ libmupdf.a: \
mupdf/image.o \
mupdf/pattern.o \
mupdf/shade.o \
+ mupdf/shade1.o \
mupdf/shade2.o \
mupdf/shade3.o \
+ mupdf/shade4.o \
mupdf/cmap.o \
mupdf/unicode.o \
mupdf/fontagl.o \
diff --git a/base/matrix.c b/base/matrix.c
index 2b831bf4..b0513940 100644
--- a/base/matrix.c
+++ b/base/matrix.c
@@ -130,6 +130,12 @@ fz_rect
fz_transformaabb(fz_matrix m, fz_rect r)
{
fz_point s, t, u, v;
+
+ if (fz_isinfiniterect(r))
+ return r;
+ if (fz_isemptyrect(r))
+ return r;
+
s.x = r.min.x; s.y = r.min.y;
t.x = r.min.x; t.y = r.max.y;
u.x = r.max.x; u.y = r.max.y;
diff --git a/mupdf/shade.c b/mupdf/shade.c
index b309a2be..7784b66b 100644
--- a/mupdf/shade.c
+++ b/mupdf/shade.c
@@ -63,6 +63,7 @@ loadshadedict(fz_shade **shadep, pdf_xref *xref, fz_obj *dict, fz_obj *ref, fz_m
shade->usebackground = 0;
shade->usefunction = 0;
shade->matrix = matrix;
+ shade->bbox = fz_infiniterect;
obj = fz_dictgets(dict, "ShadingType");
type = fz_toint(obj);
@@ -120,6 +121,10 @@ loadshadedict(fz_shade **shadep, pdf_xref *xref, fz_obj *dict, fz_obj *ref, fz_m
error = pdf_loadtype3shade(shade, xref, dict, ref);
if (error) goto cleanup;
break;
+ case 4:
+ error = pdf_loadtype4shade(shade, xref, dict, ref);
+ if (error) goto cleanup;
+ break;
default:
error = fz_throw("syntaxerror: unknown shading type: %d", type);
goto cleanup;
diff --git a/mupdf/shade1.c b/mupdf/shade1.c
index 63c276b3..c9146361 100644
--- a/mupdf/shade1.c
+++ b/mupdf/shade1.c
@@ -46,7 +46,7 @@ pdf_loadtype1shade(fz_shade *shade, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
float t;
int n;
- pdf_logshade("type1 shade {\n");
+ pdf_logshade("load type1 shade {\n");
obj = fz_dictgets(dict, "Domain");
x0 = fz_toreal(fz_arrayget(obj, 0));
@@ -94,6 +94,8 @@ pdf_loadtype1shade(fz_shade *shade, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
}
}
+ pdf_logshade("}\n");
+
return nil;
}
diff --git a/mupdf/shade4.c b/mupdf/shade4.c
new file mode 100644
index 00000000..dfc821a2
--- /dev/null
+++ b/mupdf/shade4.c
@@ -0,0 +1,157 @@
+#include <fitz.h>
+#include <mupdf.h>
+
+fz_error *
+pdf_loadtype4shade(fz_shade *shade, pdf_xref *xref, fz_obj *shading, fz_obj *ref)
+{
+ fz_error *error;
+ fz_obj *obj;
+ int bpcoord;
+ int bpcomp;
+ int bpflag;
+ int ncomp;
+ float x0, x1, y0, y1;
+ float c0[FZ_MAXCOLORS];
+ float c1[FZ_MAXCOLORS];
+ int i, z;
+ int bitspervertex;
+ int bytepervertex;
+ fz_buffer *buf;
+ int n;
+ int j;
+ float cval[16];
+
+ int flag;
+ unsigned int t;
+ float x, y;
+
+ error = nil;
+
+ ncomp = shade->cs->n;
+ bpcoord = fz_toint(fz_dictgets(shading, "BitsPerCoordinate"));
+ bpcomp = fz_toint(fz_dictgets(shading, "BitsPerComponent"));
+ bpflag = fz_toint(fz_dictgets(shading, "BitsPerFlag"));
+
+ obj = fz_dictgets(shading, "Decode");
+ if (fz_isarray(obj))
+ {
+ pdf_logshade("decode array\n");
+ x0 = fz_toreal(fz_arrayget(obj, 0));
+ x1 = fz_toreal(fz_arrayget(obj, 1));
+ y0 = fz_toreal(fz_arrayget(obj, 2));
+ y1 = fz_toreal(fz_arrayget(obj, 3));
+ for (i=0; i < fz_arraylen(obj) / 2; ++i) {
+ c0[i] = fz_toreal(fz_arrayget(obj, i*2+4));
+ c1[i] = fz_toreal(fz_arrayget(obj, i*2+5));
+ }
+ }
+ else {
+ error = fz_throw("syntaxerror: No Decode key in Type 4 Shade");
+ goto cleanup;
+ }
+
+ obj = fz_dictgets(shading, "Function");
+ if (obj) {
+ ncomp = 1;
+ pdf_loadshadefunction(shade, xref, shading, c0[0], c1[0]);
+ }
+
+ bitspervertex = bpflag + bpcoord * 2 + bpcomp * ncomp;
+ bytepervertex = (bitspervertex+7) / 8;
+
+ error = pdf_loadstream(&buf, xref, fz_tonum(ref), fz_togen(ref));
+ if (error) goto cleanup;
+
+ shade->usefunction = 0;
+
+
+ n = 2 + shade->cs->n;
+ j = 0;
+ for (z = 0; z < (buf->ep - buf->bp) / bytepervertex; ++z)
+ {
+ flag = *buf->rp++;
+
+ t = *buf->rp++;
+ t = (t << 8) + *buf->rp++;
+ t = (t << 8) + *buf->rp++;
+ x = x0 + (t * (x1 - x0) / (pow(2, 24) - 1));
+
+ t = *buf->rp++;
+ t = (t << 8) + *buf->rp++;
+ t = (t << 8) + *buf->rp++;
+ y = y0 + (t * (y1 - y0) / (pow(2, 24) - 1));
+
+ for (i=0; i < ncomp; ++i) {
+ t = *buf->rp++;
+ t = (t << 8) + *buf->rp++;
+ }
+
+ if (flag == 0) {
+ j += n;
+ }
+ if (flag == 1 || flag == 2) {
+ j += 3 * n;
+ }
+ }
+ buf->rp = buf->bp;
+
+ shade->mesh = (float*) malloc(sizeof(float) * j);
+ /* 8, 24, 16 only */
+ j = 0;
+ for (z = 0; z < (buf->ep - buf->bp) / bytepervertex; ++z)
+ {
+ flag = *buf->rp++;
+
+ t = *buf->rp++;
+ t = (t << 8) + *buf->rp++;
+ t = (t << 8) + *buf->rp++;
+ x = x0 + (t * (x1 - x0) / (pow(2, 24) - 1));
+
+ t = *buf->rp++;
+ t = (t << 8) + *buf->rp++;
+ t = (t << 8) + *buf->rp++;
+ y = y0 + (t * (y1 - y0) / (pow(2, 24) - 1));
+
+ for (i=0; i < ncomp; ++i) {
+ t = *buf->rp++;
+ t = (t << 8) + *buf->rp++;
+ cval[i] = t / (double)(pow(2, 16) - 1);
+ }
+
+ if (flag == 0) {
+ shade->mesh[j++] = x;
+ shade->mesh[j++] = y;
+ for (i=0; i < ncomp; ++i) {
+ shade->mesh[j++] = cval[i];
+ }
+ }
+ if (flag == 1) {
+ memcpy(&(shade->mesh[j]), &(shade->mesh[j - 2 * n]), n * sizeof(float));
+ memcpy(&(shade->mesh[j + 1 * n]), &(shade->mesh[j - 1 * n]), n * sizeof(float));
+ j+= 2 * n;
+ shade->mesh[j++] = x;
+ shade->mesh[j++] = y;
+ for (i=0; i < ncomp; ++i) {
+ shade->mesh[j++] = cval[i];
+ }
+ }
+ if (flag == 2) {
+ memcpy(&(shade->mesh[j]), &(shade->mesh[j - 3 * n]), n * sizeof(float));
+ memcpy(&(shade->mesh[j + 1 * n]), &(shade->mesh[j - 1 * n]), n * sizeof(float));
+ j+= 2 * n;
+ shade->mesh[j++] = x;
+ shade->mesh[j++] = y;
+ for (i=0; i < ncomp; ++i) {
+ shade->mesh[j++] = cval[i];
+ }
+ }
+ }
+ shade->meshlen = j / n / 3;
+
+ fz_dropbuffer(buf);
+
+cleanup:
+
+ return nil;
+}
+
diff --git a/tree/shade.c b/tree/shade.c
index cb33072e..67a64e4e 100644
--- a/tree/shade.c
+++ b/tree/shade.c
@@ -14,6 +14,7 @@ fz_dropshade(fz_shade *shade)
{
if (shade->cs)
fz_dropcolorspace(shade->cs);
+ fz_free(shade->mesh);
fz_free(shade);
}
}
@@ -21,6 +22,7 @@ fz_dropshade(fz_shade *shade)
fz_rect
fz_boundshade(fz_shade *shade, fz_matrix ctm)
{
- return fz_infiniterect;
+ ctm = fz_concat(shade->matrix, ctm);
+ return fz_transformaabb(ctm, shade->bbox);
}