summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fitz/dev_draw.c47
-rw-r--r--fitz/dev_list.c15
-rw-r--r--fitz/dev_null.c2
-rw-r--r--fitz/dev_text.c2
-rw-r--r--fitz/dev_trace.c3
-rw-r--r--fitz/fitz_res.h4
-rw-r--r--mupdf/mupdf.h1
-rw-r--r--mupdf/pdf_build.c7
-rw-r--r--mupdf/pdf_interpret.c2
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"))