diff options
author | Tor Andersson <tor@ghostscript.com> | 2004-11-05 07:57:47 +0100 |
---|---|---|
committer | Tor Andersson <tor@ghostscript.com> | 2004-11-05 07:57:47 +0100 |
commit | 24ee8c1e74d613b1ec394c7380b39349f07d47d6 (patch) | |
tree | 07c964441d983c713c05090021ce6da1e1c132fe | |
parent | cbbee31601e34f1f513a4d046d52963baebf07fa (diff) | |
download | mupdf-24ee8c1e74d613b1ec394c7380b39349f07d47d6.tar.xz |
tiling patterns
-rw-r--r-- | Jamfile | 1 | ||||
-rw-r--r-- | base/matrix.c | 19 | ||||
-rw-r--r-- | include/fitz/geometry.h | 1 | ||||
-rw-r--r-- | include/mupdf/content.h | 8 | ||||
-rw-r--r-- | include/mupdf/rsrc.h | 19 | ||||
-rw-r--r-- | include/mupdf/xref.h | 1 | ||||
-rw-r--r-- | mupdf/build.c | 131 | ||||
-rw-r--r-- | mupdf/colorspace.c | 7 | ||||
-rw-r--r-- | mupdf/interpret.c | 131 | ||||
-rw-r--r-- | mupdf/page.c | 10 | ||||
-rw-r--r-- | mupdf/pattern.c | 116 | ||||
-rw-r--r-- | mupdf/resources.c | 77 | ||||
-rw-r--r-- | mupdf/type3.c | 22 | ||||
-rw-r--r-- | render/pixmap.c | 42 | ||||
-rw-r--r-- | render/render.c | 2 | ||||
-rw-r--r-- | render/renderimage.c | 25 |
16 files changed, 520 insertions, 92 deletions
@@ -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; |