summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Jamfile1
-rw-r--r--base/matrix.c19
-rw-r--r--include/fitz/geometry.h1
-rw-r--r--include/mupdf/content.h8
-rw-r--r--include/mupdf/rsrc.h19
-rw-r--r--include/mupdf/xref.h1
-rw-r--r--mupdf/build.c131
-rw-r--r--mupdf/colorspace.c7
-rw-r--r--mupdf/interpret.c131
-rw-r--r--mupdf/page.c10
-rw-r--r--mupdf/pattern.c116
-rw-r--r--mupdf/resources.c77
-rw-r--r--mupdf/type3.c22
-rw-r--r--render/pixmap.c42
-rw-r--r--render/render.c2
-rw-r--r--render/renderimage.c25
16 files changed, 520 insertions, 92 deletions
diff --git a/Jamfile b/Jamfile
index 24aa952a..7f53cbe5 100644
--- a/Jamfile
+++ b/Jamfile
@@ -113,6 +113,7 @@ Library libmupdf :
mupdf/colorspace.c
mupdf/image.c
mupdf/xobject.c
+ mupdf/pattern.c
mupdf/resources.c
mupdf/page.c
mupdf/build.c
diff --git a/base/matrix.c b/base/matrix.c
index 659193f5..43c3f4e1 100644
--- a/base/matrix.c
+++ b/base/matrix.c
@@ -85,3 +85,22 @@ fz_transformpoint(fz_matrix m, fz_point p)
return t;
}
+fz_rect
+fz_transformaabb(fz_matrix m, fz_rect r)
+{
+ fz_point s, t, u, v;
+ 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;
+ v.x = r.max.x; v.y = r.min.y;
+ s = fz_transformpoint(m, s);
+ t = fz_transformpoint(m, t);
+ u = fz_transformpoint(m, u);
+ v = fz_transformpoint(m, v);
+ r.min.x = MIN4(s.x, t.x, u.x, v.x);
+ r.min.y = MIN4(s.y, t.y, u.y, v.y);
+ r.max.x = MAX4(s.x, t.x, u.x, v.x);
+ r.max.y = MAX4(s.y, t.y, u.y, v.y);
+ return r;
+}
+
diff --git a/include/fitz/geometry.h b/include/fitz/geometry.h
index 29a6b522..78e9e637 100644
--- a/include/fitz/geometry.h
+++ b/include/fitz/geometry.h
@@ -53,4 +53,5 @@ fz_irect fz_intersectirects(fz_irect a, fz_irect b);
fz_irect fz_mergeirects(fz_irect a, fz_irect b);
fz_point fz_transformpoint(fz_matrix m, fz_point p);
+fz_rect fz_transformaabb(fz_matrix m, fz_rect r);
diff --git a/include/mupdf/content.h b/include/mupdf/content.h
index 96b31f8e..6dae61da 100644
--- a/include/mupdf/content.h
+++ b/include/mupdf/content.h
@@ -18,8 +18,7 @@ enum
PDF_MCOLOR,
PDF_MLAB,
PDF_MINDEXED,
- PDF_MTILE,
- PDF_MSHADE
+ PDF_MPATTERN
};
struct pdf_material_s
@@ -28,9 +27,7 @@ struct pdf_material_s
fz_colorspace *cs;
float v[32];
pdf_indexed *indexed;
- // lookup
- // tile
- // shade
+ pdf_pattern *pattern;
};
struct pdf_gstate_s
@@ -86,6 +83,7 @@ struct pdf_csi_s
void pdf_initgstate(pdf_gstate *gs);
fz_error *pdf_setcolorspace(pdf_csi *csi, int what, fz_colorspace *cs);
fz_error *pdf_setcolor(pdf_csi *csi, int what, float *v);
+fz_error *pdf_setpattern(pdf_csi *csi, int what, pdf_pattern *pat, float *v);
fz_error *pdf_buildstrokepath(pdf_gstate *gs, fz_pathnode *path);
fz_error *pdf_buildfillpath(pdf_gstate *gs, fz_pathnode *path, int evenodd);
diff --git a/include/mupdf/rsrc.h b/include/mupdf/rsrc.h
index 896e4335..5c9c73be 100644
--- a/include/mupdf/rsrc.h
+++ b/include/mupdf/rsrc.h
@@ -44,6 +44,25 @@ extern fz_colorspace *pdf_devicecmyk;
fz_error *pdf_loadcolorspace(fz_colorspace **csp, pdf_xref *xref, fz_obj *obj);
/*
+ * Pattern
+ */
+
+typedef struct pdf_pattern_s pdf_pattern;
+
+struct pdf_pattern_s
+{
+ int ismask;
+ float xstep;
+ float ystep;
+ fz_matrix matrix;
+ fz_rect bbox;
+ fz_tree *tree;
+};
+
+fz_error *pdf_loadpattern(pdf_pattern **patp, pdf_xref *xref, fz_obj *obj, fz_obj *ref);
+void pdf_droppattern(pdf_pattern *pat);
+
+/*
* XObject
*/
diff --git a/include/mupdf/xref.h b/include/mupdf/xref.h
index ac01ca9d..2ccd3710 100644
--- a/include/mupdf/xref.h
+++ b/include/mupdf/xref.h
@@ -23,6 +23,7 @@ struct pdf_xref_s
pdf_rsrc *rfont;
pdf_rsrc *rimage;
pdf_rsrc *rxobject;
+ pdf_rsrc *rpattern;
pdf_rsrc *rcolorspace;
};
diff --git a/mupdf/build.c b/mupdf/build.c
index 6a8f4fdf..20bb0f5d 100644
--- a/mupdf/build.c
+++ b/mupdf/build.c
@@ -83,18 +83,27 @@ pdf_setcolor(pdf_csi *csi, int what, float *v)
switch (mat->kind)
{
+ case PDF_MPATTERN:
+ if (!strcmp(mat->cs->name, "Lab"))
+ goto Llab;
+ if (!strcmp(mat->cs->name, "Indexed"))
+ goto Lindexed;
+ /* fall through */
+
case PDF_MCOLOR:
for (i = 0; i < mat->cs->n; i++)
mat->v[i] = v[i];
break;
case PDF_MLAB:
+Llab:
mat->v[0] = v[0] / 100.0;
mat->v[1] = (v[1] + 100) / 200.0;
mat->v[2] = (v[2] + 100) / 200.0;
break;
case PDF_MINDEXED:
+Lindexed:
ind = mat->indexed;
i = CLAMP(v[0], 0, ind->high);
for (k = 0; k < ind->base->n; k++)
@@ -108,6 +117,27 @@ pdf_setcolor(pdf_csi *csi, int what, float *v)
return nil;
}
+fz_error *
+pdf_setpattern(pdf_csi *csi, int what, pdf_pattern *pat, float *v)
+{
+ pdf_gstate *gs = csi->gstate + csi->gtop;
+ fz_error *error;
+ pdf_material *mat;
+
+ error = pdf_flushtext(csi);
+ if (error)
+ return error;
+
+ mat = what == PDF_MFILL ? &gs->fill : &gs->stroke;
+
+ mat->kind = PDF_MPATTERN;
+ mat->pattern = pat;
+
+ if (v)
+ return pdf_setcolor(csi, what, v);
+
+ return nil;
+}
fz_error *
pdf_buildstrokepath(pdf_gstate *gs, fz_pathnode *path)
@@ -165,6 +195,96 @@ addcolorshape(pdf_gstate *gs, fz_node *shape, fz_colorspace *cs, float *v)
return nil;
}
+static fz_matrix getmatrix(fz_node *node)
+{
+ if (node->parent)
+ {
+ fz_matrix ptm = getmatrix(node->parent);
+ if (fz_istransformnode(node))
+ return fz_concat(((fz_transformnode*)node)->m, ptm);
+ return ptm;
+ }
+ if (fz_istransformnode(node))
+ return ((fz_transformnode*)node)->m;
+ return fz_identity();
+}
+
+static fz_error *
+addpatternshape(pdf_gstate *gs, fz_node *shape,
+ pdf_pattern *pat, fz_colorspace *cs, float *v)
+{
+ fz_error *error;
+ fz_node *xform;
+ fz_node *over;
+ fz_node *mask;
+ fz_node *link;
+ fz_matrix ctm;
+ fz_matrix inv;
+ fz_matrix ptm;
+ fz_rect bbox;
+ int x, y, x0, y0, x1, y1;
+
+ /* patterns are painted in user space */
+ ctm = getmatrix(gs->head);
+ inv = fz_invertmatrix(ctm);
+
+ error = fz_newmasknode(&mask);
+ if (error) return error;
+
+ ptm = fz_concat(pat->matrix, fz_invertmatrix(ctm));
+ error = fz_newtransformnode(&xform, ptm);
+ if (error) return error;
+
+ error = fz_newovernode(&over);
+ if (error) return error;
+
+ fz_insertnode(mask, shape);
+ fz_insertnode(mask, xform);
+ fz_insertnode(xform, over);
+
+ /* get bbox of shape in pattern space for stamping */
+ ptm = fz_concat(ctm, fz_invertmatrix(pat->matrix));
+ bbox = fz_boundnode(shape, ptm);
+
+ /* expand bbox by pattern bbox */
+ bbox.min.x += pat->bbox.min.x;
+ bbox.min.y += pat->bbox.min.y;
+ bbox.max.x += pat->bbox.max.x;
+ bbox.max.y += pat->bbox.max.y;
+
+printf("stamping pattern [%g %g] over [%g %g %g %g]\n",
+ pat->xstep, pat->ystep,
+ bbox.min.x, bbox.min.y,
+ bbox.max.x, bbox.max.y);
+
+ x0 = fz_floor(bbox.min.x / pat->xstep);
+ y0 = fz_floor(bbox.min.y / pat->ystep);
+ x1 = fz_ceil(bbox.max.x / pat->xstep);
+ y1 = fz_ceil(bbox.max.y / pat->ystep);
+
+printf(" %d,%d to %d,%d\n", x0, y0, x1, y1);
+
+ for (y = y0; y <= y1; y++)
+ {
+ for (x = x0; x <= x1; x++)
+ {
+ ptm = fz_translate(x * pat->xstep, y * pat->ystep);
+ error = fz_newtransformnode(&xform, ptm);
+ if (error) return error;
+ error = fz_newlinknode(&link, pat->tree);
+ if (error) return error;
+ fz_insertnode(xform, link);
+ fz_insertnode(over, xform);
+ }
+ }
+
+ if (pat->ismask)
+ return addcolorshape(gs, mask, cs, v);
+
+ fz_insertnode(gs->head, mask);
+ return nil;
+}
+
fz_error *
pdf_addfillshape(pdf_gstate *gs, fz_node *shape)
{
@@ -174,7 +294,11 @@ pdf_addfillshape(pdf_gstate *gs, fz_node *shape)
fz_insertnode(gs->head, shape);
return nil;
case PDF_MCOLOR:
+ case PDF_MLAB:
+ case PDF_MINDEXED:
return addcolorshape(gs, shape, gs->fill.cs, gs->fill.v);
+ case PDF_MPATTERN:
+ return addpatternshape(gs, shape, gs->fill.pattern, gs->fill.cs, gs->fill.v);
default:
return fz_throw("unimplemented material");
}
@@ -189,7 +313,11 @@ pdf_addstrokeshape(pdf_gstate *gs, fz_node *shape)
fz_insertnode(gs->head, shape);
return nil;
case PDF_MCOLOR:
+ case PDF_MLAB:
+ case PDF_MINDEXED:
return addcolorshape(gs, shape, gs->stroke.cs, gs->stroke.v);
+ case PDF_MPATTERN:
+ return addpatternshape(gs, shape, gs->stroke.pattern, gs->stroke.cs, gs->stroke.v);
default:
return fz_throw("unimplemented material");
}
@@ -397,6 +525,9 @@ pdf_flushtext(pdf_csi *csi)
pdf_gstate *gstate = csi->gstate + csi->gtop;
fz_error *error;
+if (gstate->render != 0)
+fz_warn("unimplemented text render mode: %d", gstate->render);
+
if (csi->text)
{
error = pdf_addfillshape(gstate, (fz_node*)csi->text);
diff --git a/mupdf/colorspace.c b/mupdf/colorspace.c
index 28c34692..917e3237 100644
--- a/mupdf/colorspace.c
+++ b/mupdf/colorspace.c
@@ -762,6 +762,13 @@ printf("\n");
if (!strcmp(fz_toname(name), "DeviceN"))
return loadseparation(csp, xref, obj);
+
+ /* pretend this never happened... */
+ if (!strcmp(fz_toname(name), "Pattern"))
+ {
+printf("oopsie, got a pattern colorspace\n");
+ return pdf_loadcolorspace(csp, xref, fz_arrayget(obj, 1));
+ }
}
}
diff --git a/mupdf/interpret.c b/mupdf/interpret.c
index 4fb10443..786e15fe 100644
--- a/mupdf/interpret.c
+++ b/mupdf/interpret.c
@@ -7,7 +7,6 @@ pdf_newcsi(pdf_csi **csip, int maskonly)
fz_error *error;
pdf_csi *csi;
fz_node *node;
- float white = 1.0;
csi = *csip = fz_malloc(sizeof(pdf_csi));
if (!csi)
@@ -42,11 +41,6 @@ pdf_newcsi(pdf_csi **csip, int maskonly)
csi->gstate[0].fill.kind = PDF_MNONE;
csi->gstate[0].stroke.kind = PDF_MNONE;
}
- else
- {
- error = fz_newcolornode(&node, pdf_devicegray, 1, &white);
- fz_insertnode(csi->tree->root, node);
- }
csi->clip = nil;
@@ -421,58 +415,105 @@ Lsetcolorspace:
obj = csi->stack[0];
- if (!strcmp(fz_toname(obj), "DeviceGray"))
- cs = pdf_devicegray;
- else if (!strcmp(fz_toname(obj), "DeviceRGB"))
- cs = pdf_devicergb;
- else if (!strcmp(fz_toname(obj), "DeviceCMYK"))
- cs = pdf_devicecmyk;
- else
+ if (!strcmp(fz_toname(obj), "Pattern"))
{
- fz_obj *dict = fz_dictgets(rdb, "ColorSpace");
- if (!dict)
- return fz_throw("syntaxerror: missing colorspace resource");
- obj = fz_dictget(dict, obj);
- if (!obj)
- return fz_throw("syntaxerror: missing colorspace resource");
- if (fz_isindirect(obj))
- cs = pdf_findresource(xref->rcolorspace, obj);
- else
- return fz_throw("syntaxerror: inline colorspace in dict");
- if (!cs)
- return fz_throw("syntaxerror: missing colorspace resource");
+ error = pdf_setpattern(csi, what, nil, nil);
+ if (error) return error;
}
- error = pdf_setcolorspace(csi, what, cs);
- if (error) return error;
+ else
+ {
+ if (!strcmp(fz_toname(obj), "DeviceGray"))
+ cs = pdf_devicegray;
+ else if (!strcmp(fz_toname(obj), "DeviceRGB"))
+ cs = pdf_devicergb;
+ else if (!strcmp(fz_toname(obj), "DeviceCMYK"))
+ cs = pdf_devicecmyk;
+ else
+ {
+ fz_obj *dict = fz_dictgets(rdb, "ColorSpace");
+ if (!dict)
+ return fz_throw("syntaxerror: missing colorspace resource");
+ obj = fz_dictget(dict, obj);
+ if (!obj)
+ return fz_throw("syntaxerror: missing colorspace resource");
+ if (fz_isindirect(obj))
+ cs = pdf_findresource(xref->rcolorspace, obj);
+ else
+ return fz_throw("syntaxerror: inline colorspace in dict");
+ if (!cs)
+ return fz_throw("syntaxerror: missing colorspace resource");
+ }
+
+ error = pdf_setcolorspace(csi, what, cs);
+ if (error) return error;
+ }
}
else if (!strcmp(buf, "sc") || !strcmp(buf, "scn"))
{
- if (gstate->fill.kind == PDF_MINDEXED && csi->top != 1)
- goto syntaxerror;
- else if (csi->top != gstate->fill.cs->n)
- goto syntaxerror;
-
- for (i = 0; i < csi->top; i++)
- v[i] = fz_toreal(csi->stack[i]);
-
- error = pdf_setcolor(csi, PDF_MFILL, v);
- if (error) return error;
+ what = PDF_MFILL;
+ goto Lsetcolor;
}
else if (!strcmp(buf, "SC") || !strcmp(buf, "SCN"))
{
- if (gstate->stroke.kind == PDF_MINDEXED && csi->top != 1)
- goto syntaxerror;
- else if (csi->top != gstate->stroke.cs->n)
- goto syntaxerror;
+ pdf_material *mat;
+ pdf_pattern *pat;
+ fz_obj *dict;
+ fz_obj *obj;
- for (i = 0; i < csi->top; i++)
- v[i] = fz_toreal(csi->stack[i]);
+ what = PDF_MSTROKE;
- error = pdf_setcolor(csi, PDF_MSTROKE, v);
- if (error) return error;
+Lsetcolor:
+ mat = what == PDF_MSTROKE ? &gstate->stroke : &gstate->fill;
+
+ if (fz_isname(csi->stack[csi->top - 1]))
+ mat->kind = PDF_MPATTERN;
+
+ switch (mat->kind)
+ {
+ case PDF_MNONE:
+ return fz_throw("syntaxerror: cannot set color in mask objects");
+
+ case PDF_MINDEXED:
+ if (csi->top != 1)
+ goto syntaxerror;
+ v[0] = fz_toreal(csi->stack[0]);
+ error = pdf_setcolor(csi, what, v);
+ if (error) return error;
+ break;
+
+ case PDF_MCOLOR:
+ case PDF_MLAB:
+ if (csi->top != mat->cs->n)
+ goto syntaxerror;
+ for (i = 0; i < csi->top; i++)
+ v[i] = fz_toreal(csi->stack[i]);
+ error = pdf_setcolor(csi, what, v);
+ if (error) return error;
+ break;
+
+ case PDF_MPATTERN:
+ for (i = 0; i < csi->top - 1; i++)
+ v[i] = fz_toreal(csi->stack[i]);
+
+ dict = fz_dictgets(rdb, "Pattern");
+ if (!dict)
+ return fz_throw("syntaxerror: missing pattern resource");
+
+ obj = fz_dictget(dict, csi->stack[csi->top - 1]);
+ if (!obj)
+ return fz_throw("syntaxerror: missing pattern resource");
+
+ pat = pdf_findresource(xref->rpattern, obj);
+ if (!pat)
+ return fz_throw("syntaxerror: missing pattern resource");
+
+ error = pdf_setpattern(csi, what, pat, csi->top == 1 ? nil : v);
+ if (error) return error;
+ break;
+ }
}
else if (!strcmp(buf, "rg"))
diff --git a/mupdf/page.c b/mupdf/page.c
index 11ab6727..f6c180f3 100644
--- a/mupdf/page.c
+++ b/mupdf/page.c
@@ -23,12 +23,22 @@ loadpagecontents(fz_tree **treep, pdf_xref *xref, fz_obj *rdb, fz_obj *ref)
fz_error *error;
fz_obj *obj;
pdf_csi *csi;
+ fz_node *node;
+ float white = 1.0;
int i;
error = pdf_newcsi(&csi, 0);
if (error)
return error;
+ error = fz_newcolornode(&node, pdf_devicegray, 1, &white);
+ if (error)
+ {
+ pdf_dropcsi(csi);
+ return error;
+ }
+ fz_insertnode(csi->tree->root, node);
+
if (fz_isindirect(ref))
{
error = pdf_loadindirect(&obj, xref, ref);
diff --git a/mupdf/pattern.c b/mupdf/pattern.c
new file mode 100644
index 00000000..fae71c45
--- /dev/null
+++ b/mupdf/pattern.c
@@ -0,0 +1,116 @@
+#include <fitz.h>
+#include <mupdf.h>
+
+void
+pdf_droppattern(pdf_pattern *pat)
+{
+ if (pat->tree)
+ fz_droptree(pat->tree);
+ fz_free(pat);
+}
+
+fz_error *
+pdf_loadpattern(pdf_pattern **patp, pdf_xref *xref, fz_obj *dict, fz_obj *stmref)
+{
+ fz_error *error;
+ pdf_pattern *pat;
+ fz_obj *resources;
+ fz_obj *obj;
+ pdf_csi *csi;
+
+printf("loading pattern %d %d\n", fz_tonum(stmref), fz_togen(stmref));
+
+ pat = fz_malloc(sizeof(pdf_pattern));
+ if (!pat)
+ return fz_outofmem;
+
+ pat->tree = nil;
+ pat->ismask = fz_toint(fz_dictgets(dict, "PaintType")) == 2;
+ pat->xstep = fz_toreal(fz_dictgets(dict, "XStep"));
+ pat->ystep = fz_toreal(fz_dictgets(dict, "YStep"));
+
+ obj = fz_dictgets(dict, "BBox");
+ pat->bbox.min.x = fz_toreal(fz_arrayget(obj, 0));
+ pat->bbox.min.y = fz_toreal(fz_arrayget(obj, 1));
+ pat->bbox.max.x = fz_toreal(fz_arrayget(obj, 2));
+ pat->bbox.max.y = fz_toreal(fz_arrayget(obj, 3));
+
+ obj = fz_dictgets(dict, "Matrix");
+ if (obj)
+ {
+ pat->matrix.a = fz_toreal(fz_arrayget(obj, 0));
+ pat->matrix.b = fz_toreal(fz_arrayget(obj, 1));
+ pat->matrix.c = fz_toreal(fz_arrayget(obj, 2));
+ pat->matrix.d = fz_toreal(fz_arrayget(obj, 3));
+ pat->matrix.e = fz_toreal(fz_arrayget(obj, 4));
+ pat->matrix.f = fz_toreal(fz_arrayget(obj, 5));
+ }
+ else
+ {
+ pat->matrix = fz_identity();
+ }
+
+printf(" mask %d\n", pat->ismask);
+printf(" xstep %g\n", pat->xstep);
+printf(" ystep %g\n", pat->ystep);
+
+ /*
+ * Resources
+ */
+
+ obj = fz_dictgets(dict, "Resources");
+ if (!obj) {
+ error = fz_throw("syntaxerror: Pattern missing Resources");
+ goto cleanup;
+ }
+
+ error = pdf_resolve(&obj, xref);
+ if (error)
+ goto cleanup;
+
+ error = pdf_loadresources(&resources, xref, obj);
+
+ fz_dropobj(obj);
+
+ if (error)
+ goto cleanup;
+
+ /*
+ * Content stream
+ */
+
+ error = pdf_newcsi(&csi, pat->ismask);
+ if (error)
+ goto cleanup;
+
+ error = pdf_openstream(xref, fz_tonum(stmref), fz_togen(stmref));
+ if (error)
+ goto cleanup2;
+
+ error = pdf_runcsi(csi, xref, resources, xref->stream);
+
+ pdf_closestream(xref);
+
+ if (error)
+ goto cleanup2;
+
+ if (csi->tree)
+ fz_debugtree(csi->tree);
+
+ pat->tree = csi->tree;
+ csi->tree = nil;
+
+ pdf_dropcsi(csi);
+
+ fz_dropobj(resources);
+
+ *patp = pat;
+ return nil;
+
+cleanup2:
+ pdf_dropcsi(csi);
+cleanup:
+ pdf_droppattern(pat);
+ return error;
+}
+
diff --git a/mupdf/resources.c b/mupdf/resources.c
index 7051c04d..b1be53ba 100644
--- a/mupdf/resources.c
+++ b/mupdf/resources.c
@@ -33,6 +33,10 @@ indirect references so we end up with a stylized structure:
/Cs0 5 0 R
/Cs1 [ /ICCBased 5 0 R ] % /Cs1 -1 0 R ???
/Cs2 [ /CalRGB << ... >> ] % /Cs2 -2 0 R ???
+ /CsX [ /Pattern /DeviceRGB ] % eep!
+ >>
+ /Pattern <<
+ /Pat0 20 0 R
>>
/XObject <<
/Im0 10 0 R
@@ -83,6 +87,60 @@ preloadcolorspace(pdf_xref *xref, fz_obj *ref)
}
static fz_error *
+preloadpattern(pdf_xref *xref, fz_obj *ref)
+{
+ fz_error *error;
+ pdf_rsrc *rsrc;
+ fz_obj *obj;
+ fz_obj *type;
+
+ if (pdf_findresource(xref->rpattern, ref))
+ return nil;
+// if (pdf_findresource(xref->rshading, ref))
+// return nil;
+
+ rsrc = fz_malloc(sizeof(pdf_rsrc));
+ if (!rsrc)
+ return fz_outofmem;
+ rsrc->oid = fz_tonum(ref);
+ rsrc->gen = fz_togen(ref);
+
+ error = pdf_loadindirect(&obj, xref, ref);
+ if (error)
+ return error;
+
+ type = fz_dictgets(obj, "PatternType");
+
+ if (fz_toint(type) == 1)
+ {
+ error = pdf_loadpattern((pdf_pattern**)&rsrc->val, xref, obj, ref);
+ fz_dropobj(obj);
+ if (error) {
+ fz_free(rsrc);
+ return error;
+ }
+ rsrc->next = xref->rpattern;
+ xref->rpattern = rsrc;
+ return nil;
+ }
+
+ else if (fz_toint(type) == 2)
+ {
+ // load shading
+ fz_dropobj(obj);
+ fz_free(rsrc);
+ return fz_throw("jeong was not here...");
+ }
+
+ else
+ {
+ fz_dropobj(obj);
+ fz_free(rsrc);
+ return fz_throw("syntaxerror: unknown Pattern type");
+ }
+}
+
+static fz_error *
preloadxobject(pdf_xref *xref, fz_obj *ref)
{
fz_error *error;
@@ -307,6 +365,25 @@ pdf_loadresources(fz_obj **rdbp, pdf_xref *xref, fz_obj *orig)
}
/*
+ * Load Patterns (and Shadings)
+ */
+
+ dict = fz_dictgets(copy, "Pattern");
+ if (dict)
+ {
+ for (i = 0; i < fz_dictlen(dict); i++)
+ {
+ obj = fz_dictgetval(dict, i);
+ if (fz_isindirect(obj))
+ {
+ error = preloadpattern(xref, obj);
+ if (error)
+ return error;
+ }
+ }
+ }
+
+ /*
* Load XObjects and Images
*/
diff --git a/mupdf/type3.c b/mupdf/type3.c
index edc205cf..ec34d090 100644
--- a/mupdf/type3.c
+++ b/mupdf/type3.c
@@ -62,22 +62,10 @@ t3render(fz_glyph *glyph, fz_font *fzfont, int cid, fz_matrix trm)
ctm = fz_concat(font->matrix, trm);
bbox = fz_boundtree(tree, ctm);
-printf("glyph bbox %g %g %g %g\n",
- bbox.min.x,
- bbox.min.y,
- bbox.max.x,
- bbox.max.y);
-
- bbox.min.x = fz_floor(bbox.min.x - 5.5);
- bbox.min.y = fz_floor(bbox.min.y - 5.5);
- bbox.max.x = fz_ceil(bbox.max.x + 5.5);
- bbox.max.y = fz_ceil(bbox.max.y + 5.5);
-
-printf("glyph bbox %g %g %g %g\n",
- bbox.min.x,
- bbox.min.y,
- bbox.max.x,
- bbox.max.y);
+ bbox.min.x = fz_floor(bbox.min.x - 0.5);
+ bbox.min.y = fz_floor(bbox.min.y - 0.5);
+ bbox.max.x = fz_ceil(bbox.max.x + 0.5);
+ bbox.max.y = fz_ceil(bbox.max.y + 0.5);
error = fz_newrenderer(&gc, nil);
if (error)
@@ -89,8 +77,6 @@ printf("glyph bbox %g %g %g %g\n",
assert(pixmap->n == 1);
-printf("pixmap %d %d\n", pixmap->x, pixmap->y);
-
glyph->lsb = pixmap->x;
glyph->top = pixmap->h + pixmap->y;
glyph->w = pixmap->w;
diff --git a/render/pixmap.c b/render/pixmap.c
index 634fe8f6..ed64769f 100644
--- a/render/pixmap.c
+++ b/render/pixmap.c
@@ -82,25 +82,46 @@ fz_blendover(fz_pixmap *src, fz_pixmap *dst)
{
int x, y, k;
- assert(dst->n == src->n);
+ assert(dst->n == src->n || src->n == 1);
assert(dst->w == src->w);
assert(dst->h == src->h);
unsigned char *s = src->samples;
unsigned char *d = dst->samples;
- for (y = 0; y < dst->h; y++)
+ if (dst->n == src->n)
{
- for (x = 0; x < dst->w; x++)
+ for (y = 0; y < dst->h; y++)
{
- int sa = s[0];
- int ssa = 255 - sa;
+ for (x = 0; x < dst->w; x++)
+ {
+ int sa = s[0];
+ int ssa = 255 - sa;
- for (k = 0; k < dst->n; k++)
- d[k] = s[k] + fz_mul255(d[k], ssa);
+ for (k = 0; k < dst->n; k++)
+ d[k] = s[k] + fz_mul255(d[k], ssa);
- s += src->n;
- d += dst->n;
+ s += src->n;
+ d += dst->n;
+ }
+ }
+ }
+ else if (src->n == 1)
+ {
+ for (y = 0; y < dst->h; y++)
+ {
+ for (x = 0; x < dst->w; x++)
+ {
+ int sa = s[0];
+ int ssa = 255 - sa;
+
+ d[0] = s[0] + fz_mul255(d[0], ssa);
+ for (k = 1; k < dst->n; k++)
+ d[k] = 0 + fz_mul255(d[k], ssa);
+
+ s += src->n;
+ d += dst->n;
+ }
}
}
}
@@ -111,7 +132,6 @@ fz_blendmask(fz_pixmap *dst, fz_pixmap *src, fz_pixmap *msk)
int x, y, k;
assert(src->n == dst->n);
- assert(msk->n == 1);
unsigned char *d = dst->samples;
unsigned char *s = src->samples;
@@ -125,7 +145,7 @@ fz_blendmask(fz_pixmap *dst, fz_pixmap *src, fz_pixmap *msk)
{
*d++ = fz_mul255(*s++, *m);
}
- m++;
+ m += msk->n;
}
}
}
diff --git a/render/render.c b/render/render.c
index dd4b543d..e1e0e04d 100644
--- a/render/render.c
+++ b/render/render.c
@@ -277,6 +277,8 @@ fz_rendernode(fz_renderer *gc, fz_node *node, fz_matrix ctm)
return fz_rendertext(gc, (fz_textnode*)node, ctm);
case FZ_NIMAGE:
return fz_renderimage(gc, (fz_imagenode*)node, ctm);
+ case FZ_NLINK:
+ return fz_rendernode(gc, ((fz_linknode*)node)->tree->root, ctm);
default:
return nil;
}
diff --git a/render/renderimage.c b/render/renderimage.c
index e2c98eb1..e4daae57 100644
--- a/render/renderimage.c
+++ b/render/renderimage.c
@@ -5,7 +5,6 @@
void fz_gammapixmap(fz_pixmap *pix, float gamma);
#define LERP(a,b,t) (a + (((b - a) * t) >> 16))
-#define OUTSIDE(x,a,b) (x < a || x >= b)
static inline int getcomp(fz_pixmap *pix, int u, int v, int k)
{
@@ -13,8 +12,8 @@ static inline int getcomp(fz_pixmap *pix, int u, int v, int k)
return 0;
if (v < 0 || v >= pix->h)
return 0;
- u = CLAMP(u, 0, pix->w - 1);
- v = CLAMP(v, 0, pix->h - 1);
+// u = CLAMP(u, 0, pix->w - 1);
+// v = CLAMP(v, 0, pix->h - 1);
return pix->samples[ (v * pix->w + u) * pix->n + k ];
}
@@ -75,10 +74,10 @@ overscanrgb(fz_matrix *invmat, fz_pixmap *dst, fz_pixmap *src, int y, int x0, in
int sg = sampleimage(src, u, v, 2);
int sb = sampleimage(src, u, v, 3);
- int da = dst->samples[ (y * dst->w + x) * dst->n + 0 ];
- int dr = dst->samples[ (y * dst->w + x) * dst->n + 1 ];
- int dg = dst->samples[ (y * dst->w + x) * dst->n + 2 ];
- int db = dst->samples[ (y * dst->w + x) * dst->n + 3 ];
+ int da = dst->samples[ ((y-dst->y) * dst->w + x-dst->x) * dst->n + 0 ];
+ int dr = dst->samples[ ((y-dst->y) * dst->w + x-dst->x) * dst->n + 1 ];
+ int dg = dst->samples[ ((y-dst->y) * dst->w + x-dst->x) * dst->n + 2 ];
+ int db = dst->samples[ ((y-dst->y) * dst->w + x-dst->x) * dst->n + 3 ];
int ssa = 255 - sa;
@@ -87,10 +86,10 @@ overscanrgb(fz_matrix *invmat, fz_pixmap *dst, fz_pixmap *src, int y, int x0, in
dg = sg + fz_mul255(dg, ssa);
db = sb + fz_mul255(db, ssa);
- dst->samples[ (y * dst->w + x) * dst->n + 0 ] = sa;
- dst->samples[ (y * dst->w + x) * dst->n + 1 ] = sr;
- dst->samples[ (y * dst->w + x) * dst->n + 2 ] = sg;
- dst->samples[ (y * dst->w + x) * dst->n + 3 ] = sb;
+ dst->samples[ ((y-dst->y) * dst->w + x-dst->x) * dst->n + 0 ] = da;
+ dst->samples[ ((y-dst->y) * dst->w + x-dst->x) * dst->n + 1 ] = dr;
+ dst->samples[ ((y-dst->y) * dst->w + x-dst->x) * dst->n + 2 ] = dg;
+ dst->samples[ ((y-dst->y) * dst->w + x-dst->x) * dst->n + 3 ] = db;
u += du;
v += dv;
@@ -131,9 +130,9 @@ drawtile(fz_renderer *gc, fz_pixmap *out, fz_pixmap *tile, fz_matrix ctm, int ov
for (y = top; y <= bot; y++)
{
if (over && tile->n == 4)
- overscanrgb(&invmat, out, tile, y, x0, x1);
+ overscanrgb(&invmat, out, tile, y, x0, x1 + 1);
else
- drawscan(&invmat, out, tile, y, x0, x1);
+ drawscan(&invmat, out, tile, y, x0, x1 + 1);
}
return nil;