diff options
-rw-r--r-- | Jamfile | 1 | ||||
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | base/matrix.c | 6 | ||||
-rw-r--r-- | mupdf/shade.c | 5 | ||||
-rw-r--r-- | mupdf/shade1.c | 4 | ||||
-rw-r--r-- | mupdf/shade4.c | 157 | ||||
-rw-r--r-- | tree/shade.c | 4 |
7 files changed, 177 insertions, 2 deletions
@@ -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 @@ -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); } |