diff options
-rw-r--r-- | fitz/dev_draw.c | 47 | ||||
-rw-r--r-- | fitz/dev_list.c | 15 | ||||
-rw-r--r-- | fitz/dev_null.c | 2 | ||||
-rw-r--r-- | fitz/dev_text.c | 2 | ||||
-rw-r--r-- | fitz/dev_trace.c | 3 | ||||
-rw-r--r-- | fitz/fitz_res.h | 4 | ||||
-rw-r--r-- | mupdf/mupdf.h | 1 | ||||
-rw-r--r-- | mupdf/pdf_build.c | 7 | ||||
-rw-r--r-- | mupdf/pdf_interpret.c | 2 |
9 files changed, 56 insertions, 27 deletions
diff --git a/fitz/dev_draw.c b/fitz/dev_draw.c index 631454e3..532df55d 100644 --- a/fitz/dev_draw.c +++ b/fitz/dev_draw.c @@ -387,7 +387,7 @@ fz_drawstroketext(void *user, fz_text *text, fz_strokestate *stroke, fz_matrix c } static void -fz_drawcliptext(void *user, fz_text *text, fz_matrix ctm) +fz_drawcliptext(void *user, fz_text *text, fz_matrix ctm, int accumulate) { fz_drawdevice *dev = user; fz_bbox clip, bbox; @@ -396,6 +396,10 @@ fz_drawcliptext(void *user, fz_text *text, fz_matrix ctm) fz_pixmap *glyph; int i, x, y, gid; + /* If accumulate == 0 then this text object is guaranteed complete */ + /* If accumulate == 1 then this text object is the first (or only) in a sequence */ + /* If accumulate == 2 then this text object is a continuation */ + if (dev->cliptop == MAXCLIP) { fz_warn("assert: too many clip masks on stack"); @@ -407,14 +411,30 @@ fz_drawcliptext(void *user, fz_text *text, fz_matrix ctm) clip.x1 = dev->dest->x + dev->dest->w; clip.y1 = dev->dest->y + dev->dest->h; - bbox = fz_roundrect(fz_boundtext(text, ctm)); - bbox = fz_intersectbbox(bbox, clip); + if (accumulate == 0) + { + /* make the mask the exact size needed */ + bbox = fz_roundrect(fz_boundtext(text, ctm)); + bbox = fz_intersectbbox(bbox, clip); + } + else + { + /* be conservative about the size of the mask needed */ + bbox = clip; + } - mask = fz_newpixmapwithrect(nil, bbox); - dest = fz_newpixmapwithrect(dev->model, bbox); + if (accumulate == 0 || accumulate == 1) + { + mask = fz_newpixmapwithrect(nil, bbox); + dest = fz_newpixmapwithrect(dev->model, bbox); - memset(mask->samples, 0, mask->w * mask->h * mask->n); - memset(dest->samples, 0, dest->w * dest->h * dest->n); + memset(mask->samples, 0, mask->w * mask->h * mask->n); + memset(dest->samples, 0, dest->w * dest->h * dest->n); + } + else + { + mask = dev->clipstack[dev->cliptop-1].mask; + } if (!fz_isemptyrect(bbox)) { @@ -440,16 +460,19 @@ fz_drawcliptext(void *user, fz_text *text, fz_matrix ctm) } } - dev->clipstack[dev->cliptop].mask = mask; - dev->clipstack[dev->cliptop].dest = dev->dest; - dev->dest = dest; - dev->cliptop++; + if (accumulate == 0 || accumulate == 1) + { + dev->clipstack[dev->cliptop].mask = mask; + dev->clipstack[dev->cliptop].dest = dev->dest; + dev->dest = dest; + dev->cliptop++; + } } static void fz_drawclipstroketext(void *user, fz_text *text, fz_strokestate *stroke, fz_matrix ctm) { - fz_drawcliptext(user, text, ctm); + fz_drawcliptext(user, text, ctm, 0); } static void diff --git a/fitz/dev_list.c b/fitz/dev_list.c index 2abdabbf..88a0bdf5 100644 --- a/fitz/dev_list.c +++ b/fitz/dev_list.c @@ -12,7 +12,7 @@ fz_newdisplaynode(fz_displaycommand cmd, fz_matrix ctm, node->next = nil; node->item.path = nil; node->stroke = nil; - node->evenodd = 0; + node->flag = 0; node->ctm = ctm; if (colorspace) { @@ -95,7 +95,7 @@ fz_listfillpath(void *user, fz_path *path, int evenodd, fz_matrix ctm, fz_displaynode *node; node = fz_newdisplaynode(FZ_CMDFILLPATH, ctm, colorspace, color, alpha); node->item.path = fz_clonepath(path); - node->evenodd = evenodd; + node->flag = evenodd; fz_appenddisplaynode(user, node); } @@ -116,7 +116,7 @@ fz_listclippath(void *user, fz_path *path, int evenodd, fz_matrix ctm) fz_displaynode *node; node = fz_newdisplaynode(FZ_CMDCLIPPATH, ctm, nil, nil, 0.0); node->item.path = fz_clonepath(path); - node->evenodd = evenodd; + node->flag = evenodd; fz_appenddisplaynode(user, node); } @@ -152,11 +152,12 @@ fz_liststroketext(void *user, fz_text *text, fz_strokestate *stroke, fz_matrix c } static void -fz_listcliptext(void *user, fz_text *text, fz_matrix ctm) +fz_listcliptext(void *user, fz_text *text, fz_matrix ctm, int accumulate) { fz_displaynode *node; node = fz_newdisplaynode(FZ_CMDCLIPTEXT, ctm, nil, nil, 0.0); node->item.text = fz_clonetext(text); + node->flag = accumulate; fz_appenddisplaynode(user, node); } @@ -281,7 +282,7 @@ fz_executedisplaylist(fz_displaylist *list, fz_device *dev, fz_matrix topctm) switch (node->cmd) { case FZ_CMDFILLPATH: - dev->fillpath(dev->user, node->item.path, node->evenodd, ctm, + dev->fillpath(dev->user, node->item.path, node->flag, ctm, node->colorspace, node->color, node->alpha); break; case FZ_CMDSTROKEPATH: @@ -289,7 +290,7 @@ fz_executedisplaylist(fz_displaylist *list, fz_device *dev, fz_matrix topctm) node->colorspace, node->color, node->alpha); break; case FZ_CMDCLIPPATH: - dev->clippath(dev->user, node->item.path, node->evenodd, ctm); + dev->clippath(dev->user, node->item.path, node->flag, ctm); break; case FZ_CMDCLIPSTROKEPATH: dev->clipstrokepath(dev->user, node->item.path, node->stroke, ctm); @@ -303,7 +304,7 @@ fz_executedisplaylist(fz_displaylist *list, fz_device *dev, fz_matrix topctm) node->colorspace, node->color, node->alpha); break; case FZ_CMDCLIPTEXT: - dev->cliptext(dev->user, node->item.text, ctm); + dev->cliptext(dev->user, node->item.text, ctm, node->flag); break; case FZ_CMDCLIPSTROKETEXT: dev->clipstroketext(dev->user, node->item.text, node->stroke, ctm); diff --git a/fitz/dev_null.c b/fitz/dev_null.c index d7a95db3..9e4ee764 100644 --- a/fitz/dev_null.c +++ b/fitz/dev_null.c @@ -7,7 +7,7 @@ static void fz_nullclippath(void *user, fz_path *path, int evenodd, fz_matrix ct static void fz_nullclipstrokepath(void *user, fz_path *path, fz_strokestate *stroke, fz_matrix ctm) {} static void fz_nullfilltext(void *user, fz_text *text, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha) {} static void fz_nullstroketext(void *user, fz_text *text, fz_strokestate *stroke, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha) {} -static void fz_nullcliptext(void *user, fz_text *text, fz_matrix ctm) {} +static void fz_nullcliptext(void *user, fz_text *text, fz_matrix ctm, int accumulate) {} static void fz_nullclipstroketext(void *user, fz_text *text, fz_strokestate *stroke, fz_matrix ctm) {} static void fz_nullignoretext(void *user, fz_text *text, fz_matrix ctm) {} static void fz_nullpopclip(void *user) {} diff --git a/fitz/dev_text.c b/fitz/dev_text.c index 8c8e869c..57db9e8a 100644 --- a/fitz/dev_text.c +++ b/fitz/dev_text.c @@ -262,7 +262,7 @@ fz_textstroketext(void *user, fz_text *text, fz_strokestate *stroke, fz_matrix c } static void -fz_textcliptext(void *user, fz_text *text, fz_matrix ctm) +fz_textcliptext(void *user, fz_text *text, fz_matrix ctm, int accumulate) { fz_textdevice *tdev = user; fz_textextractspan(&tdev->span, text, ctm, &tdev->point); diff --git a/fitz/dev_trace.c b/fitz/dev_trace.c index eb87764b..69bc00c4 100644 --- a/fitz/dev_trace.c +++ b/fitz/dev_trace.c @@ -154,10 +154,11 @@ fz_tracestroketext(void *user, fz_text *text, fz_strokestate *stroke, fz_matrix } static void -fz_tracecliptext(void *user, fz_text *text, fz_matrix ctm) +fz_tracecliptext(void *user, fz_text *text, fz_matrix ctm, int accumulate) { printf("<gsave>\n"); printf("<cliptext font=\"%s\" ", text->font->name); + printf("accumulate=\"%d\" ", accumulate); fz_tracematrix(fz_concat(ctm, text->trm)); printf(">\n"); fz_debugtext(text, 0); diff --git a/fitz/fitz_res.h b/fitz/fitz_res.h index 26cc0ae8..b9305ac1 100644 --- a/fitz/fitz_res.h +++ b/fitz/fitz_res.h @@ -84,7 +84,7 @@ struct fz_device_s void (*filltext)(void *, fz_text *, fz_matrix, fz_colorspace *, float *color, float alpha); void (*stroketext)(void *, fz_text *, fz_strokestate *, fz_matrix, fz_colorspace *, float *color, float alpha); - void (*cliptext)(void *, fz_text *, fz_matrix); + void (*cliptext)(void *, fz_text *, fz_matrix, int accumulate); void (*clipstroketext)(void *, fz_text *, fz_strokestate *, fz_matrix); void (*ignoretext)(void *, fz_text *, fz_matrix); @@ -169,7 +169,7 @@ struct fz_displaynode_s fz_pixmap *image; } item; fz_strokestate *stroke; - int evenodd; + int flag; /* evenodd, accumulate, ... */ fz_matrix ctm; fz_colorspace *colorspace; float alpha; diff --git a/mupdf/mupdf.h b/mupdf/mupdf.h index ac88a2b7..29742f22 100644 --- a/mupdf/mupdf.h +++ b/mupdf/mupdf.h @@ -649,6 +649,7 @@ struct pdf_csi_s fz_matrix tlm; fz_matrix tm; int textmode; + int accumulate; /* graphics state */ fz_matrix topctm; diff --git a/mupdf/pdf_build.c b/mupdf/pdf_build.c index 706858f7..996e1212 100644 --- a/mupdf/pdf_build.c +++ b/mupdf/pdf_build.c @@ -465,7 +465,8 @@ pdf_flushtext(pdf_csi *csi) if (doclip) { gstate->clipdepth++; - csi->dev->cliptext(csi->dev->user, text, gstate->ctm); + csi->dev->cliptext(csi->dev->user, text, gstate->ctm, csi->accumulate); + csi->accumulate = 2; } if (dofill) @@ -482,12 +483,12 @@ pdf_flushtext(pdf_csi *csi) break; case PDF_MPATTERN: bbox = fz_boundtext(text, gstate->ctm); - csi->dev->cliptext(csi->dev->user, text, gstate->ctm); + csi->dev->cliptext(csi->dev->user, text, gstate->ctm, 0); pdf_showpattern(csi, gstate->fill.pattern, bbox, PDF_MFILL); csi->dev->popclip(csi->dev->user); break; case PDF_MSHADE: - csi->dev->cliptext(csi->dev->user, text, gstate->ctm); + csi->dev->cliptext(csi->dev->user, text, gstate->ctm, 0); csi->dev->fillshade(csi->dev->user, gstate->fill.shade, gstate->ctm); csi->dev->popclip(csi->dev->user); break; diff --git a/mupdf/pdf_interpret.c b/mupdf/pdf_interpret.c index 1defd223..ffa3c0b4 100644 --- a/mupdf/pdf_interpret.c +++ b/mupdf/pdf_interpret.c @@ -22,6 +22,7 @@ pdf_newcsi(fz_device *dev, pdf_xref *xref, fz_matrix ctm) csi->tlm = fz_identity(); csi->tm = fz_identity(); csi->textmode = 0; + csi->accumulate = 1; csi->topctm = ctm; pdf_initgstate(&csi->gstate[0], ctm); @@ -731,6 +732,7 @@ Lsetcolor: if (csi->top != 0) goto syntaxerror; pdf_flushtext(csi); + csi->accumulate = 1; } else if (!strcmp(buf, "Tc")) |